aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorjwross2011-07-13 14:39:33 (EDT)
committerJohn Ross2011-07-25 16:58:45 (EDT)
commit421152f66c0b6b912906a313e81d32424c873eb2 (patch)
tree3a1db2e4c5092a5bd70a604287bee0a4ef2ecdd2
parent2883815e408713e8fb8200d84294a2b8789943e7 (diff)
downloadrt.equinox.bundles-421152f66c0b6b912906a313e81d32424c873eb2.zip
rt.equinox.bundles-421152f66c0b6b912906a313e81d32424c873eb2.tar.gz
rt.equinox.bundles-421152f66c0b6b912906a313e81d32424c873eb2.tar.bz2
Bug 349711 - [metatype] Improve metatype implementation in equinox to
allow better use of schema extensions Initial API and implementation.
-rw-r--r--bundles/org.eclipse.equinox.metatype/.settings/.api_filters11
-rw-r--r--bundles/org.eclipse.equinox.metatype/META-INF/MANIFEST.MF7
-rw-r--r--bundles/org.eclipse.equinox.metatype/src/org/eclipse/equinox/metatype/EquinoxAttributeDefinition.java19
-rw-r--r--bundles/org.eclipse.equinox.metatype/src/org/eclipse/equinox/metatype/EquinoxMetaTypeInformation.java19
-rw-r--r--bundles/org.eclipse.equinox.metatype/src/org/eclipse/equinox/metatype/EquinoxMetaTypeService.java20
-rw-r--r--bundles/org.eclipse.equinox.metatype/src/org/eclipse/equinox/metatype/EquinoxObjectClassDefinition.java19
-rw-r--r--bundles/org.eclipse.equinox.metatype/src/org/eclipse/equinox/metatype/Extendable.java22
-rw-r--r--bundles/org.eclipse.equinox.metatype/src/org/eclipse/equinox/metatype/impl/Activator.java (renamed from bundles/org.eclipse.equinox.metatype/src/org/eclipse/equinox/metatype/Activator.java)443
-rw-r--r--bundles/org.eclipse.equinox.metatype/src/org/eclipse/equinox/metatype/impl/AttributeDefinitionImpl.java (renamed from bundles/org.eclipse.equinox.metatype/src/org/eclipse/equinox/metatype/AttributeDefinitionImpl.java)609
-rw-r--r--bundles/org.eclipse.equinox.metatype/src/org/eclipse/equinox/metatype/impl/DataParser.java (renamed from bundles/org.eclipse.equinox.metatype/src/org/eclipse/equinox/metatype/DataParser.java)1690
-rw-r--r--bundles/org.eclipse.equinox.metatype/src/org/eclipse/equinox/metatype/impl/Designate.java (renamed from bundles/org.eclipse.equinox.metatype/src/org/eclipse/equinox/metatype/Designate.java)208
-rw-r--r--bundles/org.eclipse.equinox.metatype/src/org/eclipse/equinox/metatype/impl/ExtendableHelper.java39
-rw-r--r--bundles/org.eclipse.equinox.metatype/src/org/eclipse/equinox/metatype/impl/ExternalMessages.properties (renamed from bundles/org.eclipse.equinox.metatype/src/org/eclipse/equinox/metatype/ExternalMessages.properties)72
-rw-r--r--bundles/org.eclipse.equinox.metatype/src/org/eclipse/equinox/metatype/impl/FragmentUtils.java (renamed from bundles/org.eclipse.equinox.metatype/src/org/eclipse/equinox/metatype/FragmentUtils.java)116
-rw-r--r--bundles/org.eclipse.equinox.metatype/src/org/eclipse/equinox/metatype/impl/Icon.java (renamed from bundles/org.eclipse.equinox.metatype/src/org/eclipse/equinox/metatype/Icon.java)144
-rw-r--r--bundles/org.eclipse.equinox.metatype/src/org/eclipse/equinox/metatype/impl/LocalizationElement.java (renamed from bundles/org.eclipse.equinox.metatype/src/org/eclipse/equinox/metatype/LocalizationElement.java)110
-rw-r--r--bundles/org.eclipse.equinox.metatype/src/org/eclipse/equinox/metatype/impl/LogMessages.properties (renamed from bundles/org.eclipse.equinox.metatype/src/org/eclipse/equinox/metatype/LogMessages.properties)34
-rw-r--r--bundles/org.eclipse.equinox.metatype/src/org/eclipse/equinox/metatype/impl/LogTracker.java (renamed from bundles/org.eclipse.equinox.metatype/src/org/eclipse/equinox/metatype/LogTracker.java)354
-rw-r--r--bundles/org.eclipse.equinox.metatype/src/org/eclipse/equinox/metatype/impl/LogTrackerMsg.java (renamed from bundles/org.eclipse.equinox.metatype/src/org/eclipse/equinox/metatype/LogTrackerMsg.java)56
-rw-r--r--bundles/org.eclipse.equinox.metatype/src/org/eclipse/equinox/metatype/impl/MetaTypeInformationImpl.java (renamed from bundles/org.eclipse.equinox.metatype/src/org/eclipse/equinox/metatype/MetaTypeInformationImpl.java)177
-rw-r--r--bundles/org.eclipse.equinox.metatype/src/org/eclipse/equinox/metatype/impl/MetaTypeMsg.java (renamed from bundles/org.eclipse.equinox.metatype/src/org/eclipse/equinox/metatype/MetaTypeMsg.java)90
-rw-r--r--bundles/org.eclipse.equinox.metatype/src/org/eclipse/equinox/metatype/impl/MetaTypeProviderImpl.java (renamed from bundles/org.eclipse.equinox.metatype/src/org/eclipse/equinox/metatype/MetaTypeProviderImpl.java)475
-rw-r--r--bundles/org.eclipse.equinox.metatype/src/org/eclipse/equinox/metatype/impl/MetaTypeProviderTracker.java (renamed from bundles/org.eclipse.equinox.metatype/src/org/eclipse/equinox/metatype/MetaTypeProviderTracker.java)476
-rw-r--r--bundles/org.eclipse.equinox.metatype/src/org/eclipse/equinox/metatype/impl/MetaTypeServiceImpl.java (renamed from bundles/org.eclipse.equinox.metatype/src/org/eclipse/equinox/metatype/MetaTypeServiceImpl.java)244
-rw-r--r--bundles/org.eclipse.equinox.metatype/src/org/eclipse/equinox/metatype/impl/ObjectClassDefinitionImpl.java (renamed from bundles/org.eclipse.equinox.metatype/src/org/eclipse/equinox/metatype/ObjectClassDefinitionImpl.java)633
-rw-r--r--bundles/org.eclipse.equinox.metatype/src/org/eclipse/equinox/metatype/impl/ValueTokenizer.java (renamed from bundles/org.eclipse.equinox.metatype/src/org/eclipse/equinox/metatype/ValueTokenizer.java)548
26 files changed, 3495 insertions, 3140 deletions
diff --git a/bundles/org.eclipse.equinox.metatype/.settings/.api_filters b/bundles/org.eclipse.equinox.metatype/.settings/.api_filters
deleted file mode 100644
index 0da0b7a..0000000
--- a/bundles/org.eclipse.equinox.metatype/.settings/.api_filters
+++ /dev/null
@@ -1,11 +0,0 @@
-<?xml version="1.0" encoding="UTF-8" standalone="no"?>
-<component id="org.eclipse.equinox.metatype" version="2">
- <resource path="src/org/eclipse/equinox/metatype/LogTracker.java" type="org.eclipse.equinox.metatype.LogTracker">
- <filter id="574619656">
- <message_arguments>
- <message_argument value="LogService"/>
- <message_argument value="LogTracker"/>
- </message_arguments>
- </filter>
- </resource>
-</component>
diff --git a/bundles/org.eclipse.equinox.metatype/META-INF/MANIFEST.MF b/bundles/org.eclipse.equinox.metatype/META-INF/MANIFEST.MF
index 8ad6a50..c24a144 100644
--- a/bundles/org.eclipse.equinox.metatype/META-INF/MANIFEST.MF
+++ b/bundles/org.eclipse.equinox.metatype/META-INF/MANIFEST.MF
@@ -1,8 +1,8 @@
Bundle-ManifestVersion: 2
Bundle-Name: %bundleName
-Bundle-Version: 1.1.100.qualifier
+Bundle-Version: 1.2.0.qualifier
Bundle-SymbolicName: org.eclipse.equinox.metatype
-Bundle-Activator: org.eclipse.equinox.metatype.Activator
+Bundle-Activator: org.eclipse.equinox.metatype.impl.Activator
Import-Package: javax.xml.parsers,
org.eclipse.osgi.util;version="[1.1,2.0)",
org.osgi.framework;version="[1.6,2.0)",
@@ -13,7 +13,8 @@ Import-Package: javax.xml.parsers,
org.osgi.util.tracker;version="[1.5,2.0)",
org.xml.sax,
org.xml.sax.helpers
-Export-Package: org.eclipse.equinox.metatype;x-internal:=true
+Export-Package: org.eclipse.equinox.metatype;version="1.2.0",
+ org.eclipse.equinox.metatype.impl;version="1.2.0";x-internal:=true
Bundle-Vendor: %bundleVendor
Bundle-Localization: plugin
Bundle-RequiredExecutionEnvironment: J2SE-1.5,
diff --git a/bundles/org.eclipse.equinox.metatype/src/org/eclipse/equinox/metatype/EquinoxAttributeDefinition.java b/bundles/org.eclipse.equinox.metatype/src/org/eclipse/equinox/metatype/EquinoxAttributeDefinition.java
new file mode 100644
index 0000000..fb0e85c
--- /dev/null
+++ b/bundles/org.eclipse.equinox.metatype/src/org/eclipse/equinox/metatype/EquinoxAttributeDefinition.java
@@ -0,0 +1,19 @@
+/*******************************************************************************
+ * Copyright (c) 2011 IBM Corporation and others
+ * All rights reserved. This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License v1.0 which
+ * accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ ******************************************************************************/
+package org.eclipse.equinox.metatype;
+
+import org.osgi.service.metatype.AttributeDefinition;
+
+/**
+ *
+ * @since 1.2
+ *
+ */
+public interface EquinoxAttributeDefinition extends AttributeDefinition, Extendable {
+ // Empty interface to support extendable attribute definitions.
+}
diff --git a/bundles/org.eclipse.equinox.metatype/src/org/eclipse/equinox/metatype/EquinoxMetaTypeInformation.java b/bundles/org.eclipse.equinox.metatype/src/org/eclipse/equinox/metatype/EquinoxMetaTypeInformation.java
new file mode 100644
index 0000000..70b79a7
--- /dev/null
+++ b/bundles/org.eclipse.equinox.metatype/src/org/eclipse/equinox/metatype/EquinoxMetaTypeInformation.java
@@ -0,0 +1,19 @@
+/*******************************************************************************
+ * Copyright (c) 2011 IBM Corporation and others
+ * All rights reserved. This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License v1.0 which
+ * accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ ******************************************************************************/
+package org.eclipse.equinox.metatype;
+
+import org.osgi.service.metatype.MetaTypeInformation;
+
+/**
+ *
+ * @since 1.2
+ *
+ */
+public interface EquinoxMetaTypeInformation extends MetaTypeInformation {
+ EquinoxObjectClassDefinition getObjectClassDefinition(String id, String locale);
+}
diff --git a/bundles/org.eclipse.equinox.metatype/src/org/eclipse/equinox/metatype/EquinoxMetaTypeService.java b/bundles/org.eclipse.equinox.metatype/src/org/eclipse/equinox/metatype/EquinoxMetaTypeService.java
new file mode 100644
index 0000000..a9ba9c0
--- /dev/null
+++ b/bundles/org.eclipse.equinox.metatype/src/org/eclipse/equinox/metatype/EquinoxMetaTypeService.java
@@ -0,0 +1,20 @@
+/*******************************************************************************
+ * Copyright (c) 2011 IBM Corporation and others
+ * All rights reserved. This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License v1.0 which
+ * accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ ******************************************************************************/
+package org.eclipse.equinox.metatype;
+
+import org.osgi.framework.Bundle;
+import org.osgi.service.metatype.MetaTypeService;
+
+/**
+ *
+ * @since 1.2
+ *
+ */
+public interface EquinoxMetaTypeService extends MetaTypeService {
+ EquinoxMetaTypeInformation getMetaTypeInformation(Bundle bundle);
+}
diff --git a/bundles/org.eclipse.equinox.metatype/src/org/eclipse/equinox/metatype/EquinoxObjectClassDefinition.java b/bundles/org.eclipse.equinox.metatype/src/org/eclipse/equinox/metatype/EquinoxObjectClassDefinition.java
new file mode 100644
index 0000000..f8d0e80
--- /dev/null
+++ b/bundles/org.eclipse.equinox.metatype/src/org/eclipse/equinox/metatype/EquinoxObjectClassDefinition.java
@@ -0,0 +1,19 @@
+/*******************************************************************************
+ * Copyright (c) 2011 IBM Corporation and others
+ * All rights reserved. This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License v1.0 which
+ * accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ ******************************************************************************/
+package org.eclipse.equinox.metatype;
+
+import org.osgi.service.metatype.ObjectClassDefinition;
+
+/**
+ *
+ * @since 1.2
+ *
+ */
+public interface EquinoxObjectClassDefinition extends ObjectClassDefinition, Extendable {
+ EquinoxAttributeDefinition[] getAttributeDefinitions(int filter);
+}
diff --git a/bundles/org.eclipse.equinox.metatype/src/org/eclipse/equinox/metatype/Extendable.java b/bundles/org.eclipse.equinox.metatype/src/org/eclipse/equinox/metatype/Extendable.java
new file mode 100644
index 0000000..7d52b49
--- /dev/null
+++ b/bundles/org.eclipse.equinox.metatype/src/org/eclipse/equinox/metatype/Extendable.java
@@ -0,0 +1,22 @@
+/*******************************************************************************
+ * Copyright (c) 2011 IBM Corporation and others
+ * All rights reserved. This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License v1.0 which
+ * accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ ******************************************************************************/
+package org.eclipse.equinox.metatype;
+
+import java.util.Map;
+import java.util.Set;
+
+/**
+ *
+ * @since 1.2
+ *
+ */
+public interface Extendable {
+ Map<String, String> getExtensionAttributes(String uri);
+
+ Set<String> getExtensionUris();
+}
diff --git a/bundles/org.eclipse.equinox.metatype/src/org/eclipse/equinox/metatype/Activator.java b/bundles/org.eclipse.equinox.metatype/src/org/eclipse/equinox/metatype/impl/Activator.java
index 813289d..014a36c 100644
--- a/bundles/org.eclipse.equinox.metatype/src/org/eclipse/equinox/metatype/Activator.java
+++ b/bundles/org.eclipse.equinox.metatype/src/org/eclipse/equinox/metatype/impl/Activator.java
@@ -1,188 +1,255 @@
-/*******************************************************************************
- * Copyright (c) 2005, 2010 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License v1.0
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/epl-v10.html
- *
- * Contributors:
- * IBM Corporation - initial API and implementation
- *******************************************************************************/
-package org.eclipse.equinox.metatype;
-
-import java.util.Dictionary;
-import java.util.Hashtable;
-import javax.xml.parsers.SAXParserFactory;
-import org.osgi.framework.*;
-import org.osgi.service.cm.ManagedService;
-import org.osgi.service.log.LogService;
-import org.osgi.service.metatype.MetaTypeProvider;
-import org.osgi.service.metatype.MetaTypeService;
-import org.osgi.util.tracker.ServiceTracker;
-import org.osgi.util.tracker.ServiceTrackerCustomizer;
-
-/**
- * MetaType Activator
- */
-public class Activator implements BundleActivator {
- /*
- * The following filter guarantees only services meeting the following
- * criteria will be tracked.
- *
- * (1) A ManagedService or ManagedServiceFactory registered with a
- * SERVICE_PID property. May also be registered as a MetaTypeProvider.
- * (2) A MetaTypeProvider registered with a METATYPE_PID or
- * METATYPE_FACTORY_PID property.
- *
- * Note that it's still necessary to inspect a ManagedService or
- * ManagedServiceFactory to ensure it also implements MetaTypeProvider.
- */
- private static final String FILTER = "(|(&(" + Constants.OBJECTCLASS + '=' + ManagedService.class.getName() + "*)(" + Constants.SERVICE_PID + "=*))(&(" + Constants.OBJECTCLASS + '=' + MetaTypeProvider.class.getName() + ")(|(" + MetaTypeProvider.METATYPE_PID + "=*)(" + MetaTypeProvider.METATYPE_FACTORY_PID + "=*))))"; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ //$NON-NLS-5$ //$NON-NLS-6$
- private static final String SERVICE_PID = "org.osgi.impl.service.metatype.MetaTypeService"; //$NON-NLS-1$
-
- private LogTracker logServiceTracker;
- // Could be ManagedService, ManagedServiceFactory, or MetaTypeProvider.
- // The tracker tracks all services regardless of bundle. Services are
- // filtered by bundle later in the MetaTypeProviderTracker class. It may
- // therefore be shared among multiple instances of that class.
- private ServiceTracker<Object, Object> metaTypeProviderTracker;
- private ServiceTracker<SAXParserFactory, SAXParserFactory> saxParserFactoryTracker;
-
- public void start(BundleContext context) throws InvalidSyntaxException {
- LogTracker lsTracker;
- ServiceTracker<Object, Object> mtpTracker;
- ServiceTracker<SAXParserFactory, SAXParserFactory> spfTracker;
- Filter filter = context.createFilter(FILTER);
- synchronized (this) {
- lsTracker = logServiceTracker = new LogTracker(context, System.out);
- mtpTracker = metaTypeProviderTracker = new ServiceTracker<Object, Object>(context, filter, null);
- spfTracker = saxParserFactoryTracker = new ServiceTracker<SAXParserFactory, SAXParserFactory>(context, SAXParserFactory.class, new SAXParserFactoryTrackerCustomizer(context, lsTracker, mtpTracker));
- }
- // Do this first to make logging available as early as possible.
- lsTracker.open();
- lsTracker.log(LogService.LOG_DEBUG, "====== Meta Type Service starting ! ====="); //$NON-NLS-1$
- // Do this next to make MetaTypeProviders available as early as possible.
- mtpTracker.open();
- // Do this last because it may result in the MetaTypeService being registered.
- spfTracker.open();
- }
-
- public void stop(BundleContext context) {
- ServiceTracker<SAXParserFactory, SAXParserFactory> spfTracker;
- ServiceTracker<Object, Object> mtpTracker;
- LogTracker lsTracker;
- synchronized (this) {
- spfTracker = saxParserFactoryTracker;
- // Set this to null so the SAXParserFactoryTrackerCustomizer knows
- // not to register a new MetaTypeService when removedService() is
- // called while the tracker is closing.
- saxParserFactoryTracker = null;
- mtpTracker = metaTypeProviderTracker;
- lsTracker = logServiceTracker;
- }
- lsTracker.log(LogService.LOG_DEBUG, "====== Meta Type Service stopping ! ====="); //$NON-NLS-1$
- spfTracker.close();
- mtpTracker.close();
- // Do this last to leave logging available as long as possible.
- lsTracker.close();
- }
-
- synchronized ServiceTracker<SAXParserFactory, SAXParserFactory> getSAXParserFactoryTracker() {
- return saxParserFactoryTracker;
- }
-
- private class SAXParserFactoryTrackerCustomizer implements ServiceTrackerCustomizer<SAXParserFactory, SAXParserFactory> {
- private final BundleContext bundleCtx;
- private final LogService logService;
- private final ServiceTracker<Object, Object> mtpTracker;
-
- private MetaTypeServiceImpl metaTypeService;
- private ServiceRegistration<MetaTypeService> metaTypeServiceRegistration;
- private SAXParserFactory saxParserFactory;
-
- public SAXParserFactoryTrackerCustomizer(BundleContext bundleContext, LogService logService, ServiceTracker<Object, Object> metaTypeProviderTracker) {
- this.bundleCtx = bundleContext;
- this.logService = logService;
- this.mtpTracker = metaTypeProviderTracker;
- }
-
- public SAXParserFactory addingService(ServiceReference<SAXParserFactory> ref) {
- SAXParserFactory parserFactory = bundleCtx.getService(ref);
- if (parserFactory == null)
- return null;
- boolean register = false;
- synchronized (this) {
- if (saxParserFactory == null) {
- // Save this parserFactory as the currently used parserFactory
- saxParserFactory = parserFactory;
- register = true;
- }
- }
- if (register) {
- registerMetaTypeService();
- }
- return parserFactory;
- }
-
- public void modifiedService(ServiceReference<SAXParserFactory> ref, SAXParserFactory object) {
- // noop
- }
-
- public void removedService(ServiceReference<SAXParserFactory> ref, SAXParserFactory object) {
- ServiceRegistration<MetaTypeService> registration = null;
- MetaTypeServiceImpl service = null;
- synchronized (this) {
- if (object == saxParserFactory) {
- // This means that this SAXParserFactory was used to start the
- // MetaTypeService. Set to null to indicate a new MetaTypeService
- // needs to be registered.
- saxParserFactory = null;
- registration = metaTypeServiceRegistration;
- service = metaTypeService;
- }
- }
- if (registration != null) {
- registration.unregister();
- bundleCtx.removeBundleListener(service);
- // See if another factory is available
- ServiceTracker<SAXParserFactory, SAXParserFactory> tracker = getSAXParserFactoryTracker();
- // If the SAXParserFactory tracker is null, the bundle is stopping, and we
- // shouldn't register a new MetaTypeService to avoid unnecessary churn.
- if (tracker != null) {
- SAXParserFactory factory = tracker.getService();
- if (factory != null) {
- // We have another parser so lets restart the MetaTypeService
- boolean register = false;
- synchronized (this) {
- if (saxParserFactory == null) {
- saxParserFactory = factory;
- register = true;
- }
- }
- if (register) {
- registerMetaTypeService();
- }
- }
- }
- }
- bundleCtx.ungetService(ref);
- }
-
- private void registerMetaTypeService() {
- Dictionary<String, Object> properties = new Hashtable<String, Object>(7);
- properties = new Hashtable<String, Object>(7);
- properties.put(Constants.SERVICE_VENDOR, "IBM"); //$NON-NLS-1$
- properties.put(Constants.SERVICE_DESCRIPTION, MetaTypeMsg.SERVICE_DESCRIPTION);
- properties.put(Constants.SERVICE_PID, SERVICE_PID);
- MetaTypeServiceImpl service;
- synchronized (this) {
- service = metaTypeService = new MetaTypeServiceImpl(saxParserFactory, logService, mtpTracker);
- }
- bundleCtx.addBundleListener(service);
- ServiceRegistration<MetaTypeService> registration = bundleCtx.registerService(MetaTypeService.class, service, properties);
- synchronized (this) {
- metaTypeServiceRegistration = registration;
- }
- }
- }
-}
+/*******************************************************************************
+ * Copyright (c) 2005, 2011 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.equinox.metatype.impl;
+
+import org.eclipse.equinox.metatype.EquinoxMetaTypeService;
+
+import java.util.Dictionary;
+import java.util.Hashtable;
+import javax.xml.parsers.SAXParserFactory;
+import org.osgi.framework.*;
+import org.osgi.service.cm.ManagedService;
+import org.osgi.service.log.LogService;
+import org.osgi.service.metatype.MetaTypeProvider;
+import org.osgi.service.metatype.MetaTypeService;
+import org.osgi.util.tracker.ServiceTracker;
+import org.osgi.util.tracker.ServiceTrackerCustomizer;
+
+/**
+ * MetaType Activator
+ */
+public class Activator implements BundleActivator {
+ /*
+ * The following filter guarantees only services meeting the following
+ * criteria will be tracked.
+ *
+ * (1) A ManagedService or ManagedServiceFactory registered with a
+ * SERVICE_PID property. May also be registered as a MetaTypeProvider.
+ * (2) A MetaTypeProvider registered with a METATYPE_PID or
+ * METATYPE_FACTORY_PID property.
+ *
+ * Note that it's still necessary to inspect a ManagedService or
+ * ManagedServiceFactory to ensure it also implements MetaTypeProvider.
+ */
+ private static final String FILTER = "(|(&(" + Constants.OBJECTCLASS + '=' + ManagedService.class.getName() + "*)(" + Constants.SERVICE_PID + "=*))(&(" + Constants.OBJECTCLASS + '=' + MetaTypeProvider.class.getName() + ")(|(" + MetaTypeProvider.METATYPE_PID + "=*)(" + MetaTypeProvider.METATYPE_FACTORY_PID + "=*))))"; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ //$NON-NLS-5$ //$NON-NLS-6$
+ private static final String SERVICE_PID = "org.osgi.impl.service.metatype.MetaTypeService"; //$NON-NLS-1$
+
+ private LogTracker logServiceTracker;
+ // Could be ManagedService, ManagedServiceFactory, or MetaTypeProvider.
+ // The tracker tracks all services regardless of bundle. Services are
+ // filtered by bundle later in the MetaTypeProviderTracker class. It may
+ // therefore be shared among multiple instances of that class.
+ private ServiceTracker<Object, Object> metaTypeProviderTracker;
+ private ServiceTracker<SAXParserFactory, SAXParserFactory> saxParserFactoryTracker;
+
+ public void start(BundleContext context) throws InvalidSyntaxException {
+ LogTracker lsTracker;
+ ServiceTracker<Object, Object> mtpTracker;
+ ServiceTracker<SAXParserFactory, SAXParserFactory> spfTracker;
+ Filter filter = context.createFilter(FILTER);
+ synchronized (this) {
+ lsTracker = logServiceTracker = new LogTracker(context, System.out);
+ mtpTracker = metaTypeProviderTracker = new ServiceTracker<Object, Object>(context, filter, null);
+ spfTracker = saxParserFactoryTracker = new ServiceTracker<SAXParserFactory, SAXParserFactory>(context, SAXParserFactory.class, new SAXParserFactoryTrackerCustomizer(context, lsTracker, mtpTracker));
+ }
+ // Do this first to make logging available as early as possible.
+ lsTracker.open();
+ lsTracker.log(LogService.LOG_DEBUG, "====== Meta Type Service starting ! ====="); //$NON-NLS-1$
+ // Do this next to make MetaTypeProviders available as early as possible.
+ mtpTracker.open();
+ // Do this last because it may result in the MetaTypeService being registered.
+ spfTracker.open();
+ }
+
+ public void stop(BundleContext context) {
+ ServiceTracker<SAXParserFactory, SAXParserFactory> spfTracker;
+ ServiceTracker<Object, Object> mtpTracker;
+ LogTracker lsTracker;
+ synchronized (this) {
+ spfTracker = saxParserFactoryTracker;
+ // Set this to null so the SAXParserFactoryTrackerCustomizer knows
+ // not to register a new MetaTypeService when removedService() is
+ // called while the tracker is closing.
+ saxParserFactoryTracker = null;
+ mtpTracker = metaTypeProviderTracker;
+ lsTracker = logServiceTracker;
+ }
+ lsTracker.log(LogService.LOG_DEBUG, "====== Meta Type Service stopping ! ====="); //$NON-NLS-1$
+ spfTracker.close();
+ mtpTracker.close();
+ // Do this last to leave logging available as long as possible.
+ lsTracker.close();
+ }
+
+ synchronized ServiceTracker<SAXParserFactory, SAXParserFactory> getSAXParserFactoryTracker() {
+ return saxParserFactoryTracker;
+ }
+
+ private class SAXParserFactoryTrackerCustomizer implements ServiceTrackerCustomizer<SAXParserFactory, SAXParserFactory> {
+ private final BundleContext bundleCtx;
+ private final LogService logService;
+ private final ServiceTracker<Object, Object> mtpTracker;
+
+ private MetaTypeServiceImpl metaTypeService;
+ private ServiceRegistration<?> metaTypeServiceRegistration;
+ private SAXParserFactory saxParserFactory;
+
+ public SAXParserFactoryTrackerCustomizer(BundleContext bundleContext, LogService logService, ServiceTracker<Object, Object> metaTypeProviderTracker) {
+ this.bundleCtx = bundleContext;
+ this.logService = logService;
+ this.mtpTracker = metaTypeProviderTracker;
+ }
+
+ public SAXParserFactory addingService(ServiceReference<SAXParserFactory> ref) {
+ SAXParserFactory parserFactory = bundleCtx.getService(ref);
+ if (parserFactory == null)
+ return null;
+ ServiceRegistration<?> registration = null;
+ MetaTypeServiceImpl service = null;
+ SAXParserFactory oldFactory = null;
+ synchronized (this) {
+ // No previous factory case. We'll accept anything.
+ if (saxParserFactory == null) {
+ // Save this parserFactory as the currently used parserFactory
+ saxParserFactory = parserFactory;
+ }
+ // Nothing to do case. Current factory is explicitly namespace aware.
+ else if (saxParserFactory.isNamespaceAware()) {
+ return parserFactory;
+ } else if (parserFactory.isNamespaceAware() || // Previous factory not set for namespace awareness but the new one is case.
+ // Now the fun case. Neither factory is set for namespace awareness. Need to see if we're currently using
+ // a factory incapable of creating namespace aware parsers and, if so, if it can be replaced with the new one.
+ (!supportsNamespaceAwareness(saxParserFactory) && supportsNamespaceAwareness(parserFactory))) {
+ oldFactory = saxParserFactory;
+ saxParserFactory = parserFactory;
+ registration = metaTypeServiceRegistration;
+ service = metaTypeService;
+ }
+ }
+ swapFactories(oldFactory, parserFactory, registration, service);
+ return parserFactory;
+ }
+
+ private void swapFactories(SAXParserFactory oldFactory, SAXParserFactory newFactory, ServiceRegistration<?> registration, MetaTypeServiceImpl service) {
+ if (oldFactory == null) {
+ registerMetaTypeService();
+ return;
+ }
+ unregisterMetaTypeService(registration, service);
+ registerMetaTypeService();
+ }
+
+ public void modifiedService(ServiceReference<SAXParserFactory> ref, SAXParserFactory object) {
+ // Nothing.
+ }
+
+ public void removedService(ServiceReference<SAXParserFactory> ref, SAXParserFactory object) {
+ ServiceRegistration<?> registration = null;
+ MetaTypeServiceImpl service = null;
+ synchronized (this) {
+ if (object == saxParserFactory) {
+ // This means the SAXParserFactory was used to start the MetaTypeService and we need to reset.
+ saxParserFactory = null;
+ registration = metaTypeServiceRegistration;
+ service = metaTypeService;
+ }
+ }
+ if (registration != null) {
+ // Unregister the MetaType service.
+ unregisterMetaTypeService(registration, service);
+ // See if another factory is available
+ SAXParserFactory factory = findBestPossibleFactory();
+ // If the factory is null, either the bundle is stopping or there are no
+ // available services. Either way, we don't want to register the MetaType service.
+ if (factory != null) {
+ // We have another parser so let's restart the MetaType service if it hasn't been already.
+ boolean register = false;
+ synchronized (this) {
+ // If not null, something else beat us to the punch.
+ if (saxParserFactory == null) {
+ saxParserFactory = factory;
+ register = true;
+ }
+ }
+ if (register) {
+ registerMetaTypeService();
+ }
+ }
+ }
+ bundleCtx.ungetService(ref);
+ }
+
+ private SAXParserFactory findBestPossibleFactory() {
+ ServiceTracker<SAXParserFactory, SAXParserFactory> tracker = getSAXParserFactoryTracker();
+ // The tracker will be null if the bundle is stopping.
+ if (tracker == null)
+ return null;
+ SAXParserFactory[] factories = (SAXParserFactory[]) tracker.getServices();
+ // The factories will be null if there are no services being tracked.
+ if (factories == null)
+ return null;
+ SAXParserFactory result = null;
+ for (SAXParserFactory factory : factories) {
+ if (factory.isNamespaceAware()) {
+ // If the factory is namespace aware, we have exactly what we want.
+ result = factory;
+ break;
+ }
+ // If no "second best" parser has been found yet, see if this one fits the bill.
+ if (result == null && supportsNamespaceAwareness(factory)) {
+ result = factory;
+ }
+ }
+ // If no factories capable of providing namespace aware parsers have been found,
+ // just grab the first available one, if any.
+ if (result == null)
+ result = tracker.getService();
+ return result;
+ }
+
+ private void registerMetaTypeService() {
+ Dictionary<String, Object> properties = new Hashtable<String, Object>(7);
+ properties = new Hashtable<String, Object>(7);
+ properties.put(Constants.SERVICE_VENDOR, "IBM"); //$NON-NLS-1$
+ properties.put(Constants.SERVICE_DESCRIPTION, MetaTypeMsg.SERVICE_DESCRIPTION);
+ properties.put(Constants.SERVICE_PID, SERVICE_PID);
+ MetaTypeServiceImpl service;
+ synchronized (this) {
+ service = metaTypeService = new MetaTypeServiceImpl(saxParserFactory, logService, mtpTracker);
+ }
+ bundleCtx.addBundleListener(service);
+ ServiceRegistration<?> registration = bundleCtx.registerService(new String[] {MetaTypeService.class.getName(), EquinoxMetaTypeService.class.getName()}, service, properties);
+ synchronized (this) {
+ metaTypeServiceRegistration = registration;
+ }
+ }
+
+ private boolean supportsNamespaceAwareness(SAXParserFactory factory) {
+ if (factory.isNamespaceAware())
+ return true;
+ factory.setNamespaceAware(true);
+ try {
+ factory.newSAXParser();
+ return true;
+ } catch (Exception e) {
+ return false;
+ } finally {
+ // Go back to the original settings.
+ factory.setNamespaceAware(false);
+ }
+ }
+
+ private void unregisterMetaTypeService(ServiceRegistration<?> registration, MetaTypeServiceImpl service) {
+ registration.unregister();
+ bundleCtx.removeBundleListener(service);
+ }
+ }
+}
diff --git a/bundles/org.eclipse.equinox.metatype/src/org/eclipse/equinox/metatype/AttributeDefinitionImpl.java b/bundles/org.eclipse.equinox.metatype/src/org/eclipse/equinox/metatype/impl/AttributeDefinitionImpl.java
index a9d8bab..6b4d3b5 100644
--- a/bundles/org.eclipse.equinox.metatype/src/org/eclipse/equinox/metatype/AttributeDefinitionImpl.java
+++ b/bundles/org.eclipse.equinox.metatype/src/org/eclipse/equinox/metatype/impl/AttributeDefinitionImpl.java
@@ -1,298 +1,311 @@
-/*******************************************************************************
- * Copyright (c) 2005, 2011 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License v1.0
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/epl-v10.html
- *
- * Contributors:
- * IBM Corporation - initial API and implementation
- *******************************************************************************/
-package org.eclipse.equinox.metatype;
-
-import java.util.Enumeration;
-import java.util.Vector;
-import org.eclipse.osgi.util.NLS;
-import org.osgi.service.log.LogService;
-import org.osgi.service.metatype.AttributeDefinition;
-
-/**
- * Implementation of AttributeDefintion
- */
-public class AttributeDefinitionImpl extends LocalizationElement implements AttributeDefinition, Cloneable {
-
- String _name;
- String _id;
- String _description;
- int _cardinality = 0;
- int _dataType;
- Object _minValue = null;
- Object _maxValue = null;
- boolean _isRequired = true;
-
- String[] _defaults = null;
- Vector<String> _values = new Vector<String>(7);
- Vector<String> _labels = new Vector<String>(7);
-
- private final LogService logger;
-
- /**
- * Constructor of class AttributeDefinitionImpl.
- */
- public AttributeDefinitionImpl(String id, String name, String description, int type, int cardinality, Object min, Object max, boolean isRequired, String localization, LogService logger) {
-
- this._id = id;
- this._name = name;
- this._description = description;
- this._dataType = type;
- this._cardinality = cardinality;
- this._minValue = min;
- this._maxValue = max;
- this._isRequired = isRequired;
- this._localization = localization;
- this.logger = logger;
- }
-
- /*
- *
- */
- public synchronized Object clone() {
-
- AttributeDefinitionImpl ad = new AttributeDefinitionImpl(_id, _name, _description, _dataType, _cardinality, _minValue, _maxValue, _isRequired, _localization, logger);
-
- if (_defaults != null) {
- ad.setDefaultValue(_defaults.clone());
- }
- if ((_labels != null) && (_values != null)) {
- @SuppressWarnings("unchecked")
- Vector<String> labels = (Vector<String>) _labels.clone();
- @SuppressWarnings("unchecked")
- Vector<String> values = (Vector<String>) _values.clone();
- ad.setOption(labels, values, false);
- }
-
- return ad;
- }
-
- /*
- * (non-Javadoc)
- *
- * @see org.osgi.service.metatype.AttributeDefinition#getName()
- */
- public String getName() {
- return getLocalized(_name);
- }
-
- /**
- * Method to set the name of AttributeDefinition.
- */
- void setName(String name) {
- this._name = name;
- }
-
- /*
- * (non-Javadoc)
- *
- * @see org.osgi.service.metatype.AttributeDefinition#getID()
- */
- public String getID() {
- return _id;
- }
-
- /**
- * Method to set the ID of AttributeDefinition.
- */
- void setID(String id) {
- this._id = id;
- }
-
- /*
- * (non-Javadoc)
- *
- * @see org.osgi.service.metatype.AttributeDefinition#getDescription()
- */
- public String getDescription() {
- return getLocalized(_description);
- }
-
- /**
- * Method to set the description of AttributeDefinition.
- */
- void setDescription(String description) {
- this._description = description;
- }
-
- /*
- * (non-Javadoc)
- *
- * @see org.osgi.service.metatype.AttributeDefinition#getCardinality()
- */
- public int getCardinality() {
- return _cardinality;
- }
-
- /**
- * Method to set the cardinality of AttributeDefinition.
- */
- void setCardinality(int cardinality) {
- this._cardinality = cardinality;
- }
-
- /*
- * (non-Javadoc)
- *
- * @see org.osgi.service.metatype.AttributeDefinition#getType()
- */
- public int getType() {
- return _dataType;
- }
-
- /**
- * Method to set the data type of AttributeDefinition.
- */
- void setType(int type) {
- this._dataType = type;
- }
-
- /**
- * Method to get the required flag of AttributeDefinition.
- */
- boolean isRequired() {
- return _isRequired;
- }
-
- /**
- * Method to set the required flag of AttributeDefinition.
- */
- void setRequired(boolean isRequired) {
- this._isRequired = isRequired;
- }
-
- /*
- * (non-Javadoc)
- *
- * @see org.osgi.service.metatype.AttributeDefinition#getOptionLabels()
- */
- public String[] getOptionLabels() {
-
- if ((_labels == null) || (_labels.size() == 0)) {
- return null;
- }
-
- String[] returnedLabels = new String[_labels.size()];
- Enumeration<String> labelKeys = _labels.elements();
- int i = 0;
- while (labelKeys.hasMoreElements()) {
- String labelKey = labelKeys.nextElement();
- returnedLabels[i] = getLocalized(labelKey);
- i++;
- }
- return returnedLabels;
- }
-
- /*
- * (non-Javadoc)
- *
- * @see org.osgi.service.metatype.AttributeDefinition#getOptionValues()
- */
- public String[] getOptionValues() {
-
- if ((_values == null) || (_values.size() == 0)) {
- return null;
- }
-
- return _values.toArray(new String[_values.size()]);
- }
-
- /**
- * Method to set the Option values of AttributeDefinition.
- */
- void setOption(Vector<String> labels, Vector<String> values, boolean needValidation) {
- if ((labels == null) || (values == null)) {
- logger.log(LogService.LOG_ERROR, "AttributeDefinitionImpl.setOption(Vector, Vector, boolean) " + MetaTypeMsg.NULL_OPTIONS); //$NON-NLS-1$
- return;
- }
- if (labels.size() != values.size()) {
- logger.log(LogService.LOG_ERROR, "AttributeDefinitionImpl.setOption(Vector, Vector, boolean) " + MetaTypeMsg.INCONSISTENT_OPTIONS); //$NON-NLS-1$
- return;
- }
- _labels = labels;
- _values = values;
- if (needValidation) {
- for (int index = 0; index < _values.size(); index++) {
- ValueTokenizer vt = new ValueTokenizer(_values.get(index), logger);
- _values.set(index, vt.getValuesAsString());
- String reason = vt.validate(this);
- if ((reason != null) && reason.length() > 0) {
- logger.log(LogService.LOG_WARNING, NLS.bind(MetaTypeMsg.INVALID_OPTIONS, _values.get(index), reason));
- _labels.remove(index);
- _values.remove(index);
- index--; // Because this one has been removed.
- }
- }
- }
- }
-
- /*
- * (non-Javadoc)
- *
- * @see org.osgi.service.metatype.AttributeDefinition#getDefaultValue()
- */
- public String[] getDefaultValue() {
- return _defaults;
- }
-
- /**
- * Method to set the default value of AttributeDefinition.
- * The given parameter is a comma delimited list needed to be parsed.
- */
- void setDefaultValue(String defaults_str, boolean needValidation) {
- ValueTokenizer vt = new ValueTokenizer(defaults_str, logger);
- String reason = vt.validate(this);
- if ((reason != null) && reason.length() > 0) {
- logger.log(LogService.LOG_WARNING, NLS.bind(MetaTypeMsg.INVALID_DEFAULTS, vt.getValuesAsString(), reason));
- return;
- }
- setDefaultValue(vt.getValuesAsArray());
- }
-
- /**
- * Method to set the default value of AttributeDefinition.
- * The given parameter is a String array of multi values.
- */
- void setDefaultValue(String[] defaults) {
- _defaults = defaults;
- }
-
- /**
- * Method to set the validation value - min of AttributeDefinition.
- */
- void setMinValue(Object minValue) {
- this._minValue = minValue;
- }
-
- /**
- * Method to set the validation value - max of AttributeDefinition.
- */
- void setMaxValue(Object maxValue) {
- this._maxValue = maxValue;
- }
-
- /*
- * (non-Javadoc)
- * In order to be valid, a value must pass all of the following tests.
- * (1) The value must not be null.
- * (2) The value must be convertible into the attribute definition's type.
- * (3) The following relation must hold: min <= value <= max, if either min or max was specified.
- * (4) If options were specified, the value must be equal to one of them.
- *
- * Note this method will never return null to indicate there's no validation
- * present. The type compatibility check can always be performed.
- *
- * @see org.osgi.service.metatype.AttributeDefinition#validate(java.lang.String)
- */
- public String validate(String value) {
- ValueTokenizer vt = new ValueTokenizer(value, logger);
- return vt.validate(this);
- }
-}
+/*******************************************************************************
+ * Copyright (c) 2005, 2011 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.equinox.metatype.impl;
+
+import org.eclipse.equinox.metatype.EquinoxAttributeDefinition;
+
+import java.util.*;
+import org.eclipse.osgi.util.NLS;
+import org.osgi.service.log.LogService;
+
+/**
+ * Implementation of AttributeDefintion
+ */
+public class AttributeDefinitionImpl extends LocalizationElement implements EquinoxAttributeDefinition, Cloneable {
+
+ String _name;
+ String _id;
+ String _description;
+ int _cardinality = 0;
+ int _dataType;
+ Object _minValue = null;
+ Object _maxValue = null;
+ boolean _isRequired = true;
+
+ String[] _defaults = null;
+ Vector<String> _values = new Vector<String>(7);
+ Vector<String> _labels = new Vector<String>(7);
+
+ private final LogService logger;
+ private final ExtendableHelper helper;
+
+ /**
+ * Constructor of class AttributeDefinitionImpl.
+ */
+ public AttributeDefinitionImpl(String id, String name, String description, int type, int cardinality, Object min, Object max, boolean isRequired, String localization, LogService logger, Map<String, Map<String, String>> extensionAttributes) {
+ this(id, name, description, type, cardinality, min, max, isRequired, localization, logger, new ExtendableHelper(extensionAttributes));
+ }
+
+ private AttributeDefinitionImpl(String id, String name, String description, int type, int cardinality, Object min, Object max, boolean isRequired, String localization, LogService logger, ExtendableHelper helper) {
+ this._id = id;
+ this._name = name;
+ this._description = description;
+ this._dataType = type;
+ this._cardinality = cardinality;
+ this._minValue = min;
+ this._maxValue = max;
+ this._isRequired = isRequired;
+ this._localization = localization;
+ this.logger = logger;
+ this.helper = helper;
+ }
+
+ /*
+ *
+ */
+ public synchronized Object clone() {
+
+ AttributeDefinitionImpl ad = new AttributeDefinitionImpl(_id, _name, _description, _dataType, _cardinality, _minValue, _maxValue, _isRequired, _localization, logger, helper);
+
+ if (_defaults != null) {
+ ad.setDefaultValue(_defaults.clone());
+ }
+ if ((_labels != null) && (_values != null)) {
+ @SuppressWarnings("unchecked")
+ Vector<String> labels = (Vector<String>) _labels.clone();
+ @SuppressWarnings("unchecked")
+ Vector<String> values = (Vector<String>) _values.clone();
+ ad.setOption(labels, values, false);
+ }
+
+ return ad;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.osgi.service.metatype.AttributeDefinition#getName()
+ */
+ public String getName() {
+ return getLocalized(_name);
+ }
+
+ /**
+ * Method to set the name of AttributeDefinition.
+ */
+ void setName(String name) {
+ this._name = name;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.osgi.service.metatype.AttributeDefinition#getID()
+ */
+ public String getID() {
+ return _id;
+ }
+
+ /**
+ * Method to set the ID of AttributeDefinition.
+ */
+ void setID(String id) {
+ this._id = id;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.osgi.service.metatype.AttributeDefinition#getDescription()
+ */
+ public String getDescription() {
+ return getLocalized(_description);
+ }
+
+ /**
+ * Method to set the description of AttributeDefinition.
+ */
+ void setDescription(String description) {
+ this._description = description;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.osgi.service.metatype.AttributeDefinition#getCardinality()
+ */
+ public int getCardinality() {
+ return _cardinality;
+ }
+
+ /**
+ * Method to set the cardinality of AttributeDefinition.
+ */
+ void setCardinality(int cardinality) {
+ this._cardinality = cardinality;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.osgi.service.metatype.AttributeDefinition#getType()
+ */
+ public int getType() {
+ return _dataType;
+ }
+
+ /**
+ * Method to set the data type of AttributeDefinition.
+ */
+ void setType(int type) {
+ this._dataType = type;
+ }
+
+ /**
+ * Method to get the required flag of AttributeDefinition.
+ */
+ boolean isRequired() {
+ return _isRequired;
+ }
+
+ /**
+ * Method to set the required flag of AttributeDefinition.
+ */
+ void setRequired(boolean isRequired) {
+ this._isRequired = isRequired;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.osgi.service.metatype.AttributeDefinition#getOptionLabels()
+ */
+ public String[] getOptionLabels() {
+
+ if ((_labels == null) || (_labels.size() == 0)) {
+ return null;
+ }
+
+ String[] returnedLabels = new String[_labels.size()];
+ Enumeration<String> labelKeys = _labels.elements();
+ int i = 0;
+ while (labelKeys.hasMoreElements()) {
+ String labelKey = labelKeys.nextElement();
+ returnedLabels[i] = getLocalized(labelKey);
+ i++;
+ }
+ return returnedLabels;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.osgi.service.metatype.AttributeDefinition#getOptionValues()
+ */
+ public String[] getOptionValues() {
+
+ if ((_values == null) || (_values.size() == 0)) {
+ return null;
+ }
+
+ return _values.toArray(new String[_values.size()]);
+ }
+
+ /**
+ * Method to set the Option values of AttributeDefinition.
+ */
+ void setOption(Vector<String> labels, Vector<String> values, boolean needValidation) {
+ if ((labels == null) || (values == null)) {
+ logger.log(LogService.LOG_ERROR, "AttributeDefinitionImpl.setOption(Vector, Vector, boolean) " + MetaTypeMsg.NULL_OPTIONS); //$NON-NLS-1$
+ return;
+ }
+ if (labels.size() != values.size()) {
+ logger.log(LogService.LOG_ERROR, "AttributeDefinitionImpl.setOption(Vector, Vector, boolean) " + MetaTypeMsg.INCONSISTENT_OPTIONS); //$NON-NLS-1$
+ return;
+ }
+ _labels = labels;
+ _values = values;
+ if (needValidation) {
+ for (int index = 0; index < _values.size(); index++) {
+ ValueTokenizer vt = new ValueTokenizer(_values.get(index), logger);
+ _values.set(index, vt.getValuesAsString());
+ String reason = vt.validate(this);
+ if ((reason != null) && reason.length() > 0) {
+ logger.log(LogService.LOG_WARNING, NLS.bind(MetaTypeMsg.INVALID_OPTIONS, _values.get(index), reason));
+ _labels.remove(index);
+ _values.remove(index);
+ index--; // Because this one has been removed.
+ }
+ }
+ }
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.osgi.service.metatype.AttributeDefinition#getDefaultValue()
+ */
+ public String[] getDefaultValue() {
+ return _defaults;
+ }
+
+ /**
+ * Method to set the default value of AttributeDefinition.
+ * The given parameter is a comma delimited list needed to be parsed.
+ */
+ void setDefaultValue(String defaults_str, boolean needValidation) {
+ ValueTokenizer vt = new ValueTokenizer(defaults_str, logger);
+ String reason = vt.validate(this);
+ if ((reason != null) && reason.length() > 0) {
+ logger.log(LogService.LOG_WARNING, NLS.bind(MetaTypeMsg.INVALID_DEFAULTS, vt.getValuesAsString(), reason));
+ return;
+ }
+ setDefaultValue(vt.getValuesAsArray());
+ }
+
+ /**
+ * Method to set the default value of AttributeDefinition.
+ * The given parameter is a String array of multi values.
+ */
+ void setDefaultValue(String[] defaults) {
+ _defaults = defaults;
+ }
+
+ /**
+ * Method to set the validation value - min of AttributeDefinition.
+ */
+ void setMinValue(Object minValue) {
+ this._minValue = minValue;
+ }
+
+ /**
+ * Method to set the validation value - max of AttributeDefinition.
+ */
+ void setMaxValue(Object maxValue) {
+ this._maxValue = maxValue;
+ }
+
+ /*
+ * (non-Javadoc)
+ * In order to be valid, a value must pass all of the following tests.
+ * (1) The value must not be null.
+ * (2) The value must be convertible into the attribute definition's type.
+ * (3) The following relation must hold: min <= value <= max, if either min or max was specified.
+ * (4) If options were specified, the value must be equal to one of them.
+ *
+ * Note this method will never return null to indicate there's no validation
+ * present. The type compatibility check can always be performed.
+ *
+ * @see org.osgi.service.metatype.AttributeDefinition#validate(java.lang.String)
+ */
+ public String validate(String value) {
+ ValueTokenizer vt = new ValueTokenizer(value, logger);
+ return vt.validate(this);
+ }
+
+ public Map<String, String> getExtensionAttributes(String schema) {
+ return helper.getExtensionAttributes(schema);
+ }
+
+ public Set<String> getExtensionUris() {
+ return helper.getExtensionUris();
+ }
+}
diff --git a/bundles/org.eclipse.equinox.metatype/src/org/eclipse/equinox/metatype/DataParser.java b/bundles/org.eclipse.equinox.metatype/src/org/eclipse/equinox/metatype/impl/DataParser.java
index 7621d05..f7cb329 100644
--- a/bundles/org.eclipse.equinox.metatype/src/org/eclipse/equinox/metatype/DataParser.java
+++ b/bundles/org.eclipse.equinox.metatype/src/org/eclipse/equinox/metatype/impl/DataParser.java
@@ -1,841 +1,849 @@
-/*******************************************************************************
- * Copyright (c) 2005, 2011 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License v1.0
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/epl-v10.html
- *
- * Contributors:
- * IBM Corporation - initial API and implementation
- *******************************************************************************/
-package org.eclipse.equinox.metatype;
-
-import java.io.*;
-import java.math.BigDecimal;
-import java.math.BigInteger;
-import java.net.URL;
-import java.util.*;
-import javax.xml.parsers.*;
-import org.eclipse.osgi.util.NLS;
-import org.osgi.framework.Bundle;
-import org.osgi.service.log.LogService;
-import org.osgi.service.metatype.AttributeDefinition;
-import org.xml.sax.*;
-import org.xml.sax.helpers.DefaultHandler;
-
-/**
- * Meta XML Data Parser
- */
-public class DataParser {
- private static final String METADATA = "MetaData"; //$NON-NLS-1$
- private static final String LOCALIZATION = "localization"; //$NON-NLS-1$
- private static final String OCD = "OCD"; //$NON-NLS-1$
- private static final String ICON = "Icon"; //$NON-NLS-1$
- private static final String AD = "AD"; //$NON-NLS-1$
- private static final String CARDINALITY = "cardinality"; //$NON-NLS-1$
- private static final String OPTION = "Option"; //$NON-NLS-1$
- private static final String LABEL = "label"; //$NON-NLS-1$
- private static final String VALUE = "value"; //$NON-NLS-1$
- private static final String MIN = "min"; //$NON-NLS-1$
- private static final String MAX = "max"; //$NON-NLS-1$
- private static final String TYPE = "type"; //$NON-NLS-1$
- private static final String SIZE = "size"; //$NON-NLS-1$
- private static final String ID = "id"; //$NON-NLS-1$
- private static final String NAME = "name"; //$NON-NLS-1$
- private static final String DESCRIPTION = "description"; //$NON-NLS-1$
- private static final String RESOURCE = "resource"; //$NON-NLS-1$
- private static final String PID = "pid"; //$NON-NLS-1$
- private static final String DEFAULT = "default"; //$NON-NLS-1$
- private static final String ADREF = "adref"; //$NON-NLS-1$
- private static final String CONTENT = "content"; //$NON-NLS-1$
- private static final String FACTORY = "factoryPid"; //$NON-NLS-1$
- private static final String BUNDLE = "bundle"; //$NON-NLS-1$
- private static final String OPTIONAL = "optional"; //$NON-NLS-1$
- private static final String OBJECT = "Object"; //$NON-NLS-1$
- private static final String OCDREF = "ocdref"; //$NON-NLS-1$
- private static final String ATTRIBUTE = "Attribute"; //$NON-NLS-1$
- private static final String DESIGNATE = "Designate"; //$NON-NLS-1$
- private static final String MERGE = "merge"; //$NON-NLS-1$
- private static final String REQUIRED = "required"; //$NON-NLS-1$
-
- private static final String INTEGER = "Integer"; //$NON-NLS-1$
- private static final String STRING = "String"; //$NON-NLS-1$
- private static final String FLOAT = "Float"; //$NON-NLS-1$
- private static final String DOUBLE = "Double"; //$NON-NLS-1$
- private static final String BYTE = "Byte"; //$NON-NLS-1$
- private static final String LONG = "Long"; //$NON-NLS-1$
- private static final String CHAR = "Char"; //$NON-NLS-1$
- private static final String BOOLEAN = "Boolean"; //$NON-NLS-1$
- private static final String SHORT = "Short"; //$NON-NLS-1$
- private static final String PASSWORD = "Password"; //$NON-NLS-1$
-
- protected Bundle _dp_bundle;
- protected URL _dp_url;
- protected SAXParserFactory _dp_parserFactory;
- protected XMLReader _dp_xmlReader;
-
- // DesignateHanders in DataParser class
- Vector<DesignateHandler> _dp_designateHandlers = new Vector<DesignateHandler>(7);
- // ObjectClassDefinitions in DataParser class w/ corresponding reference keys
- Hashtable<String, ObjectClassDefinitionImpl> _dp_OCDs = new Hashtable<String, ObjectClassDefinitionImpl>(7);
- // Localization in DataParser class
- String _dp_localization;
-
- // Default visibility to avoid a plethora of synthetic accessor method warnings.
- final LogService logger;
- final Collection<Designate> designates = new ArrayList<Designate>(7);
-
- /*
- * Constructor of class DataParser.
- */
- public DataParser(Bundle bundle, URL url, SAXParserFactory parserFactory, LogService logger) {
-
- this._dp_bundle = bundle;
- this._dp_url = url;
- this._dp_parserFactory = parserFactory;
- parserFactory.setValidating(false);
- this.logger = logger;
- }
-
- /*
- * Main method to parse specific MetaData file.
- */
- public Collection<Designate> doParse() throws IOException, ParserConfigurationException, SAXException {
- SAXParser saxParser = _dp_parserFactory.newSAXParser();
- _dp_xmlReader = saxParser.getXMLReader();
- _dp_xmlReader.setContentHandler(new RootHandler());
- _dp_xmlReader.setErrorHandler(new MyErrorHandler(System.err));
- InputStream is = _dp_url.openStream();
- InputSource isource = new InputSource(is);
- logger.log(LogService.LOG_DEBUG, "Starting to parse " + _dp_url); //$NON-NLS-1$
- _dp_xmlReader.parse(isource);
- return designates;
- }
-
- /*
- * Convert String for expected data type.
- */
- static Object convert(String value, int type) {
-
- if (value == null) {
- return null;
- }
-
- switch (type) {
- // PASSWORD should be treated like STRING.
- case AttributeDefinition.PASSWORD :
- case AttributeDefinition.STRING :
- // Both the min and max of STRING are Integers.
- return new Integer(value);
- case AttributeDefinition.LONG :
- return new Long(value);
- case AttributeDefinition.INTEGER :
- return new Integer(value);
- case AttributeDefinition.SHORT :
- return new Short(value);
- case AttributeDefinition.CHARACTER :
- return new Character(value.charAt(0));
- case AttributeDefinition.BYTE :
- return new Byte(value);
- case AttributeDefinition.DOUBLE :
- return new Double(value);
- case AttributeDefinition.FLOAT :
- return new Float(value);
- case AttributeDefinition.BIGINTEGER :
- return new BigInteger(value);
- case AttributeDefinition.BIGDECIMAL :
- return new BigDecimal(value);
- case AttributeDefinition.BOOLEAN :
- return new Boolean(value);
- default :
- // Unknown data type
- return null;
- }
- }
-
- /**
- * Abstract of all Handlers.
- */
- private class AbstractHandler extends DefaultHandler {
-
- protected ContentHandler _doc_handler;
- protected boolean _isParsedDataValid = true;
-
- public AbstractHandler(ContentHandler parentHandler) {
-
- this._doc_handler = parentHandler;
- _dp_xmlReader.setContentHandler(this);
- }
-
- public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException {
-
- throw new SAXException(NLS.bind(MetaTypeMsg.UNEXPECTED_ELEMENT, qName));
- }
-
- public void characters(char[] buf, int start, int end) throws SAXException {
-
- String s = new String(buf, start, end).trim();
- if (s.length() > 0) {
- throw new SAXException(NLS.bind(MetaTypeMsg.UNEXPECTED_TEXT, s));
- }
- }
-
- /**
- * Called when this element and all elements nested into it have been
- * handled.
- */
- protected void finished() {
- // do nothing by default
- }
-
- public void endElement(String namespaceURI, String localName, String qName) {
-
- finished();
- // Let parent resume handling SAX events
- _dp_xmlReader.setContentHandler(_doc_handler);
- }
- }
-
- /**
- * Handler for the root element.
- */
- private class RootHandler extends DefaultHandler {
-
- public RootHandler() {
- super();
- }
-
- public void startElement(String uri, String localName, String qName, Attributes attributes) {
-
- logger.log(LogService.LOG_DEBUG, "Here is AbstractHandler:startElement():" //$NON-NLS-1$
- + qName);
- String name = getName(localName, qName);
- if (name.equalsIgnoreCase(METADATA)) {
- new MetaDataHandler(this).init(name, attributes);
- } else {
- logger.log(LogService.LOG_WARNING, NLS.bind(MetaTypeMsg.UNEXPECTED_ELEMENT, name));
- }
- }
-
- public void setDocumentLocator(Locator locator) {
- // do nothing
- }
- }
-
- /**
- * Handler for the MetaData element.
- */
- private class MetaDataHandler extends AbstractHandler {
-
- public MetaDataHandler(ContentHandler handler) {
- super(handler);
- }
-
- public void init(String name, Attributes attributes) {
-
- logger.log(LogService.LOG_DEBUG, "Here is MetaDataHandler():init()"); //$NON-NLS-1$
- _dp_localization = attributes.getValue(LOCALIZATION);
- if (_dp_localization == null) {
- // Not a problem, because LOCALIZATION is an optional attribute.
- }
- // The global variable "_dp_localization" will be used within
- // OcdHandler and AttributeDefinitionHandler later.
- }
-
- public void startElement(String uri, String localName, String qName, Attributes atts) {
-
- logger.log(LogService.LOG_DEBUG, "Here is MetaDataHandler:startElement():" //$NON-NLS-1$
- + qName);
- String name = getName(localName, qName);
- if (name.equalsIgnoreCase(DESIGNATE)) {
- DesignateHandler designateHandler = new DesignateHandler(this);
- designateHandler.init(name, atts);
- if (designateHandler._isParsedDataValid) {
- _dp_designateHandlers.addElement(designateHandler);
- }
- } else if (name.equalsIgnoreCase(OCD)) {
- OcdHandler ocdHandler = new OcdHandler(this);
- ocdHandler.init(name, atts, _dp_OCDs);
- } else {
- logger.log(LogService.LOG_WARNING, NLS.bind(MetaTypeMsg.UNEXPECTED_ELEMENT, name));
- }
- }
-
- protected void finished() {
-
- logger.log(LogService.LOG_DEBUG, "Here is MetaDataHandler():finished()"); //$NON-NLS-1$
- if (_dp_designateHandlers.size() == 0) {
- // Schema defines at least one DESIGNATE is required.
- _isParsedDataValid = false;
- logger.log(LogService.LOG_WARNING, "DataParser.finished() " + NLS.bind(MetaTypeMsg.MISSING_ELEMENT, DESIGNATE)); //$NON-NLS-1$
- return;
- }
- Enumeration<DesignateHandler> designateHandlerKeys = _dp_designateHandlers.elements();
- while (designateHandlerKeys.hasMoreElements()) {
- DesignateHandler dh = designateHandlerKeys.nextElement();
-
- ObjectClassDefinitionImpl ocd = _dp_OCDs.get(dh._ocdref);
- if (ocd != null) {
- designates.add(new Designate.Builder(ocd).bundle(dh._bundle_val).factoryPid(dh._factory_val).merge(dh._merge_val).pid(dh._pid_val).optional(dh._optional_val).build());
- } else {
- logger.log(LogService.LOG_ERROR, "DataParser.finished() " + NLS.bind(MetaTypeMsg.OCD_ID_NOT_FOUND, dh._ocdref)); //$NON-NLS-1$
-
- }
- }
- }
- }
-
- /**
- * Handler for the ObjectClassDefinition element.
- */
- private class OcdHandler extends AbstractHandler {
-
- Hashtable<String, ObjectClassDefinitionImpl> _parent_OCDs_hashtable;
- // This ID "_refID" is only used for reference by Designate element,
- // not the PID or FPID of this OCD.
- String _refID;
- ObjectClassDefinitionImpl _ocd;
- Vector<AttributeDefinitionImpl> _ad_vector = new Vector<AttributeDefinitionImpl>(7);
-
- public OcdHandler(ContentHandler handler) {
- super(handler);
- }
-
- public void init(String name, Attributes atts, Hashtable<String, ObjectClassDefinitionImpl> ocds_hashtable) {
-
- logger.log(LogService.LOG_DEBUG, "Here is OcdHandler():init()"); //$NON-NLS-1$
- _parent_OCDs_hashtable = ocds_hashtable;
-
- String ocd_name_val = atts.getValue(NAME);
- if (ocd_name_val == null) {
- _isParsedDataValid = false;
- logger.log(LogService.LOG_ERROR, "DataParser.init(String, Attributes, Hashtable) " + NLS.bind(MetaTypeMsg.MISSING_ATTRIBUTE, NAME, name)); //$NON-NLS-1$
- return;
- }
-
- String ocd_description_val = atts.getValue(DESCRIPTION);
- if (ocd_description_val == null) {
- // Not a problem, because DESCRIPTION is an optional attribute.
- }
-
- _refID = atts.getValue(ID);
- if (_refID == null) {
- _isParsedDataValid = false;
- logger.log(LogService.LOG_ERROR, "DataParser.init(String, Attributes, Hashtable) " + NLS.bind(MetaTypeMsg.MISSING_ATTRIBUTE, ID, name)); //$NON-NLS-1$
- return;
- }
-
- _ocd = new ObjectClassDefinitionImpl(ocd_name_val, ocd_description_val, _refID, _dp_localization);
- }
-
- public void startElement(String uri, String localName, String qName, Attributes atts) {
-
- logger.log(LogService.LOG_DEBUG, "Here is OcdHandler:startElement():" //$NON-NLS-1$
- + qName);
- if (!_isParsedDataValid)
- return;
-
- String name = getName(localName, qName);
- if (name.equalsIgnoreCase(AD)) {
- AttributeDefinitionHandler attributeDefHandler = new AttributeDefinitionHandler(this);
- attributeDefHandler.init(name, atts, _ad_vector);
- } else if (name.equalsIgnoreCase(ICON)) {
- IconHandler iconHandler = new IconHandler(this);
- iconHandler.init(name, atts);
- if (iconHandler._isParsedDataValid) {
- // Because XML schema allows at most one icon for
- // one OCD, if more than one icons are read from
- // MetaData, then only the final icon will be kept.
- _ocd.setIcon(iconHandler._icon);
- }
- } else {
- logger.log(LogService.LOG_WARNING, NLS.bind(MetaTypeMsg.UNEXPECTED_ELEMENT, name));
- }
- }
-
- protected void finished() {
-
- logger.log(LogService.LOG_DEBUG, "Here is OcdHandler():finished()"); //$NON-NLS-1$
- if (!_isParsedDataValid)
- return;
-
- if (_ad_vector.size() == 0) {
- // Schema defines at least one AD is required.
- _isParsedDataValid = false;
- logger.log(LogService.LOG_ERROR, "DataParser.finished() " + NLS.bind(MetaTypeMsg.MISSING_ELEMENT, AD, _refID)); //$NON-NLS-1$
- return;
- }
- // OCD gets all parsed ADs.
- Enumeration<AttributeDefinitionImpl> adKey = _ad_vector.elements();
- while (adKey.hasMoreElements()) {
- AttributeDefinitionImpl ad = adKey.nextElement();
- _ocd.addAttributeDefinition(ad, ad._isRequired);
- }
-
- _parent_OCDs_hashtable.put(_refID, _ocd);
- }
- }
-
- /**
- * Handler for the Icon element.
- */
- private class IconHandler extends AbstractHandler {
-
- Icon _icon;
-
- public IconHandler(ContentHandler handler) {
- super(handler);
- }
-
- public void init(String name, Attributes atts) {
-
- logger.log(LogService.LOG_DEBUG, "Here is IconHandler:init()"); //$NON-NLS-1$
- String icon_resource_val = atts.getValue(RESOURCE);
- if (icon_resource_val == null) {
- _isParsedDataValid = false;
- logger.log(LogService.LOG_ERROR, "DataParser.init(String, Attributes) " + NLS.bind(MetaTypeMsg.MISSING_ATTRIBUTE, RESOURCE, name)); //$NON-NLS-1$
- return;
- }
-
- String icon_size_val = atts.getValue(SIZE);
- if (icon_size_val == null) {
- // Not a problem, because SIZE is an optional attribute.
- icon_size_val = "0"; //$NON-NLS-1$
- } else if (icon_size_val.equalsIgnoreCase("")) { //$NON-NLS-1$
- icon_size_val = "0"; //$NON-NLS-1$
- }
-
- _icon = new Icon(icon_resource_val, Integer.parseInt(icon_size_val), _dp_bundle);
- }
- }
-
- /**
- * Handler for the Attribute element.
- */
- private class AttributeDefinitionHandler extends AbstractHandler {
-
- AttributeDefinitionImpl _ad;
- int _dataType;
-
- Vector<AttributeDefinitionImpl> _parent_ADs_vector;
- Vector<String> _optionLabel_vector = new Vector<String>(7);
- Vector<String> _optionValue_vector = new Vector<String>(7);
-
- public AttributeDefinitionHandler(ContentHandler handler) {
- super(handler);
- }
-
- public void init(String name, Attributes atts, Vector<AttributeDefinitionImpl> ad_vector) {
-
- logger.log(LogService.LOG_DEBUG, "Here is AttributeDefinitionHandler():init()"); //$NON-NLS-1$
- _parent_ADs_vector = ad_vector;
-
- String ad_name_val = atts.getValue(NAME);
- if (ad_name_val == null) {
- // Not a problem, because NAME is an optional attribute.
- }
-
- String ad_description_val = atts.getValue(DESCRIPTION);
- if (ad_description_val == null) {
- // Not a problem, because DESCRIPTION is an optional attribute.
- }
-
- String ad_id_val = atts.getValue(ID);
- if (ad_id_val == null) {
- _isParsedDataValid = false;
- logger.log(LogService.LOG_ERROR, "DataParser.init(String, Attributes, Vector) " + NLS.bind(MetaTypeMsg.MISSING_ATTRIBUTE, ID, name)); //$NON-NLS-1$
- return;
- }
-
- String ad_type_val = atts.getValue(TYPE);
- if (ad_type_val == null) {
- _isParsedDataValid = false;
- logger.log(LogService.LOG_ERROR, "DataParser.init(String, Attributes, Vector) " + NLS.bind(MetaTypeMsg.MISSING_ATTRIBUTE, TYPE, name)); //$NON-NLS-1$
- return;
- }
- if (ad_type_val.equalsIgnoreCase(STRING)) {
- _dataType = AttributeDefinition.STRING;
- } else if (ad_type_val.equalsIgnoreCase(LONG)) {
- _dataType = AttributeDefinition.LONG;
- } else if (ad_type_val.equalsIgnoreCase(DOUBLE)) {
- _dataType = AttributeDefinition.DOUBLE;
- } else if (ad_type_val.equalsIgnoreCase(FLOAT)) {
- _dataType = AttributeDefinition.FLOAT;
- } else if (ad_type_val.equalsIgnoreCase(INTEGER)) {
- _dataType = AttributeDefinition.INTEGER;
- } else if (ad_type_val.equalsIgnoreCase(BYTE)) {
- _dataType = AttributeDefinition.BYTE;
- } else if (ad_type_val.equalsIgnoreCase(CHAR)) {
- _dataType = AttributeDefinition.CHARACTER;
- } else if (ad_type_val.equalsIgnoreCase(BOOLEAN)) {
- _dataType = AttributeDefinition.BOOLEAN;
- } else if (ad_type_val.equalsIgnoreCase(SHORT)) {
- _dataType = AttributeDefinition.SHORT;
- } else if (ad_type_val.equalsIgnoreCase(PASSWORD)) {
- _dataType = AttributeDefinition.PASSWORD;
- } else {
- _isParsedDataValid = false;
- logger.log(LogService.LOG_ERROR, "DataParser.init(String, Attributes, Vector) " + NLS.bind(MetaTypeMsg.INVALID_TYPE, new Object[] {ad_type_val, _dp_url, _dp_bundle.getBundleId()})); //$NON-NLS-1$
- return;
- }
-
- String ad_cardinality_str = atts.getValue(CARDINALITY);
- int ad_cardinality_val = 0;
- if (ad_cardinality_str == null) {
- // Not a problem, because CARDINALITY is an optional attribute.
- // And the default value is 0.
- } else {
- ad_cardinality_val = Integer.parseInt(ad_cardinality_str);
- }
-
- String ad_min_val = atts.getValue(MIN);
- if (ad_min_val == null) {
- // Not a problem, because MIN is an optional attribute.
- }
-
- String ad_max_val = atts.getValue(MAX);
- if (ad_max_val == null) {
- // Not a problem, because MAX is an optional attribute.
- }
-
- String ad_defaults_str = atts.getValue(DEFAULT);
- if (ad_defaults_str == null) {
- // Not a problem, because DEFAULT is an optional attribute.
- }
-
- String ad_required_val = atts.getValue(REQUIRED);
- if (ad_required_val == null) {
- // Not a problem, because REQUIRED is an optional attribute.
- // And the default value is 'true'.
- ad_required_val = Boolean.TRUE.toString();
- }
-
- _ad = new AttributeDefinitionImpl(ad_id_val, ad_name_val, ad_description_val, _dataType, ad_cardinality_val, convert(ad_min_val, _dataType), convert(ad_max_val, _dataType), Boolean.valueOf(ad_required_val).booleanValue(), _dp_localization, logger);
-
- if (ad_defaults_str != null) {
- _ad.setDefaultValue(ad_defaults_str, true);
- }
- }
-
- public void startElement(String uri, String localName, String qName, Attributes atts) {
-
- logger.log(LogService.LOG_DEBUG, "Here is AttributeDefinitionHandler:startElement():" //$NON-NLS-1$
- + qName);
- if (!_isParsedDataValid)
- return;
-
- String name = getName(localName, qName);
- if (name.equalsIgnoreCase(OPTION)) {
- OptionHandler optionHandler = new OptionHandler(this);
- optionHandler.init(name, atts);
- if (optionHandler._isParsedDataValid) {
- // Only add valid Option
- _optionLabel_vector.addElement(optionHandler._label_val);
- _optionValue_vector.addElement(optionHandler._value_val);
- }
- } else {
- logger.log(LogService.LOG_WARNING, NLS.bind(MetaTypeMsg.UNEXPECTED_ELEMENT, name));
- }
- }
-
- protected void finished() {
-
- logger.log(LogService.LOG_DEBUG, "Here is AttributeDefinitionHandler():finished()"); //$NON-NLS-1$
- if (!_isParsedDataValid)
- return;
-
- _ad.setOption(_optionLabel_vector, _optionValue_vector, true);
- _parent_ADs_vector.addElement(_ad);
- }
- }
-
- /**
- * Handler for the Option element.
- */
- private class OptionHandler extends AbstractHandler {
-
- String _label_val;
- String _value_val;
-
- public OptionHandler(ContentHandler handler) {
- super(handler);
- }
-
- public void init(String name, Attributes atts) {
-
- logger.log(LogService.LOG_DEBUG, "Here is OptionHandler:init()"); //$NON-NLS-1$
- _label_val = atts.getValue(LABEL);
- if (_label_val == null) {
- _isParsedDataValid = false;
- logger.log(LogService.LOG_ERROR, "DataParser.init(String, Attributes) " + NLS.bind(MetaTypeMsg.MISSING_ATTRIBUTE, LABEL, name)); //$NON-NLS-1$
- return;
- }
-
- _value_val = atts.getValue(VALUE);
- if (_value_val == null) {
- _isParsedDataValid = false;
- logger.log(LogService.LOG_ERROR, "DataParser.init(String, Attributes) " + NLS.bind(MetaTypeMsg.MISSING_ATTRIBUTE, VALUE, name)); //$NON-NLS-1$
- return;
- }
- }
- }
-
- // /**
- // * Handler for the Simple Value element.
- // */
- // private class SimpleValueHandler extends AbstractHandler {
- //
- // StringBuffer _buffer = new StringBuffer();
- // Vector _parent_value_vector;
- // String _elementName;
- //
- // public SimpleValueHandler(ContentHandler handler) {
- // super(handler);
- // }
- //
- // public void init(String name, Attributes atts, Vector value_vector)
- // throws SAXException {
- //
- // Logging.log(LogService.LOG_DEBUG,
- // "Here is SimpleValueHandler():init()"); //$NON-NLS-1$
- // _elementName = name;
- // _parent_value_vector = value_vector;
- // }
- //
- // protected void finished() throws SAXException {
- //
- // Logging.log(LogService.LOG_DEBUG,
- // "Here is SimpleValueHandler():finished()"); //$NON-NLS-1$
- // if (_parent_value_vector != null) {
- // _parent_value_vector.addElement(_buffer.toString());
- // }
- // }
- //
- // public void characters(char buf[], int offset, int len)
- // throws SAXException {
- //
- // Logging.log(LogService.LOG_DEBUG,
- // "Here is SimpleValueHandler(" //$NON-NLS-1$
- // + _elementName
- // + "):characters():[" //$NON-NLS-1$
- // + new String(buf, offset, len)
- // + "]"); //$NON-NLS-1$
- // _buffer.append(new String(buf, offset, len));
- // }
- // }
-
- /**
- * Handler for the Designate element.
- */
- class DesignateHandler extends AbstractHandler {
-
- String _pid_val = null;
- String _factory_val = null;
- String _bundle_val = null; // Only used by RFC94
- boolean _optional_val = false; // Only used by RFC94
- boolean _merge_val = false; // Only used by RFC94
-
- // Referenced OCD ID
- String _ocdref;
-
- public DesignateHandler(ContentHandler handler) {
- super(handler);
- }
-
- public void init(String name, Attributes atts) {
-
- logger.log(LogService.LOG_DEBUG, "Here is DesignateHandler():init()"); //$NON-NLS-1$
- _pid_val = atts.getValue(PID);
- _factory_val = atts.getValue(FACTORY);
- if (_pid_val == null && _factory_val == null) {
- _isParsedDataValid = false;
- logger.log(LogService.LOG_ERROR, MetaTypeMsg.MISSING_DESIGNATE_PID_AND_FACTORYPID);
- return;
- }
-
- _bundle_val = atts.getValue(BUNDLE);
- if (_bundle_val == null) {
- // Not a problem because BUNDLE is an optional attribute.
- }
-
- String optional_str = atts.getValue(OPTIONAL);
- if (optional_str == null) {
- // Not a problem, because OPTIONAL is an optional attribute.
- // The default value is "false".
- _optional_val = false;
- } else {
- _optional_val = Boolean.valueOf(optional_str).booleanValue();
- }
-
- String merge_str = atts.getValue(MERGE);
- if (merge_str == null) {
- // Not a problem, because MERGE is an optional attribute.
- // The default value is "false".
- _merge_val = false;
- } else {
- _merge_val = Boolean.valueOf(merge_str).booleanValue();
- }
- }
-
- public void startElement(String uri, String localName, String qName, Attributes atts) {
-
- logger.log(LogService.LOG_DEBUG, "Here is DesignateHandler:startElement():" //$NON-NLS-1$
- + qName);
- if (!_isParsedDataValid)
- return;
-
- String name = getName(localName, qName);
- if (name.equalsIgnoreCase(OBJECT)) {
- ObjectHandler objectHandler = new ObjectHandler(this);
- objectHandler.init(name, atts);
- if (objectHandler._isParsedDataValid) {
- _ocdref = objectHandler._ocdref;
- }
- } else {
- logger.log(LogService.LOG_WARNING, NLS.bind(MetaTypeMsg.UNEXPECTED_ELEMENT, name));
- }
- }
-
- protected void finished() {
-
- logger.log(LogService.LOG_DEBUG, "Here is DesignateHandler():finished()"); //$NON-NLS-1$
- if (!_isParsedDataValid)
- return;
-
- if (_ocdref == null) {
- _isParsedDataValid = false;
- // Schema defines at least one OBJECT is required.
- logger.log(LogService.LOG_ERROR, "DataParser.finished() " + NLS.bind(MetaTypeMsg.MISSING_ELEMENT, OBJECT, _pid_val)); //$NON-NLS-1$
- return;
-
- }
- }
- }
-
- /**
- * Handler for the Object element.
- */
- private class ObjectHandler extends AbstractHandler {
-
- String _ocdref;
-
- public ObjectHandler(ContentHandler handler) {
- super(handler);
- }
-
- public void init(String name, Attributes atts) {
-
- logger.log(LogService.LOG_DEBUG, "Here is ObjectHandler():init()"); //$NON-NLS-1$
- _ocdref = atts.getValue(OCDREF);
- if (_ocdref == null) {
- _isParsedDataValid = false;
- logger.log(LogService.LOG_ERROR, "DataParser.init(String, Attributes) " + NLS.bind(MetaTypeMsg.MISSING_ATTRIBUTE, OCDREF, name)); //$NON-NLS-1$
- return;
- }
- }
-
- public void startElement(String uri, String localName, String qName, Attributes atts) {
-
- logger.log(LogService.LOG_DEBUG, "Here is ObjectHandler:startElement():" //$NON-NLS-1$
- + qName);
- if (!_isParsedDataValid)
- return;
-
- String name = getName(localName, qName);
- if (name.equalsIgnoreCase(ATTRIBUTE)) {
- AttributeHandler attributeHandler = new AttributeHandler(this);
- attributeHandler.init(name, atts);
- // The ATTRIBUTE element is only used by RFC94, do nothing for it here.
- } else {
- logger.log(LogService.LOG_WARNING, NLS.bind(MetaTypeMsg.UNEXPECTED_ELEMENT, name));
- }
- }
- }
-
- /**
- * Handler for the Attribute element.
- *
- * This Handler is only used by RFC94.
- */
- private class AttributeHandler extends AbstractHandler {
-
- String _adref_val;
- String _content_val;
-
- public AttributeHandler(ContentHandler handler) {
- super(handler);
- }
-
- public void init(String name, Attributes atts) {
-
- logger.log(LogService.LOG_DEBUG, "Here is AttributeHandler():init()"); //$NON-NLS-1$
- _adref_val = atts.getValue(ADREF);
- if (_adref_val == null) {
- _isParsedDataValid = false;
- logger.log(LogService.LOG_ERROR, "DataParser.init(String, Attributes) " + NLS.bind(MetaTypeMsg.MISSING_ATTRIBUTE, ADREF, name)); //$NON-NLS-1$
- return;
- }
-
- _content_val = atts.getValue(CONTENT);
- if (_content_val == null) {
- _isParsedDataValid = false;
- logger.log(LogService.LOG_ERROR, "DataParser.init(String, Attributes) " + NLS.bind(MetaTypeMsg.MISSING_ATTRIBUTE, CONTENT, name)); //$NON-NLS-1$
- return;
- }
- }
- }
-
- /**
- * Error Handler to report errors and warnings
- */
- private static class MyErrorHandler implements ErrorHandler {
-
- /** Error handler output goes here */
- private PrintStream _out;
-
- MyErrorHandler(PrintStream out) {
- this._out = out;
- }
-
- /**
- * Returns a string describing parse exception details
- */
- private String getParseExceptionInfo(SAXParseException spe) {
- String systemId = spe.getSystemId();
- if (systemId == null) {
- systemId = "null"; //$NON-NLS-1$
- }
- String info = "URI=" + systemId + //$NON-NLS-1$
- " Line=" + spe.getLineNumber() + //$NON-NLS-1$
- ": " + spe.getMessage(); //$NON-NLS-1$
-
- return info;
- }
-
- // The following methods are standard SAX ErrorHandler methods.
- // See SAX documentation for more info.
-
- public void warning(SAXParseException spe) {
- _out.println("Warning: " + getParseExceptionInfo(spe)); //$NON-NLS-1$
- }
-
- public void error(SAXParseException spe) throws SAXException {
- String message = "Error: " + getParseExceptionInfo(spe); //$NON-NLS-1$
- throw new SAXException(message);
- }
-
- public void fatalError(SAXParseException spe) throws SAXException {
- String message = "Fatal Error: " + getParseExceptionInfo(spe); //$NON-NLS-1$
- throw new SAXException(message);
- }
- }
-
- public static String getName(String localName, String qName) {
- if (localName != null && localName.length() > 0) {
- return localName;
- }
-
- int nameSpaceIndex = qName.indexOf(":"); //$NON-NLS-1$
- return nameSpaceIndex == -1 ? qName : qName.substring(nameSpaceIndex + 1);
- }
-}
+/*******************************************************************************
+ * Copyright (c) 2005, 2011 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.equinox.metatype.impl;
+
+import java.io.*;
+import java.math.BigDecimal;
+import java.math.BigInteger;
+import java.net.URL;
+import java.util.*;
+import javax.xml.parsers.SAXParser;
+import org.eclipse.osgi.util.NLS;
+import org.osgi.framework.Bundle;
+import org.osgi.service.log.LogService;
+import org.osgi.service.metatype.AttributeDefinition;
+import org.xml.sax.*;
+import org.xml.sax.helpers.DefaultHandler;
+
+/**
+ * Meta XML Data Parser
+ */
+public class DataParser {
+ private static final String METADATA = "MetaData"; //$NON-NLS-1$
+ private static final String LOCALIZATION = "localization"; //$NON-NLS-1$
+ private static final String OCD = "OCD"; //$NON-NLS-1$
+ private static final String ICON = "Icon"; //$NON-NLS-1$
+ private static final String AD = "AD"; //$NON-NLS-1$
+ private static final String CARDINALITY = "cardinality"; //$NON-NLS-1$
+ private static final String OPTION = "Option"; //$NON-NLS-1$
+ private static final String LABEL = "label"; //$NON-NLS-1$
+ private static final String VALUE = "value"; //$NON-NLS-1$
+ private static final String MIN = "min"; //$NON-NLS-1$
+ private static final String MAX = "max"; //$NON-NLS-1$
+ private static final String TYPE = "type"; //$NON-NLS-1$
+ private static final String SIZE = "size"; //$NON-NLS-1$
+ private static final String ID = "id"; //$NON-NLS-1$
+ private static final String NAME = "name"; //$NON-NLS-1$
+ private static final String DESCRIPTION = "description"; //$NON-NLS-1$
+ private static final String RESOURCE = "resource"; //$NON-NLS-1$
+ private static final String PID = "pid"; //$NON-NLS-1$
+ private static final String DEFAULT = "default"; //$NON-NLS-1$
+ private static final String ADREF = "adref"; //$NON-NLS-1$
+ private static final String CONTENT = "content"; //$NON-NLS-1$
+ private static final String FACTORY = "factoryPid"; //$NON-NLS-1$
+ private static final String BUNDLE = "bundle"; //$NON-NLS-1$
+ private static final String OPTIONAL = "optional"; //$NON-NLS-1$
+ private static final String OBJECT = "Object"; //$NON-NLS-1$
+ private static final String OCDREF = "ocdref"; //$NON-NLS-1$
+ private static final String ATTRIBUTE = "Attribute"; //$NON-NLS-1$
+ private static final String DESIGNATE = "Designate"; //$NON-NLS-1$
+ private static final String MERGE = "merge"; //$NON-NLS-1$
+ private static final String REQUIRED = "required"; //$NON-NLS-1$
+
+ private static final String INTEGER = "Integer"; //$NON-NLS-1$
+ private static final String STRING = "String"; //$NON-NLS-1$
+ private static final String FLOAT = "Float"; //$NON-NLS-1$
+ private static final String DOUBLE = "Double"; //$NON-NLS-1$
+ private static final String BYTE = "Byte"; //$NON-NLS-1$
+ private static final String LONG = "Long"; //$NON-NLS-1$
+ private static final String CHAR = "Char"; //$NON-NLS-1$
+ private static final String BOOLEAN = "Boolean"; //$NON-NLS-1$
+ private static final String SHORT = "Short"; //$NON-NLS-1$
+ private static final String PASSWORD = "Password"; //$NON-NLS-1$
+
+ protected Bundle _dp_bundle;
+ protected URL _dp_url;
+ protected SAXParser _dp_parser;
+ protected XMLReader _dp_xmlReader;
+
+ // DesignateHanders in DataParser class
+ Vector<DesignateHandler> _dp_designateHandlers = new Vector<DesignateHandler>(7);
+ // ObjectClassDefinitions in DataParser class w/ corresponding reference keys
+ Hashtable<String, ObjectClassDefinitionImpl> _dp_OCDs = new Hashtable<String, ObjectClassDefinitionImpl>(7);
+ // Localization in DataParser class
+ String _dp_localization;
+
+ // Default visibility to avoid a plethora of synthetic accessor method warnings.
+ final LogService logger;
+ final Collection<Designate> designates = new ArrayList<Designate>(7);
+
+ /*
+ * Constructor of class DataParser.
+ */
+ public DataParser(Bundle bundle, URL url, SAXParser parser, LogService logger) {
+
+ this._dp_bundle = bundle;
+ this._dp_url = url;
+ this._dp_parser = parser;
+ this.logger = logger;
+ }
+
+ /*
+ * Main method to parse specific MetaData file.
+ */
+ public Collection<Designate> doParse() throws IOException, SAXException {
+ _dp_xmlReader = _dp_parser.getXMLReader();
+ _dp_xmlReader.setContentHandler(new RootHandler());
+ _dp_xmlReader.setErrorHandler(new MyErrorHandler(System.err));
+ InputStream is = _dp_url.openStream();
+ InputSource isource = new InputSource(is);
+ logger.log(LogService.LOG_DEBUG, "Starting to parse " + _dp_url); //$NON-NLS-1$
+ _dp_xmlReader.parse(isource);
+ return designates;
+ }
+
+ /*
+ * Convert String for expected data type.
+ */
+ static Object convert(String value, int type) {
+
+ if (value == null) {
+ return null;
+ }
+
+ switch (type) {
+ // PASSWORD should be treated like STRING.
+ case AttributeDefinition.PASSWORD :
+ case AttributeDefinition.STRING :
+ // Both the min and max of STRING are Integers.
+ return new Integer(value);
+ case AttributeDefinition.LONG :
+ return new Long(value);
+ case AttributeDefinition.INTEGER :
+ return new Integer(value);
+ case AttributeDefinition.SHORT :
+ return new Short(value);
+ case AttributeDefinition.CHARACTER :
+ return new Character(value.charAt(0));
+ case AttributeDefinition.BYTE :
+ return new Byte(value);
+ case AttributeDefinition.DOUBLE :
+ return new Double(value);
+ case AttributeDefinition.FLOAT :
+ return new Float(value);
+ case AttributeDefinition.BIGINTEGER :
+ return new BigInteger(value);
+ case AttributeDefinition.BIGDECIMAL :
+ return new BigDecimal(value);
+ case AttributeDefinition.BOOLEAN :
+ return new Boolean(value);
+ default :
+ // Unknown data type
+ return null;
+ }
+ }
+
+ /**
+ * Abstract of all Handlers.
+ */
+ private class AbstractHandler extends DefaultHandler {
+ protected ContentHandler _doc_handler;
+ protected boolean _isParsedDataValid = true;
+ protected Map<String, Map<String, String>> extensionAttributes = new HashMap<String, Map<String, String>>();
+
+ public AbstractHandler(ContentHandler parentHandler) {
+ this._doc_handler = parentHandler;
+ _dp_xmlReader.setContentHandler(this);
+ }
+
+ public void endElement(String namespaceURI, String localName, String qName) {
+ finished();
+ // Let parent resume handling SAX events
+ _dp_xmlReader.setContentHandler(_doc_handler);
+ }
+
+ public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException {
+ throw new SAXException(NLS.bind(MetaTypeMsg.UNEXPECTED_ELEMENT, qName));
+ }
+
+ public void characters(char[] buf, int start, int end) throws SAXException {
+ String s = new String(buf, start, end).trim();
+ if (s.length() > 0) {
+ throw new SAXException(NLS.bind(MetaTypeMsg.UNEXPECTED_TEXT, s));
+ }
+ }
+
+ protected void collectExtensionAttributes(Attributes attributes) {
+ for (int i = 0; i < attributes.getLength(); i++) {
+ String key = attributes.getURI(i);
+ if (key.length() == 0 || key.startsWith("http://www.osgi.org/xmlns/metatype/v")) //$NON-NLS-1$
+ continue;
+ Map<String, String> value = extensionAttributes.get(key);
+ if (value == null) {
+ value = new HashMap<String, String>();
+ extensionAttributes.put(key, value);
+ }
+ value.put(getName(attributes.getLocalName(i), attributes.getQName(i)), attributes.getValue(i));
+ }
+ }
+
+ /**
+ * Called when this element and all elements nested into it have been
+ * handled.
+ */
+ protected void finished() {
+ // do nothing by default
+ }
+ }
+
+ /**
+ * Handler for the root element.
+ */
+ private class RootHandler extends DefaultHandler {
+
+ public RootHandler() {
+ super();
+ }
+
+ public void startElement(String uri, String localName, String qName, Attributes attributes) {
+
+ logger.log(LogService.LOG_DEBUG, "Here is AbstractHandler:startElement():" //$NON-NLS-1$
+ + qName);
+ String name = getName(localName, qName);
+ if (name.equalsIgnoreCase(METADATA)) {
+ new MetaDataHandler(this).init(name, attributes);
+ } else {
+ logger.log(LogService.LOG_WARNING, NLS.bind(MetaTypeMsg.UNEXPECTED_ELEMENT, name));
+ }
+ }
+
+ public void setDocumentLocator(Locator locator) {
+ // do nothing
+ }
+ }
+
+ /**
+ * Handler for the MetaData element.
+ */
+ private class MetaDataHandler extends AbstractHandler {
+
+ public MetaDataHandler(ContentHandler handler) {
+ super(handler);
+ }
+
+ public void init(String name, Attributes attributes) {
+
+ logger.log(LogService.LOG_DEBUG, "Here is MetaDataHandler():init()"); //$NON-NLS-1$
+ _dp_localization = attributes.getValue(LOCALIZATION);
+ if (_dp_localization == null) {
+ // Not a problem, because LOCALIZATION is an optional attribute.
+ }
+ // The global variable "_dp_localization" will be used within
+ // OcdHandler and AttributeDefinitionHandler later.
+ }
+
+ public void startElement(String uri, String localName, String qName, Attributes atts) {
+
+ logger.log(LogService.LOG_DEBUG, "Here is MetaDataHandler:startElement():" //$NON-NLS-1$
+ + qName);
+ String name = getName(localName, qName);
+ if (name.equalsIgnoreCase(DESIGNATE)) {
+ DesignateHandler designateHandler = new DesignateHandler(this);
+ designateHandler.init(name, atts);
+ if (designateHandler._isParsedDataValid) {
+ _dp_designateHandlers.addElement(designateHandler);
+ }
+ } else if (name.equalsIgnoreCase(OCD)) {
+ OcdHandler ocdHandler = new OcdHandler(this);
+ ocdHandler.init(name, atts, _dp_OCDs);
+ } else {
+ logger.log(LogService.LOG_WARNING, NLS.bind(MetaTypeMsg.UNEXPECTED_ELEMENT, name));
+ }
+ }
+
+ protected void finished() {
+
+ logger.log(LogService.LOG_DEBUG, "Here is MetaDataHandler():finished()"); //$NON-NLS-1$
+ if (_dp_designateHandlers.size() == 0) {
+ // Schema defines at least one DESIGNATE is required.
+ _isParsedDataValid = false;
+ logger.log(LogService.LOG_WARNING, "DataParser.finished() " + NLS.bind(MetaTypeMsg.MISSING_ELEMENT, DESIGNATE)); //$NON-NLS-1$
+ return;
+ }
+ Enumeration<DesignateHandler> designateHandlerKeys = _dp_designateHandlers.elements();
+ while (designateHandlerKeys.hasMoreElements()) {
+ DesignateHandler dh = designateHandlerKeys.nextElement();
+
+ ObjectClassDefinitionImpl ocd = _dp_OCDs.get(dh._ocdref);
+ if (ocd != null) {
+ designates.add(new Designate.Builder(ocd).bundle(dh._bundle_val).factoryPid(dh._factory_val).merge(dh._merge_val).pid(dh._pid_val).optional(dh._optional_val).build());
+ } else {
+ logger.log(LogService.LOG_ERROR, "DataParser.finished() " + NLS.bind(MetaTypeMsg.OCD_ID_NOT_FOUND, dh._ocdref)); //$NON-NLS-1$
+
+ }
+ }
+ }
+ }
+
+ /**
+ * Handler for the ObjectClassDefinition element.
+ */
+ private class OcdHandler extends AbstractHandler {
+
+ Hashtable<String, ObjectClassDefinitionImpl> _parent_OCDs_hashtable;
+ // This ID "_refID" is only used for reference by Designate element,
+ // not the PID or FPID of this OCD.
+ String _refID;
+ ObjectClassDefinitionImpl _ocd;
+ Vector<AttributeDefinitionImpl> _ad_vector = new Vector<AttributeDefinitionImpl>(7);
+
+ public OcdHandler(ContentHandler handler) {
+ super(handler);
+ }
+
+ public void init(String name, Attributes atts, Hashtable<String, ObjectClassDefinitionImpl> ocds_hashtable) {
+
+ logger.log(LogService.LOG_DEBUG, "Here is OcdHandler():init()"); //$NON-NLS-1$
+ _parent_OCDs_hashtable = ocds_hashtable;
+ collectExtensionAttributes(atts);
+ String ocd_name_val = atts.getValue(NAME);
+ if (ocd_name_val == null) {
+ _isParsedDataValid = false;
+ logger.log(LogService.LOG_ERROR, "DataParser.init(String, Attributes, Hashtable) " + NLS.bind(MetaTypeMsg.MISSING_ATTRIBUTE, NAME, name)); //$NON-NLS-1$
+ return;
+ }
+
+ String ocd_description_val = atts.getValue(DESCRIPTION);
+ if (ocd_description_val == null) {
+ // Not a problem, because DESCRIPTION is an optional attribute.
+ }
+
+ _refID = atts.getValue(ID);
+ if (_refID == null) {
+ _isParsedDataValid = false;
+ logger.log(LogService.LOG_ERROR, "DataParser.init(String, Attributes, Hashtable) " + NLS.bind(MetaTypeMsg.MISSING_ATTRIBUTE, ID, name)); //$NON-NLS-1$
+ return;
+ }
+
+ _ocd = new ObjectClassDefinitionImpl(ocd_name_val, ocd_description_val, _refID, _dp_localization, extensionAttributes);
+ }
+
+ public void startElement(String uri, String localName, String qName, Attributes atts) {
+
+ logger.log(LogService.LOG_DEBUG, "Here is OcdHandler:startElement():" //$NON-NLS-1$
+ + qName);
+ if (!_isParsedDataValid)
+ return;
+
+ String name = getName(localName, qName);
+ if (name.equalsIgnoreCase(AD)) {
+ AttributeDefinitionHandler attributeDefHandler = new AttributeDefinitionHandler(this);
+ attributeDefHandler.init(name, atts, _ad_vector);
+ } else if (name.equalsIgnoreCase(ICON)) {
+ IconHandler iconHandler = new IconHandler(this);
+ iconHandler.init(name, atts);
+ if (iconHandler._isParsedDataValid) {
+ // Because XML schema allows at most one icon for
+ // one OCD, if more than one icons are read from
+ // MetaData, then only the final icon will be kept.
+ _ocd.setIcon(iconHandler._icon);
+ }
+ } else {
+ logger.log(LogService.LOG_WARNING, NLS.bind(MetaTypeMsg.UNEXPECTED_ELEMENT, name));
+ }
+ }
+
+ protected void finished() {
+
+ logger.log(LogService.LOG_DEBUG, "Here is OcdHandler():finished()"); //$NON-NLS-1$
+ if (!_isParsedDataValid)
+ return;
+
+ if (_ad_vector.size() == 0) {
+ // Schema defines at least one AD is required.
+ _isParsedDataValid = false;
+ logger.log(LogService.LOG_ERROR, "DataParser.finished() " + NLS.bind(MetaTypeMsg.MISSING_ELEMENT, AD, _refID)); //$NON-NLS-1$
+ return;
+ }
+ // OCD gets all parsed ADs.
+ Enumeration<AttributeDefinitionImpl> adKey = _ad_vector.elements();
+ while (adKey.hasMoreElements()) {
+ AttributeDefinitionImpl ad = adKey.nextElement();
+ _ocd.addAttributeDefinition(ad, ad._isRequired);
+ }
+
+ _parent_OCDs_hashtable.put(_refID, _ocd);
+ }
+ }
+
+ /**
+ * Handler for the Icon element.
+ */
+ private class IconHandler extends AbstractHandler {
+
+ Icon _icon;
+
+ public IconHandler(ContentHandler handler) {
+ super(handler);
+ }
+
+ public void init(String name, Attributes atts) {
+
+ logger.log(LogService.LOG_DEBUG, "Here is IconHandler:init()"); //$NON-NLS-1$
+ String icon_resource_val = atts.getValue(RESOURCE);
+ if (icon_resource_val == null) {
+ _isParsedDataValid = false;
+ logger.log(LogService.LOG_ERROR, "DataParser.init(String, Attributes) " + NLS.bind(MetaTypeMsg.MISSING_ATTRIBUTE, RESOURCE, name)); //$NON-NLS-1$
+ return;
+ }
+
+ String icon_size_val = atts.getValue(SIZE);
+ if (icon_size_val == null) {
+ // Not a problem, because SIZE is an optional attribute.
+ icon_size_val = "0"; //$NON-NLS-1$
+ } else if (icon_size_val.equalsIgnoreCase("")) { //$NON-NLS-1$
+ icon_size_val = "0"; //$NON-NLS-1$
+ }
+
+ _icon = new Icon(icon_resource_val, Integer.parseInt(icon_size_val), _dp_bundle);
+ }
+ }
+
+ /**
+ * Handler for the Attribute element.
+ */
+ private class AttributeDefinitionHandler extends AbstractHandler {
+
+ AttributeDefinitionImpl _ad;
+ int _dataType;
+
+ Vector<AttributeDefinitionImpl> _parent_ADs_vector;
+ Vector<String> _optionLabel_vector = new Vector<String>(7);
+ Vector<String> _optionValue_vector = new Vector<String>(7);
+
+ public AttributeDefinitionHandler(ContentHandler handler) {
+ super(handler);
+ }
+
+ public void init(String name, Attributes atts, Vector<AttributeDefinitionImpl> ad_vector) {
+
+ logger.log(LogService.LOG_DEBUG, "Here is AttributeDefinitionHandler():init()"); //$NON-NLS-1$
+ _parent_ADs_vector = ad_vector;
+ collectExtensionAttributes(atts);
+ String ad_name_val = atts.getValue(NAME);
+ if (ad_name_val == null) {
+ // Not a problem, because NAME is an optional attribute.
+ }
+
+ String ad_description_val = atts.getValue(DESCRIPTION);
+ if (ad_description_val == null) {
+ // Not a problem, because DESCRIPTION is an optional attribute.
+ }
+
+ String ad_id_val = atts.getValue(ID);
+ if (ad_id_val == null) {
+ _isParsedDataValid = false;
+ logger.log(LogService.LOG_ERROR, "DataParser.init(String, Attributes, Vector) " + NLS.bind(MetaTypeMsg.MISSING_ATTRIBUTE, ID, name)); //$NON-NLS-1$
+ return;
+ }
+
+ String ad_type_val = atts.getValue(TYPE);
+ if (ad_type_val == null) {
+ _isParsedDataValid = false;
+ logger.log(LogService.LOG_ERROR, "DataParser.init(String, Attributes, Vector) " + NLS.bind(MetaTypeMsg.MISSING_ATTRIBUTE, TYPE, name)); //$NON-NLS-1$
+ return;
+ }
+ if (ad_type_val.equalsIgnoreCase(STRING)) {
+ _dataType = AttributeDefinition.STRING;
+ } else if (ad_type_val.equalsIgnoreCase(LONG)) {
+ _dataType = AttributeDefinition.LONG;
+ } else if (ad_type_val.equalsIgnoreCase(DOUBLE)) {
+ _dataType = AttributeDefinition.DOUBLE;
+ } else if (ad_type_val.equalsIgnoreCase(FLOAT)) {
+ _dataType = AttributeDefinition.FLOAT;
+ } else if (ad_type_val.equalsIgnoreCase(INTEGER)) {
+ _dataType = AttributeDefinition.INTEGER;
+ } else if (ad_type_val.equalsIgnoreCase(BYTE)) {
+ _dataType = AttributeDefinition.BYTE;
+ } else if (ad_type_val.equalsIgnoreCase(CHAR)) {
+ _dataType = AttributeDefinition.CHARACTER;
+ } else if (ad_type_val.equalsIgnoreCase(BOOLEAN)) {
+ _dataType = AttributeDefinition.BOOLEAN;
+ } else if (ad_type_val.equalsIgnoreCase(SHORT)) {
+ _dataType = AttributeDefinition.SHORT;
+ } else if (ad_type_val.equalsIgnoreCase(PASSWORD)) {
+ _dataType = AttributeDefinition.PASSWORD;
+ } else {
+ _isParsedDataValid = false;
+ logger.log(LogService.LOG_ERROR, "DataParser.init(String, Attributes, Vector) " + NLS.bind(MetaTypeMsg.INVALID_TYPE, new Object[] {ad_type_val, _dp_url, _dp_bundle.getBundleId()})); //$NON-NLS-1$
+ return;
+ }
+
+ String ad_cardinality_str = atts.getValue(CARDINALITY);
+ int ad_cardinality_val = 0;
+ if (ad_cardinality_str == null) {
+ // Not a problem, because CARDINALITY is an optional attribute.
+ // And the default value is 0.
+ } else {
+ ad_cardinality_val = Integer.parseInt(ad_cardinality_str);
+ }
+
+ String ad_min_val = atts.getValue(MIN);
+ if (ad_min_val == null) {
+ // Not a problem, because MIN is an optional attribute.
+ }
+
+ String ad_max_val = atts.getValue(MAX);
+ if (ad_max_val == null) {
+ // Not a problem, because MAX is an optional attribute.
+ }
+
+ String ad_defaults_str = atts.getValue(DEFAULT);
+ if (ad_defaults_str == null) {
+ // Not a problem, because DEFAULT is an optional attribute.
+ }
+
+ String ad_required_val = atts.getValue(REQUIRED);
+ if (ad_required_val == null) {
+ // Not a problem, because REQUIRED is an optional attribute.
+ // And the default value is 'true'.
+ ad_required_val = Boolean.TRUE.toString();
+ }
+
+ _ad = new AttributeDefinitionImpl(ad_id_val, ad_name_val, ad_description_val, _dataType, ad_cardinality_val, convert(ad_min_val, _dataType), convert(ad_max_val, _dataType), Boolean.valueOf(ad_required_val).booleanValue(), _dp_localization, logger, extensionAttributes);
+
+ if (ad_defaults_str != null) {
+ _ad.setDefaultValue(ad_defaults_str, true);
+ }
+ }
+
+ public void startElement(String uri, String localName, String qName, Attributes atts) {
+
+ logger.log(LogService.LOG_DEBUG, "Here is AttributeDefinitionHandler:startElement():" //$NON-NLS-1$
+ + qName);
+ if (!_isParsedDataValid)
+ return;
+
+ String name = getName(localName, qName);
+ if (name.equalsIgnoreCase(OPTION)) {
+ OptionHandler optionHandler = new OptionHandler(this);
+ optionHandler.init(name, atts);
+ if (optionHandler._isParsedDataValid) {
+ // Only add valid Option
+ _optionLabel_vector.addElement(optionHandler._label_val);
+ _optionValue_vector.addElement(optionHandler._value_val);
+ }
+ } else {
+ logger.log(LogService.LOG_WARNING, NLS.bind(MetaTypeMsg.UNEXPECTED_ELEMENT, name));
+ }
+ }
+
+ protected void finished() {
+
+ logger.log(LogService.LOG_DEBUG, "Here is AttributeDefinitionHandler():finished()"); //$NON-NLS-1$
+ if (!_isParsedDataValid)
+ return;
+
+ _ad.setOption(_optionLabel_vector, _optionValue_vector, true);
+ _parent_ADs_vector.addElement(_ad);
+ }
+ }
+
+ /**
+ * Handler for the Option element.
+ */
+ private class OptionHandler extends AbstractHandler {
+
+ String _label_val;
+ String _value_val;
+
+ public OptionHandler(ContentHandler handler) {
+ super(handler);
+ }
+
+ public void init(String name, Attributes atts) {
+
+ logger.log(LogService.LOG_DEBUG, "Here is OptionHandler:init()"); //$NON-NLS-1$
+ _label_val = atts.getValue(LABEL);
+ if (_label_val == null) {
+ _isParsedDataValid = false;
+ logger.log(LogService.LOG_ERROR, "DataParser.init(String, Attributes) " + NLS.bind(MetaTypeMsg.MISSING_ATTRIBUTE, LABEL, name)); //$NON-NLS-1$
+ return;
+ }
+
+ _value_val = atts.getValue(VALUE);
+ if (_value_val == null) {
+ _isParsedDataValid = false;
+ logger.log(LogService.LOG_ERROR, "DataParser.init(String, Attributes) " + NLS.bind(MetaTypeMsg.MISSING_ATTRIBUTE, VALUE, name)); //$NON-NLS-1$
+ return;
+ }
+ }
+ }
+
+ // /**
+ // * Handler for the Simple Value element.
+ // */
+ // private class SimpleValueHandler extends AbstractHandler {
+ //
+ // StringBuffer _buffer = new StringBuffer();
+ // Vector _parent_value_vector;
+ // String _elementName;
+ //
+ // public SimpleValueHandler(ContentHandler handler) {
+ // super(handler);
+ // }
+ //
+ // public void init(String name, Attributes atts, Vector value_vector)
+ // throws SAXException {
+ //
+ // Logging.log(LogService.LOG_DEBUG,
+ // "Here is SimpleValueHandler():init()"); //$NON-NLS-1$
+ // _elementName = name;
+ // _parent_value_vector = value_vector;
+ // }
+ //
+ // protected void finished() throws SAXException {
+ //
+ // Logging.log(LogService.LOG_DEBUG,
+ // "Here is SimpleValueHandler():finished()"); //$NON-NLS-1$
+ // if (_parent_value_vector != null) {
+ // _parent_value_vector.addElement(_buffer.toString());
+ // }
+ // }
+ //
+ // public void characters(char buf[], int offset, int len)
+ // throws SAXException {
+ //
+ // Logging.log(LogService.LOG_DEBUG,
+ // "Here is SimpleValueHandler(" //$NON-NLS-1$
+ // + _elementName
+ // + "):characters():[" //$NON-NLS-1$
+ // + new String(buf, offset, len)
+ // + "]"); //$NON-NLS-1$
+ // _buffer.append(new String(buf, offset, len));
+ // }
+ // }
+
+ /**
+ * Handler for the Designate element.
+ */
+ class DesignateHandler extends AbstractHandler {
+
+ String _pid_val = null;
+ String _factory_val = null;
+ String _bundle_val = null; // Only used by RFC94
+ boolean _optional_val = false; // Only used by RFC94
+ boolean _merge_val = false; // Only used by RFC94
+
+ // Referenced OCD ID
+ String _ocdref;
+
+ public DesignateHandler(ContentHandler handler) {
+ super(handler);
+ }
+
+ public void init(String name, Attributes atts) {
+
+ logger.log(LogService.LOG_DEBUG, "Here is DesignateHandler():init()"); //$NON-NLS-1$
+ _pid_val = atts.getValue(PID);
+ _factory_val = atts.getValue(FACTORY);
+ if (_pid_val == null && _factory_val == null) {
+ _isParsedDataValid = false;
+ logger.log(LogService.LOG_ERROR, MetaTypeMsg.MISSING_DESIGNATE_PID_AND_FACTORYPID);
+ return;
+ }
+
+ _bundle_val = atts.getValue(BUNDLE);
+ if (_bundle_val == null) {
+ // Not a problem because BUNDLE is an optional attribute.
+ }
+
+ String optional_str = atts.getValue(OPTIONAL);
+ if (optional_str == null) {
+ // Not a problem, because OPTIONAL is an optional attribute.
+ // The default value is "false".
+ _optional_val = false;
+ } else {
+ _optional_val = Boolean.valueOf(optional_str).booleanValue();
+ }
+
+ String merge_str = atts.getValue(MERGE);
+ if (merge_str == null) {
+ // Not a problem, because MERGE is an optional attribute.
+ // The default value is "false".
+ _merge_val = false;
+ } else {
+ _merge_val = Boolean.valueOf(merge_str).booleanValue();
+ }
+ }
+
+ public void startElement(String uri, String localName, String qName, Attributes atts) {
+
+ logger.log(LogService.LOG_DEBUG, "Here is DesignateHandler:startElement():" //$NON-NLS-1$
+ + qName);
+ if (!_isParsedDataValid)
+ return;
+
+ String name = getName(localName, qName);
+ if (name.equalsIgnoreCase(OBJECT)) {
+ ObjectHandler objectHandler = new ObjectHandler(this);
+ objectHandler.init(name, atts);
+ if (objectHandler._isParsedDataValid) {
+ _ocdref = objectHandler._ocdref;
+ }
+ } else {
+ logger.log(LogService.LOG_WARNING, NLS.bind(MetaTypeMsg.UNEXPECTED_ELEMENT, name));
+ }
+ }
+
+ protected void finished() {
+
+ logger.log(LogService.LOG_DEBUG, "Here is DesignateHandler():finished()"); //$NON-NLS-1$
+ if (!_isParsedDataValid)
+ return;
+
+ if (_ocdref == null) {
+ _isParsedDataValid = false;
+ // Schema defines at least one OBJECT is required.
+ logger.log(LogService.LOG_ERROR, "DataParser.finished() " + NLS.bind(MetaTypeMsg.MISSING_ELEMENT, OBJECT, _pid_val)); //$NON-NLS-1$
+ return;
+
+ }
+ }
+ }
+
+ /**
+ * Handler for the Object element.
+ */
+ private class ObjectHandler extends AbstractHandler {
+
+ String _ocdref;
+
+ public ObjectHandler(ContentHandler handler) {
+ super(handler);
+ }
+
+ public void init(String name, Attributes atts) {
+
+ logger.log(LogService.LOG_DEBUG, "Here is ObjectHandler():init()"); //$NON-NLS-1$
+ _ocdref = atts.getValue(OCDREF);
+ if (_ocdref == null) {
+ _isParsedDataValid = false;
+ logger.log(LogService.LOG_ERROR, "DataParser.init(String, Attributes) " + NLS.bind(MetaTypeMsg.MISSING_ATTRIBUTE, OCDREF, name)); //$NON-NLS-1$
+ return;
+ }
+ }
+
+ public void startElement(String uri, String localName, String qName, Attributes atts) {
+
+ logger.log(LogService.LOG_DEBUG, "Here is ObjectHandler:startElement():" //$NON-NLS-1$
+ + qName);
+ if (!_isParsedDataValid)
+ return;
+
+ String name = getName(localName, qName);
+ if (name.equalsIgnoreCase(ATTRIBUTE)) {
+ AttributeHandler attributeHandler = new AttributeHandler(this);
+ attributeHandler.init(name, atts);
+ // The ATTRIBUTE element is only used by RFC94, do nothing for it here.
+ } else {
+ logger.log(LogService.LOG_WARNING, NLS.bind(MetaTypeMsg.UNEXPECTED_ELEMENT, name));
+ }
+ }
+ }
+
+ /**
+ * Handler for the Attribute element.
+ *
+ * This Handler is only used by RFC94.
+ */
+ private class AttributeHandler extends AbstractHandler {
+
+ String _adref_val;
+ String _content_val;
+
+ public AttributeHandler(ContentHandler handler) {
+ super(handler);
+ }
+
+ public void init(String name, Attributes atts) {
+
+ logger.log(LogService.LOG_DEBUG, "Here is AttributeHandler():init()"); //$NON-NLS-1$
+ _adref_val = atts.getValue(ADREF);
+ if (_adref_val == null) {
+ _isParsedDataValid = false;
+ logger.log(LogService.LOG_ERROR, "DataParser.init(String, Attributes) " + NLS.bind(MetaTypeMsg.MISSING_ATTRIBUTE, ADREF, name)); //$NON-NLS-1$
+ return;
+ }
+
+ _content_val = atts.getValue(CONTENT);
+ if (_content_val == null) {
+ _isParsedDataValid = false;
+ logger.log(LogService.LOG_ERROR, "DataParser.init(String, Attributes) " + NLS.bind(MetaTypeMsg.MISSING_ATTRIBUTE, CONTENT, name)); //$NON-NLS-1$
+ return;
+ }
+ }
+ }
+
+ /**
+ * Error Handler to report errors and warnings
+ */
+ private static class MyErrorHandler implements ErrorHandler {
+
+ /** Error handler output goes here */
+ private PrintStream _out;
+
+ MyErrorHandler(PrintStream out) {
+ this._out = out;
+ }
+
+ /**
+ * Returns a string describing parse exception details
+ */
+ private String getParseExceptionInfo(SAXParseException spe) {
+ String systemId = spe.getSystemId();
+ if (systemId == null) {
+ systemId = "null"; //$NON-NLS-1$
+ }
+ String info = "URI=" + systemId + //$NON-NLS-1$
+ " Line=" + spe.getLineNumber() + //$NON-NLS-1$
+ ": " + spe.getMessage(); //$NON-NLS-1$
+
+ return info;
+ }
+
+ // The following methods are standard SAX ErrorHandler methods.
+ // See SAX documentation for more info.
+
+ public void warning(SAXParseException spe) {
+ _out.println("Warning: " + getParseExceptionInfo(spe)); //$NON-NLS-1$
+ }
+
+ public void error(SAXParseException spe) throws SAXException {
+ String message = "Error: " + getParseExceptionInfo(spe); //$NON-NLS-1$
+ throw new SAXException(message);
+ }
+
+ public void fatalError(SAXParseException spe) throws SAXException {
+ String message = "Fatal Error: " + getParseExceptionInfo(spe); //$NON-NLS-1$
+ throw new SAXException(message);
+ }
+ }
+
+ public static String getName(String localName, String qName) {
+ if (localName != null && localName.length() > 0) {
+ return localName;
+ }
+
+ int nameSpaceIndex = qName.indexOf(":"); //$NON-NLS-1$
+ return nameSpaceIndex == -1 ? qName : qName.substring(nameSpaceIndex + 1);
+ }
+}
diff --git a/bundles/org.eclipse.equinox.metatype/src/org/eclipse/equinox/metatype/Designate.java b/bundles/org.eclipse.equinox.metatype/src/org/eclipse/equinox/metatype/impl/Designate.java
index 4b448e6..83b31b1 100644
--- a/bundles/org.eclipse.equinox.metatype/src/org/eclipse/equinox/metatype/Designate.java
+++ b/bundles/org.eclipse.equinox.metatype/src/org/eclipse/equinox/metatype/impl/Designate.java
@@ -1,104 +1,104 @@
-/*******************************************************************************
- * Copyright (c) 2011 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License v1.0
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/epl-v10.html
- *
- * Contributors:
- * IBM Corporation - initial API and implementation
- *******************************************************************************/
-package org.eclipse.equinox.metatype;
-
-import org.eclipse.osgi.util.NLS;
-
-public class Designate {
- public static class Builder {
- String bundle;
- String factoryPid;
- boolean merge;
- ObjectClassDefinitionImpl ocd;
- boolean optional;
- String pid;
-
- public Builder(ObjectClassDefinitionImpl ocd) {
- if (ocd == null) {
- throw new IllegalArgumentException(NLS.bind(MetaTypeMsg.MISSING_REQUIRED_PARAMETER, "ocd")); //$NON-NLS-1$
- }
- this.ocd = ocd;
- }
-
- public Designate build() {
- return new Designate(this);
- }
-
- public Builder bundle(String value) {
- bundle = value;
- return this;
- }
-
- public Builder factoryPid(String value) {
- factoryPid = value;
- return this;
- }
-
- public Builder merge(boolean value) {
- merge = value;
- return this;
- }
-
- public Builder optional(boolean value) {
- optional = value;
- return this;
- }
-
- public Builder pid(String value) {
- pid = value;
- return this;
- }
- }
-
- private final String bundle;
- private final String factoryPid;
- private final boolean merge;
- private final ObjectClassDefinitionImpl ocd;
- private final boolean optional;
- private final String pid;
-
- Designate(Builder b) {
- bundle = b.bundle;
- factoryPid = b.factoryPid;
- merge = b.merge;
- ocd = b.ocd;
- optional = b.optional;
- pid = b.pid;
- }
-
- public String getBundle() {
- return bundle;
- }
-
- public String getFactoryPid() {
- return factoryPid;
- }
-
- public boolean isFactory() {
- return factoryPid != null && factoryPid.length() != 0;
- }
-
- public boolean isMerge() {
- return merge;
- }
-
- public ObjectClassDefinitionImpl getObjectClassDefinition() {
- return ocd;
- }
-
- public boolean isOptional() {
- return optional;
- }
-
- public String getPid() {
- return pid;
- }
-}
+/*******************************************************************************
+ * Copyright (c) 2011 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.equinox.metatype.impl;
+
+import org.eclipse.osgi.util.NLS;
+
+public class Designate {
+ public static class Builder {
+ String bundle;
+ String factoryPid;
+ boolean merge;
+ ObjectClassDefinitionImpl ocd;
+ boolean optional;
+ String pid;
+
+ public Builder(ObjectClassDefinitionImpl ocd) {
+ if (ocd == null) {
+ throw new IllegalArgumentException(NLS.bind(MetaTypeMsg.MISSING_REQUIRED_PARAMETER, "ocd")); //$NON-NLS-1$
+ }
+ this.ocd = ocd;
+ }
+
+ public Designate build() {
+ return new Designate(this);
+ }
+
+ public Builder bundle(String value) {
+ bundle = value;
+ return this;
+ }
+
+ public Builder factoryPid(String value) {
+ factoryPid = value;
+ return this;
+ }
+
+ public Builder merge(boolean value) {
+ merge = value;
+ return this;
+ }
+
+ public Builder optional(boolean value) {
+ optional = value;
+ return this;
+ }
+
+ public Builder pid(String value) {
+ pid = value;
+ return this;
+ }
+ }
+
+ private final String bundle;
+ private final String factoryPid;
+ private final boolean merge;
+ private final ObjectClassDefinitionImpl ocd;
+ private final boolean optional;
+ private final String pid;
+
+ Designate(Builder b) {
+ bundle = b.bundle;
+ factoryPid = b.factoryPid;
+ merge = b.merge;
+ ocd = b.ocd;
+ optional = b.optional;
+ pid = b.pid;
+ }
+
+ public String getBundle() {
+ return bundle;
+ }
+
+ public String getFactoryPid() {
+ return factoryPid;
+ }
+
+ public boolean isFactory() {
+ return factoryPid != null && factoryPid.length() != 0;
+ }
+
+ public boolean isMerge() {
+ return merge;
+ }
+
+ public ObjectClassDefinitionImpl getObjectClassDefinition() {
+ return ocd;
+ }
+
+ public boolean isOptional() {
+ return optional;
+ }
+
+ public String getPid() {
+ return pid;
+ }
+}
diff --git a/bundles/org.eclipse.equinox.metatype/src/org/eclipse/equinox/metatype/impl/ExtendableHelper.java b/bundles/org.eclipse.equinox.metatype/src/org/eclipse/equinox/metatype/impl/ExtendableHelper.java
new file mode 100644
index 0000000..c48b753
--- /dev/null
+++ b/bundles/org.eclipse.equinox.metatype/src/org/eclipse/equinox/metatype/impl/ExtendableHelper.java
@@ -0,0 +1,39 @@
+/*******************************************************************************
+ * Copyright (c) 2011 IBM Corporation and others
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.equinox.metatype.impl;
+
+import org.eclipse.equinox.metatype.Extendable;
+
+import java.util.*;
+
+public class ExtendableHelper implements Extendable {
+ private final Map<String, Map<String, String>> attributes;
+
+ @SuppressWarnings("unchecked")
+ public ExtendableHelper() {
+ this(Collections.EMPTY_MAP);
+ }
+
+ public ExtendableHelper(Map<String, Map<String, String>> attributes) {
+ if (attributes == null)
+ throw new NullPointerException();
+ this.attributes = attributes;
+ }
+
+ public Map<String, String> getExtensionAttributes(String schema) {
+ return Collections.unmodifiableMap(attributes.get(schema));
+ }
+
+ public Set<String> getExtensionUris() {
+ return Collections.unmodifiableSet(attributes.keySet());
+ }
+
+}
diff --git a/bundles/org.eclipse.equinox.metatype/src/org/eclipse/equinox/metatype/ExternalMessages.properties b/bundles/org.eclipse.equinox.metatype/src/org/eclipse/equinox/metatype/impl/ExternalMessages.properties
index 820963a..ff60175 100644
--- a/bundles/org.eclipse.equinox.metatype/src/org/eclipse/equinox/metatype/ExternalMessages.properties
+++ b/bundles/org.eclipse.equinox.metatype/src/org/eclipse/equinox/metatype/impl/ExternalMessages.properties
@@ -1,37 +1,37 @@
-###############################################################################
-# Copyright (c) 2005, 2011 IBM Corporation.
-# All rights reserved. This program and the accompanying materials
-# are made available under the terms of the Eclipse Public License v1.0
-# which accompanies this distribution, and is available at
-# http://www.eclipse.org/legal/epl-v10.html
-#
-# Contributors:
-# IBM Corporation - initial API and implementation
-###############################################################################
-#External Messages for EN locale
-SERVICE_DESCRIPTION=OSGi Metatype Service - IBM Implementation
-
-UNEXPECTED_ELEMENT=Unexpected element {0}.
-UNEXPECTED_TEXT=Unexpected text {0}.
-MISSING_ATTRIBUTE=Missing attribute {0} in tag {1}.
-INVALID_TYPE=Invalid attribute definition type {0} in metadata XML at {1} for bundle ID {2}.
-MISSING_DESIGNATE_PID_AND_FACTORYPID=A <Designate> element must specify either the 'pid' or 'factoryPid' attribute.
-OCD_ID_NOT_FOUND=Object Class Definition ID not found {0}.
-MISSING_ELEMENT=Missing element {0} (Reference ID = {1}.
-
-EXCEPTION_MESSAGE=Unexpected exception {0} with message {1}.
-NULL_IS_INVALID=Cannot validate a null.
-VALUE_OUT_OF_RANGE=Value {0} is out of range.
-VALUE_OUT_OF_OPTION=Value {0} is out of Option.
-CARDINALITY_VIOLATION=Cardinality violation: \"{0}\" has {1} value(s) but must have between {2} and {3} value(s).
-NULL_OPTIONS=Cannot set Option labels or values as null.
-INCONSISTENT_OPTIONS=Labels and Values of Option have different sizes.
-INVALID_OPTIONS=Option value {0} is invalid because of {1}.
-INVALID_DEFAULTS=Dafaults value {0} is invalid because of {1}.
-
-METADATA_NOT_FOUND=Bundle(ID=\"{0}\", name=\"{1}\") has no MetaData file.
-ASK_INVALID_LOCALE=OCD(ID=\"{0}\") cannot support this locale \"{1}\".
-MISSING_REQUIRED_PARAMETER=Missing required parameter: {0}
-TOKENIZER_GOT_INVALID_DATA=The Tokenizer got invalid data.
-INVALID_PID_METATYPE_PROVIDER_IGNORED=Bundle {0} with ID {1} provided a MetaTypeProvider with an invalid property. Property {2} with value {3} was not of the expected type (String, String[], or Collection<String>) and will be ignored.
+###############################################################################
+# Copyright (c) 2005, 2011 IBM Corporation.
+# All rights reserved. This program and the accompanying materials
+# are made available under the terms of the Eclipse Public License v1.0
+# which accompanies this distribution, and is available at
+# http://www.eclipse.org/legal/epl-v10.html
+#
+# Contributors:
+# IBM Corporation - initial API and implementation
+###############################################################################
+#External Messages for EN locale
+SERVICE_DESCRIPTION=OSGi Metatype Service - IBM Implementation
+
+UNEXPECTED_ELEMENT=Unexpected element {0}.
+UNEXPECTED_TEXT=Unexpected text {0}.
+MISSING_ATTRIBUTE=Missing attribute {0} in tag {1}.
+INVALID_TYPE=Invalid attribute definition type {0} in metadata XML at {1} for bundle ID {2}.
+MISSING_DESIGNATE_PID_AND_FACTORYPID=A <Designate> element must specify either the 'pid' or 'factoryPid' attribute.
+OCD_ID_NOT_FOUND=Object Class Definition ID not found {0}.
+MISSING_ELEMENT=Missing element {0} (Reference ID = {1}.
+
+EXCEPTION_MESSAGE=Unexpected exception {0} with message {1}.
+NULL_IS_INVALID=Cannot validate a null.
+VALUE_OUT_OF_RANGE=Value {0} is out of range.
+VALUE_OUT_OF_OPTION=Value {0} is out of Option.
+CARDINALITY_VIOLATION=Cardinality violation: \"{0}\" has {1} value(s) but must have between {2} and {3} value(s).
+NULL_OPTIONS=Cannot set Option labels or values as null.
+INCONSISTENT_OPTIONS=Labels and Values of Option have different sizes.
+INVALID_OPTIONS=Option value {0} is invalid because of {1}.
+INVALID_DEFAULTS=Dafaults value {0} is invalid because of {1}.
+
+METADATA_NOT_FOUND=Bundle(ID=\"{0}\", name=\"{1}\") has no MetaData file.
+ASK_INVALID_LOCALE=OCD(ID=\"{0}\") cannot support this locale \"{1}\".
+MISSING_REQUIRED_PARAMETER=Missing required parameter: {0}
+TOKENIZER_GOT_INVALID_DATA=The Tokenizer got invalid data.
+INVALID_PID_METATYPE_PROVIDER_IGNORED=Bundle {0} with ID {1} provided a MetaTypeProvider with an invalid property. Property {2} with value {3} was not of the expected type (String, String[], or Collection<String>) and will be ignored.
METADATA_PARSE_ERROR=Unable to parse metadata XML at {0} for bundle ID {1}. \ No newline at end of file
diff --git a/bundles/org.eclipse.equinox.metatype/src/org/eclipse/equinox/metatype/FragmentUtils.java b/bundles/org.eclipse.equinox.metatype/src/org/eclipse/equinox/metatype/impl/FragmentUtils.java
index 0253eaa..0685e15 100644
--- a/bundles/org.eclipse.equinox.metatype/src/org/eclipse/equinox/metatype/FragmentUtils.java
+++ b/bundles/org.eclipse.equinox.metatype/src/org/eclipse/equinox/metatype/impl/FragmentUtils.java
@@ -1,58 +1,58 @@
-/*******************************************************************************
- * Copyright (c) 2005, 2011 IBM Corporation.
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License v1.0
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/epl-v10.html
- *
- * Contributors:
- * IBM Corporation - initial API and implementation
- *******************************************************************************/
-package org.eclipse.equinox.metatype;
-
-import java.net.URL;
-import java.util.List;
-import org.osgi.framework.Bundle;
-import org.osgi.framework.wiring.BundleRevision;
-import org.osgi.framework.wiring.BundleWiring;
-
-/*
- * Fragment Utilities
- */
-public class FragmentUtils {
-
- /*
- *
- */
- public static boolean isFragment(Bundle bundle) {
- return (bundle.adapt(BundleRevision.class).getTypes() & BundleRevision.TYPE_FRAGMENT) != 0;
- }
-
- /*
- * Find all the URLs to entries for the bundle and its fragments.
- */
- public static URL[] findEntries(Bundle bundle, String path) {
- BundleWiring wiring = bundle.adapt(BundleWiring.class);
- if (wiring == null)
- return null;
- String directory = "/"; //$NON-NLS-1$
- String file = "*"; //$NON-NLS-1$
- int index = path.lastIndexOf(MetaTypeProviderImpl.DIRECTORY_SEP);
- switch (index) {
- case -1 :
- file = path;
- break;
- case 0 :
- if (path.length() > 1)
- file = path.substring(1);
- break;
- default :
- directory = path.substring(0, index);
- file = path.substring(index + 1);
- }
- List<URL> entries = wiring.findEntries(directory, file, 0);
- if (entries == null)
- return null;
- return entries.toArray(new URL[entries.size()]);
- }
-}
+/*******************************************************************************
+ * Copyright (c) 2005, 2011 IBM Corporation.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.equinox.metatype.impl;
+
+import java.net.URL;
+import java.util.List;
+import org.osgi.framework.Bundle;
+import org.osgi.framework.wiring.BundleRevision;
+import org.osgi.framework.wiring.BundleWiring;
+
+/*
+ * Fragment Utilities
+ */
+public class FragmentUtils {
+
+ /*
+ *
+ */
+ public static boolean isFragment(Bundle bundle) {
+ return (bundle.adapt(BundleRevision.class).getTypes() & BundleRevision.TYPE_FRAGMENT) != 0;
+ }
+
+ /*
+ * Find all the URLs to entries for the bundle and its fragments.
+ */
+ public static URL[] findEntries(Bundle bundle, String path) {
+ BundleWiring wiring = bundle.adapt(BundleWiring.class);
+ if (wiring == null)
+ return null;
+ String directory = "/"; //$NON-NLS-1$
+ String file = "*"; //$NON-NLS-1$
+ int index = path.lastIndexOf(MetaTypeProviderImpl.DIRECTORY_SEP);
+ switch (index) {
+ case -1 :
+ file = path;
+ break;
+ case 0 :
+ if (path.length() > 1)
+ file = path.substring(1);
+ break;
+ default :
+ directory = path.substring(0, index);
+ file = path.substring(index + 1);
+ }
+ List<URL> entries = wiring.findEntries(directory, file, 0);
+ if (entries == null)
+ return null;
+ return entries.toArray(new URL[entries.size()]);
+ }
+}
diff --git a/bundles/org.eclipse.equinox.metatype/src/org/eclipse/equinox/metatype/Icon.java b/bundles/org.eclipse.equinox.metatype/src/org/eclipse/equinox/metatype/impl/Icon.java
index 8817f8c..1613097 100644
--- a/bundles/org.eclipse.equinox.metatype/src/org/eclipse/equinox/metatype/Icon.java
+++ b/bundles/org.eclipse.equinox.metatype/src/org/eclipse/equinox/metatype/impl/Icon.java
@@ -1,72 +1,72 @@
-/*******************************************************************************
- * Copyright (c) 2005 IBM Corporation.
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License v1.0
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/epl-v10.html
- *
- * Contributors:
- * IBM Corporation - initial API and implementation
- *******************************************************************************/
-package org.eclipse.equinox.metatype;
-
-import org.osgi.framework.Bundle;
-
-/**
- * Represents an Icon with a name and a size
- */
-class Icon implements Cloneable {
-
- private String _fileName;
- private int _size;
- private Bundle _bundle;
-
- /**
- * Constructor of class Icon.
- */
- public Icon(String fileName, int size, Bundle bundle) {
-
- this._fileName = fileName;
- this._size = size;
- this._bundle = bundle;
- }
-
- /**
- * Constructor of class Icon.
- */
- public Icon(String fileName, Bundle bundle) {
-
- // Integer.MIN_VALUE signifies size was not specified
- this(fileName, Integer.MIN_VALUE, bundle);
- }
-
- /*
- *
- */
- public synchronized Object clone() {
- return new Icon(this._fileName, this._size, this._bundle);
- }
-
- /**
- * Method to get the icon's file name.
- */
- String getIconName() {
- return _fileName;
- }
-
- /**
- * returns the size specified when the icon was created
- *
- * @return size or Integer.MIN_VALUE if no size was specified
- */
- int getIconSize() {
- return _size;
- }
-
- /**
- * Method to get the bundle having this Icon.
- */
- Bundle getIconBundle() {
- return _bundle;
- }
-}
+/*******************************************************************************
+ * Copyright (c) 2005 IBM Corporation.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.equinox.metatype.impl;
+
+import org.osgi.framework.Bundle;
+
+/**
+ * Represents an Icon with a name and a size
+ */
+class Icon implements Cloneable {
+
+ private String _fileName;
+ private int _size;
+ private Bundle _bundle;
+
+ /**
+ * Constructor of class Icon.
+ */
+ public Icon(String fileName, int size, Bundle bundle) {
+
+ this._fileName = fileName;
+ this._size = size;
+ this._bundle = bundle;
+ }
+
+ /**
+ * Constructor of class Icon.
+ */
+ public Icon(String fileName, Bundle bundle) {
+
+ // Integer.MIN_VALUE signifies size was not specified
+ this(fileName, Integer.MIN_VALUE, bundle);
+ }
+
+ /*
+ *
+ */
+ public synchronized Object clone() {
+ return new Icon(this._fileName, this._size, this._bundle);
+ }
+
+ /**
+ * Method to get the icon's file name.
+ */
+ String getIconName() {
+ return _fileName;
+ }
+
+ /**
+ * returns the size specified when the icon was created
+ *
+ * @return size or Integer.MIN_VALUE if no size was specified
+ */
+ int getIconSize() {
+ return _size;
+ }
+
+ /**
+ * Method to get the bundle having this Icon.
+ */
+ Bundle getIconBundle() {
+ return _bundle;
+ }
+}
diff --git a/bundles/org.eclipse.equinox.metatype/src/org/eclipse/equinox/metatype/LocalizationElement.java b/bundles/org.eclipse.equinox.metatype/src/org/eclipse/equinox/metatype/impl/LocalizationElement.java
index a440439..fbb0ebc 100644
--- a/bundles/org.eclipse.equinox.metatype/src/org/eclipse/equinox/metatype/LocalizationElement.java
+++ b/bundles/org.eclipse.equinox.metatype/src/org/eclipse/equinox/metatype/impl/LocalizationElement.java
@@ -1,55 +1,55 @@
-/*******************************************************************************
- * Copyright (c) 2005, 2011 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License v1.0
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/epl-v10.html
- *
- * Contributors:
- * IBM Corporation - initial API and implementation
- *******************************************************************************/
-package org.eclipse.equinox.metatype;
-
-import java.util.MissingResourceException;
-import java.util.ResourceBundle;
-
-public class LocalizationElement {
-
- public static final char KEY_SIGN = '%';
- String _localization = null;
- ResourceBundle _rb;
-
- /**
- * Internal method
- */
- void setResourceBundle(ResourceBundle rb) {
- this._rb = rb;
- }
-
- /**
- * Method to get the localized text of inputed String.
- */
- String getLocalized(String key) {
-
- if (key == null) {
- return null;
- }
-
- if ((key.length() > 1) && (key.charAt(0) == KEY_SIGN)) {
- if (_rb != null) {
- try {
- String transfered = _rb.getString(key.substring(1));
- if (transfered != null) {
- return transfered;
- }
- } catch (MissingResourceException mre) {
- // Nothing found for this key.
- }
- }
- // If no localization file available or no localized value found
- // for the key, then return the raw data without the key-sign.
- return key.substring(1);
- }
- return key;
- }
-}
+/*******************************************************************************
+ * Copyright (c) 2005, 2011 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.equinox.metatype.impl;
+
+import java.util.MissingResourceException;
+import java.util.ResourceBundle;
+
+public class LocalizationElement {
+
+ public static final char KEY_SIGN = '%';
+ String _localization = null;
+ ResourceBundle _rb;
+
+ /**
+ * Internal method
+ */
+ void setResourceBundle(ResourceBundle rb) {
+ this._rb = rb;
+ }
+
+ /**
+ * Method to get the localized text of inputed String.
+ */
+ String getLocalized(String key) {
+
+ if (key == null) {
+ return null;
+ }
+
+ if ((key.length() > 1) && (key.charAt(0) == KEY_SIGN)) {
+ if (_rb != null) {
+ try {
+ String transfered = _rb.getString(key.substring(1));
+ if (transfered != null) {
+ return transfered;
+ }
+ } catch (MissingResourceException mre) {
+ // Nothing found for this key.
+ }
+ }
+ // If no localization file available or no localized value found
+ // for the key, then return the raw data without the key-sign.
+ return key.substring(1);
+ }
+ return key;
+ }
+}
diff --git a/bundles/org.eclipse.equinox.metatype/src/org/eclipse/equinox/metatype/LogMessages.properties b/bundles/org.eclipse.equinox.metatype/src/org/eclipse/equinox/metatype/impl/LogMessages.properties
index cf8d9a4..6ac1238 100644
--- a/bundles/org.eclipse.equinox.metatype/src/org/eclipse/equinox/metatype/LogMessages.properties
+++ b/bundles/org.eclipse.equinox.metatype/src/org/eclipse/equinox/metatype/impl/LogMessages.properties
@@ -1,17 +1,17 @@
-###############################################################################
-# Copyright (c) 2005, 2010 IBM Corporation and others.
-# All rights reserved. This program and the accompanying materials
-# are made available under the terms of the Eclipse Public License v1.0
-# which accompanies this distribution, and is available at
-# http://www.eclipse.org/legal/epl-v10.html
-#
-# Contributors:
-# IBM Corporation - initial API and implementation
-###############################################################################
-# NLS_MESSAGEFORMAT_ALL
-
-Unknown_Log_level=Unknown Log Level
-Info=Log Info
-Warning=Log Warning
-Error=Log Error
-Debug=Log Debug
+###############################################################################
+# Copyright (c) 2005, 2010 IBM Corporation and others.
+# All rights reserved. This program and the accompanying materials
+# are made available under the terms of the Eclipse Public License v1.0
+# which accompanies this distribution, and is available at
+# http://www.eclipse.org/legal/epl-v10.html
+#
+# Contributors:
+# IBM Corporation - initial API and implementation
+###############################################################################
+# NLS_MESSAGEFORMAT_ALL
+
+Unknown_Log_level=Unknown Log Level
+Info=Log Info
+Warning=Log Warning
+Error=Log Error
+Debug=Log Debug
diff --git a/bundles/org.eclipse.equinox.metatype/src/org/eclipse/equinox/metatype/LogTracker.java b/bundles/org.eclipse.equinox.metatype/src/org/eclipse/equinox/metatype/impl/LogTracker.java
index 2ba9185..51e58c9 100644
--- a/bundles/org.eclipse.equinox.metatype/src/org/eclipse/equinox/metatype/LogTracker.java
+++ b/bundles/org.eclipse.equinox.metatype/src/org/eclipse/equinox/metatype/impl/LogTracker.java
@@ -1,177 +1,177 @@
-/*******************************************************************************
- * Copyright (c) 1998, 2010 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License v1.0
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/epl-v10.html
- *
- * Contributors:
- * IBM Corporation - initial API and implementation
- *******************************************************************************/
-package org.eclipse.equinox.metatype;
-
-import java.io.PrintStream;
-import java.util.Calendar;
-import java.util.Date;
-import org.osgi.framework.BundleContext;
-import org.osgi.framework.ServiceReference;
-import org.osgi.service.log.LogService;
-import org.osgi.util.tracker.ServiceTracker;
-
-/**
- * LogTracker class. This class encapsulates the LogService
- * and handles all issues such as the service coming and going.
- */
-
-public class LogTracker extends ServiceTracker<LogService, LogService> implements LogService {
- /** LogService interface class name */
- protected final static String clazz = "org.osgi.service.log.LogService"; //$NON-NLS-1$
-
- /** PrintStream to use if LogService is unavailable */
- private final PrintStream out;
-
- /**
- * Create new LogTracker.
- *
- * @param context BundleContext of parent bundle.
- * @param out Default PrintStream to use if LogService is unavailable.
- */
- public LogTracker(BundleContext context, PrintStream out) {
- super(context, clazz, null);
- this.out = out;
- }
-
- /*
- * ----------------------------------------------------------------------
- * LogService Interface implementation
- * ----------------------------------------------------------------------
- */
-
- public void log(int level, String message) {
- log(null, level, message, null);
- }
-
- public void log(int level, String message, Throwable exception) {
- log(null, level, message, exception);
- }
-
- // Must suppress warnings here because the log service is not
- @SuppressWarnings("rawtypes")
- public void log(ServiceReference reference, int level, String message) {
- log(reference, level, message, null);
- }
-
- // Must suppress warnings here because the log service is not
- @SuppressWarnings("rawtypes")
- public synchronized void log(ServiceReference reference, int level, String message, Throwable exception) {
- ServiceReference<LogService>[] references = getServiceReferences();
-
- if (references != null) {
- int size = references.length;
-
- for (int i = 0; i < size; i++) {
- LogService service = getService(references[i]);
- if (service != null) {
- try {
- service.log(reference, level, message, exception);
- } catch (Exception e) {
- // TODO: consider printing to System Error
- }
- }
- }
-
- return;
- }
-
- noLogService(level, message, exception, reference);
- }
-
- /**
- * The LogService is not available so we write the message to a PrintStream.
- *
- * @param level Logging level
- * @param message Log message.
- * @param throwable Log exception or null if none.
- * @param reference ServiceReference associated with message or null if none.
- */
- protected void noLogService(int level, String message, Throwable throwable, ServiceReference<?> reference) {
- if (out != null) {
- synchronized (out) {
- // Bug #113286. If no log service present and messages are being
- // printed to stdout, prepend message with a timestamp.
- String timestamp = getDate(new Date());
- out.print(timestamp + " "); //$NON-NLS-1$
-
- switch (level) {
- case LOG_DEBUG : {
- out.print(LogTrackerMsg.Debug);
-
- break;
- }
- case LOG_INFO : {
- out.print(LogTrackerMsg.Info);
-
- break;
- }
- case LOG_WARNING : {
- out.print(LogTrackerMsg.Warning);
-
- break;
- }
- case LOG_ERROR : {
- out.print(LogTrackerMsg.Error);
-
- break;
- }
- default : {
- out.print("["); //$NON-NLS-1$
- out.print(LogTrackerMsg.Unknown_Log_level);
- out.print("]: "); //$NON-NLS-1$
-
- break;
- }
- }
-
- out.println(message);
-
- if (reference != null) {
- out.println(reference);
- }
-
- if (throwable != null) {
- throwable.printStackTrace(out);
- }
- }
- }
- }
-
- // from EclipseLog to avoid using DateFormat -- see bug 149892#c10
- private String getDate(Date date) {
- Calendar c = Calendar.getInstance();
- c.setTime(date);
- StringBuffer sb = new StringBuffer();
- appendPaddedInt(c.get(Calendar.YEAR), 4, sb).append('-');
- appendPaddedInt(c.get(Calendar.MONTH) + 1, 2, sb).append('-');
- appendPaddedInt(c.get(Calendar.DAY_OF_MONTH), 2, sb).append(' ');
- appendPaddedInt(c.get(Calendar.HOUR_OF_DAY), 2, sb).append(':');
- appendPaddedInt(c.get(Calendar.MINUTE), 2, sb).append(':');
- appendPaddedInt(c.get(Calendar.SECOND), 2, sb).append('.');
- appendPaddedInt(c.get(Calendar.MILLISECOND), 3, sb);
- return sb.toString();
- }
-
- private StringBuffer appendPaddedInt(int value, int pad, StringBuffer buffer) {
- pad = pad - 1;
- if (pad == 0)
- return buffer.append(Integer.toString(value));
- int padding = (int) Math.pow(10, pad);
- if (value >= padding)
- return buffer.append(Integer.toString(value));
- while (padding > value && padding > 1) {
- buffer.append('0');
- padding = padding / 10;
- }
- buffer.append(value);
- return buffer;
- }
-}
+/*******************************************************************************
+ * Copyright (c) 1998, 2010 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.equinox.metatype.impl;
+
+import java.io.PrintStream;
+import java.util.Calendar;
+import java.util.Date;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.ServiceReference;
+import org.osgi.service.log.LogService;
+import org.osgi.util.tracker.ServiceTracker;
+
+/**
+ * LogTracker class. This class encapsulates the LogService
+ * and handles all issues such as the service coming and going.
+ */
+
+public class LogTracker extends ServiceTracker<LogService, LogService> implements LogService {
+ /** LogService interface class name */
+ protected final static String clazz = "org.osgi.service.log.LogService"; //$NON-NLS-1$
+
+ /** PrintStream to use if LogService is unavailable */
+ private final PrintStream out;
+
+ /**
+ * Create new LogTracker.
+ *
+ * @param context BundleContext of parent bundle.
+ * @param out Default PrintStream to use if LogService is unavailable.
+ */
+ public LogTracker(BundleContext context, PrintStream out) {
+ super(context, clazz, null);
+ this.out = out;
+ }
+
+ /*
+ * ----------------------------------------------------------------------
+ * LogService Interface implementation
+ * ----------------------------------------------------------------------
+ */
+
+ public void log(int level, String message) {
+ log(null, level, message, null);
+ }
+
+ public void log(int level, String message, Throwable exception) {
+ log(null, level, message, exception);
+ }
+
+ // Must suppress warnings here because the log service is not
+ @SuppressWarnings("rawtypes")
+ public void log(ServiceReference reference, int level, String message) {
+ log(reference, level, message, null);
+ }
+
+ // Must suppress warnings here because the log service is not
+ @SuppressWarnings("rawtypes")
+ public synchronized void log(ServiceReference reference, int level, String message, Throwable exception) {
+ ServiceReference<LogService>[] references = getServiceReferences();
+
+ if (references != null) {
+ int size = references.length;
+
+ for (int i = 0; i < size; i++) {
+ LogService service = getService(references[i]);
+ if (service != null) {
+ try {
+ service.log(reference, level, message, exception);
+ } catch (Exception e) {
+ // TODO: consider printing to System Error
+ }
+ }
+ }
+
+ return;
+ }
+
+ noLogService(level, message, exception, reference);
+ }
+
+ /**
+ * The LogService is not available so we write the message to a PrintStream.
+ *
+ * @param level Logging level
+ * @param message Log message.
+ * @param throwable Log exception or null if none.
+ * @param reference ServiceReference associated with message or null if none.
+ */
+ protected void noLogService(int level, String message, Throwable throwable, ServiceReference<?> reference) {
+ if (out != null) {
+ synchronized (out) {
+ // Bug #113286. If no log service present and messages are being
+ // printed to stdout, prepend message with a timestamp.
+ String timestamp = getDate(new Date());
+ out.print(timestamp + " "); //$NON-NLS-1$
+
+ switch (level) {
+ case LOG_DEBUG : {
+ out.print(LogTrackerMsg.Debug);
+
+ break;
+ }
+ case LOG_INFO : {
+ out.print(LogTrackerMsg.Info);
+
+ break;
+ }
+ case LOG_WARNING : {
+ out.print(LogTrackerMsg.Warning);
+
+ break;
+ }
+ case LOG_ERROR : {
+ out.print(LogTrackerMsg.Error);
+
+ break;
+ }
+ default : {
+ out.print("["); //$NON-NLS-1$
+ out.print(LogTrackerMsg.Unknown_Log_level);
+ out.print("]: "); //$NON-NLS-1$
+
+ break;
+ }
+ }
+
+ out.println(message);
+
+ if (reference != null) {
+ out.println(reference);
+ }
+
+ if (throwable != null) {
+ throwable.printStackTrace(out);
+ }
+ }
+ }
+ }
+
+ // from EclipseLog to avoid using DateFormat -- see bug 149892#c10
+ private String getDate(Date date) {
+ Calendar c = Calendar.getInstance();
+ c.setTime(date);
+ StringBuffer sb = new StringBuffer();
+ appendPaddedInt(c.get(Calendar.YEAR), 4, sb).append('-');
+ appendPaddedInt(c.get(Calendar.MONTH) + 1, 2, sb).append('-');
+ appendPaddedInt(c.get(Calendar.DAY_OF_MONTH), 2, sb).append(' ');
+ appendPaddedInt(c.get(Calendar.HOUR_OF_DAY), 2, sb).append(':');
+ appendPaddedInt(c.get(Calendar.MINUTE), 2, sb).append(':');
+ appendPaddedInt(c.get(Calendar.SECOND), 2, sb).append('.');
+ appendPaddedInt(c.get(Calendar.MILLISECOND), 3, sb);
+ return sb.toString();
+ }
+
+ private StringBuffer appendPaddedInt(int value, int pad, StringBuffer buffer) {
+ pad = pad - 1;
+ if (pad == 0)
+ return buffer.append(Integer.toString(value));
+ int padding = (int) Math.pow(10, pad);
+ if (value >= padding)
+ return buffer.append(Integer.toString(value));
+ while (padding > value && padding > 1) {
+ buffer.append('0');
+ padding = padding / 10;
+ }
+ buffer.append(value);
+ return buffer;
+ }
+}
diff --git a/bundles/org.eclipse.equinox.metatype/src/org/eclipse/equinox/metatype/LogTrackerMsg.java b/bundles/org.eclipse.equinox.metatype/src/org/eclipse/equinox/metatype/impl/LogTrackerMsg.java
index 1cf0e38..4fde900 100644
--- a/bundles/org.eclipse.equinox.metatype/src/org/eclipse/equinox/metatype/LogTrackerMsg.java
+++ b/bundles/org.eclipse.equinox.metatype/src/org/eclipse/equinox/metatype/impl/LogTrackerMsg.java
@@ -1,28 +1,28 @@
-/*******************************************************************************
- * Copyright (c) 2005, 2010 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License v1.0
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/epl-v10.html
- *
- * Contributors:
- * IBM Corporation - initial API and implementation
- *******************************************************************************/
-package org.eclipse.equinox.metatype;
-
-import org.eclipse.osgi.util.NLS;
-
-public class LogTrackerMsg extends NLS {
- private static final String BUNDLE_NAME = "org.eclipse.equinox.metatype.LogMessages"; //$NON-NLS-1$
-
- public static String Unknown_Log_level;
- public static String Info;
- public static String Warning;
- public static String Error;
- public static String Debug;
-
- static {
- // initialize resource bundles
- NLS.initializeMessages(BUNDLE_NAME, LogTrackerMsg.class);
- }
-}
+/*******************************************************************************
+ * Copyright (c) 2005, 2010 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.equinox.metatype.impl;
+
+import org.eclipse.osgi.util.NLS;
+
+public class LogTrackerMsg extends NLS {
+ private static final String BUNDLE_NAME = "org.eclipse.equinox.metatype.LogMessages"; //$NON-NLS-1$
+
+ public static String Unknown_Log_level;
+ public static String Info;
+ public static String Warning;
+ public static String Error;
+ public static String Debug;
+
+ static {
+ // initialize resource bundles
+ NLS.initializeMessages(BUNDLE_NAME, LogTrackerMsg.class);
+ }
+}
diff --git a/bundles/org.eclipse.equinox.metatype/src/org/eclipse/equinox/metatype/MetaTypeInformationImpl.java b/bundles/org.eclipse.equinox.metatype/src/org/eclipse/equinox/metatype/impl/MetaTypeInformationImpl.java
index d6ef08e..11e8238 100644
--- a/bundles/org.eclipse.equinox.metatype/src/org/eclipse/equinox/metatype/MetaTypeInformationImpl.java
+++ b/bundles/org.eclipse.equinox.metatype/src/org/eclipse/equinox/metatype/impl/MetaTypeInformationImpl.java
@@ -1,88 +1,89 @@
-/*******************************************************************************
- * Copyright (c) 2005, 2011 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License v1.0
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/epl-v10.html
- *
- * Contributors:
- * IBM Corporation - initial API and implementation
- *******************************************************************************/
-package org.eclipse.equinox.metatype;
-
-import java.util.Enumeration;
-import java.util.Vector;
-import javax.xml.parsers.SAXParserFactory;
-import org.osgi.framework.Bundle;
-import org.osgi.service.log.LogService;
-import org.osgi.service.metatype.MetaTypeInformation;
-
-/**
- * Implementation of MetaTypeProvider
- * <p>
- * Extension of MetaTypeProvider
- * <p>
- * Provides methods to:
- * <p> - getPids() get the Pids for a given Locale
- * <p> - getFactoryPids() get the Factory Pids for a given Locale
- * <p>
- */
-public class MetaTypeInformationImpl extends MetaTypeProviderImpl implements MetaTypeInformation {
-
- /**
- * Constructor of class MetaTypeInformationImpl.
- */
- MetaTypeInformationImpl(Bundle bundle, SAXParserFactory parserFactory, LogService logger) {
- super(bundle, parserFactory, logger);
- }
-
- /*
- * (non-Javadoc)
- *
- * @see org.osgi.service.metatype.MetaTypeInformation#getPids()
- */
- public String[] getPids() {
-
- if (_allPidOCDs.size() == 0) {
- return new String[0];
- }
-
- Vector<String> pids = new Vector<String>(7);
- Enumeration<String> e = _allPidOCDs.keys();
- while (e.hasMoreElements()) {
- pids.addElement(e.nextElement());
- }
-
- String[] retvalue = new String[pids.size()];
- pids.toArray(retvalue);
- return retvalue;
- }
-
- /*
- * (non-Javadoc)
- *
- * @see org.osgi.service.metatype.MetaTypeInformation#getFactoryPids()
- */
- public String[] getFactoryPids() {
- if (_allFPidOCDs.size() == 0) {
- return new String[0];
- }
- Vector<String> fpids = new Vector<String>(7);
- Enumeration<String> e = _allFPidOCDs.keys();
- while (e.hasMoreElements()) {
- fpids.addElement(e.nextElement());
- }
- String[] retvalue = new String[fpids.size()];
- fpids.toArray(retvalue);
- return retvalue;
- }
-
- /*
- * (non-Javadoc)
- *
- * @see org.osgi.service.metatype.MetaTypeInformation#getBundle()
- */
- public Bundle getBundle() {
- return this._bundle;
- }
-}
+/*******************************************************************************
+ * Copyright (c) 2005, 2011 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.equinox.metatype.impl;
+
+import org.eclipse.equinox.metatype.EquinoxMetaTypeInformation;
+
+import java.util.Enumeration;
+import java.util.Vector;
+import javax.xml.parsers.SAXParser;
+import org.osgi.framework.Bundle;
+import org.osgi.service.log.LogService;
+
+/**
+ * Implementation of MetaTypeProvider
+ * <p>
+ * Extension of MetaTypeProvider
+ * <p>
+ * Provides methods to:
+ * <p> - getPids() get the Pids for a given Locale
+ * <p> - getFactoryPids() get the Factory Pids for a given Locale
+ * <p>
+ */
+public class MetaTypeInformationImpl extends MetaTypeProviderImpl implements EquinoxMetaTypeInformation {
+
+ /**
+ * Constructor of class MetaTypeInformationImpl.
+ */
+ MetaTypeInformationImpl(Bundle bundle, SAXParser parser, LogService logger) {
+ super(bundle, parser, logger);
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.osgi.service.metatype.MetaTypeInformation#getPids()
+ */
+ public String[] getPids() {
+
+ if (_allPidOCDs.size() == 0) {
+ return new String[0];
+ }
+
+ Vector<String> pids = new Vector<String>(7);
+ Enumeration<String> e = _allPidOCDs.keys();
+ while (e.hasMoreElements()) {
+ pids.addElement(e.nextElement());
+ }
+
+ String[] retvalue = new String[pids.size()];
+ pids.toArray(retvalue);
+ return retvalue;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.osgi.service.metatype.MetaTypeInformation#getFactoryPids()
+ */
+ public String[] getFactoryPids() {
+ if (_allFPidOCDs.size() == 0) {
+ return new String[0];
+ }
+ Vector<String> fpids = new Vector<String>(7);
+ Enumeration<String> e = _allFPidOCDs.keys();
+ while (e.hasMoreElements()) {
+ fpids.addElement(e.nextElement());
+ }
+ String[] retvalue = new String[fpids.size()];
+ fpids.toArray(retvalue);
+ return retvalue;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.osgi.service.metatype.MetaTypeInformation#getBundle()
+ */
+ public Bundle getBundle() {
+ return this._bundle;
+ }
+}
diff --git a/bundles/org.eclipse.equinox.metatype/src/org/eclipse/equinox/metatype/MetaTypeMsg.java b/bundles/org.eclipse.equinox.metatype/src/org/eclipse/equinox/metatype/impl/MetaTypeMsg.java
index a34ab17..38a4edf 100644
--- a/bundles/org.eclipse.equinox.metatype/src/org/eclipse/equinox/metatype/MetaTypeMsg.java
+++ b/bundles/org.eclipse.equinox.metatype/src/org/eclipse/equinox/metatype/impl/MetaTypeMsg.java
@@ -1,46 +1,46 @@
-/*******************************************************************************
- * Copyright (c) 2005, 2011 IBM Corporation.
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License v1.0
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/epl-v10.html
- *
- * Contributors:
- * IBM Corporation - initial API and implementation
- *******************************************************************************/
-package org.eclipse.equinox.metatype;
-
-import org.eclipse.osgi.util.NLS;
-
-public class MetaTypeMsg extends NLS {
- private static final String BUNDLE_NAME = "org.eclipse.equinox.metatype.ExternalMessages"; //$NON-NLS-1$
-
- public static String SERVICE_DESCRIPTION;
- public static String UNEXPECTED_ELEMENT;
- public static String UNEXPECTED_TEXT;
- public static String MISSING_ATTRIBUTE;
- public static String INVALID_TYPE;
- public static String MISSING_DESIGNATE_PID_AND_FACTORYPID;
- public static String OCD_ID_NOT_FOUND;
- public static String MISSING_ELEMENT;
- public static String EXCEPTION_MESSAGE;
- public static String NULL_IS_INVALID;
- public static String VALUE_OUT_OF_RANGE;
- public static String VALUE_OUT_OF_OPTION;
- public static String CARDINALITY_VIOLATION;
- public static String NULL_OPTIONS;
- public static String INCONSISTENT_OPTIONS;
- public static String INVALID_OPTIONS;
- public static String INVALID_DEFAULTS;
- public static String METADATA_NOT_FOUND;
- public static String ASK_INVALID_LOCALE;
- public static String MISSING_REQUIRED_PARAMETER;
- public static String TOKENIZER_GOT_INVALID_DATA;
- public static String INVALID_PID_METATYPE_PROVIDER_IGNORED;
- public static String METADATA_PARSE_ERROR;
-
- static {
- // initialize resource bundles
- NLS.initializeMessages(BUNDLE_NAME, MetaTypeMsg.class);
- }
+/*******************************************************************************
+ * Copyright (c) 2005, 2011 IBM Corporation.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.equinox.metatype.impl;
+
+import org.eclipse.osgi.util.NLS;
+
+public class MetaTypeMsg extends NLS {
+ private static final String BUNDLE_NAME = "org.eclipse.equinox.metatype.ExternalMessages"; //$NON-NLS-1$
+
+ public static String SERVICE_DESCRIPTION;
+ public static String UNEXPECTED_ELEMENT;
+ public static String UNEXPECTED_TEXT;
+ public static String MISSING_ATTRIBUTE;
+ public static String INVALID_TYPE;
+ public static String MISSING_DESIGNATE_PID_AND_FACTORYPID;
+ public static String OCD_ID_NOT_FOUND;
+ public static String MISSING_ELEMENT;
+ public static String EXCEPTION_MESSAGE;
+ public static String NULL_IS_INVALID;
+ public static String VALUE_OUT_OF_RANGE;
+ public static String VALUE_OUT_OF_OPTION;
+ public static String CARDINALITY_VIOLATION;
+ public static String NULL_OPTIONS;
+ public static String INCONSISTENT_OPTIONS;
+ public static String INVALID_OPTIONS;
+ public static String INVALID_DEFAULTS;
+ public static String METADATA_NOT_FOUND;
+ public static String ASK_INVALID_LOCALE;
+ public static String MISSING_REQUIRED_PARAMETER;
+ public static String TOKENIZER_GOT_INVALID_DATA;
+ public static String INVALID_PID_METATYPE_PROVIDER_IGNORED;
+ public static String METADATA_PARSE_ERROR;
+
+ static {
+ // initialize resource bundles
+ NLS.initializeMessages(BUNDLE_NAME, MetaTypeMsg.class);
+ }
} \ No newline at end of file
diff --git a/bundles/org.eclipse.equinox.metatype/src/org/eclipse/equinox/metatype/MetaTypeProviderImpl.java b/bundles/org.eclipse.equinox.metatype/src/org/eclipse/equinox/metatype/impl/MetaTypeProviderImpl.java
index ffbb3d9..9342689 100644
--- a/bundles/org.eclipse.equinox.metatype/src/org/eclipse/equinox/metatype/MetaTypeProviderImpl.java
+++ b/bundles/org.eclipse.equinox.metatype/src/org/eclipse/equinox/metatype/impl/MetaTypeProviderImpl.java
@@ -1,236 +1,239 @@
-/*******************************************************************************
- * Copyright (c) 2005, 2011 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License v1.0
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/epl-v10.html
- *
- * Contributors:
- * IBM Corporation - initial API and implementation
- *******************************************************************************/
-package org.eclipse.equinox.metatype;
-
-import java.io.IOException;
-import java.net.URL;
-import java.util.*;
-import javax.xml.parsers.SAXParserFactory;
-import org.eclipse.osgi.util.NLS;
-import org.osgi.framework.Bundle;
-import org.osgi.framework.Constants;
-import org.osgi.framework.wiring.BundleWiring;
-import org.osgi.service.log.LogService;
-import org.osgi.service.metatype.*;
-
-/**
- * Implementation of MetaTypeProvider
- */
-public class MetaTypeProviderImpl implements MetaTypeProvider {
-
- public static final String METADATA_NOT_FOUND = "METADATA_NOT_FOUND"; //$NON-NLS-1$
- public static final String OCD_ID_NOT_FOUND = "OCD_ID_NOT_FOUND"; //$NON-NLS-1$
- public static final String ASK_INVALID_LOCALE = "ASK_INVALID_LOCALE"; //$NON-NLS-1$
-
- public static final String META_FILE_EXT = ".XML"; //$NON-NLS-1$
- public static final String RESOURCE_FILE_CONN = "_"; //$NON-NLS-1$
- public static final String RESOURCE_FILE_EXT = ".properties"; //$NON-NLS-1$
- public static final char DIRECTORY_SEP = '/';
-
- Bundle _bundle;
-
- Hashtable<String, ObjectClassDefinitionImpl> _allPidOCDs = new Hashtable<String, ObjectClassDefinitionImpl>(7);
- Hashtable<String, ObjectClassDefinitionImpl> _allFPidOCDs = new Hashtable<String, ObjectClassDefinitionImpl>(7);
-
- String[] _locales;
- boolean _isThereMeta = false;
-
- // Give access to subclasses.
- protected final LogService logger;
-
- /**
- * Constructor of class MetaTypeProviderImpl.
- */
- MetaTypeProviderImpl(Bundle bundle, SAXParserFactory parserFactory, LogService logger) {
-
- this._bundle = bundle;
- this.logger = logger;
-
- // read all bundle's metadata files and build internal data structures
- _isThereMeta = readMetaFiles(bundle, parserFactory);
-
- if (!_isThereMeta) {
- logger.log(LogService.LOG_DEBUG, NLS.bind(MetaTypeMsg.METADATA_NOT_FOUND, new Long(bundle.getBundleId()), bundle.getSymbolicName()));
- }
- }
-
- /**
- * This method should do the following:
- * <p> - Obtain a SAX parser from the XML Parser Service:
- * <p>
- *
- * <pre> </pre>
- *
- * The parser may be SAX 1 (eXML) or SAX 2 (XML4J). It should attempt to use
- * a SAX2 parser by instantiating an XMLReader and extending DefaultHandler
- * BUT if that fails it should fall back to instantiating a SAX1 Parser and
- * extending HandlerBase.
- * <p> - Pass the parser the URL for the bundle's METADATA.XML file
- * <p> - Handle the callbacks from the parser and build the appropriate
- * MetaType objects - ObjectClassDefinitions & AttributeDefinitions
- *
- * @param bundle The bundle object for which the metadata should be read
- * @param parserFactory The bundle object for which the metadata should be
- * read
- * @return void
- * @throws IOException If there are errors accessing the metadata.xml file
- */
- private boolean readMetaFiles(Bundle bundle, SAXParserFactory parserFactory) {
- BundleWiring wiring = bundle.adapt(BundleWiring.class);
- if (wiring == null)
- return false;
- List<URL> entries = wiring.findEntries(MetaTypeService.METATYPE_DOCUMENTS_LOCATION, "*", 0); //$NON-NLS-1$
- if (entries == null)
- return false;
- boolean result = false;
- for (URL entry : entries) {
- if (entry.getPath().endsWith("/"))
- continue;
- DataParser parser = new DataParser(bundle, entry, parserFactory, logger);
- try {
- Collection<Designate> designates = parser.doParse();
- if (!designates.isEmpty()) {
- result = true;
- }
- for (Designate designate : designates) {
- if (designate.isFactory()) {
- _allFPidOCDs.put(designate.getFactoryPid(), designate.getObjectClassDefinition());
- } else {
- _allPidOCDs.put(designate.getPid(), designate.getObjectClassDefinition());
- }
- }
- } catch (Exception e) {
- logger.log(LogService.LOG_ERROR, NLS.bind(MetaTypeMsg.METADATA_PARSE_ERROR, new Object[] {entry, bundle.getBundleId()}), e);
- }
- }
- return result;
- }
-
- /*
- * (non-Javadoc)
- *
- * @see org.osgi.service.metatype.MetaTypeProvider#getObjectClassDefinition(java.lang.String,
- * java.lang.String)
- */
- public ObjectClassDefinition getObjectClassDefinition(String pid, String locale) {
-
- if (isInvalidLocale(locale)) {
- throw new IllegalArgumentException(NLS.bind(MetaTypeMsg.ASK_INVALID_LOCALE, pid, locale));
- }
-
- ObjectClassDefinitionImpl ocd;
- if (_allPidOCDs.containsKey(pid)) {
- ocd = (ObjectClassDefinitionImpl) (_allPidOCDs.get(pid)).clone();
- ocd.setResourceBundle(locale, _bundle);
- return ocd;
- } else if (_allFPidOCDs.containsKey(pid)) {
- ocd = (ObjectClassDefinitionImpl) (_allFPidOCDs.get(pid)).clone();
- ocd.setResourceBundle(locale, _bundle);
- return ocd;
- } else {
- throw new IllegalArgumentException(NLS.bind(MetaTypeMsg.OCD_ID_NOT_FOUND, pid));
- }
- }
-
- /**
- * Internal Method - Check if the locale is invalid.
- */
- public boolean isInvalidLocale(String locale) {
-
- // Just a simple and quick check here.
- if (locale == null || locale.length() == 0)
- return false;
-
- int idx_first = locale.indexOf(ObjectClassDefinitionImpl.LOCALE_SEP);
- int idx_second = locale.lastIndexOf(ObjectClassDefinitionImpl.LOCALE_SEP);
- if (idx_first == -1 && locale.length() == 2)
- // It is format of only language.
- return false;
- if ((idx_first == 2) && (idx_second == 5 || idx_second == 2))
- // It is format of language + "_" + country [ + "_" + variation ].
- return false;
- return true;
- }
-
- /*
- * (non-Javadoc)
- *
- * @see org.osgi.service.metatype.MetaTypeProvider#getLocales()
- */
- public synchronized String[] getLocales() {
-
- if (_locales != null)
- return checkForDefault(_locales);
- BundleWiring wiring = _bundle.adapt(BundleWiring.class);
- if (wiring == null)
- return null;
- Vector<String> localizationFiles = new Vector<String>(7);
- // get all the localization resources for PIDS
- Enumeration<ObjectClassDefinitionImpl> ocds = _allPidOCDs.elements();
- while (ocds.hasMoreElements()) {
- ObjectClassDefinitionImpl ocd = ocds.nextElement();
- if (ocd._localization != null && !localizationFiles.contains(ocd._localization))
- localizationFiles.add(ocd._localization);
- }
- // get all the localization resources for FPIDS
- ocds = _allFPidOCDs.elements();
- while (ocds.hasMoreElements()) {
- ObjectClassDefinitionImpl ocd = ocds.nextElement();
- if (ocd._localization != null && !localizationFiles.contains(ocd._localization))
- localizationFiles.add(ocd._localization);
- }
- if (localizationFiles.size() == 0)
- localizationFiles.add(getBundleLocalization(_bundle));
- Vector<String> locales = new Vector<String>(7);
- Enumeration<String> eLocalizationFiles = localizationFiles.elements();
- while (eLocalizationFiles.hasMoreElements()) {
- String localizationFile = eLocalizationFiles.nextElement();
- int iSlash = localizationFile.lastIndexOf(DIRECTORY_SEP);
- String baseDir;
- String baseFileName;
- if (iSlash < 0) {
- baseDir = ""; //$NON-NLS-1$
- } else {
- baseDir = localizationFile.substring(0, iSlash);
- }
- baseFileName = '/' + localizationFile + RESOURCE_FILE_CONN;
- List<URL> entries = wiring.findEntries(baseDir, "*.properties", 0); //$NON-NLS-1$
- if (entries == null)
- continue;
- for (URL entry : entries) {
- String resource = entry.getPath();
- if (resource.startsWith(baseFileName) && resource.toLowerCase().endsWith(RESOURCE_FILE_EXT))
- locales.add(resource.substring(baseFileName.length(), resource.length() - RESOURCE_FILE_EXT.length()));
- }
- }
- _locales = locales.toArray(new String[locales.size()]);
- return checkForDefault(_locales);
- }
-
- static String getBundleLocalization(Bundle bundle) {
- // Use the Bundle-Localization manifest header value if it exists.
- String baseName = bundle.getHeaders("").get(Constants.BUNDLE_LOCALIZATION); //$NON-NLS-1$
- if (baseName == null)
- // If the manifest header does not exist, use the default.
- baseName = Constants.BUNDLE_LOCALIZATION_DEFAULT_BASENAME;
- return baseName;
- }
-
- /**
- * Internal Method - checkForDefault
- */
- private String[] checkForDefault(String[] locales) {
-
- if (locales == null || locales.length == 0 || (locales.length == 1 && Locale.getDefault().toString().equals(locales[0])))
- return null;
- return locales;
- }
-}
+/*******************************************************************************
+ * Copyright (c) 2005, 2011 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.equinox.metatype.impl;
+
+import org.eclipse.equinox.metatype.EquinoxObjectClassDefinition;
+
+import java.io.IOException;
+import java.net.URL;
+import java.util.*;
+import javax.xml.parsers.SAXParser;
+import org.eclipse.osgi.util.NLS;
+import org.osgi.framework.Bundle;
+import org.osgi.framework.Constants;
+import org.osgi.framework.wiring.BundleWiring;
+import org.osgi.service.log.LogService;
+import org.osgi.service.metatype.MetaTypeProvider;
+import org.osgi.service.metatype.MetaTypeService;
+
+/**
+ * Implementation of MetaTypeProvider
+ */
+public class MetaTypeProviderImpl implements MetaTypeProvider {
+
+ public static final String METADATA_NOT_FOUND = "METADATA_NOT_FOUND"; //$NON-NLS-1$
+ public static final String OCD_ID_NOT_FOUND = "OCD_ID_NOT_FOUND"; //$NON-NLS-1$
+ public static final String ASK_INVALID_LOCALE = "ASK_INVALID_LOCALE"; //$NON-NLS-1$
+
+ public static final String META_FILE_EXT = ".XML"; //$NON-NLS-1$
+ public static final String RESOURCE_FILE_CONN = "_"; //$NON-NLS-1$
+ public static final String RESOURCE_FILE_EXT = ".properties"; //$NON-NLS-1$
+ public static final char DIRECTORY_SEP = '/';
+
+ Bundle _bundle;
+
+ Hashtable<String, ObjectClassDefinitionImpl> _allPidOCDs = new Hashtable<String, ObjectClassDefinitionImpl>(7);
+ Hashtable<String, ObjectClassDefinitionImpl> _allFPidOCDs = new Hashtable<String, ObjectClassDefinitionImpl>(7);
+
+ String[] _locales;
+ boolean _isThereMeta = false;
+
+ // Give access to subclasses.
+ protected final LogService logger;
+
+ /**
+ * Constructor of class MetaTypeProviderImpl.
+ */
+ MetaTypeProviderImpl(Bundle bundle, SAXParser parser, LogService logger) {
+
+ this._bundle = bundle;
+ this.logger = logger;
+
+ // read all bundle's metadata files and build internal data structures
+ _isThereMeta = readMetaFiles(bundle, parser);
+
+ if (!_isThereMeta) {
+ logger.log(LogService.LOG_DEBUG, NLS.bind(MetaTypeMsg.METADATA_NOT_FOUND, new Long(bundle.getBundleId()), bundle.getSymbolicName()));
+ }
+ }
+
+ /**
+ * This method should do the following:
+ * <p> - Obtain a SAX parser from the XML Parser Service:
+ * <p>
+ *
+ * <pre> </pre>
+ *
+ * The parser may be SAX 1 (eXML) or SAX 2 (XML4J). It should attempt to use
+ * a SAX2 parser by instantiating an XMLReader and extending DefaultHandler
+ * BUT if that fails it should fall back to instantiating a SAX1 Parser and
+ * extending HandlerBase.
+ * <p> - Pass the parser the URL for the bundle's METADATA.XML file
+ * <p> - Handle the callbacks from the parser and build the appropriate
+ * MetaType objects - ObjectClassDefinitions & AttributeDefinitions
+ *
+ * @param bundle The bundle object for which the metadata should be read
+ * @param parserFactory The bundle object for which the metadata should be
+ * read
+ * @return void
+ * @throws IOException If there are errors accessing the metadata.xml file
+ */
+ private boolean readMetaFiles(Bundle bundle, SAXParser saxParser) {
+ BundleWiring wiring = bundle.adapt(BundleWiring.class);
+ if (wiring == null)
+ return false;
+ List<URL> entries = wiring.findEntries(MetaTypeService.METATYPE_DOCUMENTS_LOCATION, "*", 0); //$NON-NLS-1$
+ if (entries == null)
+ return false;
+ boolean result = false;
+ for (URL entry : entries) {
+ if (entry.getPath().endsWith("/")) //$NON-NLS-1$
+ continue;
+ DataParser parser = new DataParser(bundle, entry, saxParser, logger);
+ try {
+ Collection<Designate> designates = parser.doParse();
+ if (!designates.isEmpty()) {
+ result = true;
+ }
+ for (Designate designate : designates) {
+ if (designate.isFactory()) {
+ _allFPidOCDs.put(designate.getFactoryPid(), designate.getObjectClassDefinition());
+ } else {
+ _allPidOCDs.put(designate.getPid(), designate.getObjectClassDefinition());
+ }
+ }
+ } catch (Exception e) {
+ logger.log(LogService.LOG_ERROR, NLS.bind(MetaTypeMsg.METADATA_PARSE_ERROR, new Object[] {entry, bundle.getBundleId()}), e);
+ }
+ }
+ return result;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.osgi.service.metatype.MetaTypeProvider#getObjectClassDefinition(java.lang.String,
+ * java.lang.String)
+ */
+ public EquinoxObjectClassDefinition getObjectClassDefinition(String pid, String locale) {
+
+ if (isInvalidLocale(locale)) {
+ throw new IllegalArgumentException(NLS.bind(MetaTypeMsg.ASK_INVALID_LOCALE, pid, locale));
+ }
+
+ ObjectClassDefinitionImpl ocd;
+ if (_allPidOCDs.containsKey(pid)) {
+ ocd = (ObjectClassDefinitionImpl) (_allPidOCDs.get(pid)).clone();
+ ocd.setResourceBundle(locale, _bundle);
+ return ocd;
+ } else if (_allFPidOCDs.containsKey(pid)) {
+ ocd = (ObjectClassDefinitionImpl) (_allFPidOCDs.get(pid)).clone();
+ ocd.setResourceBundle(locale, _bundle);
+ return ocd;
+ } else {
+ throw new IllegalArgumentException(NLS.bind(MetaTypeMsg.OCD_ID_NOT_FOUND, pid));
+ }
+ }
+
+ /**
+ * Internal Method - Check if the locale is invalid.
+ */
+ public boolean isInvalidLocale(String locale) {
+
+ // Just a simple and quick check here.
+ if (locale == null || locale.length() == 0)
+ return false;
+
+ int idx_first = locale.indexOf(ObjectClassDefinitionImpl.LOCALE_SEP);
+ int idx_second = locale.lastIndexOf(ObjectClassDefinitionImpl.LOCALE_SEP);
+ if (idx_first == -1 && locale.length() == 2)
+ // It is format of only language.
+ return false;
+ if ((idx_first == 2) && (idx_second == 5 || idx_second == 2))
+ // It is format of language + "_" + country [ + "_" + variation ].
+ return false;
+ return true;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.osgi.service.metatype.MetaTypeProvider#getLocales()
+ */
+ public synchronized String[] getLocales() {
+
+ if (_locales != null)
+ return checkForDefault(_locales);
+ BundleWiring wiring = _bundle.adapt(BundleWiring.class);
+ if (wiring == null)
+ return null;
+ Vector<String> localizationFiles = new Vector<String>(7);
+ // get all the localization resources for PIDS
+ Enumeration<ObjectClassDefinitionImpl> ocds = _allPidOCDs.elements();
+ while (ocds.hasMoreElements()) {
+ ObjectClassDefinitionImpl ocd = ocds.nextElement();
+ if (ocd._localization != null && !localizationFiles.contains(ocd._localization))
+ localizationFiles.add(ocd._localization);
+ }
+ // get all the localization resources for FPIDS
+ ocds = _allFPidOCDs.elements();
+ while (ocds.hasMoreElements()) {
+ ObjectClassDefinitionImpl ocd = ocds.nextElement();
+ if (ocd._localization != null && !localizationFiles.contains(ocd._localization))
+ localizationFiles.add(ocd._localization);
+ }
+ if (localizationFiles.size() == 0)
+ localizationFiles.add(getBundleLocalization(_bundle));
+ Vector<String> locales = new Vector<String>(7);
+ Enumeration<String> eLocalizationFiles = localizationFiles.elements();
+ while (eLocalizationFiles.hasMoreElements()) {
+ String localizationFile = eLocalizationFiles.nextElement();
+ int iSlash = localizationFile.lastIndexOf(DIRECTORY_SEP);
+ String baseDir;
+ String baseFileName;
+ if (iSlash < 0) {
+ baseDir = ""; //$NON-NLS-1$
+ } else {
+ baseDir = localizationFile.substring(0, iSlash);
+ }
+ baseFileName = '/' + localizationFile + RESOURCE_FILE_CONN;
+ List<URL> entries = wiring.findEntries(baseDir, "*.properties", 0); //$NON-NLS-1$
+ if (entries == null)
+ continue;
+ for (URL entry : entries) {
+ String resource = entry.getPath();
+ if (resource.startsWith(baseFileName) && resource.toLowerCase().endsWith(RESOURCE_FILE_EXT))
+ locales.add(resource.substring(baseFileName.length(), resource.length() - RESOURCE_FILE_EXT.length()));
+ }
+ }
+ _locales = locales.toArray(new String[locales.size()]);
+ return checkForDefault(_locales);
+ }
+
+ static String getBundleLocalization(Bundle bundle) {
+ // Use the Bundle-Localization manifest header value if it exists.
+ String baseName = bundle.getHeaders("").get(Constants.BUNDLE_LOCALIZATION); //$NON-NLS-1$
+ if (baseName == null)
+ // If the manifest header does not exist, use the default.
+ baseName = Constants.BUNDLE_LOCALIZATION_DEFAULT_BASENAME;
+ return baseName;
+ }
+
+ /**
+ * Internal Method - checkForDefault
+ */
+ private String[] checkForDefault(String[] locales) {
+
+ if (locales == null || locales.length == 0 || (locales.length == 1 && Locale.getDefault().toString().equals(locales[0])))
+ return null;
+ return locales;
+ }
+}
diff --git a/bundles/org.eclipse.equinox.metatype/src/org/eclipse/equinox/metatype/MetaTypeProviderTracker.java b/bundles/org.eclipse.equinox.metatype/src/org/eclipse/equinox/metatype/impl/MetaTypeProviderTracker.java
index fbdd76e..b7e27ff 100644
--- a/bundles/org.eclipse.equinox.metatype/src/org/eclipse/equinox/metatype/MetaTypeProviderTracker.java
+++ b/bundles/org.eclipse.equinox.metatype/src/org/eclipse/equinox/metatype/impl/MetaTypeProviderTracker.java
@@ -1,189 +1,287 @@
-/*******************************************************************************
- * Copyright (c) 2005, 2010 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License v1.0
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/epl-v10.html
- *
- * Contributors:
- * IBM Corporation - initial API and implementation
- *******************************************************************************/
-package org.eclipse.equinox.metatype;
-
-import java.util.*;
-import org.eclipse.osgi.util.NLS;
-import org.osgi.framework.*;
-import org.osgi.service.cm.ManagedService;
-import org.osgi.service.cm.ManagedServiceFactory;
-import org.osgi.service.log.LogService;
-import org.osgi.service.metatype.*;
-import org.osgi.util.tracker.ServiceTracker;
-
-public class MetaTypeProviderTracker implements MetaTypeInformation {
- private final Bundle _bundle;
- private final LogService log;
- private final ServiceTracker<Object, Object> _tracker;
-
- /**
- * Constructs a MetaTypeProviderTracker which tracks all MetaTypeProviders
- * registered by the specified bundle.
- * @param context The BundleContext of the MetaTypeService implementation
- * @param bundle The bundle to track all MetaTypeProviders for.
- * @param log The {@code LogService} to use for logging messages.
- */
- public MetaTypeProviderTracker(Bundle bundle, LogService log, ServiceTracker<Object, Object> tracker) {
- this._bundle = bundle;
- this._tracker = tracker;
- this.log = log;
- }
-
- private String[] getPids(boolean factory) {
- if (_bundle.getState() != Bundle.ACTIVE)
- return new String[0]; // return none if not active
- MetaTypeProviderWrapper[] wrappers = getMetaTypeProviders();
- ArrayList<String> results = new ArrayList<String>();
- for (int i = 0; i < wrappers.length; i++) {
- // return only the correct type of pids (regular or factory)
- if (factory == wrappers[i].factory)
- results.add(wrappers[i].pid);
- }
- return results.toArray(new String[results.size()]);
- }
-
- public String[] getPids() {
- return getPids(false);
- }
-
- public String[] getFactoryPids() {
- return getPids(true);
- }
-
- public Bundle getBundle() {
- return _bundle;
- }
-
- public ObjectClassDefinition getObjectClassDefinition(String id, String locale) {
- if (_bundle.getState() != Bundle.ACTIVE)
- return null; // return none if not active
- MetaTypeProviderWrapper[] wrappers = getMetaTypeProviders();
- for (int i = 0; i < wrappers.length; i++) {
- if (id.equals(wrappers[i].pid))
- // found a matching pid now call the actual provider
- return wrappers[i].provider.getObjectClassDefinition(id, locale);
- }
- return null;
- }
-
- public String[] getLocales() {
- if (_bundle.getState() != Bundle.ACTIVE)
- return new String[0]; // return none if not active
- MetaTypeProviderWrapper[] wrappers = getMetaTypeProviders();
- ArrayList<String> locales = new ArrayList<String>();
- // collect all the unique locales from all providers we found
- for (int i = 0; i < wrappers.length; i++) {
- String[] wrappedLocales = wrappers[i].provider.getLocales();
- if (wrappedLocales == null)
- continue;
- for (int j = 0; j < wrappedLocales.length; j++)
- if (!locales.contains(wrappedLocales[j]))
- locales.add(wrappedLocales[j]);
- }
- return locales.toArray(new String[locales.size()]);
- }
-
- private MetaTypeProviderWrapper[] getMetaTypeProviders() {
- Map<ServiceReference<Object>, Object> services = _tracker.getTracked();
- if (services.isEmpty())
- return new MetaTypeProviderWrapper[0];
- Set<ServiceReference<Object>> serviceReferences = services.keySet();
- Set<MetaTypeProviderWrapper> result = new HashSet<MetaTypeProviderWrapper>();
- for (ServiceReference<Object> serviceReference : serviceReferences) {
- if (serviceReference.getBundle() == _bundle) {
- Object service = services.get(serviceReference);
- // If the service is not a MetaTypeProvider, we're not interested in it.
- if (service instanceof MetaTypeProvider) {
- // Include the METATYPE_PID, if present, to return as part of getPids(). Also, include the
- // METATYPE_FACTORY_PID, if present, to return as part of getFactoryPids().
- // The filter ensures at least one of these properties was set for a standalone MetaTypeProvider.
- addMetaTypeProviderWrappers(MetaTypeProvider.METATYPE_PID, serviceReference, (MetaTypeProvider) service, false, result);
- addMetaTypeProviderWrappers(MetaTypeProvider.METATYPE_FACTORY_PID, serviceReference, (MetaTypeProvider) service, true, result);
- // If the service is a ManagedService, include the SERVICE_PID to return as part of getPids().
- // The filter ensures the SERVICE_PID property was set.
- if (service instanceof ManagedService) {
- addMetaTypeProviderWrappers(Constants.SERVICE_PID, serviceReference, (MetaTypeProvider) service, false, result);
- }
- // If the service is a ManagedServiceFactory, include the SERVICE_PID to return as part of getFactoryPids().
- // The filter ensures the SERVICE_PID property was set.
- else if (service instanceof ManagedServiceFactory) {
- addMetaTypeProviderWrappers(Constants.SERVICE_PID, serviceReference, (MetaTypeProvider) service, true, result);
- }
- }
- }
- }
- return result.toArray(new MetaTypeProviderWrapper[result.size()]);
- }
-
- private void addMetaTypeProviderWrappers(String servicePropertyName, ServiceReference<Object> serviceReference, MetaTypeProvider service, boolean factory, Set<MetaTypeProviderWrapper> wrappers) {
- String[] pids = getStringProperty(servicePropertyName, serviceReference.getProperty(servicePropertyName));
- for (String pid : pids) {
- wrappers.add(new MetaTypeProviderWrapper(service, pid, factory));
- }
- }
-
- private String[] getStringProperty(String name, Object value) {
- // Don't log a warning if the value is null. The filter guarantees at least one of the necessary properties
- // is there. If others are not, this method will get called with value equal to null.
- if (value == null)
- return new String[0];
- if (value instanceof String) {
- return new String[] {(String) value};
- }
- if (value instanceof String[]) {
- return (String[]) value;
- }
- Exception e = null;
- if (value instanceof Collection) {
- @SuppressWarnings("unchecked")
- Collection<String> temp = (Collection<String>) value;
- try {
- return temp.toArray(new String[temp.size()]);
- } catch (ArrayStoreException ase) {
- e = ase;
- }
- }
- log.log(LogService.LOG_WARNING, NLS.bind(MetaTypeMsg.INVALID_PID_METATYPE_PROVIDER_IGNORED, new Object[] {_bundle.getSymbolicName(), _bundle.getBundleId(), name, value}), e);
- return new String[0];
- }
-
- // this is a simple class just used to temporarily store information about a provider
- public class MetaTypeProviderWrapper {
- MetaTypeProvider provider;
- String pid;
- boolean factory;
-
- MetaTypeProviderWrapper(MetaTypeProvider provider, String pid, boolean factory) {
- this.provider = provider;
- this.pid = pid;
- this.factory = factory;
- }
-
- @Override
- public boolean equals(Object object) {
- if (object == this)
- return true;
- if (!(object instanceof MetaTypeProviderWrapper))
- return false;
- MetaTypeProviderWrapper that = (MetaTypeProviderWrapper) object;
- return this.provider.equals(that.provider) && this.pid.equals(that.pid) && this.factory == that.factory;
- }
-
- @Override
- public int hashCode() {
- int result = 17;
- result = 31 * result + provider.hashCode();
- result = 31 * result + pid.hashCode();
- result = 31 * result + (factory ? 1 : 0);
- return result;
- }
- }
-}
+/*******************************************************************************
+ * Copyright (c) 2005, 2011 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.equinox.metatype.impl;
+
+import org.eclipse.equinox.metatype.*;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.*;
+import org.eclipse.osgi.util.NLS;
+import org.osgi.framework.*;
+import org.osgi.service.cm.ManagedService;
+import org.osgi.service.cm.ManagedServiceFactory;
+import org.osgi.service.log.LogService;
+import org.osgi.service.metatype.*;
+import org.osgi.util.tracker.ServiceTracker;
+
+public class MetaTypeProviderTracker implements EquinoxMetaTypeInformation {
+ private final Bundle _bundle;
+ private final LogService log;
+ private final ServiceTracker<Object, Object> _tracker;
+
+ /**
+ * Constructs a MetaTypeProviderTracker which tracks all MetaTypeProviders
+ * registered by the specified bundle.
+ * @param context The BundleContext of the MetaTypeService implementation
+ * @param bundle The bundle to track all MetaTypeProviders for.
+ * @param log The {@code LogService} to use for logging messages.
+ */
+ public MetaTypeProviderTracker(Bundle bundle, LogService log, ServiceTracker<Object, Object> tracker) {
+ this._bundle = bundle;
+ this._tracker = tracker;
+ this.log = log;
+ }
+
+ private String[] getPids(boolean factory) {
+ if (_bundle.getState() != Bundle.ACTIVE)
+ return new String[0]; // return none if not active
+ MetaTypeProviderWrapper[] wrappers = getMetaTypeProviders();
+ ArrayList<String> results = new ArrayList<String>();
+ for (int i = 0; i < wrappers.length; i++) {
+ // return only the correct type of pids (regular or factory)
+ if (factory == wrappers[i].factory)
+ results.add(wrappers[i].pid);
+ }
+ return results.toArray(new String[results.size()]);
+ }
+
+ public String[] getPids() {
+ return getPids(false);
+ }
+
+ public String[] getFactoryPids() {
+ return getPids(true);
+ }
+
+ public Bundle getBundle() {
+ return _bundle;
+ }
+
+ public EquinoxObjectClassDefinition getObjectClassDefinition(String id, String locale) {
+ if (_bundle.getState() != Bundle.ACTIVE)
+ return null; // return none if not active
+ MetaTypeProviderWrapper[] wrappers = getMetaTypeProviders();
+ for (int i = 0; i < wrappers.length; i++) {
+ if (id.equals(wrappers[i].pid))
+ // found a matching pid now call the actual provider
+ return wrappers[i].getObjectClassDefinition(id, locale);
+ }
+ return null;
+ }
+
+ public String[] getLocales() {
+ if (_bundle.getState() != Bundle.ACTIVE)
+ return new String[0]; // return none if not active
+ MetaTypeProviderWrapper[] wrappers = getMetaTypeProviders();
+ ArrayList<String> locales = new ArrayList<String>();
+ // collect all the unique locales from all providers we found
+ for (int i = 0; i < wrappers.length; i++) {
+ String[] wrappedLocales = wrappers[i].getLocales();
+ if (wrappedLocales == null)
+ continue;
+ for (int j = 0; j < wrappedLocales.length; j++)
+ if (!locales.contains(wrappedLocales[j]))
+ locales.add(wrappedLocales[j]);
+ }
+ return locales.toArray(new String[locales.size()]);
+ }
+
+ private MetaTypeProviderWrapper[] getMetaTypeProviders() {
+ Map<ServiceReference<Object>, Object> services = _tracker.getTracked();
+ if (services.isEmpty())
+ return new MetaTypeProviderWrapper[0];
+ Set<ServiceReference<Object>> serviceReferences = services.keySet();
+ Set<MetaTypeProviderWrapper> result = new HashSet<MetaTypeProviderWrapper>();
+ for (ServiceReference<Object> serviceReference : serviceReferences) {
+ if (serviceReference.getBundle() == _bundle) {
+ Object service = services.get(serviceReference);
+ // If the service is not a MetaTypeProvider, we're not interested in it.
+ if (service instanceof MetaTypeProvider) {
+ // Include the METATYPE_PID, if present, to return as part of getPids(). Also, include the
+ // METATYPE_FACTORY_PID, if present, to return as part of getFactoryPids().
+ // The filter ensures at least one of these properties was set for a standalone MetaTypeProvider.
+ addMetaTypeProviderWrappers(MetaTypeProvider.METATYPE_PID, serviceReference, (MetaTypeProvider) service, false, result);
+ addMetaTypeProviderWrappers(MetaTypeProvider.METATYPE_FACTORY_PID, serviceReference, (MetaTypeProvider) service, true, result);
+ // If the service is a ManagedService, include the SERVICE_PID to return as part of getPids().
+ // The filter ensures the SERVICE_PID property was set.
+ if (service instanceof ManagedService) {
+ addMetaTypeProviderWrappers(Constants.SERVICE_PID, serviceReference, (MetaTypeProvider) service, false, result);
+ }
+ // If the service is a ManagedServiceFactory, include the SERVICE_PID to return as part of getFactoryPids().
+ // The filter ensures the SERVICE_PID property was set.
+ else if (service instanceof ManagedServiceFactory) {
+ addMetaTypeProviderWrappers(Constants.SERVICE_PID, serviceReference, (MetaTypeProvider) service, true, result);
+ }
+ }
+ }
+ }
+ return result.toArray(new MetaTypeProviderWrapper[result.size()]);
+ }
+
+ private void addMetaTypeProviderWrappers(String servicePropertyName, ServiceReference<Object> serviceReference, MetaTypeProvider service, boolean factory, Set<MetaTypeProviderWrapper> wrappers) {
+ String[] pids = getStringProperty(servicePropertyName, serviceReference.getProperty(servicePropertyName));
+ for (String pid : pids) {
+ wrappers.add(new MetaTypeProviderWrapper(service, pid, factory));
+ }
+ }
+
+ private String[] getStringProperty(String name, Object value) {
+ // Don't log a warning if the value is null. The filter guarantees at least one of the necessary properties
+ // is there. If others are not, this method will get called with value equal to null.
+ if (value == null)
+ return new String[0];
+ if (value instanceof String) {
+ return new String[] {(String) value};
+ }
+ if (value instanceof String[]) {
+ return (String[]) value;
+ }
+ Exception e = null;
+ if (value instanceof Collection) {
+ @SuppressWarnings("unchecked")
+ Collection<String> temp = (Collection<String>) value;
+ try {
+ return temp.toArray(new String[temp.size()]);
+ } catch (ArrayStoreException ase) {
+ e = ase;
+ }
+ }
+ log.log(LogService.LOG_WARNING, NLS.bind(MetaTypeMsg.INVALID_PID_METATYPE_PROVIDER_IGNORED, new Object[] {_bundle.getSymbolicName(), _bundle.getBundleId(), name, value}), e);
+ return new String[0];
+ }
+
+ // this is a simple class just used to temporarily store information about a provider
+ public class MetaTypeProviderWrapper implements MetaTypeProvider {
+ private final MetaTypeProvider provider;
+ final String pid;
+ final boolean factory;
+
+ MetaTypeProviderWrapper(MetaTypeProvider provider, String pid, boolean factory) {
+ this.provider = provider;
+ this.pid = pid;
+ this.factory = factory;
+ }
+
+ @Override
+ public boolean equals(Object object) {
+ if (object == this)
+ return true;
+ if (!(object instanceof MetaTypeProviderWrapper))
+ return false;
+ MetaTypeProviderWrapper that = (MetaTypeProviderWrapper) object;
+ return this.provider.equals(that.provider) && this.pid.equals(that.pid) && this.factory == that.factory;
+ }
+
+ @Override
+ public int hashCode() {
+ int result = 17;
+ result = 31 * result + provider.hashCode();
+ result = 31 * result + pid.hashCode();
+ result = 31 * result + (factory ? 1 : 0);
+ return result;
+ }
+
+ public EquinoxObjectClassDefinition getObjectClassDefinition(String id, String locale) {
+ final ObjectClassDefinition ocd = provider.getObjectClassDefinition(id, locale);
+ if (ocd == null)
+ return null;
+ return new EquinoxObjectClassDefinition() {
+ public String getName() {
+ return ocd.getName();
+ }
+
+ public String getID() {
+ return ocd.getID();
+ }
+
+ public String getDescription() {
+ return ocd.getDescription();
+ }
+
+ public InputStream getIcon(int size) throws IOException {
+ return ocd.getIcon(size);
+ }
+
+ @SuppressWarnings("unchecked")
+ public Map<String, String> getExtensionAttributes(String schema) {
+ return Collections.EMPTY_MAP;
+ }
+
+ @SuppressWarnings("unchecked")
+ public Set<String> getExtensionUris() {
+ return Collections.EMPTY_SET;
+ }
+
+ public EquinoxAttributeDefinition[] getAttributeDefinitions(int filter) {
+ AttributeDefinition[] ads = ocd.getAttributeDefinitions(filter);
+ if (ads == null || ads.length == 0)
+ return new EquinoxAttributeDefinition[0];
+ Collection<EquinoxAttributeDefinition> result = new ArrayList<EquinoxAttributeDefinition>(ads.length);
+ for (final AttributeDefinition ad : ads) {
+ result.add(new EquinoxAttributeDefinition() {
+ public String getName() {
+ return ad.getName();
+ }
+
+ public String getID() {
+ return ad.getID();
+ }
+
+ public String getDescription() {
+ return ad.getDescription();
+ }
+
+ public int getCardinality() {
+ return ad.getCardinality();
+ }
+
+ public int getType() {
+ return ad.getType();
+ }
+
+ public String[] getOptionValues() {
+ return ad.getOptionValues();
+ }
+
+ public String[] getOptionLabels() {
+ return ad.getOptionLabels();
+ }
+
+ public String validate(String value) {
+ return ad.validate(value);
+ }
+
+ public String[] getDefaultValue() {
+ return ad.getDefaultValue();
+ }
+
+ @SuppressWarnings("unchecked")
+ public Map<String, String> getExtensionAttributes(String schema) {
+ return Collections.EMPTY_MAP;
+ }
+
+ @SuppressWarnings("unchecked")
+ public Set<String> getExtensionUris() {
+ return Collections.EMPTY_SET;
+ }
+ });
+ }
+ return result.toArray(new EquinoxAttributeDefinition[result.size()]);
+ }
+ };
+ }
+
+ public String[] getLocales() {
+ return provider.getLocales();
+ }
+ }
+}
diff --git a/bundles/org.eclipse.equinox.metatype/src/org/eclipse/equinox/metatype/MetaTypeServiceImpl.java b/bundles/org.eclipse.equinox.metatype/src/org/eclipse/equinox/metatype/impl/MetaTypeServiceImpl.java
index 9944e8c..6adf793 100644
--- a/bundles/org.eclipse.equinox.metatype/src/org/eclipse/equinox/metatype/MetaTypeServiceImpl.java
+++ b/bundles/org.eclipse.equinox.metatype/src/org/eclipse/equinox/metatype/impl/MetaTypeServiceImpl.java
@@ -1,107 +1,137 @@
-/*******************************************************************************
- * Copyright (c) 2005, 2011 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License v1.0
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/epl-v10.html
- *
- * Contributors:
- * IBM Corporation - initial API and implementation
- *******************************************************************************/
-package org.eclipse.equinox.metatype;
-
-import java.security.AccessController;
-import java.security.PrivilegedExceptionAction;
-import java.util.Hashtable;
-import javax.xml.parsers.SAXParserFactory;
-import org.eclipse.osgi.util.NLS;
-import org.osgi.framework.*;
-import org.osgi.service.log.LogService;
-import org.osgi.service.metatype.MetaTypeInformation;
-import org.osgi.service.metatype.MetaTypeService;
-import org.osgi.util.tracker.ServiceTracker;
-
-/**
- * Implementation of MetaTypeService
- */
-public class MetaTypeServiceImpl implements MetaTypeService, SynchronousBundleListener {
-
- SAXParserFactory _parserFactory;
- private Hashtable<Long, MetaTypeInformation> _mtps = new Hashtable<Long, MetaTypeInformation>(7);
-
- private final LogService logger;
- private final ServiceTracker<Object, Object> metaTypeProviderTracker;
-
- /**
- * Constructor of class MetaTypeServiceImpl.
- */
- public MetaTypeServiceImpl(SAXParserFactory parserFactory, LogService logger, ServiceTracker<Object, Object> metaTypeProviderTracker) {
- this._parserFactory = parserFactory;
- this.logger = logger;
- this.metaTypeProviderTracker = metaTypeProviderTracker;
- }
-
- /*
- * (non-Javadoc)
- *
- * @see org.osgi.service.metatype.MetaTypeService#getMetaTypeInformation(org.osgi.framework.Bundle)
- */
- public MetaTypeInformation getMetaTypeInformation(Bundle bundle) {
- return getMetaTypeProvider(bundle);
- }
-
- /**
- * Internal Method - to get MetaTypeProvider object.
- */
- private MetaTypeInformation getMetaTypeProvider(final Bundle b) {
- final LogService loggerTemp = this.logger;
- final ServiceTracker<Object, Object> tracker = this.metaTypeProviderTracker;
- try {
- Long bID = new Long(b.getBundleId());
- synchronized (_mtps) {
- if (_mtps.containsKey(bID))
- return _mtps.get(bID);
- // Avoid synthetic accessor method warnings.
-
- MetaTypeInformation mti = AccessController.doPrivileged(new PrivilegedExceptionAction<MetaTypeInformation>() {
- public MetaTypeInformation run() {
- MetaTypeInformationImpl impl = new MetaTypeInformationImpl(b, _parserFactory, loggerTemp);
- if (!impl._isThereMeta)
- return new MetaTypeProviderTracker(b, loggerTemp, tracker);
- return impl;
- }
- });
- _mtps.put(bID, mti);
- return mti;
- }
- } catch (Exception e) {
- logger.log(LogService.LOG_ERROR, NLS.bind(MetaTypeMsg.EXCEPTION_MESSAGE, e.getMessage()), e);
- return new MetaTypeProviderTracker(b, loggerTemp, tracker);
- }
- }
-
- /*
- * (non-Javadoc)
- *
- * @see org.osgi.framework.BundleListener#bundleChanged(org.osgi.framework.BundleEvent)
- */
- public void bundleChanged(BundleEvent event) {
-
- int type = event.getType();
- Long bID = new Long(event.getBundle().getBundleId());
-
- switch (type) {
- case BundleEvent.UPDATED :
- case BundleEvent.UNINSTALLED :
- _mtps.remove(bID);
- break;
- case BundleEvent.INSTALLED :
- case BundleEvent.RESOLVED :
- case BundleEvent.STARTED :
- case BundleEvent.STOPPED :
- case BundleEvent.UNRESOLVED :
- default :
- break;
- }
- }
-}
+/*******************************************************************************
+ * Copyright (c) 2005, 2011 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.equinox.metatype.impl;
+
+import org.eclipse.equinox.metatype.EquinoxMetaTypeInformation;
+import org.eclipse.equinox.metatype.EquinoxMetaTypeService;
+
+import java.security.AccessController;
+import java.security.PrivilegedExceptionAction;
+import java.util.Hashtable;
+import javax.xml.parsers.*;
+import org.eclipse.osgi.util.NLS;
+import org.osgi.framework.*;
+import org.osgi.service.log.LogService;
+import org.osgi.util.tracker.ServiceTracker;
+import org.xml.sax.SAXException;
+
+/**
+ * Implementation of MetaTypeService
+ */
+public class MetaTypeServiceImpl implements EquinoxMetaTypeService, SynchronousBundleListener {
+
+ SAXParserFactory _parserFactory;
+ private Hashtable<Long, EquinoxMetaTypeInformation> _mtps = new Hashtable<Long, EquinoxMetaTypeInformation>(7);
+
+ private final LogService logger;
+ private final ServiceTracker<Object, Object> metaTypeProviderTracker;
+
+ /**
+ * Constructor of class MetaTypeServiceImpl.
+ */
+ public MetaTypeServiceImpl(SAXParserFactory parserFactory, LogService logger, ServiceTracker<Object, Object> metaTypeProviderTracker) {
+ this._parserFactory = parserFactory;
+ this.logger = logger;
+ this.metaTypeProviderTracker = metaTypeProviderTracker;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.osgi.service.metatype.MetaTypeService#getMetaTypeInformation(org.osgi.framework.Bundle)
+ */
+ public EquinoxMetaTypeInformation getMetaTypeInformation(Bundle bundle) {
+ return getMetaTypeProvider(bundle);
+ }
+
+ /**
+ * Internal Method - to get MetaTypeProvider object.
+ */
+ private EquinoxMetaTypeInformation getMetaTypeProvider(final Bundle b) {
+ final LogService loggerTemp = this.logger;
+ final ServiceTracker<Object, Object> tracker = this.metaTypeProviderTracker;
+ try {
+ Long bID = new Long(b.getBundleId());
+ synchronized (_mtps) {
+ if (_mtps.containsKey(bID))
+ return _mtps.get(bID);
+ // Avoid synthetic accessor method warnings.
+
+ EquinoxMetaTypeInformation mti = AccessController.doPrivileged(new PrivilegedExceptionAction<EquinoxMetaTypeInformation>() {
+ public EquinoxMetaTypeInformation run() throws ParserConfigurationException, SAXException {
+ MetaTypeInformationImpl impl = new MetaTypeInformationImpl(b, newParser(), loggerTemp);
+ if (!impl._isThereMeta)
+ return new MetaTypeProviderTracker(b, loggerTemp, tracker);
+ return impl;
+ }
+ });
+ _mtps.put(bID, mti);
+ return mti;
+ }
+ } catch (Exception e) {
+ logger.log(LogService.LOG_ERROR, NLS.bind(MetaTypeMsg.EXCEPTION_MESSAGE, e.getMessage()), e);
+ return new MetaTypeProviderTracker(b, loggerTemp, tracker);
+ }
+ }
+
+ SAXParser newParser() throws ParserConfigurationException, SAXException {
+ boolean namespaceAware = _parserFactory.isNamespaceAware();
+ boolean validating = _parserFactory.isValidating();
+ // Always want a non-validating parser.
+ _parserFactory.setValidating(false);
+ try {
+ // If the factory is already namespace aware, we know it can create namespace aware parsers
+ // because that was checked in the service tracker.
+ if (namespaceAware) {
+ return _parserFactory.newSAXParser();
+ }
+ // If the factory is not already namespace aware, it may or may not be able to create
+ // namespace aware parsers.
+ _parserFactory.setNamespaceAware(true);
+ try {
+ return _parserFactory.newSAXParser();
+ } catch (Exception e) {
+ // Factory cannot create namespace aware parsers. Go with the last resort.
+ _parserFactory.setNamespaceAware(false);
+ return _parserFactory.newSAXParser();
+ }
+ } finally {
+ // Restore the previous settings in all cases.
+ _parserFactory.setNamespaceAware(namespaceAware);
+ _parserFactory.setValidating(validating);
+ }
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.osgi.framework.BundleListener#bundleChanged(org.osgi.framework.BundleEvent)
+ */
+ public void bundleChanged(BundleEvent event) {
+
+ int type = event.getType();
+ Long bID = new Long(event.getBundle().getBundleId());
+
+ switch (type) {
+ case BundleEvent.UPDATED :
+ case BundleEvent.UNINSTALLED :
+ _mtps.remove(bID);
+ break;
+ case BundleEvent.INSTALLED :
+ case BundleEvent.RESOLVED :
+ case BundleEvent.STARTED :
+ case BundleEvent.STOPPED :
+ case BundleEvent.UNRESOLVED :
+ default :
+ break;
+ }
+ }
+}
diff --git a/bundles/org.eclipse.equinox.metatype/src/org/eclipse/equinox/metatype/ObjectClassDefinitionImpl.java b/bundles/org.eclipse.equinox.metatype/src/org/eclipse/equinox/metatype/impl/ObjectClassDefinitionImpl.java
index 244412e..22d0f76 100644
--- a/bundles/org.eclipse.equinox.metatype/src/org/eclipse/equinox/metatype/ObjectClassDefinitionImpl.java
+++ b/bundles/org.eclipse.equinox.metatype/src/org/eclipse/equinox/metatype/impl/ObjectClassDefinitionImpl.java
@@ -1,313 +1,320 @@
-/*******************************************************************************
- * Copyright (c) 2005, 2011 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License v1.0
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/epl-v10.html
- *
- * Contributors:
- * IBM Corporation - initial API and implementation
- *******************************************************************************/
-package org.eclipse.equinox.metatype;
-
-import java.io.IOException;
-import java.io.InputStream;
-import java.net.URL;
-import java.util.*;
-import org.osgi.framework.Bundle;
-import org.osgi.service.metatype.AttributeDefinition;
-import org.osgi.service.metatype.ObjectClassDefinition;
-
-/**
- * Implementation of ObjectClassDefinition
- */
-public class ObjectClassDefinitionImpl extends LocalizationElement implements ObjectClassDefinition, Cloneable {
-
- public static final char LOCALE_SEP = '_';
-
- String _name;
- String _id;
- String _description;
-
- int _type;
- Vector<AttributeDefinitionImpl> _required = new Vector<AttributeDefinitionImpl>(7);
- Vector<AttributeDefinitionImpl> _optional = new Vector<AttributeDefinitionImpl>(7);
- Icon _icon;
-
- /*
- * Constructor of class ObjectClassDefinitionImpl.
- */
- public ObjectClassDefinitionImpl(String name, String description, String id, String localization) {
-
- this._name = name;
- this._description = description;
- this._id = id;
- this._localization = localization;
- }
-
- /*
- * Constructor of class ObjectClassDefinitionImpl.
- */
- public ObjectClassDefinitionImpl(String name, String description, String id, int type, String localization) {
-
- this._name = name;
- this._id = id;
- this._description = description;
- this._type = type;
- this._localization = localization;
- }
-
- /*
- *
- */
- public synchronized Object clone() {
-
- ObjectClassDefinitionImpl ocd = new ObjectClassDefinitionImpl(_name, _description, _id, _type, _localization);
- for (int i = 0; i < _required.size(); i++) {
- AttributeDefinitionImpl ad = _required.elementAt(i);
- ocd.addAttributeDefinition((AttributeDefinitionImpl) ad.clone(), true);
- }
- for (int i = 0; i < _optional.size(); i++) {
- AttributeDefinitionImpl ad = _optional.elementAt(i);
- ocd.addAttributeDefinition((AttributeDefinitionImpl) ad.clone(), false);
- }
- if (_icon != null) {
- ocd.setIcon((Icon) _icon.clone());
- }
- return ocd;
- }
-
- /*
- * (non-Javadoc)
- *
- * @see org.osgi.service.metatype.ObjectClassDefinition#getName()
- */
- public String getName() {
- return getLocalized(_name);
- }
-
- /**
- * Method to set the name of ObjectClassDefinition.
- */
- void setName(String name) {
- this._name = name;
- }
-
- /*
- * (non-Javadoc)
- *
- * @see org.osgi.service.metatype.ObjectClassDefinition#getID()
- */
- public String getID() {
- return _id;
- }
-
- /*
- * (non-Javadoc)
- *
- * @see org.osgi.service.metatype.ObjectClassDefinition#getDescription()
- */
- public String getDescription() {
- return getLocalized(_description);
- }
-
- /*
- * Method to set the description of ObjectClassDefinition.
- */
- void setDescription(String description) {
- this._description = description;
- }
-
- /*
- * (non-Javadoc)
- *
- * @see org.osgi.service.metatype.ObjectClassDefinition#getAttributeDefinitions(int)
- */
- public AttributeDefinition[] getAttributeDefinitions(int filter) {
-
- AttributeDefinition[] atts;
- switch (filter) {
- case REQUIRED :
- atts = new AttributeDefinition[_required.size()];
- _required.toArray(atts);
- return atts;
- case OPTIONAL :
- atts = new AttributeDefinition[_optional.size()];
- _optional.toArray(atts);
- return atts;
- case ALL :
- default :
- atts = new AttributeDefinition[_required.size() + _optional.size()];
- Enumeration<AttributeDefinitionImpl> e = _required.elements();
- int i = 0;
- while (e.hasMoreElements()) {
- atts[i] = e.nextElement();
- i++;
- }
- e = _optional.elements();
- while (e.hasMoreElements()) {
- atts[i] = e.nextElement();
- i++;
- }
- return atts;
- }
- }
-
- /*
- * Method to add one new AD to ObjectClassDefinition.
- */
- void addAttributeDefinition(AttributeDefinitionImpl ad, boolean isRequired) {
-
- if (isRequired) {
- _required.addElement(ad);
- } else {
- _optional.addElement(ad);
- }
- }
-
- /*
- * (non-Javadoc)
- *
- * @see org.osgi.service.metatype.ObjectClassDefinition#getIcon(int)
- */
- public InputStream getIcon(int sizeHint) throws IOException {
- // The parameter simply represents a requested size. This method should never return null if an
- // icon exists.
- // TODO This method may change further depending on the outcome of certain ongoing CPEG discussions.
- // It is thought that users should be able to specify the same icon multiple times but of different
- // sizes. This would require a change to the XML schema. This method would then return the icon with
- // a size closest to the requested size.
- if ((_icon == null)) {
- return null;
- }
- Bundle b = _icon.getIconBundle();
- URL[] urls = FragmentUtils.findEntries(b, getLocalized(_icon.getIconName()));
- if (urls != null && urls.length > 0) {
- return urls[0].openStream();
- }
- return null;
- }
-
- /**
- * Method to set the icon of ObjectClassDefinition.
- */
- void setIcon(Icon icon) {
- this._icon = icon;
- }
-
- /**
- * Method to set the resource bundle for this OCD and all its ADs.
- */
- void setResourceBundle(String assignedLocale, Bundle bundle) {
-
- _rb = getResourceBundle(assignedLocale, bundle);
-
- Enumeration<AttributeDefinitionImpl> allADReqs = _required.elements();
- while (allADReqs.hasMoreElements()) {
- AttributeDefinitionImpl ad = allADReqs.nextElement();
- ad.setResourceBundle(_rb);
- }
-
- Enumeration<AttributeDefinitionImpl> allADOpts = _optional.elements();
- while (allADOpts.hasMoreElements()) {
- AttributeDefinitionImpl ad = allADOpts.nextElement();
- ad.setResourceBundle(_rb);
- }
- }
-
- /*
- * Internal Method - to get resource bundle.
- */
- private ResourceBundle getResourceBundle(String locale, final Bundle bundle) {
- // Determine the base name of the bundle localization property files.
- // If the <MetaData> 'localization' attribute was not specified,
- // use the Bundle-Localization manifest header value instead if it exists.
- String resourceBase = _localization != null ? _localization : MetaTypeProviderImpl.getBundleLocalization(bundle);
-
- // There are seven searching candidates possible:
- // baseName +
- // "_" + language1 + "_" + country1 + "_" + variation1 + ".properties"
- // or "_" + language1 + "_" + country1 + ".properties"
- // or "_" + language1 + ".properties"
- // or "_" + language2 + "_" + country2 + "_" + variation2 + ".properties"
- // or "_" + language2 + "_" + country2 + ".properties"
- // or "_" + language2 + ".properties"
- // or "" + ".properties"
- //
- // Where language1[_country1[_variation1]] is the requested locale,
- // and language2[_country2[_variation2]] is the default locale.
-
- String[] searchCandidates = new String[7];
-
- // Candidates from passed locale:
- if (locale != null && locale.length() > 0) {
- int idx1_first = locale.indexOf(LOCALE_SEP);
- if (idx1_first == -1) {
- // locale has only language.
- searchCandidates[2] = MetaTypeProviderImpl.RESOURCE_FILE_CONN + locale;
- } else {
- // locale has at least language and country.
- searchCandidates[2] = MetaTypeProviderImpl.RESOURCE_FILE_CONN + locale.substring(0, idx1_first);
- int idx1_second = locale.indexOf(LOCALE_SEP, idx1_first + 1);
- if (idx1_second == -1) {
- // locale just has both language and country.
- searchCandidates[1] = MetaTypeProviderImpl.RESOURCE_FILE_CONN + locale;
- } else {
- // locale has language, country, and variation all.
- searchCandidates[1] = MetaTypeProviderImpl.RESOURCE_FILE_CONN + locale.substring(0, idx1_second);
- searchCandidates[0] = MetaTypeProviderImpl.RESOURCE_FILE_CONN + locale;
- }
- }
- }
-
- // Candidates from Locale.getDefault():
- String defaultLocale = Locale.getDefault().toString();
- int idx2_first = defaultLocale.indexOf(LOCALE_SEP);
- int idx2_second = defaultLocale.indexOf(LOCALE_SEP, idx2_first + 1);
- if (idx2_second != -1) {
- // default-locale is format of [language]_[country]_variation.
- searchCandidates[3] = MetaTypeProviderImpl.RESOURCE_FILE_CONN + defaultLocale;
- if (searchCandidates[3].equalsIgnoreCase(searchCandidates[0])) {
- searchCandidates[3] = null;
- }
- }
- if ((idx2_first != -1) && (idx2_second != idx2_first + 1)) {
- // default-locale is format of [language]_country[_variation].
- searchCandidates[4] = MetaTypeProviderImpl.RESOURCE_FILE_CONN + ((idx2_second == -1) ? defaultLocale : defaultLocale.substring(0, idx2_second));
- if (searchCandidates[4].equalsIgnoreCase(searchCandidates[1])) {
- searchCandidates[4] = null;
- }
- }
- if ((idx2_first == -1) && (defaultLocale.length() > 0)) {
- // default-locale has only language.
- searchCandidates[5] = MetaTypeProviderImpl.RESOURCE_FILE_CONN + defaultLocale;
- } else if (idx2_first > 0) {
- // default-locale is format of language_[...].
- searchCandidates[5] = MetaTypeProviderImpl.RESOURCE_FILE_CONN + defaultLocale.substring(0, idx2_first);
- }
- if (searchCandidates[5] != null && searchCandidates[5].equalsIgnoreCase(searchCandidates[2])) {
- searchCandidates[5] = null;
- }
-
- // The final candidate.
- searchCandidates[6] = ""; //$NON-NLS-1$
-
- URL resourceUrl = null;
- URL[] urls = null;
-
- for (int idx = 0; (idx < searchCandidates.length) && (resourceUrl == null); idx++) {
- urls = (searchCandidates[idx] == null ? null : FragmentUtils.findEntries(bundle, resourceBase + searchCandidates[idx] + MetaTypeProviderImpl.RESOURCE_FILE_EXT));
- if (urls != null && urls.length > 0)
- resourceUrl = urls[0];
- }
-
- if (resourceUrl != null) {
- try {
- return new PropertyResourceBundle(resourceUrl.openStream());
- } catch (IOException ioe) {
- // Exception when creating PropertyResourceBundle object.
- }
- }
- return null;
- }
-}
+/*******************************************************************************
+ * Copyright (c) 2005, 2011 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.equinox.metatype.impl;
+
+import org.eclipse.equinox.metatype.EquinoxAttributeDefinition;
+import org.eclipse.equinox.metatype.EquinoxObjectClassDefinition;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.net.URL;
+import java.util.*;
+import org.osgi.framework.Bundle;
+
+/**
+ * Implementation of ObjectClassDefinition
+ */
+public class ObjectClassDefinitionImpl extends LocalizationElement implements EquinoxObjectClassDefinition, Cloneable {
+
+ public static final char LOCALE_SEP = '_';
+
+ String _name;
+ String _id;
+ String _description;
+
+ int _type;
+ Vector<AttributeDefinitionImpl> _required = new Vector<AttributeDefinitionImpl>(7);
+ Vector<AttributeDefinitionImpl> _optional = new Vector<AttributeDefinitionImpl>(7);
+ Icon _icon;
+
+ private final ExtendableHelper helper;
+
+ /*
+ * Constructor of class ObjectClassDefinitionImpl.
+ */
+ public ObjectClassDefinitionImpl(String name, String description, String id, String localization, Map<String, Map<String, String>> extensionAttributes) {
+ this(name, description, id, 0, localization, new ExtendableHelper(extensionAttributes));
+ }
+
+ /*
+ * Constructor of class ObjectClassDefinitionImpl.
+ */
+ public ObjectClassDefinitionImpl(String name, String description, String id, int type, String localization, ExtendableHelper helper) {
+ this._name = name;
+ this._id = id;
+ this._description = description;
+ this._type = type;
+ this._localization = localization;
+ this.helper = helper;
+ }
+
+ /*
+ *
+ */
+ public synchronized Object clone() {
+
+ ObjectClassDefinitionImpl ocd = new ObjectClassDefinitionImpl(_name, _description, _id, _type, _localization, helper);
+ for (int i = 0; i < _required.size(); i++) {
+ AttributeDefinitionImpl ad = _required.elementAt(i);
+ ocd.addAttributeDefinition((AttributeDefinitionImpl) ad.clone(), true);
+ }
+ for (int i = 0; i < _optional.size(); i++) {
+ AttributeDefinitionImpl ad = _optional.elementAt(i);
+ ocd.addAttributeDefinition((AttributeDefinitionImpl) ad.clone(), false);
+ }
+ if (_icon != null) {
+ ocd.setIcon((Icon) _icon.clone());
+ }
+ return ocd;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.osgi.service.metatype.ObjectClassDefinition#getName()
+ */
+ public String getName() {
+ return getLocalized(_name);
+ }
+
+ /**
+ * Method to set the name of ObjectClassDefinition.
+ */
+ void setName(String name) {
+ this._name = name;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.osgi.service.metatype.ObjectClassDefinition#getID()
+ */
+ public String getID() {
+ return _id;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.osgi.service.metatype.ObjectClassDefinition#getDescription()
+ */
+ public String getDescription() {
+ return getLocalized(_description);
+ }
+
+ /*
+ * Method to set the description of ObjectClassDefinition.
+ */
+ void setDescription(String description) {
+ this._description = description;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.osgi.service.metatype.ObjectClassDefinition#getAttributeDefinitions(int)
+ */
+ public EquinoxAttributeDefinition[] getAttributeDefinitions(int filter) {
+
+ EquinoxAttributeDefinition[] atts;
+ switch (filter) {
+ case REQUIRED :
+ atts = new EquinoxAttributeDefinition[_required.size()];
+ _required.toArray(atts);
+ return atts;
+ case OPTIONAL :
+ atts = new EquinoxAttributeDefinition[_optional.size()];
+ _optional.toArray(atts);
+ return atts;
+ case ALL :
+ default :
+ atts = new EquinoxAttributeDefinition[_required.size() + _optional.size()];
+ Enumeration<AttributeDefinitionImpl> e = _required.elements();
+ int i = 0;
+ while (e.hasMoreElements()) {
+ atts[i] = e.nextElement();
+ i++;
+ }
+ e = _optional.elements();
+ while (e.hasMoreElements()) {
+ atts[i] = e.nextElement();
+ i++;
+ }
+ return atts;
+ }
+ }
+
+ /*
+ * Method to add one new AD to ObjectClassDefinition.
+ */
+ void addAttributeDefinition(AttributeDefinitionImpl ad, boolean isRequired) {
+
+ if (isRequired) {
+ _required.addElement(ad);
+ } else {
+ _optional.addElement(ad);
+ }
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.osgi.service.metatype.ObjectClassDefinition#getIcon(int)
+ */
+ public InputStream getIcon(int sizeHint) throws IOException {
+ // The parameter simply represents a requested size. This method should never return null if an
+ // icon exists.
+ // TODO This method may change further depending on the outcome of certain ongoing CPEG discussions.
+ // It is thought that users should be able to specify the same icon multiple times but of different
+ // sizes. This would require a change to the XML schema. This method would then return the icon with
+ // a size closest to the requested size.
+ if ((_icon == null)) {
+ return null;
+ }
+ Bundle b = _icon.getIconBundle();
+ URL[] urls = FragmentUtils.findEntries(b, getLocalized(_icon.getIconName()));
+ if (urls != null && urls.length > 0) {
+ return urls[0].openStream();
+ }
+ return null;
+ }
+
+ /**
+ * Method to set the icon of ObjectClassDefinition.
+ */
+ void setIcon(Icon icon) {
+ this._icon = icon;
+ }
+
+ /**
+ * Method to set the resource bundle for this OCD and all its ADs.
+ */
+ void setResourceBundle(String assignedLocale, Bundle bundle) {
+
+ _rb = getResourceBundle(assignedLocale, bundle);
+
+ Enumeration<AttributeDefinitionImpl> allADReqs = _required.elements();
+ while (allADReqs.hasMoreElements()) {
+ AttributeDefinitionImpl ad = allADReqs.nextElement();
+ ad.setResourceBundle(_rb);
+ }
+
+ Enumeration<AttributeDefinitionImpl> allADOpts = _optional.elements();
+ while (allADOpts.hasMoreElements()) {
+ AttributeDefinitionImpl ad = allADOpts.nextElement();
+ ad.setResourceBundle(_rb);
+ }
+ }
+
+ /*
+ * Internal Method - to get resource bundle.
+ */
+ private ResourceBundle getResourceBundle(String locale, final Bundle bundle) {
+ // Determine the base name of the bundle localization property files.
+ // If the <MetaData> 'localization' attribute was not specified,
+ // use the Bundle-Localization manifest header value instead if it exists.
+ String resourceBase = _localization != null ? _localization : MetaTypeProviderImpl.getBundleLocalization(bundle);
+
+ // There are seven searching candidates possible:
+ // baseName +
+ // "_" + language1 + "_" + country1 + "_" + variation1 + ".properties"
+ // or "_" + language1 + "_" + country1 + ".properties"
+ // or "_" + language1 + ".properties"
+ // or "_" + language2 + "_" + country2 + "_" + variation2 + ".properties"
+ // or "_" + language2 + "_" + country2 + ".properties"
+ // or "_" + language2 + ".properties"
+ // or "" + ".properties"
+ //
+ // Where language1[_country1[_variation1]] is the requested locale,
+ // and language2[_country2[_variation2]] is the default locale.
+
+ String[] searchCandidates = new String[7];
+
+ // Candidates from passed locale:
+ if (locale != null && locale.length() > 0) {
+ int idx1_first = locale.indexOf(LOCALE_SEP);
+ if (idx1_first == -1) {
+ // locale has only language.
+ searchCandidates[2] = MetaTypeProviderImpl.RESOURCE_FILE_CONN + locale;
+ } else {
+ // locale has at least language and country.
+ searchCandidates[2] = MetaTypeProviderImpl.RESOURCE_FILE_CONN + locale.substring(0, idx1_first);
+ int idx1_second = locale.indexOf(LOCALE_SEP, idx1_first + 1);
+ if (idx1_second == -1) {
+ // locale just has both language and country.
+ searchCandidates[1] = MetaTypeProviderImpl.RESOURCE_FILE_CONN + locale;
+ } else {
+ // locale has language, country, and variation all.
+ searchCandidates[1] = MetaTypeProviderImpl.RESOURCE_FILE_CONN + locale.substring(0, idx1_second);
+ searchCandidates[0] = MetaTypeProviderImpl.RESOURCE_FILE_CONN + locale;
+ }
+ }
+ }
+
+ // Candidates from Locale.getDefault():
+ String defaultLocale = Locale.getDefault().toString();
+ int idx2_first = defaultLocale.indexOf(LOCALE_SEP);
+ int idx2_second = defaultLocale.indexOf(LOCALE_SEP, idx2_first + 1);
+ if (idx2_second != -1) {
+ // default-locale is format of [language]_[country]_variation.
+ searchCandidates[3] = MetaTypeProviderImpl.RESOURCE_FILE_CONN + defaultLocale;
+ if (searchCandidates[3].equalsIgnoreCase(searchCandidates[0])) {
+ searchCandidates[3] = null;
+ }
+ }
+ if ((idx2_first != -1) && (idx2_second != idx2_first + 1)) {
+ // default-locale is format of [language]_country[_variation].
+ searchCandidates[4] = MetaTypeProviderImpl.RESOURCE_FILE_CONN + ((idx2_second == -1) ? defaultLocale : defaultLocale.substring(0, idx2_second));
+ if (searchCandidates[4].equalsIgnoreCase(searchCandidates[1])) {
+ searchCandidates[4] = null;
+ }
+ }
+ if ((idx2_first == -1) && (defaultLocale.length() > 0)) {
+ // default-locale has only language.
+ searchCandidates[5] = MetaTypeProviderImpl.RESOURCE_FILE_CONN + defaultLocale;
+ } else if (idx2_first > 0) {
+ // default-locale is format of language_[...].
+ searchCandidates[5] = MetaTypeProviderImpl.RESOURCE_FILE_CONN + defaultLocale.substring(0, idx2_first);
+ }
+ if (searchCandidates[5] != null && searchCandidates[5].equalsIgnoreCase(searchCandidates[2])) {
+ searchCandidates[5] = null;
+ }
+
+ // The final candidate.
+ searchCandidates[6] = ""; //$NON-NLS-1$
+
+ URL resourceUrl = null;
+ URL[] urls = null;
+
+ for (int idx = 0; (idx < searchCandidates.length) && (resourceUrl == null); idx++) {
+ urls = (searchCandidates[idx] == null ? null : FragmentUtils.findEntries(bundle, resourceBase + searchCandidates[idx] + MetaTypeProviderImpl.RESOURCE_FILE_EXT));
+ if (urls != null && urls.length > 0)
+ resourceUrl = urls[0];
+ }
+
+ if (resourceUrl != null) {
+ try {
+ return new PropertyResourceBundle(resourceUrl.openStream());
+ } catch (IOException ioe) {
+ // Exception when creating PropertyResourceBundle object.
+ }
+ }
+ return null;
+ }
+
+ public Map<String, String> getExtensionAttributes(String schema) {
+ return helper.getExtensionAttributes(schema);
+ }
+
+ public Set<String> getExtensionUris() {
+ return helper.getExtensionUris();
+ }
+}
diff --git a/bundles/org.eclipse.equinox.metatype/src/org/eclipse/equinox/metatype/ValueTokenizer.java b/bundles/org.eclipse.equinox.metatype/src/org/eclipse/equinox/metatype/impl/ValueTokenizer.java
index da829c5..6c868d7 100644
--- a/bundles/org.eclipse.equinox.metatype/src/org/eclipse/equinox/metatype/ValueTokenizer.java
+++ b/bundles/org.eclipse.equinox.metatype/src/org/eclipse/equinox/metatype/impl/ValueTokenizer.java
@@ -1,274 +1,274 @@
-/*******************************************************************************
- * Copyright (c) 2005, 2011 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License v1.0
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/epl-v10.html
- *
- * Contributors:
- * IBM Corporation - initial API and implementation
- *******************************************************************************/
-package org.eclipse.equinox.metatype;
-
-import java.math.BigDecimal;
-import java.math.BigInteger;
-import java.util.*;
-import org.eclipse.osgi.util.NLS;
-import org.osgi.service.log.LogService;
-import org.osgi.service.metatype.AttributeDefinition;
-
-public class ValueTokenizer {
- private static final char DELIMITER = ',';
- private static final char ESCAPE = '\\';
-
- private final LogService logger;
- private final List<String> values = new ArrayList<String>();
-
- /*
- * Constructor of class ValueTokenizer
- */
- public ValueTokenizer(String values_str, LogService logger) {
- this.logger = logger;
- if (values_str == null)
- return;
- // The trick is to strip out unescaped whitespace characters before and
- // after the input string as well as before and after each
- // individual token within the input string without losing any escaped
- // whitespace characters. Whitespace between two non-whitespace
- // characters may or may not be escaped. Also, any character may be
- // escaped. The escape character is '\'. The delimiter is ','.
- StringBuffer buffer = new StringBuffer();
- // Loop over the characters within the input string and extract each
- // value token.
- for (int i = 0; i < values_str.length(); i++) {
- char c1 = values_str.charAt(i);
- switch (c1) {
- case DELIMITER :
- // When the delimiter is encountered, add the extracted
- // token to the result and prepare the buffer to receive the
- // next token.
- values.add(buffer.toString());
- buffer.delete(0, buffer.length());
- break;
- case ESCAPE :
- // When the escape is encountered, add the immediately
- // following character to the token, unless the end of the
- // input has been reached. Note this will result in loop
- // counter 'i' being incremented twice, once here and once
- // at the end of the loop.
- if (i + 1 < values_str.length()) {
- buffer.append(values_str.charAt(++i));
- } else {
- // If the ESCAPE character occurs as the last character
- // of the string, log the error and ignore it.
- logger.log(LogService.LOG_ERROR, "ValueTokenizer.ValueTokenizer(String) " + MetaTypeMsg.TOKENIZER_GOT_INVALID_DATA); //$NON-NLS-1$
- }
- break;
- default :
- // For all other characters, add them to the current token
- // unless dealing with unescaped whitespace at the beginning
- // or end. We know the whitespace is unescaped because it
- // would have been handled in the ESCAPE case otherwise.
- if (Character.isWhitespace(c1)) {
- // Ignore unescaped whitespace at the beginning of the
- // token.
- if (buffer.length() == 0) {
- continue;
- }
- // If the whitespace is not at the beginning, look
- // forward, starting with the next character, to see if
- // it's in the middle or at the end. Unescaped
- // whitespace in the middle is okay.
- for (int j = i + 1; j < values_str.length(); j++) {
- // Keep looping until the end of the string is
- // reached or a non-whitespace character other than
- // the escape is seen.
- char c2 = values_str.charAt(j);
- if (!Character.isWhitespace(c2)) {
- // If the current character is not the DELIMITER, all whitespace
- // characters are significant and should be added to the token.
- // Otherwise, they're at the end and should be ignored. But watch
- // out for an escape character at the end of the input. Ignore it
- // and any previous insignificant whitespace if it exists.
- if (c2 == ESCAPE && j + 1 >= values_str.length()) {
- continue;
- }
- if (c2 != DELIMITER) {
- buffer.append(values_str.substring(i, j));
- }
- // Let loop counter i catch up with the inner loop but keep in
- // mind it will still be incremented at the end of the outer loop.
- i = j - 1;
- break;
- }
- }
- } else {
- // For non-whitespace characters.
- buffer.append(c1);
- }
- }
- }
- // Don't forget to add the last token.
- values.add(buffer.toString());
- }
-
- /*
- * Method to return values as Vector.
- */
- public Collection<String> getValues() {
- return Collections.unmodifiableList(values);
- }
-
- /*
- * Method to return values as String[] or null.
- */
- public String[] getValuesAsArray() {
- if (values.isEmpty()) {
- return null;
- }
- return values.toArray(new String[values.size()]);
- }
-
- public String getValuesAsString() {
- if (values.isEmpty()) {
- return null;
- }
- if (values.size() == 1) {
- return values.get(0);
- }
- StringBuffer buffer = new StringBuffer(values.get(0));
- for (int i = 1; i < values.size(); i++) {
- buffer.append(',');
- buffer.append(values.get(i));
- }
- return buffer.toString();
- }
-
- public String validate(AttributeDefinitionImpl ad) {
- // An empty list means the original value was null. Null is never valid.
- if (values.isEmpty()) {
- return MetaTypeMsg.NULL_IS_INVALID;
- }
- try {
- // A value must match the cardinality.
- int cardinality = Math.abs(ad.getCardinality());
- // If the cardinality is zero, the value must contain one and only one token.
- if (cardinality == 0) {
- if (values.size() != 1) {
- return NLS.bind(MetaTypeMsg.CARDINALITY_VIOLATION, new Object[] {getValuesAsString(), values.size(), 1, 1});
- }
- }
- // Otherwise, the number of tokens must be between 0 and cardinality, inclusive.
- else if (values.size() > cardinality) {
- return NLS.bind(MetaTypeMsg.CARDINALITY_VIOLATION, new Object[] {getValuesAsString(), values.size(), 0, cardinality});
- }
- // Now inspect each token.
- for (Iterator<String> i = values.iterator(); i.hasNext();) {
- String s = i.next();
- // If options were declared and the value does not match one of them, the value is not valid.
- if (!ad._values.isEmpty() && !ad._values.contains(s)) {
- return NLS.bind(MetaTypeMsg.VALUE_OUT_OF_OPTION, s);
- }
- // Check the type. Also check the range if min or max were declared.
- boolean rangeError = false;
- switch (ad._dataType) {
- case AttributeDefinition.PASSWORD :
- case AttributeDefinition.STRING :
- if (ad._minValue != null && s.length() < (Integer) ad._minValue) {
- rangeError = true;
- } else if (ad._maxValue != null && s.length() > (Integer) ad._maxValue) {
- rangeError = true;
- }
- break;
- case AttributeDefinition.INTEGER :
- Integer intVal = new Integer(s);
- if (ad._minValue != null && intVal.compareTo((Integer) ad._minValue) < 0) {
- rangeError = true;
- } else if (ad._maxValue != null && intVal.compareTo((Integer) ad._maxValue) > 0) {
- rangeError = true;
- }
- break;
- case AttributeDefinition.LONG :
- Long longVal = new Long(s);
- if (ad._minValue != null && longVal.compareTo((Long) ad._minValue) < 0) {
- rangeError = true;
- } else if (ad._maxValue != null && longVal.compareTo((Long) ad._maxValue) > 0) {
- rangeError = true;
- }
- break;
- case AttributeDefinition.DOUBLE :
- Double doubleVal = new Double(s);
- if (ad._minValue != null && doubleVal.compareTo((Double) ad._minValue) < 0) {
- rangeError = true;
- } else if (ad._maxValue != null && doubleVal.compareTo((Double) ad._maxValue) > 0) {
- rangeError = true;
- }
- break;
- case AttributeDefinition.BOOLEAN :
- // Any string can be converted into a boolean via Boolean.valueOf(String).
- // Seems unnecessary to impose any further restrictions.
- break;
- case AttributeDefinition.CHARACTER :
- Character charVal = new Character(s.charAt(0));
- if (ad._minValue != null && charVal.compareTo((Character) ad._minValue) < 0) {
- rangeError = true;
- } else if (ad._maxValue != null && charVal.compareTo((Character) ad._maxValue) > 0) {
- rangeError = true;
- }
- break;
- case AttributeDefinition.FLOAT :
- Float floatVal = new Float(s);
- if (ad._minValue != null && floatVal.compareTo((Float) ad._minValue) < 0) {
- rangeError = true;
- } else if (ad._maxValue != null && floatVal.compareTo((Float) ad._maxValue) > 0) {
- rangeError = true;
- }
- break;
- case AttributeDefinition.SHORT :
- Short shortVal = new Short(s);
- if (ad._minValue != null && shortVal.compareTo((Short) ad._minValue) < 0) {
- rangeError = true;
- } else if (ad._maxValue != null && shortVal.compareTo((Short) ad._maxValue) > 0) {
- rangeError = true;
- }
- break;
- case AttributeDefinition.BYTE :
- Byte byteVal = new Byte(s);
- if (ad._minValue != null && byteVal.compareTo((Byte) ad._minValue) < 0) {
- rangeError = true;
- } else if (ad._maxValue != null && byteVal.compareTo((Byte) ad._maxValue) > 0) {
- rangeError = true;
- }
- break;
- case AttributeDefinition.BIGDECIMAL :
- BigDecimal bigDecVal = new BigDecimal(s);
- if (ad._minValue != null && bigDecVal.compareTo((BigDecimal) ad._minValue) < 0) {
- rangeError = true;
- } else if (ad._maxValue != null && bigDecVal.compareTo((BigDecimal) ad._maxValue) > 0) {
- rangeError = true;
- }
- break;
- case AttributeDefinition.BIGINTEGER :
- BigInteger bigIntVal = new BigInteger(s);
- if (ad._minValue != null && bigIntVal.compareTo((BigInteger) ad._minValue) < 0) {
- rangeError = true;
- } else if (ad._maxValue != null && bigIntVal.compareTo((BigInteger) ad._maxValue) > 0) {
- rangeError = true;
- }
- break;
- default :
- throw new IllegalStateException();
- }
- if (rangeError) {
- return (NLS.bind(MetaTypeMsg.VALUE_OUT_OF_RANGE, s));
- }
- }
- // No problems detected
- return ""; //$NON-NLS-1$
- } catch (Throwable t) {
- String message = NLS.bind(MetaTypeMsg.EXCEPTION_MESSAGE, t.getClass().getName(), t.getMessage());
- logger.log(LogService.LOG_DEBUG, message, t);
- return message;
- }
- }
-}
+/*******************************************************************************
+ * Copyright (c) 2005, 2011 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.equinox.metatype.impl;
+
+import java.math.BigDecimal;
+import java.math.BigInteger;
+import java.util.*;
+import org.eclipse.osgi.util.NLS;
+import org.osgi.service.log.LogService;
+import org.osgi.service.metatype.AttributeDefinition;
+
+public class ValueTokenizer {
+ private static final char DELIMITER = ',';
+ private static final char ESCAPE = '\\';
+
+ private final LogService logger;
+ private final List<String> values = new ArrayList<String>();
+
+ /*
+ * Constructor of class ValueTokenizer
+ */
+ public ValueTokenizer(String values_str, LogService logger) {
+ this.logger = logger;
+ if (values_str == null)
+ return;
+ // The trick is to strip out unescaped whitespace characters before and
+ // after the input string as well as before and after each
+ // individual token within the input string without losing any escaped
+ // whitespace characters. Whitespace between two non-whitespace
+ // characters may or may not be escaped. Also, any character may be
+ // escaped. The escape character is '\'. The delimiter is ','.
+ StringBuffer buffer = new StringBuffer();
+ // Loop over the characters within the input string and extract each
+ // value token.
+ for (int i = 0; i < values_str.length(); i++) {
+ char c1 = values_str.charAt(i);
+ switch (c1) {
+ case DELIMITER :
+ // When the delimiter is encountered, add the extracted
+ // token to the result and prepare the buffer to receive the
+ // next token.
+ values.add(buffer.toString());
+ buffer.delete(0, buffer.length());
+ break;
+ case ESCAPE :
+ // When the escape is encountered, add the immediately
+ // following character to the token, unless the end of the
+ // input has been reached. Note this will result in loop
+ // counter 'i' being incremented twice, once here and once
+ // at the end of the loop.
+ if (i + 1 < values_str.length()) {
+ buffer.append(values_str.charAt(++i));
+ } else {
+ // If the ESCAPE character occurs as the last character
+ // of the string, log the error and ignore it.
+ logger.log(LogService.LOG_ERROR, "ValueTokenizer.ValueTokenizer(String) " + MetaTypeMsg.TOKENIZER_GOT_INVALID_DATA); //$NON-NLS-1$
+ }
+ break;
+ default :
+ // For all other characters, add them to the current token
+ // unless dealing with unescaped whitespace at the beginning
+ // or end. We know the whitespace is unescaped because it
+ // would have been handled in the ESCAPE case otherwise.
+ if (Character.isWhitespace(c1)) {
+ // Ignore unescaped whitespace at the beginning of the
+ // token.
+ if (buffer.length() == 0) {
+ continue;
+ }
+ // If the whitespace is not at the beginning, look
+ // forward, starting with the next character, to see if
+ // it's in the middle or at the end. Unescaped
+ // whitespace in the middle is okay.
+ for (int j = i + 1; j < values_str.length(); j++) {
+ // Keep looping until the end of the string is
+ // reached or a non-whitespace character other than
+ // the escape is seen.
+ char c2 = values_str.charAt(j);
+ if (!Character.isWhitespace(c2)) {
+ // If the current character is not the DELIMITER, all whitespace
+ // characters are significant and should be added to the token.
+ // Otherwise, they're at the end and should be ignored. But watch
+ // out for an escape character at the end of the input. Ignore it
+ // and any previous insignificant whitespace if it exists.
+ if (c2 == ESCAPE && j + 1 >= values_str.length()) {
+ continue;
+ }
+ if (c2 != DELIMITER) {
+ buffer.append(values_str.substring(i, j));
+ }
+ // Let loop counter i catch up with the inner loop but keep in
+ // mind it will still be incremented at the end of the outer loop.
+ i = j - 1;
+ break;
+ }
+ }
+ } else {
+ // For non-whitespace characters.
+ buffer.append(c1);
+ }
+ }
+ }
+ // Don't forget to add the last token.
+ values.add(buffer.toString());
+ }
+
+ /*
+ * Method to return values as Vector.
+ */
+ public Collection<String> getValues() {
+ return Collections.unmodifiableList(values);
+ }
+
+ /*
+ * Method to return values as String[] or null.
+ */
+ public String[] getValuesAsArray() {
+ if (values.isEmpty()) {
+ return null;
+ }
+ return values.toArray(new String[values.size()]);
+ }
+
+ public String getValuesAsString() {
+ if (values.isEmpty()) {
+ return null;
+ }
+ if (values.size() == 1) {
+ return values.get(0);
+ }
+ StringBuffer buffer = new StringBuffer(values.get(0));
+ for (int i = 1; i < values.size(); i++) {
+ buffer.append(',');
+ buffer.append(values.get(i));
+ }
+ return buffer.toString();
+ }
+
+ public String validate(AttributeDefinitionImpl ad) {
+ // An empty list means the original value was null. Null is never valid.
+ if (values.isEmpty()) {
+ return MetaTypeMsg.NULL_IS_INVALID;
+ }
+ try {
+ // A value must match the cardinality.
+ int cardinality = Math.abs(ad.getCardinality());
+ // If the cardinality is zero, the value must contain one and only one token.
+ if (cardinality == 0) {
+ if (values.size() != 1) {
+ return NLS.bind(MetaTypeMsg.CARDINALITY_VIOLATION, new Object[] {getValuesAsString(), values.size(), 1, 1});
+ }
+ }
+ // Otherwise, the number of tokens must be between 0 and cardinality, inclusive.
+ else if (values.size() > cardinality) {
+ return NLS.bind(MetaTypeMsg.CARDINALITY_VIOLATION, new Object[] {getValuesAsString(), values.size(), 0, cardinality});
+ }
+ // Now inspect each token.
+ for (Iterator<String> i = values.iterator(); i.hasNext();) {
+ String s = i.next();
+ // If options were declared and the value does not match one of them, the value is not valid.
+ if (!ad._values.isEmpty() && !ad._values.contains(s)) {
+ return NLS.bind(MetaTypeMsg.VALUE_OUT_OF_OPTION, s);
+ }
+ // Check the type. Also check the range if min or max were declared.
+ boolean rangeError = false;
+ switch (ad._dataType) {
+ case AttributeDefinition.PASSWORD :
+ case AttributeDefinition.STRING :
+ if (ad._minValue != null && s.length() < (Integer) ad._minValue) {
+ rangeError = true;
+ } else if (ad._maxValue != null && s.length() > (Integer) ad._maxValue) {
+ rangeError = true;
+ }
+ break;
+ case AttributeDefinition.INTEGER :
+ Integer intVal = new Integer(s);
+ if (ad._minValue != null && intVal.compareTo((Integer) ad._minValue) < 0) {
+ rangeError = true;
+ } else if (ad._maxValue != null && intVal.compareTo((Integer) ad._maxValue) > 0) {
+ rangeError = true;
+ }
+ break;
+ case AttributeDefinition.LONG :
+ Long longVal = new Long(s);
+ if (ad._minValue != null && longVal.compareTo((Long) ad._minValue) < 0) {
+ rangeError = true;
+ } else if (ad._maxValue != null && longVal.compareTo((Long) ad._maxValue) > 0) {
+ rangeError = true;
+ }
+ break;
+ case AttributeDefinition.DOUBLE :
+ Double doubleVal = new Double(s);
+ if (ad._minValue != null && doubleVal.compareTo((Double) ad._minValue) < 0) {
+ rangeError = true;
+ } else if (ad._maxValue != null && doubleVal.compareTo((Double) ad._maxValue) > 0) {
+ rangeError = true;
+ }
+ break;
+ case AttributeDefinition.BOOLEAN :
+ // Any string can be converted into a boolean via Boolean.valueOf(String).
+ // Seems unnecessary to impose any further restrictions.
+ break;
+ case AttributeDefinition.CHARACTER :
+ Character charVal = new Character(s.charAt(0));
+ if (ad._minValue != null && charVal.compareTo((Character) ad._minValue) < 0) {
+ rangeError = true;
+ } else if (ad._maxValue != null && charVal.compareTo((Character) ad._maxValue) > 0) {
+ rangeError = true;
+ }
+ break;
+ case AttributeDefinition.FLOAT :
+ Float floatVal = new Float(s);
+ if (ad._minValue != null && floatVal.compareTo((Float) ad._minValue) < 0) {
+ rangeError = true;
+ } else if (ad._maxValue != null && floatVal.compareTo((Float) ad._maxValue) > 0) {
+ rangeError = true;
+ }
+ break;
+ case AttributeDefinition.SHORT :
+ Short shortVal = new Short(s);
+ if (ad._minValue != null && shortVal.compareTo((Short) ad._minValue) < 0) {
+ rangeError = true;
+ } else if (ad._maxValue != null && shortVal.compareTo((Short) ad._maxValue) > 0) {
+ rangeError = true;
+ }
+ break;
+ case AttributeDefinition.BYTE :
+ Byte byteVal = new Byte(s);
+ if (ad._minValue != null && byteVal.compareTo((Byte) ad._minValue) < 0) {
+ rangeError = true;
+ } else if (ad._maxValue != null && byteVal.compareTo((Byte) ad._maxValue) > 0) {
+ rangeError = true;
+ }
+ break;
+ case AttributeDefinition.BIGDECIMAL :
+ BigDecimal bigDecVal = new BigDecimal(s);
+ if (ad._minValue != null && bigDecVal.compareTo((BigDecimal) ad._minValue) < 0) {
+ rangeError = true;
+ } else if (ad._maxValue != null && bigDecVal.compareTo((BigDecimal) ad._maxValue) > 0) {
+ rangeError = true;
+ }
+ break;
+ case AttributeDefinition.BIGINTEGER :
+ BigInteger bigIntVal = new BigInteger(s);
+ if (ad._minValue != null && bigIntVal.compareTo((BigInteger) ad._minValue) < 0) {
+ rangeError = true;
+ } else if (ad._maxValue != null && bigIntVal.compareTo((BigInteger) ad._maxValue) > 0) {
+ rangeError = true;
+ }
+ break;
+ default :
+ throw new IllegalStateException();
+ }
+ if (rangeError) {
+ return (NLS.bind(MetaTypeMsg.VALUE_OUT_OF_RANGE, s));
+ }
+ }
+ // No problems detected
+ return ""; //$NON-NLS-1$
+ } catch (Throwable t) {
+ String message = NLS.bind(MetaTypeMsg.EXCEPTION_MESSAGE, t.getClass().getName(), t.getMessage());
+ logger.log(LogService.LOG_DEBUG, message, t);
+ return message;
+ }
+ }
+}