Skip to main content
aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBJ Hargrave2011-09-28 15:39:24 -0400
committerBJ Hargrave2011-09-28 15:39:24 -0400
commit0609664b9dfe07dea5c53a06106a9abf9a4d638a (patch)
tree080e53a9add2f8c9c9e68339e61dcfc45b91aa5f
parentaa763f5e7c764c5f579aa0d0142b858dffd76850 (diff)
downloadrt.equinox.bundles-0609664b9dfe07dea5c53a06106a9abf9a4d638a.tar.gz
rt.equinox.bundles-0609664b9dfe07dea5c53a06106a9abf9a4d638a.tar.xz
rt.equinox.bundles-0609664b9dfe07dea5c53a06106a9abf9a4d638a.zip
Convert line endings to LF
-rw-r--r--bundles/org.eclipse.equinox.metatype/src/org/eclipse/equinox/metatype/EquinoxAttributeDefinition.java38
-rw-r--r--bundles/org.eclipse.equinox.metatype/src/org/eclipse/equinox/metatype/EquinoxMetaTypeInformation.java38
-rw-r--r--bundles/org.eclipse.equinox.metatype/src/org/eclipse/equinox/metatype/EquinoxMetaTypeService.java40
-rw-r--r--bundles/org.eclipse.equinox.metatype/src/org/eclipse/equinox/metatype/EquinoxObjectClassDefinition.java38
-rw-r--r--bundles/org.eclipse.equinox.metatype/src/org/eclipse/equinox/metatype/Extendable.java44
-rw-r--r--bundles/org.eclipse.equinox.metatype/src/org/eclipse/equinox/metatype/impl/Activator.java510
-rw-r--r--bundles/org.eclipse.equinox.metatype/src/org/eclipse/equinox/metatype/impl/AttributeDefinitionImpl.java622
-rw-r--r--bundles/org.eclipse.equinox.metatype/src/org/eclipse/equinox/metatype/impl/DataParser.java1698
-rw-r--r--bundles/org.eclipse.equinox.metatype/src/org/eclipse/equinox/metatype/impl/Designate.java208
-rw-r--r--bundles/org.eclipse.equinox.metatype/src/org/eclipse/equinox/metatype/impl/ExtendableHelper.java78
-rw-r--r--bundles/org.eclipse.equinox.metatype/src/org/eclipse/equinox/metatype/impl/ExternalMessages.properties72
-rw-r--r--bundles/org.eclipse.equinox.metatype/src/org/eclipse/equinox/metatype/impl/FragmentUtils.java116
-rw-r--r--bundles/org.eclipse.equinox.metatype/src/org/eclipse/equinox/metatype/impl/Icon.java144
-rw-r--r--bundles/org.eclipse.equinox.metatype/src/org/eclipse/equinox/metatype/impl/LocalizationElement.java110
-rw-r--r--bundles/org.eclipse.equinox.metatype/src/org/eclipse/equinox/metatype/impl/LogMessages.properties34
-rw-r--r--bundles/org.eclipse.equinox.metatype/src/org/eclipse/equinox/metatype/impl/LogTracker.java354
-rw-r--r--bundles/org.eclipse.equinox.metatype/src/org/eclipse/equinox/metatype/impl/LogTrackerMsg.java56
-rw-r--r--bundles/org.eclipse.equinox.metatype/src/org/eclipse/equinox/metatype/impl/MetaTypeInformationImpl.java178
-rw-r--r--bundles/org.eclipse.equinox.metatype/src/org/eclipse/equinox/metatype/impl/MetaTypeMsg.java90
-rw-r--r--bundles/org.eclipse.equinox.metatype/src/org/eclipse/equinox/metatype/impl/MetaTypeProviderImpl.java478
-rw-r--r--bundles/org.eclipse.equinox.metatype/src/org/eclipse/equinox/metatype/impl/MetaTypeProviderTracker.java574
-rw-r--r--bundles/org.eclipse.equinox.metatype/src/org/eclipse/equinox/metatype/impl/MetaTypeServiceImpl.java274
-rw-r--r--bundles/org.eclipse.equinox.metatype/src/org/eclipse/equinox/metatype/impl/ObjectClassDefinitionImpl.java640
-rw-r--r--bundles/org.eclipse.equinox.metatype/src/org/eclipse/equinox/metatype/impl/ValueTokenizer.java548
-rw-r--r--bundles/org.eclipse.equinox.preferences/src/org/eclipse/core/internal/preferences/EclipsePreferences.java2476
-rw-r--r--bundles/org.eclipse.equinox.preferences/src/org/osgi/service/prefs/BackingStoreException.java2
-rw-r--r--bundles/org.eclipse.equinox.preferences/src/org/osgi/service/prefs/Preferences.java2
-rw-r--r--bundles/org.eclipse.equinox.preferences/src/org/osgi/service/prefs/PreferencesService.java2
-rw-r--r--bundles/org.eclipse.equinox.resolver/src/org/osgi/service/resolver/Resolver.java2
-rw-r--r--bundles/org.eclipse.equinox.resolver/src/org/osgi/service/resolver/package-info.java2
30 files changed, 4734 insertions, 4734 deletions
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
index fb0e85c3c..5baaae0b7 100644
--- 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
@@ -1,19 +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.
-}
+/*******************************************************************************
+ * 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
index 70b79a76f..345d79d55 100644
--- 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
@@ -1,19 +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);
-}
+/*******************************************************************************
+ * 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
index a9ba9c0c2..e2154f5bf 100644
--- 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
@@ -1,20 +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);
-}
+/*******************************************************************************
+ * 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
index f8d0e8039..efb8c3ff3 100644
--- 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
@@ -1,19 +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);
-}
+/*******************************************************************************
+ * 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
index 7d52b498b..4f6069ec5 100644
--- 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
@@ -1,22 +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();
-}
+/*******************************************************************************
+ * 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/impl/Activator.java b/bundles/org.eclipse.equinox.metatype/src/org/eclipse/equinox/metatype/impl/Activator.java
index 014a36cd5..3daf3f4f3 100644
--- a/bundles/org.eclipse.equinox.metatype/src/org/eclipse/equinox/metatype/impl/Activator.java
+++ b/bundles/org.eclipse.equinox.metatype/src/org/eclipse/equinox/metatype/impl/Activator.java
@@ -1,255 +1,255 @@
-/*******************************************************************************
- * 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);
- }
- }
-}
+/*******************************************************************************
+ * 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/impl/AttributeDefinitionImpl.java b/bundles/org.eclipse.equinox.metatype/src/org/eclipse/equinox/metatype/impl/AttributeDefinitionImpl.java
index 6b4d3b583..73d34da39 100644
--- a/bundles/org.eclipse.equinox.metatype/src/org/eclipse/equinox/metatype/impl/AttributeDefinitionImpl.java
+++ b/bundles/org.eclipse.equinox.metatype/src/org/eclipse/equinox/metatype/impl/AttributeDefinitionImpl.java
@@ -1,311 +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.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();
- }
-}
+/*******************************************************************************
+ * 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/impl/DataParser.java b/bundles/org.eclipse.equinox.metatype/src/org/eclipse/equinox/metatype/impl/DataParser.java
index f7cb3296c..e8d20a8e1 100644
--- a/bundles/org.eclipse.equinox.metatype/src/org/eclipse/equinox/metatype/impl/DataParser.java
+++ b/bundles/org.eclipse.equinox.metatype/src/org/eclipse/equinox/metatype/impl/DataParser.java
@@ -1,849 +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.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);
- }
-}
+/*******************************************************************************
+ * 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/impl/Designate.java b/bundles/org.eclipse.equinox.metatype/src/org/eclipse/equinox/metatype/impl/Designate.java
index 83b31b1a8..f15e9457d 100644
--- a/bundles/org.eclipse.equinox.metatype/src/org/eclipse/equinox/metatype/impl/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.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;
- }
-}
+/*******************************************************************************
+ * 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
index c48b75374..0bccad9a5 100644
--- 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
@@ -1,39 +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());
- }
-
-}
+/*******************************************************************************
+ * 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/impl/ExternalMessages.properties b/bundles/org.eclipse.equinox.metatype/src/org/eclipse/equinox/metatype/impl/ExternalMessages.properties
index ff60175e8..820963ad5 100644
--- a/bundles/org.eclipse.equinox.metatype/src/org/eclipse/equinox/metatype/impl/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/impl/FragmentUtils.java b/bundles/org.eclipse.equinox.metatype/src/org/eclipse/equinox/metatype/impl/FragmentUtils.java
index 0685e1509..e455ae641 100644
--- a/bundles/org.eclipse.equinox.metatype/src/org/eclipse/equinox/metatype/impl/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.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()]);
- }
-}
+/*******************************************************************************
+ * 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/impl/Icon.java b/bundles/org.eclipse.equinox.metatype/src/org/eclipse/equinox/metatype/impl/Icon.java
index 161309721..591914e94 100644
--- a/bundles/org.eclipse.equinox.metatype/src/org/eclipse/equinox/metatype/impl/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.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;
- }
-}
+/*******************************************************************************
+ * 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/impl/LocalizationElement.java b/bundles/org.eclipse.equinox.metatype/src/org/eclipse/equinox/metatype/impl/LocalizationElement.java
index fbb0ebce3..46dce3155 100644
--- a/bundles/org.eclipse.equinox.metatype/src/org/eclipse/equinox/metatype/impl/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.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;
- }
-}
+/*******************************************************************************
+ * 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/impl/LogMessages.properties b/bundles/org.eclipse.equinox.metatype/src/org/eclipse/equinox/metatype/impl/LogMessages.properties
index 6ac12381c..cf8d9a411 100644
--- a/bundles/org.eclipse.equinox.metatype/src/org/eclipse/equinox/metatype/impl/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/impl/LogTracker.java b/bundles/org.eclipse.equinox.metatype/src/org/eclipse/equinox/metatype/impl/LogTracker.java
index 51e58c9db..3f4fc71dc 100644
--- a/bundles/org.eclipse.equinox.metatype/src/org/eclipse/equinox/metatype/impl/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.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;
- }
-}
+/*******************************************************************************
+ * 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/impl/LogTrackerMsg.java b/bundles/org.eclipse.equinox.metatype/src/org/eclipse/equinox/metatype/impl/LogTrackerMsg.java
index 06cdaab34..3a30ef14b 100644
--- a/bundles/org.eclipse.equinox.metatype/src/org/eclipse/equinox/metatype/impl/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.impl;
-
-import org.eclipse.osgi.util.NLS;
-
-public class LogTrackerMsg extends NLS {
- private static final String BUNDLE_NAME = "org.eclipse.equinox.metatype.impl.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.impl.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/impl/MetaTypeInformationImpl.java b/bundles/org.eclipse.equinox.metatype/src/org/eclipse/equinox/metatype/impl/MetaTypeInformationImpl.java
index 11e823871..a9780ff68 100644
--- a/bundles/org.eclipse.equinox.metatype/src/org/eclipse/equinox/metatype/impl/MetaTypeInformationImpl.java
+++ b/bundles/org.eclipse.equinox.metatype/src/org/eclipse/equinox/metatype/impl/MetaTypeInformationImpl.java
@@ -1,89 +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.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;
- }
-}
+/*******************************************************************************
+ * 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/impl/MetaTypeMsg.java b/bundles/org.eclipse.equinox.metatype/src/org/eclipse/equinox/metatype/impl/MetaTypeMsg.java
index 6c7d4e9d8..b5fb57428 100644
--- a/bundles/org.eclipse.equinox.metatype/src/org/eclipse/equinox/metatype/impl/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.impl;
-
-import org.eclipse.osgi.util.NLS;
-
-public class MetaTypeMsg extends NLS {
- private static final String BUNDLE_NAME = "org.eclipse.equinox.metatype.impl.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.impl.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/impl/MetaTypeProviderImpl.java b/bundles/org.eclipse.equinox.metatype/src/org/eclipse/equinox/metatype/impl/MetaTypeProviderImpl.java
index 9342689e7..66d518bf9 100644
--- a/bundles/org.eclipse.equinox.metatype/src/org/eclipse/equinox/metatype/impl/MetaTypeProviderImpl.java
+++ b/bundles/org.eclipse.equinox.metatype/src/org/eclipse/equinox/metatype/impl/MetaTypeProviderImpl.java
@@ -1,239 +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.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;
- }
-}
+/*******************************************************************************
+ * 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/impl/MetaTypeProviderTracker.java b/bundles/org.eclipse.equinox.metatype/src/org/eclipse/equinox/metatype/impl/MetaTypeProviderTracker.java
index b7e27ff43..5433cebcf 100644
--- a/bundles/org.eclipse.equinox.metatype/src/org/eclipse/equinox/metatype/impl/MetaTypeProviderTracker.java
+++ b/bundles/org.eclipse.equinox.metatype/src/org/eclipse/equinox/metatype/impl/MetaTypeProviderTracker.java
@@ -1,287 +1,287 @@
-/*******************************************************************************
- * 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();
- }
- }
-}
+/*******************************************************************************
+ * 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/impl/MetaTypeServiceImpl.java b/bundles/org.eclipse.equinox.metatype/src/org/eclipse/equinox/metatype/impl/MetaTypeServiceImpl.java
index 6adf79321..28175be44 100644
--- a/bundles/org.eclipse.equinox.metatype/src/org/eclipse/equinox/metatype/impl/MetaTypeServiceImpl.java
+++ b/bundles/org.eclipse.equinox.metatype/src/org/eclipse/equinox/metatype/impl/MetaTypeServiceImpl.java
@@ -1,137 +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.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;
- }
- }
-}
+/*******************************************************************************
+ * 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/impl/ObjectClassDefinitionImpl.java b/bundles/org.eclipse.equinox.metatype/src/org/eclipse/equinox/metatype/impl/ObjectClassDefinitionImpl.java
index 22d0f76ad..6cc887983 100644
--- a/bundles/org.eclipse.equinox.metatype/src/org/eclipse/equinox/metatype/impl/ObjectClassDefinitionImpl.java
+++ b/bundles/org.eclipse.equinox.metatype/src/org/eclipse/equinox/metatype/impl/ObjectClassDefinitionImpl.java
@@ -1,320 +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.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();
- }
-}
+/*******************************************************************************
+ * 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/impl/ValueTokenizer.java b/bundles/org.eclipse.equinox.metatype/src/org/eclipse/equinox/metatype/impl/ValueTokenizer.java
index 6c868d772..c0c5914f3 100644
--- a/bundles/org.eclipse.equinox.metatype/src/org/eclipse/equinox/metatype/impl/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.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;
- }
- }
-}
+/*******************************************************************************
+ * 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;
+ }
+ }
+}
diff --git a/bundles/org.eclipse.equinox.preferences/src/org/eclipse/core/internal/preferences/EclipsePreferences.java b/bundles/org.eclipse.equinox.preferences/src/org/eclipse/core/internal/preferences/EclipsePreferences.java
index f419200b2..578a21b43 100644
--- a/bundles/org.eclipse.equinox.preferences/src/org/eclipse/core/internal/preferences/EclipsePreferences.java
+++ b/bundles/org.eclipse.equinox.preferences/src/org/eclipse/core/internal/preferences/EclipsePreferences.java
@@ -1,1238 +1,1238 @@
-/*******************************************************************************
- * Copyright (c) 2004, 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
- * Julian Chen - fix for bug #92572, jclRM
- *******************************************************************************/
-package org.eclipse.core.internal.preferences;
-
-import java.io.*;
-import java.util.*;
-import org.eclipse.core.internal.runtime.RuntimeLog;
-import org.eclipse.core.runtime.*;
-import org.eclipse.core.runtime.preferences.*;
-import org.eclipse.osgi.util.NLS;
-import org.osgi.service.prefs.BackingStoreException;
-import org.osgi.service.prefs.Preferences;
-
-/**
- * Represents a node in the Eclipse preference node hierarchy. This class
- * is used as a default implementation/super class for those nodes which
- * belong to scopes which are contributed by the Platform.
- *
- * Implementation notes:
- *
- * - For thread safety, we always synchronize on the node object when writing
- * the children or properties fields. Must ensure we don't synchronize when calling
- * client code such as listeners.
- *
- * @since 3.0
- */
-public class EclipsePreferences implements IEclipsePreferences, IScope {
-
- public static final String DEFAULT_PREFERENCES_DIRNAME = ".settings"; //$NON-NLS-1$
- public static final String PREFS_FILE_EXTENSION = "prefs"; //$NON-NLS-1$
- protected static final IEclipsePreferences[] EMPTY_NODE_ARRAY = new IEclipsePreferences[0];
- protected static final String[] EMPTY_STRING_ARRAY = new String[0];
- private static final String FALSE = "false"; //$NON-NLS-1$
- private static final String TRUE = "true"; //$NON-NLS-1$
- protected static final String VERSION_KEY = "eclipse.preferences.version"; //$NON-NLS-1$
- protected static final String VERSION_VALUE = "1"; //$NON-NLS-1$
- protected static final String PATH_SEPARATOR = String.valueOf(IPath.SEPARATOR);
- protected static final String DOUBLE_SLASH = "//"; //$NON-NLS-1$
- protected static final String EMPTY_STRING = ""; //$NON-NLS-1$
-
- private String cachedPath;
- protected Map children;
- protected boolean dirty = false;
- protected boolean loading = false;
- protected final String name;
- // the parent of an EclipsePreference node is always an EclipsePreference node. (or null)
- protected final EclipsePreferences parent;
- protected ImmutableMap properties = ImmutableMap.EMPTY;
- protected boolean removed = false;
- private ListenerList nodeChangeListeners;
- private ListenerList preferenceChangeListeners;
-
- public static boolean DEBUG_PREFERENCE_GENERAL = false;
- public static boolean DEBUG_PREFERENCE_SET = false;
- public static boolean DEBUG_PREFERENCE_GET = false;
-
- protected final static String debugPluginName = "org.eclipse.equinox.preferences"; //$NON-NLS-1$
-
- static {
- DEBUG_PREFERENCE_GENERAL = PreferencesOSGiUtils.getDefault().getBooleanDebugOption(debugPluginName + "/general", false); //$NON-NLS-1$
- DEBUG_PREFERENCE_SET = PreferencesOSGiUtils.getDefault().getBooleanDebugOption(debugPluginName + "/set", false); //$NON-NLS-1$
- DEBUG_PREFERENCE_GET = PreferencesOSGiUtils.getDefault().getBooleanDebugOption(debugPluginName + "/get", false); //$NON-NLS-1$
- }
-
- protected class SortedProperties extends Properties {
-
- private static final long serialVersionUID = 1L;
-
- public SortedProperties() {
- super();
- }
-
- /* (non-Javadoc)
- * @see java.util.Hashtable#keys()
- */
- public synchronized Enumeration keys() {
- TreeSet set = new TreeSet();
- for (Enumeration e = super.keys(); e.hasMoreElements();)
- set.add(e.nextElement());
- return Collections.enumeration(set);
- }
-
- /* (non-Javadoc)
- * @see java.util.Hashtable#entrySet()
- */
- public Set entrySet() {
- TreeSet set = new TreeSet(new Comparator() {
- public int compare(Object e1, Object e2) {
- String s1 = (String) ((Map.Entry) e1).getKey();
- String s2 = (String) ((Map.Entry) e2).getKey();
- return s1.compareTo(s2);
- }
- });
- for (Iterator i = super.entrySet().iterator(); i.hasNext();)
- set.add(i.next());
- return set;
- }
- }
-
- public EclipsePreferences() {
- this(null, null);
- }
-
- protected EclipsePreferences(EclipsePreferences parent, String name) {
- super();
- this.parent = parent;
- this.name = name;
- this.cachedPath = null; // make sure the cached path is cleared after setting the parent
- }
-
- /*
- * @see org.osgi.service.prefs.Preferences#absolutePath()
- */
- public String absolutePath() {
- if (cachedPath == null) {
- if (parent == null)
- cachedPath = PATH_SEPARATOR;
- else {
- String parentPath = parent.absolutePath();
- // if the parent is the root then we don't have to add a separator
- // between the parent path and our path
- if (parentPath.length() == 1)
- cachedPath = parentPath + name();
- else
- cachedPath = parentPath + PATH_SEPARATOR + name();
- }
- }
- return cachedPath;
- }
-
- public void accept(IPreferenceNodeVisitor visitor) throws BackingStoreException {
- if (!visitor.visit(this))
- return;
- IEclipsePreferences[] toVisit = getChildren(true);
- for (int i = 0; i < toVisit.length; i++)
- toVisit[i].accept(visitor);
- }
-
- protected synchronized IEclipsePreferences addChild(String childName, IEclipsePreferences child) {
- //Thread safety: synchronize method to protect modification of children field
- if (children == null)
- children = Collections.synchronizedMap(new HashMap());
- children.put(childName, child == null ? (Object) childName : child);
- return child;
- }
-
- /*
- * @see org.eclipse.core.runtime.IEclipsePreferences#addNodeChangeListener(org.eclipse.core.runtime.IEclipsePreferences.INodeChangeListener)
- */
- public void addNodeChangeListener(INodeChangeListener listener) {
- checkRemoved();
- if (nodeChangeListeners == null)
- nodeChangeListeners = new ListenerList();
- nodeChangeListeners.add(listener);
- if (DEBUG_PREFERENCE_GENERAL)
- PrefsMessages.message("Added preference node change listener: " + listener + " to: " + absolutePath()); //$NON-NLS-1$ //$NON-NLS-2$
- }
-
- /*
- * @see org.eclipse.core.runtime.IEclipsePreferences#addPreferenceChangeListener(org.eclipse.core.runtime.IEclipsePreferences.IPreferenceChangeListener)
- */
- public void addPreferenceChangeListener(IPreferenceChangeListener listener) {
- checkRemoved();
- if (preferenceChangeListeners == null)
- preferenceChangeListeners = new ListenerList();
- preferenceChangeListeners.add(listener);
- if (DEBUG_PREFERENCE_GENERAL)
- PrefsMessages.message("Added preference property change listener: " + listener + " to: " + absolutePath()); //$NON-NLS-1$ //$NON-NLS-2$
- }
-
- private IEclipsePreferences calculateRoot() {
- IEclipsePreferences result = this;
- while (result.parent() != null)
- result = (IEclipsePreferences) result.parent();
- return result;
- }
-
- /*
- * Convenience method for throwing an exception when methods
- * are called on a removed node.
- */
- protected void checkRemoved() {
- if (removed)
- throw new IllegalStateException(NLS.bind(PrefsMessages.preferences_removedNode, name));
- }
-
- /*
- * @see org.osgi.service.prefs.Preferences#childrenNames()
- */
- public String[] childrenNames() {
- // illegal state if this node has been removed
- checkRemoved();
- return internalChildNames();
- }
-
- protected String[] internalChildNames() {
- Map temp = children;
- if (temp == null || temp.size() == 0)
- return EMPTY_STRING_ARRAY;
- return (String[]) temp.keySet().toArray(EMPTY_STRING_ARRAY);
- }
-
- /*
- * @see org.osgi.service.prefs.Preferences#clear()
- */
- public void clear() {
- // illegal state if this node has been removed
- checkRemoved();
- // call each one separately (instead of Properties.clear) so
- // clients get change notification
- String[] keys = properties.keys();
- for (int i = 0; i < keys.length; i++)
- remove(keys[i]);
- makeDirty();
- }
-
- protected String[] computeChildren(IPath root) {
- if (root == null)
- return EMPTY_STRING_ARRAY;
- IPath dir = root.append(DEFAULT_PREFERENCES_DIRNAME);
- final ArrayList result = new ArrayList();
- final String extension = '.' + PREFS_FILE_EXTENSION;
- File file = dir.toFile();
- File[] totalFiles = file.listFiles();
- if (totalFiles != null) {
- for (int i = 0; i < totalFiles.length; i++) {
- if (totalFiles[i].isFile()) {
- String filename = totalFiles[i].getName();
- if (filename.endsWith(extension)) {
- String shortName = filename.substring(0, filename.length() - extension.length());
- result.add(shortName);
- }
- }
- }
- }
- return (String[]) result.toArray(EMPTY_STRING_ARRAY);
- }
-
- protected IPath computeLocation(IPath root, String qualifier) {
- return root == null ? null : root.append(DEFAULT_PREFERENCES_DIRNAME).append(qualifier).addFileExtension(PREFS_FILE_EXTENSION);
- }
-
- /*
- * Version 1 (current version)
- * path/key=value
- */
- protected static void convertFromProperties(EclipsePreferences node, Properties table, boolean notify) {
- String version = table.getProperty(VERSION_KEY);
- if (version == null || !VERSION_VALUE.equals(version)) {
- // ignore for now
- }
- table.remove(VERSION_KEY);
- for (Iterator i = table.keySet().iterator(); i.hasNext();) {
- String fullKey = (String) i.next();
- String value = table.getProperty(fullKey);
- if (value != null) {
- String[] splitPath = decodePath(fullKey);
- String path = splitPath[0];
- path = makeRelative(path);
- String key = splitPath[1];
- if (DEBUG_PREFERENCE_SET)
- PrefsMessages.message("Setting preference: " + path + '/' + key + '=' + value); //$NON-NLS-1$
- //use internal methods to avoid notifying listeners
- EclipsePreferences childNode = (EclipsePreferences) node.internalNode(path, false, null);
- String oldValue = childNode.internalPut(key, value);
- // notify listeners if applicable
- if (notify && !value.equals(oldValue))
- childNode.firePreferenceEvent(key, oldValue, value);
- }
- }
- PreferencesService.getDefault().shareStrings();
- }
-
- /*
- * Helper method to persist a Properties object to the filesystem. We use this
- * helper so we can remove the date/timestamp that Properties#store always
- * puts in the file.
- */
- protected static void write(Properties properties, IPath location) throws BackingStoreException {
- // create the parent dirs if they don't exist
- File parentFile = location.toFile().getParentFile();
- if (parentFile == null)
- return;
- parentFile.mkdirs();
-
- OutputStream output = null;
- try {
- output = new BufferedOutputStream(new FileOutputStream(new File(location.toOSString())));
- output.write(removeTimestampFromTable(properties).getBytes("UTF-8")); //$NON-NLS-1$
- output.flush();
- } catch (IOException e) {
- String message = NLS.bind(PrefsMessages.preferences_saveException, location);
- log(new Status(IStatus.ERROR, PrefsMessages.OWNER_NAME, IStatus.ERROR, message, e));
- throw new BackingStoreException(message);
- } finally {
- if (output != null)
- try {
- output.close();
- } catch (IOException e) {
- // ignore
- }
- }
- }
-
- protected static String removeTimestampFromTable(Properties properties) throws IOException {
- // store the properties in a string and then skip the first line (date/timestamp)
- ByteArrayOutputStream output = new ByteArrayOutputStream();
- try {
- properties.store(output, null);
- } finally {
- output.close();
- }
- String string = output.toString("UTF-8"); //$NON-NLS-1$
- String separator = System.getProperty("line.separator"); //$NON-NLS-1$
- return string.substring(string.indexOf(separator) + separator.length());
- }
-
- /*
- * Helper method to convert this node to a Properties file suitable
- * for persistence.
- */
- protected Properties convertToProperties(Properties result, String prefix) throws BackingStoreException {
- // add the key/value pairs from this node
- boolean addSeparator = prefix.length() != 0;
- //thread safety: copy reference in case of concurrent change
- ImmutableMap temp = properties;
- String[] keys = temp.keys();
- for (int i = 0, imax = keys.length; i < imax; i++) {
- String value = temp.get(keys[i]);
- if (value != null)
- result.put(encodePath(prefix, keys[i]), value);
- }
- // recursively add the child information
- IEclipsePreferences[] childNodes = getChildren(true);
- for (int i = 0; i < childNodes.length; i++) {
- EclipsePreferences child = (EclipsePreferences) childNodes[i];
- String fullPath = addSeparator ? prefix + PATH_SEPARATOR + child.name() : child.name();
- child.convertToProperties(result, fullPath);
- }
- PreferencesService.getDefault().shareStrings();
- return result;
- }
-
- /*
- * @see org.eclipse.core.runtime.preferences.IScope#create(org.eclipse.core.runtime.preferences.IEclipsePreferences)
- */
- public IEclipsePreferences create(IEclipsePreferences nodeParent, String nodeName) {
- return create((EclipsePreferences) nodeParent, nodeName, null);
- }
-
- protected boolean isLoading() {
- return loading;
- }
-
- protected void setLoading(boolean isLoading) {
- loading = isLoading;
- }
-
- public IEclipsePreferences create(EclipsePreferences nodeParent, String nodeName, Object context) {
- EclipsePreferences result = internalCreate(nodeParent, nodeName, context);
- nodeParent.addChild(nodeName, result);
- IEclipsePreferences loadLevel = result.getLoadLevel();
-
- // if this node or a parent node is not the load level then return
- if (loadLevel == null)
- return result;
-
- // if the result node is not a load level, then a child must be
- if (result != loadLevel)
- return result;
-
- // the result node is a load level
- if (isAlreadyLoaded(result) || result.isLoading())
- return result;
- try {
- result.setLoading(true);
- result.loadLegacy();
- result.load();
- result.loaded();
- result.flush();
- } catch (BackingStoreException e) {
- IPath location = result.getLocation();
- String message = NLS.bind(PrefsMessages.preferences_loadException, location == null ? EMPTY_STRING : location.toString());
- IStatus status = new Status(IStatus.ERROR, PrefsMessages.OWNER_NAME, IStatus.ERROR, message, e);
- RuntimeLog.log(status);
- } finally {
- result.setLoading(false);
- }
- return result;
- }
-
- /*
- * @see org.osgi.service.prefs.Preferences#flush()
- */
- synchronized public void flush() throws BackingStoreException {
- // illegal state if this node has been removed
- checkRemoved();
-
- IEclipsePreferences loadLevel = getLoadLevel();
-
- // if this node or a parent is not the load level, then flush the children
- if (loadLevel == null) {
- String[] childrenNames = childrenNames();
- for (int i = 0; i < childrenNames.length; i++)
- node(childrenNames[i]).flush();
- return;
- }
-
- // a parent is the load level for this node
- if (this != loadLevel) {
- loadLevel.flush();
- return;
- }
-
- // this node is a load level
- // any work to do?
- if (!dirty)
- return;
- //remove dirty bit before saving, to ensure that concurrent
- //changes during save mark the store as dirty
- dirty = false;
- try {
- save();
- } catch (BackingStoreException e) {
- //mark it dirty again because the save failed
- dirty = true;
- throw e;
- }
- }
-
- /*
- * @see org.osgi.service.prefs.Preferences#get(java.lang.String, java.lang.String)
- */
- public String get(String key, String defaultValue) {
- String value = internalGet(key);
- return value == null ? defaultValue : value;
- }
-
- /*
- * @see org.osgi.service.prefs.Preferences#getBoolean(java.lang.String, boolean)
- */
- public boolean getBoolean(String key, boolean defaultValue) {
- String value = internalGet(key);
- return value == null ? defaultValue : TRUE.equalsIgnoreCase(value);
- }
-
- /*
- * @see org.osgi.service.prefs.Preferences#getByteArray(java.lang.String, byte[])
- */
- public byte[] getByteArray(String key, byte[] defaultValue) {
- String value = internalGet(key);
- return value == null ? defaultValue : Base64.decode(value.getBytes());
- }
-
- /*
- * Return a boolean value indicating whether or not a child with the given
- * name is known to this node.
- */
- protected synchronized boolean childExists(String childName) {
- if (children == null)
- return false;
- return children.get(childName) != null;
- }
-
- /**
- * Thread safe way to obtain a child for a given key. Returns the child
- * that matches the given key, or null if there is no matching child.
- */
- protected IEclipsePreferences getChild(String key, Object context, boolean create) {
- synchronized (this) {
- if (children == null)
- return null;
- Object value = children.get(key);
- if (value == null)
- return null;
- if (value instanceof IEclipsePreferences)
- return (IEclipsePreferences) value;
- // if we aren't supposed to create this node, then
- // just return null
- if (!create)
- return null;
- }
- return addChild(key, create(this, key, context));
- }
-
- /**
- * Thread safe way to obtain all children of this node. Never returns null.
- */
- protected IEclipsePreferences[] getChildren(boolean create) {
- ArrayList result = new ArrayList();
- String[] names = internalChildNames();
- for (int i = 0; i < names.length; i++) {
- IEclipsePreferences child = getChild(names[i], null, create);
- if (child != null)
- result.add(child);
- }
- return (IEclipsePreferences[]) result.toArray(EMPTY_NODE_ARRAY);
- }
-
- /*
- * @see org.osgi.service.prefs.Preferences#getDouble(java.lang.String, double)
- */
- public double getDouble(String key, double defaultValue) {
- String value = internalGet(key);
- double result = defaultValue;
- if (value != null)
- try {
- result = Double.parseDouble(value);
- } catch (NumberFormatException e) {
- // use default
- }
- return result;
- }
-
- /*
- * @see org.osgi.service.prefs.Preferences#getFloat(java.lang.String, float)
- */
- public float getFloat(String key, float defaultValue) {
- String value = internalGet(key);
- float result = defaultValue;
- if (value != null)
- try {
- result = Float.parseFloat(value);
- } catch (NumberFormatException e) {
- // use default
- }
- return result;
- }
-
- /*
- * @see org.osgi.service.prefs.Preferences#getInt(java.lang.String, int)
- */
- public int getInt(String key, int defaultValue) {
- String value = internalGet(key);
- int result = defaultValue;
- if (value != null)
- try {
- result = Integer.parseInt(value);
- } catch (NumberFormatException e) {
- // use default
- }
- return result;
- }
-
- protected IEclipsePreferences getLoadLevel() {
- return null;
- }
-
- /*
- * Subclasses to over-ride
- */
- protected IPath getLocation() {
- return null;
- }
-
- /*
- * @see org.osgi.service.prefs.Preferences#getLong(java.lang.String, long)
- */
- public long getLong(String key, long defaultValue) {
- String value = internalGet(key);
- long result = defaultValue;
- if (value != null)
- try {
- result = Long.parseLong(value);
- } catch (NumberFormatException e) {
- // use default
- }
- return result;
- }
-
- protected EclipsePreferences internalCreate(EclipsePreferences nodeParent, String nodeName, Object context) {
- return new EclipsePreferences(nodeParent, nodeName);
- }
-
- /**
- * Returns the existing value at the given key, or null if
- * no such value exists.
- */
- protected String internalGet(String key) {
- // throw NPE if key is null
- if (key == null)
- throw new NullPointerException();
- // illegal state if this node has been removed
- checkRemoved();
- String result = properties.get(key);
- if (DEBUG_PREFERENCE_GET)
- PrefsMessages.message("Getting preference value: " + absolutePath() + '/' + key + "->" + result); //$NON-NLS-1$ //$NON-NLS-2$
- return result;
- }
-
- /**
- * Implements the node(String) method, and optionally notifies listeners.
- */
- protected IEclipsePreferences internalNode(String path, boolean notify, Object context) {
-
- // illegal state if this node has been removed
- checkRemoved();
-
- // short circuit this node
- if (path.length() == 0)
- return this;
-
- // if we have an absolute path use the root relative to
- // this node instead of the global root
- // in case we have a different hierarchy. (e.g. export)
- if (path.charAt(0) == IPath.SEPARATOR)
- return (IEclipsePreferences) calculateRoot().node(path.substring(1));
-
- int index = path.indexOf(IPath.SEPARATOR);
- String key = index == -1 ? path : path.substring(0, index);
- boolean added = false;
- IEclipsePreferences child = getChild(key, context, true);
- if (child == null) {
- child = create(this, key, context);
- added = true;
- }
- // notify listeners if a child was added
- if (added && notify)
- fireNodeEvent(new NodeChangeEvent(this, child), true);
- return (IEclipsePreferences) child.node(index == -1 ? EMPTY_STRING : path.substring(index + 1));
- }
-
- /**
- * Stores the given (key,value) pair, performing lazy initialization of the
- * properties field if necessary. Returns the old value for the given key,
- * or null if no value existed.
- */
- protected String internalPut(String key, String newValue) {
- // illegal state if this node has been removed
- checkRemoved();
- String oldValue = properties.get(key);
- if (oldValue != null && oldValue.equals(newValue))
- return oldValue;
- if (DEBUG_PREFERENCE_SET)
- PrefsMessages.message("Setting preference: " + absolutePath() + '/' + key + '=' + newValue); //$NON-NLS-1$
- properties = properties.put(key, newValue);
- return oldValue;
- }
-
- /*
- * Subclasses to over-ride.
- */
- protected boolean isAlreadyLoaded(IEclipsePreferences node) {
- return true;
- }
-
- /*
- * @see org.osgi.service.prefs.Preferences#keys()
- */
- public String[] keys() {
- // illegal state if this node has been removed
- checkRemoved();
- return properties.keys();
- }
-
- /**
- * Loads the preference node. This method returns silently if the node does not exist
- * in the backing store (for example non-existent project).
- *
- * @throws BackingStoreException if the node exists in the backing store but it
- * could not be loaded
- */
- protected void load() throws BackingStoreException {
- load(getLocation());
- }
-
- protected static Properties loadProperties(IPath location) throws BackingStoreException {
- if (DEBUG_PREFERENCE_GENERAL)
- PrefsMessages.message("Loading preferences from file: " + location); //$NON-NLS-1$
- InputStream input = null;
- Properties result = new Properties();
- try {
- input = new BufferedInputStream(new FileInputStream(location.toFile()));
- result.load(input);
- } catch (FileNotFoundException e) {
- // file doesn't exist but that's ok.
- if (DEBUG_PREFERENCE_GENERAL)
- PrefsMessages.message("Preference file does not exist: " + location); //$NON-NLS-1$
- return result;
- } catch (IOException e) {
- String message = NLS.bind(PrefsMessages.preferences_loadException, location);
- log(new Status(IStatus.INFO, PrefsMessages.OWNER_NAME, IStatus.INFO, message, e));
- throw new BackingStoreException(message);
- } finally {
- if (input != null)
- try {
- input.close();
- } catch (IOException e) {
- // ignore
- }
- }
- return result;
- }
-
- protected void load(IPath location) throws BackingStoreException {
- if (location == null) {
- if (DEBUG_PREFERENCE_GENERAL)
- PrefsMessages.message("Unable to determine location of preference file for node: " + absolutePath()); //$NON-NLS-1$
- return;
- }
- Properties fromDisk = loadProperties(location);
- convertFromProperties(this, fromDisk, false);
- }
-
- protected void loaded() {
- // do nothing
- }
-
- protected void loadLegacy() {
- // sub-classes to over-ride if necessary
- }
-
- public static void log(IStatus status) {
- RuntimeLog.log(status);
- }
-
- protected void makeDirty() {
- EclipsePreferences node = this;
- while (node != null && !node.removed) {
- node.dirty = true;
- node = (EclipsePreferences) node.parent();
- }
- }
-
- public boolean isDirty() {
- return dirty;
- }
-
- /*
- * @see org.osgi.service.prefs.Preferences#name()
- */
- public String name() {
- return name;
- }
-
- /*
- * @see org.osgi.service.prefs.Preferences#node(java.lang.String)
- */
- public Preferences node(String pathName) {
- return internalNode(pathName, true, null);
- }
-
- protected void fireNodeEvent(final NodeChangeEvent event, final boolean added) {
- if (nodeChangeListeners == null)
- return;
- Object[] listeners = nodeChangeListeners.getListeners();
- for (int i = 0; i < listeners.length; i++) {
- final INodeChangeListener listener = (INodeChangeListener) listeners[i];
- ISafeRunnable job = new ISafeRunnable() {
- public void handleException(Throwable exception) {
- // already logged in Platform#run()
- }
-
- public void run() throws Exception {
- if (added)
- listener.added(event);
- else
- listener.removed(event);
- }
- };
- SafeRunner.run(job);
- }
- }
-
- /*
- * @see org.osgi.service.prefs.Preferences#nodeExists(java.lang.String)
- */
- public boolean nodeExists(String path) throws BackingStoreException {
- // short circuit for checking this node
- if (path.length() == 0)
- return !removed;
-
- // illegal state if this node has been removed.
- // do this AFTER checking for the empty string.
- checkRemoved();
-
- // use the root relative to this node instead of the global root
- // in case we have a different hierarchy. (e.g. export)
- if (path.charAt(0) == IPath.SEPARATOR)
- return calculateRoot().nodeExists(path.substring(1));
-
- int index = path.indexOf(IPath.SEPARATOR);
- boolean noSlash = index == -1;
-
- // if we are looking for a simple child then just look in the table and return
- if (noSlash)
- return childExists(path);
-
- // otherwise load the parent of the child and then recursively ask
- String childName = path.substring(0, index);
- if (!childExists(childName))
- return false;
- IEclipsePreferences child = getChild(childName, null, true);
- if (child == null)
- return false;
- return child.nodeExists(path.substring(index + 1));
- }
-
- /*
- * @see org.osgi.service.prefs.Preferences#parent()
- */
- public Preferences parent() {
- // illegal state if this node has been removed
- checkRemoved();
- return parent;
- }
-
- /*
- * Convenience method for notifying preference change listeners.
- */
- protected void firePreferenceEvent(String key, Object oldValue, Object newValue) {
- if (preferenceChangeListeners == null)
- return;
- Object[] listeners = preferenceChangeListeners.getListeners();
- final PreferenceChangeEvent event = new PreferenceChangeEvent(this, key, oldValue, newValue);
- for (int i = 0; i < listeners.length; i++) {
- final IPreferenceChangeListener listener = (IPreferenceChangeListener) listeners[i];
- ISafeRunnable job = new ISafeRunnable() {
- public void handleException(Throwable exception) {
- // already logged in Platform#run()
- }
-
- public void run() throws Exception {
- listener.preferenceChange(event);
- }
- };
- SafeRunner.run(job);
- }
- }
-
- /*
- * @see org.osgi.service.prefs.Preferences#put(java.lang.String, java.lang.String)
- */
- public void put(String key, String newValue) {
- if (key == null || newValue == null)
- throw new NullPointerException();
- String oldValue = internalPut(key, newValue);
- if (!newValue.equals(oldValue)) {
- makeDirty();
- firePreferenceEvent(key, oldValue, newValue);
- }
- }
-
- /*
- * @see org.osgi.service.prefs.Preferences#putBoolean(java.lang.String, boolean)
- */
- public void putBoolean(String key, boolean value) {
- if (key == null)
- throw new NullPointerException();
- String newValue = value ? TRUE : FALSE;
- String oldValue = internalPut(key, newValue);
- if (!newValue.equals(oldValue)) {
- makeDirty();
- firePreferenceEvent(key, oldValue, newValue);
- }
- }
-
- /*
- * @see org.osgi.service.prefs.Preferences#putByteArray(java.lang.String, byte[])
- */
- public void putByteArray(String key, byte[] value) {
- if (key == null || value == null)
- throw new NullPointerException();
- String newValue = new String(Base64.encode(value));
- String oldValue = internalPut(key, newValue);
- if (!newValue.equals(oldValue)) {
- makeDirty();
- firePreferenceEvent(key, oldValue, newValue);
- }
- }
-
- /*
- * @see org.osgi.service.prefs.Preferences#putDouble(java.lang.String, double)
- */
- public void putDouble(String key, double value) {
- if (key == null)
- throw new NullPointerException();
- String newValue = Double.toString(value);
- String oldValue = internalPut(key, newValue);
- if (!newValue.equals(oldValue)) {
- makeDirty();
- firePreferenceEvent(key, oldValue, newValue);
- }
- }
-
- /*
- * @see org.osgi.service.prefs.Preferences#putFloat(java.lang.String, float)
- */
- public void putFloat(String key, float value) {
- if (key == null)
- throw new NullPointerException();
- String newValue = Float.toString(value);
- String oldValue = internalPut(key, newValue);
- if (!newValue.equals(oldValue)) {
- makeDirty();
- firePreferenceEvent(key, oldValue, newValue);
- }
- }
-
- /*
- * @see org.osgi.service.prefs.Preferences#putInt(java.lang.String, int)
- */
- public void putInt(String key, int value) {
- if (key == null)
- throw new NullPointerException();
- String newValue = Integer.toString(value);
- String oldValue = internalPut(key, newValue);
- if (!newValue.equals(oldValue)) {
- makeDirty();
- firePreferenceEvent(key, oldValue, newValue);
- }
- }
-
- /*
- * @see org.osgi.service.prefs.Preferences#putLong(java.lang.String, long)
- */
- public void putLong(String key, long value) {
- if (key == null)
- throw new NullPointerException();
- String newValue = Long.toString(value);
- String oldValue = internalPut(key, newValue);
- if (!newValue.equals(oldValue)) {
- makeDirty();
- firePreferenceEvent(key, oldValue, newValue);
- }
- }
-
- /*
- * @see org.osgi.service.prefs.Preferences#remove(java.lang.String)
- */
- public void remove(String key) {
- // illegal state if this node has been removed
- checkRemoved();
- String oldValue = properties.get(key);
- if (oldValue == null)
- return;
- properties = properties.removeKey(key);
- makeDirty();
- firePreferenceEvent(key, oldValue, null);
- }
-
- /*
- * @see org.osgi.service.prefs.Preferences#removeNode()
- */
- public void removeNode() throws BackingStoreException {
- // illegal state if this node has been removed
- checkRemoved();
- // clear all the property values. do it "the long way" so
- // everyone gets notification
- String[] keys = keys();
- for (int i = 0; i < keys.length; i++)
- remove(keys[i]);
- // don't remove the global root or the scope root from the
- // parent but remove all its children
- if (parent != null && !(parent instanceof RootPreferences)) {
- // remove the node from the parent's collection and notify listeners
- removed = true;
- parent.removeNode(this);
- }
- IEclipsePreferences[] childNodes = getChildren(false);
- for (int i = 0; i < childNodes.length; i++)
- try {
- childNodes[i].removeNode();
- } catch (IllegalStateException e) {
- // ignore since we only get this exception if we have already
- // been removed. no work to do.
- }
- }
-
- /*
- * Remove the child from the collection and notify the listeners if something
- * was actually removed.
- */
- protected void removeNode(IEclipsePreferences child) {
- boolean wasRemoved = false;
- synchronized (this) {
- if (children != null) {
- wasRemoved = children.remove(child.name()) != null;
- if (wasRemoved)
- makeDirty();
- if (children.isEmpty())
- children = null;
- }
- }
- if (wasRemoved)
- fireNodeEvent(new NodeChangeEvent(this, child), false);
- }
-
- /*
- * Remove non-initialized node from the collection.
- */
- protected void removeNode(String key) {
- synchronized (this) {
- if (children != null) {
- boolean wasRemoved = children.remove(key) != null;
- if (wasRemoved)
- makeDirty();
- if (children.isEmpty())
- children = null;
- }
- }
- }
-
- /*
- * @see org.eclipse.core.runtime.IEclipsePreferences#removeNodeChangeListener(org.eclipse.core.runtime.IEclipsePreferences.removeNodeChangeListener)
- */
- public void removeNodeChangeListener(INodeChangeListener listener) {
- checkRemoved();
- if (nodeChangeListeners == null)
- return;
- nodeChangeListeners.remove(listener);
- if (nodeChangeListeners.size() == 0)
- nodeChangeListeners = null;
- if (DEBUG_PREFERENCE_GENERAL)
- PrefsMessages.message("Removed preference node change listener: " + listener + " from: " + absolutePath()); //$NON-NLS-1$ //$NON-NLS-2$
- }
-
- /*
- * @see org.eclipse.core.runtime.IEclipsePreferences#removePreferenceChangeListener(org.eclipse.core.runtime.IEclipsePreferences.IPreferenceChangeListener)
- */
- public void removePreferenceChangeListener(IPreferenceChangeListener listener) {
- checkRemoved();
- if (preferenceChangeListeners == null)
- return;
- preferenceChangeListeners.remove(listener);
- if (preferenceChangeListeners.size() == 0)
- preferenceChangeListeners = null;
- if (DEBUG_PREFERENCE_GENERAL)
- PrefsMessages.message("Removed preference property change listener: " + listener + " from: " + absolutePath()); //$NON-NLS-1$ //$NON-NLS-2$
- }
-
- /**
- * Saves the preference node. This method returns silently if the node does not exist
- * in the backing store (for example non-existent project)
- *
- * @throws BackingStoreException if the node exists in the backing store but it
- * could not be saved
- */
- protected void save() throws BackingStoreException {
- save(getLocation());
- }
-
- protected void save(IPath location) throws BackingStoreException {
- if (location == null) {
- if (DEBUG_PREFERENCE_GENERAL)
- PrefsMessages.message("Unable to determine location of preference file for node: " + absolutePath()); //$NON-NLS-1$
- return;
- }
- if (DEBUG_PREFERENCE_GENERAL)
- PrefsMessages.message("Saving preferences to file: " + location); //$NON-NLS-1$
- Properties table = convertToProperties(new SortedProperties(), EMPTY_STRING);
- if (table.isEmpty()) {
- // nothing to save. delete existing file if one exists.
- if (location.toFile().exists() && !location.toFile().delete()) {
- String message = NLS.bind(PrefsMessages.preferences_failedDelete, location);
- log(new Status(IStatus.WARNING, PrefsMessages.OWNER_NAME, IStatus.WARNING, message, null));
- }
- return;
- }
- table.put(VERSION_KEY, VERSION_VALUE);
- write(table, location);
- }
-
- /**
- * Traverses the preference hierarchy rooted at this node, and adds
- * all preference key and value strings to the provided pool. If an added
- * string was already in the pool, all references will be replaced with the
- * canonical copy of the string.
- *
- * @param pool The pool to share strings in
- */
- public void shareStrings(StringPool pool) {
- properties.shareStrings(pool);
- IEclipsePreferences[] myChildren = getChildren(false);
- for (int i = 0; i < myChildren.length; i++)
- if (myChildren[i] instanceof EclipsePreferences)
- ((EclipsePreferences) myChildren[i]).shareStrings(pool);
- }
-
- /*
- * Encode the given path and key combo to a form which is suitable for
- * persisting or using when searching. If the key contains a slash character
- * then we must use a double-slash to indicate the end of the
- * path/the beginning of the key.
- */
- public static String encodePath(String path, String key) {
- String result;
- int pathLength = path == null ? 0 : path.length();
- if (key.indexOf(IPath.SEPARATOR) == -1) {
- if (pathLength == 0)
- result = key;
- else
- result = path + IPath.SEPARATOR + key;
- } else {
- if (pathLength == 0)
- result = DOUBLE_SLASH + key;
- else
- result = path + DOUBLE_SLASH + key;
- }
- return result;
- }
-
- /*
- * Return the segment from the given path or null.
- * "segment" parameter is 0-based.
- */
- public static String getSegment(String path, int segment) {
- int start = path.indexOf(IPath.SEPARATOR) == 0 ? 1 : 0;
- int end = path.indexOf(IPath.SEPARATOR, start);
- if (end == path.length() - 1)
- end = -1;
- for (int i = 0; i < segment; i++) {
- if (end == -1)
- return null;
- start = end + 1;
- end = path.indexOf(IPath.SEPARATOR, start);
- }
- if (end == -1)
- end = path.length();
- return path.substring(start, end);
- }
-
- public static int getSegmentCount(String path) {
- StringTokenizer tokenizer = new StringTokenizer(path, String.valueOf(IPath.SEPARATOR));
- return tokenizer.countTokens();
- }
-
- /*
- * Return a relative path
- */
- public static String makeRelative(String path) {
- String result = path;
- if (path == null)
- return EMPTY_STRING;
- if (path.length() > 0 && path.charAt(0) == IPath.SEPARATOR)
- result = path.length() == 0 ? EMPTY_STRING : path.substring(1);
- return result;
- }
-
- /*
- * Return a 2 element String array.
- * element 0 - the path
- * element 1 - the key
- * The path may be null.
- * The key is never null.
- */
- public static String[] decodePath(String fullPath) {
- String key = null;
- String path = null;
-
- // check to see if we have an indicator which tells us where the path ends
- int index = fullPath.indexOf(DOUBLE_SLASH);
- if (index == -1) {
- // we don't have a double-slash telling us where the path ends
- // so the path is up to the last slash character
- int lastIndex = fullPath.lastIndexOf(IPath.SEPARATOR);
- if (lastIndex == -1) {
- key = fullPath;
- } else {
- path = fullPath.substring(0, lastIndex);
- key = fullPath.substring(lastIndex + 1);
- }
- } else {
- // the child path is up to the double-slash and the key
- // is the string after it
- path = fullPath.substring(0, index);
- key = fullPath.substring(index + 2);
- }
-
- // adjust if we have an absolute path
- if (path != null)
- if (path.length() == 0)
- path = null;
- else if (path.charAt(0) == IPath.SEPARATOR)
- path = path.substring(1);
-
- return new String[] {path, key};
- }
-
- /*
- * @see org.osgi.service.prefs.Preferences#sync()
- */
-
- public void sync() throws BackingStoreException {
- // illegal state if this node has been removed
- checkRemoved();
- IEclipsePreferences node = getLoadLevel();
- if (node == null) {
- if (DEBUG_PREFERENCE_GENERAL)
- PrefsMessages.message("Preference node is not a load root: " + absolutePath()); //$NON-NLS-1$
- return;
- }
- if (node instanceof EclipsePreferences) {
- ((EclipsePreferences) node).load();
- node.flush();
- }
- }
-
- public String toDeepDebugString() {
- final StringBuffer buffer = new StringBuffer();
- IPreferenceNodeVisitor visitor = new IPreferenceNodeVisitor() {
- public boolean visit(IEclipsePreferences node) throws BackingStoreException {
- buffer.append(node);
- buffer.append('\n');
- String[] keys = node.keys();
- for (int i = 0; i < keys.length; i++) {
- buffer.append(node.absolutePath());
- buffer.append(PATH_SEPARATOR);
- buffer.append(keys[i]);
- buffer.append('=');
- buffer.append(node.get(keys[i], "*default*")); //$NON-NLS-1$
- buffer.append('\n');
- }
- return true;
- }
- };
- try {
- accept(visitor);
- } catch (BackingStoreException e) {
- System.out.println("Exception while calling #toDeepDebugString()"); //$NON-NLS-1$
- e.printStackTrace();
- }
- return buffer.toString();
- }
-
- public String toString() {
- return absolutePath();
- }
-}
+/*******************************************************************************
+ * Copyright (c) 2004, 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
+ * Julian Chen - fix for bug #92572, jclRM
+ *******************************************************************************/
+package org.eclipse.core.internal.preferences;
+
+import java.io.*;
+import java.util.*;
+import org.eclipse.core.internal.runtime.RuntimeLog;
+import org.eclipse.core.runtime.*;
+import org.eclipse.core.runtime.preferences.*;
+import org.eclipse.osgi.util.NLS;
+import org.osgi.service.prefs.BackingStoreException;
+import org.osgi.service.prefs.Preferences;
+
+/**
+ * Represents a node in the Eclipse preference node hierarchy. This class
+ * is used as a default implementation/super class for those nodes which
+ * belong to scopes which are contributed by the Platform.
+ *
+ * Implementation notes:
+ *
+ * - For thread safety, we always synchronize on the node object when writing
+ * the children or properties fields. Must ensure we don't synchronize when calling
+ * client code such as listeners.
+ *
+ * @since 3.0
+ */
+public class EclipsePreferences implements IEclipsePreferences, IScope {
+
+ public static final String DEFAULT_PREFERENCES_DIRNAME = ".settings"; //$NON-NLS-1$
+ public static final String PREFS_FILE_EXTENSION = "prefs"; //$NON-NLS-1$
+ protected static final IEclipsePreferences[] EMPTY_NODE_ARRAY = new IEclipsePreferences[0];
+ protected static final String[] EMPTY_STRING_ARRAY = new String[0];
+ private static final String FALSE = "false"; //$NON-NLS-1$
+ private static final String TRUE = "true"; //$NON-NLS-1$
+ protected static final String VERSION_KEY = "eclipse.preferences.version"; //$NON-NLS-1$
+ protected static final String VERSION_VALUE = "1"; //$NON-NLS-1$
+ protected static final String PATH_SEPARATOR = String.valueOf(IPath.SEPARATOR);
+ protected static final String DOUBLE_SLASH = "//"; //$NON-NLS-1$
+ protected static final String EMPTY_STRING = ""; //$NON-NLS-1$
+
+ private String cachedPath;
+ protected Map children;
+ protected boolean dirty = false;
+ protected boolean loading = false;
+ protected final String name;
+ // the parent of an EclipsePreference node is always an EclipsePreference node. (or null)
+ protected final EclipsePreferences parent;
+ protected ImmutableMap properties = ImmutableMap.EMPTY;
+ protected boolean removed = false;
+ private ListenerList nodeChangeListeners;
+ private ListenerList preferenceChangeListeners;
+
+ public static boolean DEBUG_PREFERENCE_GENERAL = false;
+ public static boolean DEBUG_PREFERENCE_SET = false;
+ public static boolean DEBUG_PREFERENCE_GET = false;
+
+ protected final static String debugPluginName = "org.eclipse.equinox.preferences"; //$NON-NLS-1$
+
+ static {
+ DEBUG_PREFERENCE_GENERAL = PreferencesOSGiUtils.getDefault().getBooleanDebugOption(debugPluginName + "/general", false); //$NON-NLS-1$
+ DEBUG_PREFERENCE_SET = PreferencesOSGiUtils.getDefault().getBooleanDebugOption(debugPluginName + "/set", false); //$NON-NLS-1$
+ DEBUG_PREFERENCE_GET = PreferencesOSGiUtils.getDefault().getBooleanDebugOption(debugPluginName + "/get", false); //$NON-NLS-1$
+ }
+
+ protected class SortedProperties extends Properties {
+
+ private static final long serialVersionUID = 1L;
+
+ public SortedProperties() {
+ super();
+ }
+
+ /* (non-Javadoc)
+ * @see java.util.Hashtable#keys()
+ */
+ public synchronized Enumeration keys() {
+ TreeSet set = new TreeSet();
+ for (Enumeration e = super.keys(); e.hasMoreElements();)
+ set.add(e.nextElement());
+ return Collections.enumeration(set);
+ }
+
+ /* (non-Javadoc)
+ * @see java.util.Hashtable#entrySet()
+ */
+ public Set entrySet() {
+ TreeSet set = new TreeSet(new Comparator() {
+ public int compare(Object e1, Object e2) {
+ String s1 = (String) ((Map.Entry) e1).getKey();
+ String s2 = (String) ((Map.Entry) e2).getKey();
+ return s1.compareTo(s2);
+ }
+ });
+ for (Iterator i = super.entrySet().iterator(); i.hasNext();)
+ set.add(i.next());
+ return set;
+ }
+ }
+
+ public EclipsePreferences() {
+ this(null, null);
+ }
+
+ protected EclipsePreferences(EclipsePreferences parent, String name) {
+ super();
+ this.parent = parent;
+ this.name = name;
+ this.cachedPath = null; // make sure the cached path is cleared after setting the parent
+ }
+
+ /*
+ * @see org.osgi.service.prefs.Preferences#absolutePath()
+ */
+ public String absolutePath() {
+ if (cachedPath == null) {
+ if (parent == null)
+ cachedPath = PATH_SEPARATOR;
+ else {
+ String parentPath = parent.absolutePath();
+ // if the parent is the root then we don't have to add a separator
+ // between the parent path and our path
+ if (parentPath.length() == 1)
+ cachedPath = parentPath + name();
+ else
+ cachedPath = parentPath + PATH_SEPARATOR + name();
+ }
+ }
+ return cachedPath;
+ }
+
+ public void accept(IPreferenceNodeVisitor visitor) throws BackingStoreException {
+ if (!visitor.visit(this))
+ return;
+ IEclipsePreferences[] toVisit = getChildren(true);
+ for (int i = 0; i < toVisit.length; i++)
+ toVisit[i].accept(visitor);
+ }
+
+ protected synchronized IEclipsePreferences addChild(String childName, IEclipsePreferences child) {
+ //Thread safety: synchronize method to protect modification of children field
+ if (children == null)
+ children = Collections.synchronizedMap(new HashMap());
+ children.put(childName, child == null ? (Object) childName : child);
+ return child;
+ }
+
+ /*
+ * @see org.eclipse.core.runtime.IEclipsePreferences#addNodeChangeListener(org.eclipse.core.runtime.IEclipsePreferences.INodeChangeListener)
+ */
+ public void addNodeChangeListener(INodeChangeListener listener) {
+ checkRemoved();
+ if (nodeChangeListeners == null)
+ nodeChangeListeners = new ListenerList();
+ nodeChangeListeners.add(listener);
+ if (DEBUG_PREFERENCE_GENERAL)
+ PrefsMessages.message("Added preference node change listener: " + listener + " to: " + absolutePath()); //$NON-NLS-1$ //$NON-NLS-2$
+ }
+
+ /*
+ * @see org.eclipse.core.runtime.IEclipsePreferences#addPreferenceChangeListener(org.eclipse.core.runtime.IEclipsePreferences.IPreferenceChangeListener)
+ */
+ public void addPreferenceChangeListener(IPreferenceChangeListener listener) {
+ checkRemoved();
+ if (preferenceChangeListeners == null)
+ preferenceChangeListeners = new ListenerList();
+ preferenceChangeListeners.add(listener);
+ if (DEBUG_PREFERENCE_GENERAL)
+ PrefsMessages.message("Added preference property change listener: " + listener + " to: " + absolutePath()); //$NON-NLS-1$ //$NON-NLS-2$
+ }
+
+ private IEclipsePreferences calculateRoot() {
+ IEclipsePreferences result = this;
+ while (result.parent() != null)
+ result = (IEclipsePreferences) result.parent();
+ return result;
+ }
+
+ /*
+ * Convenience method for throwing an exception when methods
+ * are called on a removed node.
+ */
+ protected void checkRemoved() {
+ if (removed)
+ throw new IllegalStateException(NLS.bind(PrefsMessages.preferences_removedNode, name));
+ }
+
+ /*
+ * @see org.osgi.service.prefs.Preferences#childrenNames()
+ */
+ public String[] childrenNames() {
+ // illegal state if this node has been removed
+ checkRemoved();
+ return internalChildNames();
+ }
+
+ protected String[] internalChildNames() {
+ Map temp = children;
+ if (temp == null || temp.size() == 0)
+ return EMPTY_STRING_ARRAY;
+ return (String[]) temp.keySet().toArray(EMPTY_STRING_ARRAY);
+ }
+
+ /*
+ * @see org.osgi.service.prefs.Preferences#clear()
+ */
+ public void clear() {
+ // illegal state if this node has been removed
+ checkRemoved();
+ // call each one separately (instead of Properties.clear) so
+ // clients get change notification
+ String[] keys = properties.keys();
+ for (int i = 0; i < keys.length; i++)
+ remove(keys[i]);
+ makeDirty();
+ }
+
+ protected String[] computeChildren(IPath root) {
+ if (root == null)
+ return EMPTY_STRING_ARRAY;
+ IPath dir = root.append(DEFAULT_PREFERENCES_DIRNAME);
+ final ArrayList result = new ArrayList();
+ final String extension = '.' + PREFS_FILE_EXTENSION;
+ File file = dir.toFile();
+ File[] totalFiles = file.listFiles();
+ if (totalFiles != null) {
+ for (int i = 0; i < totalFiles.length; i++) {
+ if (totalFiles[i].isFile()) {
+ String filename = totalFiles[i].getName();
+ if (filename.endsWith(extension)) {
+ String shortName = filename.substring(0, filename.length() - extension.length());
+ result.add(shortName);
+ }
+ }
+ }
+ }
+ return (String[]) result.toArray(EMPTY_STRING_ARRAY);
+ }
+
+ protected IPath computeLocation(IPath root, String qualifier) {
+ return root == null ? null : root.append(DEFAULT_PREFERENCES_DIRNAME).append(qualifier).addFileExtension(PREFS_FILE_EXTENSION);
+ }
+
+ /*
+ * Version 1 (current version)
+ * path/key=value
+ */
+ protected static void convertFromProperties(EclipsePreferences node, Properties table, boolean notify) {
+ String version = table.getProperty(VERSION_KEY);
+ if (version == null || !VERSION_VALUE.equals(version)) {
+ // ignore for now
+ }
+ table.remove(VERSION_KEY);
+ for (Iterator i = table.keySet().iterator(); i.hasNext();) {
+ String fullKey = (String) i.next();
+ String value = table.getProperty(fullKey);
+ if (value != null) {
+ String[] splitPath = decodePath(fullKey);
+ String path = splitPath[0];
+ path = makeRelative(path);
+ String key = splitPath[1];
+ if (DEBUG_PREFERENCE_SET)
+ PrefsMessages.message("Setting preference: " + path + '/' + key + '=' + value); //$NON-NLS-1$
+ //use internal methods to avoid notifying listeners
+ EclipsePreferences childNode = (EclipsePreferences) node.internalNode(path, false, null);
+ String oldValue = childNode.internalPut(key, value);
+ // notify listeners if applicable
+ if (notify && !value.equals(oldValue))
+ childNode.firePreferenceEvent(key, oldValue, value);
+ }
+ }
+ PreferencesService.getDefault().shareStrings();
+ }
+
+ /*
+ * Helper method to persist a Properties object to the filesystem. We use this
+ * helper so we can remove the date/timestamp that Properties#store always
+ * puts in the file.
+ */
+ protected static void write(Properties properties, IPath location) throws BackingStoreException {
+ // create the parent dirs if they don't exist
+ File parentFile = location.toFile().getParentFile();
+ if (parentFile == null)
+ return;
+ parentFile.mkdirs();
+
+ OutputStream output = null;
+ try {
+ output = new BufferedOutputStream(new FileOutputStream(new File(location.toOSString())));
+ output.write(removeTimestampFromTable(properties).getBytes("UTF-8")); //$NON-NLS-1$
+ output.flush();
+ } catch (IOException e) {
+ String message = NLS.bind(PrefsMessages.preferences_saveException, location);
+ log(new Status(IStatus.ERROR, PrefsMessages.OWNER_NAME, IStatus.ERROR, message, e));
+ throw new BackingStoreException(message);
+ } finally {
+ if (output != null)
+ try {
+ output.close();
+ } catch (IOException e) {
+ // ignore
+ }
+ }
+ }
+
+ protected static String removeTimestampFromTable(Properties properties) throws IOException {
+ // store the properties in a string and then skip the first line (date/timestamp)
+ ByteArrayOutputStream output = new ByteArrayOutputStream();
+ try {
+ properties.store(output, null);
+ } finally {
+ output.close();
+ }
+ String string = output.toString("UTF-8"); //$NON-NLS-1$
+ String separator = System.getProperty("line.separator"); //$NON-NLS-1$
+ return string.substring(string.indexOf(separator) + separator.length());
+ }
+
+ /*
+ * Helper method to convert this node to a Properties file suitable
+ * for persistence.
+ */
+ protected Properties convertToProperties(Properties result, String prefix) throws BackingStoreException {
+ // add the key/value pairs from this node
+ boolean addSeparator = prefix.length() != 0;
+ //thread safety: copy reference in case of concurrent change
+ ImmutableMap temp = properties;
+ String[] keys = temp.keys();
+ for (int i = 0, imax = keys.length; i < imax; i++) {
+ String value = temp.get(keys[i]);
+ if (value != null)
+ result.put(encodePath(prefix, keys[i]), value);
+ }
+ // recursively add the child information
+ IEclipsePreferences[] childNodes = getChildren(true);
+ for (int i = 0; i < childNodes.length; i++) {
+ EclipsePreferences child = (EclipsePreferences) childNodes[i];
+ String fullPath = addSeparator ? prefix + PATH_SEPARATOR + child.name() : child.name();
+ child.convertToProperties(result, fullPath);
+ }
+ PreferencesService.getDefault().shareStrings();
+ return result;
+ }
+
+ /*
+ * @see org.eclipse.core.runtime.preferences.IScope#create(org.eclipse.core.runtime.preferences.IEclipsePreferences)
+ */
+ public IEclipsePreferences create(IEclipsePreferences nodeParent, String nodeName) {
+ return create((EclipsePreferences) nodeParent, nodeName, null);
+ }
+
+ protected boolean isLoading() {
+ return loading;
+ }
+
+ protected void setLoading(boolean isLoading) {
+ loading = isLoading;
+ }
+
+ public IEclipsePreferences create(EclipsePreferences nodeParent, String nodeName, Object context) {
+ EclipsePreferences result = internalCreate(nodeParent, nodeName, context);
+ nodeParent.addChild(nodeName, result);
+ IEclipsePreferences loadLevel = result.getLoadLevel();
+
+ // if this node or a parent node is not the load level then return
+ if (loadLevel == null)
+ return result;
+
+ // if the result node is not a load level, then a child must be
+ if (result != loadLevel)
+ return result;
+
+ // the result node is a load level
+ if (isAlreadyLoaded(result) || result.isLoading())
+ return result;
+ try {
+ result.setLoading(true);
+ result.loadLegacy();
+ result.load();
+ result.loaded();
+ result.flush();
+ } catch (BackingStoreException e) {
+ IPath location = result.getLocation();
+ String message = NLS.bind(PrefsMessages.preferences_loadException, location == null ? EMPTY_STRING : location.toString());
+ IStatus status = new Status(IStatus.ERROR, PrefsMessages.OWNER_NAME, IStatus.ERROR, message, e);
+ RuntimeLog.log(status);
+ } finally {
+ result.setLoading(false);
+ }
+ return result;
+ }
+
+ /*
+ * @see org.osgi.service.prefs.Preferences#flush()
+ */
+ synchronized public void flush() throws BackingStoreException {
+ // illegal state if this node has been removed
+ checkRemoved();
+
+ IEclipsePreferences loadLevel = getLoadLevel();
+
+ // if this node or a parent is not the load level, then flush the children
+ if (loadLevel == null) {
+ String[] childrenNames = childrenNames();
+ for (int i = 0; i < childrenNames.length; i++)
+ node(childrenNames[i]).flush();
+ return;
+ }
+
+ // a parent is the load level for this node
+ if (this != loadLevel) {
+ loadLevel.flush();
+ return;
+ }
+
+ // this node is a load level
+ // any work to do?
+ if (!dirty)
+ return;
+ //remove dirty bit before saving, to ensure that concurrent
+ //changes during save mark the store as dirty
+ dirty = false;
+ try {
+ save();
+ } catch (BackingStoreException e) {
+ //mark it dirty again because the save failed
+ dirty = true;
+ throw e;
+ }
+ }
+
+ /*
+ * @see org.osgi.service.prefs.Preferences#get(java.lang.String, java.lang.String)
+ */
+ public String get(String key, String defaultValue) {
+ String value = internalGet(key);
+ return value == null ? defaultValue : value;
+ }
+
+ /*
+ * @see org.osgi.service.prefs.Preferences#getBoolean(java.lang.String, boolean)
+ */
+ public boolean getBoolean(String key, boolean defaultValue) {
+ String value = internalGet(key);
+ return value == null ? defaultValue : TRUE.equalsIgnoreCase(value);
+ }
+
+ /*
+ * @see org.osgi.service.prefs.Preferences#getByteArray(java.lang.String, byte[])
+ */
+ public byte[] getByteArray(String key, byte[] defaultValue) {
+ String value = internalGet(key);
+ return value == null ? defaultValue : Base64.decode(value.getBytes());
+ }
+
+ /*
+ * Return a boolean value indicating whether or not a child with the given
+ * name is known to this node.
+ */
+ protected synchronized boolean childExists(String childName) {
+ if (children == null)
+ return false;
+ return children.get(childName) != null;
+ }
+
+ /**
+ * Thread safe way to obtain a child for a given key. Returns the child
+ * that matches the given key, or null if there is no matching child.
+ */
+ protected IEclipsePreferences getChild(String key, Object context, boolean create) {
+ synchronized (this) {
+ if (children == null)
+ return null;
+ Object value = children.get(key);
+ if (value == null)
+ return null;
+ if (value instanceof IEclipsePreferences)
+ return (IEclipsePreferences) value;
+ // if we aren't supposed to create this node, then
+ // just return null
+ if (!create)
+ return null;
+ }
+ return addChild(key, create(this, key, context));
+ }
+
+ /**
+ * Thread safe way to obtain all children of this node. Never returns null.
+ */
+ protected IEclipsePreferences[] getChildren(boolean create) {
+ ArrayList result = new ArrayList();
+ String[] names = internalChildNames();
+ for (int i = 0; i < names.length; i++) {
+ IEclipsePreferences child = getChild(names[i], null, create);
+ if (child != null)
+ result.add(child);
+ }
+ return (IEclipsePreferences[]) result.toArray(EMPTY_NODE_ARRAY);
+ }
+
+ /*
+ * @see org.osgi.service.prefs.Preferences#getDouble(java.lang.String, double)
+ */
+ public double getDouble(String key, double defaultValue) {
+ String value = internalGet(key);
+ double result = defaultValue;
+ if (value != null)
+ try {
+ result = Double.parseDouble(value);
+ } catch (NumberFormatException e) {
+ // use default
+ }
+ return result;
+ }
+
+ /*
+ * @see org.osgi.service.prefs.Preferences#getFloat(java.lang.String, float)
+ */
+ public float getFloat(String key, float defaultValue) {
+ String value = internalGet(key);
+ float result = defaultValue;
+ if (value != null)
+ try {
+ result = Float.parseFloat(value);
+ } catch (NumberFormatException e) {
+ // use default
+ }
+ return result;
+ }
+
+ /*
+ * @see org.osgi.service.prefs.Preferences#getInt(java.lang.String, int)
+ */
+ public int getInt(String key, int defaultValue) {
+ String value = internalGet(key);
+ int result = defaultValue;
+ if (value != null)
+ try {
+ result = Integer.parseInt(value);
+ } catch (NumberFormatException e) {
+ // use default
+ }
+ return result;
+ }
+
+ protected IEclipsePreferences getLoadLevel() {
+ return null;
+ }
+
+ /*
+ * Subclasses to over-ride
+ */
+ protected IPath getLocation() {
+ return null;
+ }
+
+ /*
+ * @see org.osgi.service.prefs.Preferences#getLong(java.lang.String, long)
+ */
+ public long getLong(String key, long defaultValue) {
+ String value = internalGet(key);
+ long result = defaultValue;
+ if (value != null)
+ try {
+ result = Long.parseLong(value);
+ } catch (NumberFormatException e) {
+ // use default
+ }
+ return result;
+ }
+
+ protected EclipsePreferences internalCreate(EclipsePreferences nodeParent, String nodeName, Object context) {
+ return new EclipsePreferences(nodeParent, nodeName);
+ }
+
+ /**
+ * Returns the existing value at the given key, or null if
+ * no such value exists.
+ */
+ protected String internalGet(String key) {
+ // throw NPE if key is null
+ if (key == null)
+ throw new NullPointerException();
+ // illegal state if this node has been removed
+ checkRemoved();
+ String result = properties.get(key);
+ if (DEBUG_PREFERENCE_GET)
+ PrefsMessages.message("Getting preference value: " + absolutePath() + '/' + key + "->" + result); //$NON-NLS-1$ //$NON-NLS-2$
+ return result;
+ }
+
+ /**
+ * Implements the node(String) method, and optionally notifies listeners.
+ */
+ protected IEclipsePreferences internalNode(String path, boolean notify, Object context) {
+
+ // illegal state if this node has been removed
+ checkRemoved();
+
+ // short circuit this node
+ if (path.length() == 0)
+ return this;
+
+ // if we have an absolute path use the root relative to
+ // this node instead of the global root
+ // in case we have a different hierarchy. (e.g. export)
+ if (path.charAt(0) == IPath.SEPARATOR)
+ return (IEclipsePreferences) calculateRoot().node(path.substring(1));
+
+ int index = path.indexOf(IPath.SEPARATOR);
+ String key = index == -1 ? path : path.substring(0, index);
+ boolean added = false;
+ IEclipsePreferences child = getChild(key, context, true);
+ if (child == null) {
+ child = create(this, key, context);
+ added = true;
+ }
+ // notify listeners if a child was added
+ if (added && notify)
+ fireNodeEvent(new NodeChangeEvent(this, child), true);
+ return (IEclipsePreferences) child.node(index == -1 ? EMPTY_STRING : path.substring(index + 1));
+ }
+
+ /**
+ * Stores the given (key,value) pair, performing lazy initialization of the
+ * properties field if necessary. Returns the old value for the given key,
+ * or null if no value existed.
+ */
+ protected String internalPut(String key, String newValue) {
+ // illegal state if this node has been removed
+ checkRemoved();
+ String oldValue = properties.get(key);
+ if (oldValue != null && oldValue.equals(newValue))
+ return oldValue;
+ if (DEBUG_PREFERENCE_SET)
+ PrefsMessages.message("Setting preference: " + absolutePath() + '/' + key + '=' + newValue); //$NON-NLS-1$
+ properties = properties.put(key, newValue);
+ return oldValue;
+ }
+
+ /*
+ * Subclasses to over-ride.
+ */
+ protected boolean isAlreadyLoaded(IEclipsePreferences node) {
+ return true;
+ }
+
+ /*
+ * @see org.osgi.service.prefs.Preferences#keys()
+ */
+ public String[] keys() {
+ // illegal state if this node has been removed
+ checkRemoved();
+ return properties.keys();
+ }
+
+ /**
+ * Loads the preference node. This method returns silently if the node does not exist
+ * in the backing store (for example non-existent project).
+ *
+ * @throws BackingStoreException if the node exists in the backing store but it
+ * could not be loaded
+ */
+ protected void load() throws BackingStoreException {
+ load(getLocation());
+ }
+
+ protected static Properties loadProperties(IPath location) throws BackingStoreException {
+ if (DEBUG_PREFERENCE_GENERAL)
+ PrefsMessages.message("Loading preferences from file: " + location); //$NON-NLS-1$
+ InputStream input = null;
+ Properties result = new Properties();
+ try {
+ input = new BufferedInputStream(new FileInputStream(location.toFile()));
+ result.load(input);
+ } catch (FileNotFoundException e) {
+ // file doesn't exist but that's ok.
+ if (DEBUG_PREFERENCE_GENERAL)
+ PrefsMessages.message("Preference file does not exist: " + location); //$NON-NLS-1$
+ return result;
+ } catch (IOException e) {
+ String message = NLS.bind(PrefsMessages.preferences_loadException, location);
+ log(new Status(IStatus.INFO, PrefsMessages.OWNER_NAME, IStatus.INFO, message, e));
+ throw new BackingStoreException(message);
+ } finally {
+ if (input != null)
+ try {
+ input.close();
+ } catch (IOException e) {
+ // ignore
+ }
+ }
+ return result;
+ }
+
+ protected void load(IPath location) throws BackingStoreException {
+ if (location == null) {
+ if (DEBUG_PREFERENCE_GENERAL)
+ PrefsMessages.message("Unable to determine location of preference file for node: " + absolutePath()); //$NON-NLS-1$
+ return;
+ }
+ Properties fromDisk = loadProperties(location);
+ convertFromProperties(this, fromDisk, false);
+ }
+
+ protected void loaded() {
+ // do nothing
+ }
+
+ protected void loadLegacy() {
+ // sub-classes to over-ride if necessary
+ }
+
+ public static void log(IStatus status) {
+ RuntimeLog.log(status);
+ }
+
+ protected void makeDirty() {
+ EclipsePreferences node = this;
+ while (node != null && !node.removed) {
+ node.dirty = true;
+ node = (EclipsePreferences) node.parent();
+ }
+ }
+
+ public boolean isDirty() {
+ return dirty;
+ }
+
+ /*
+ * @see org.osgi.service.prefs.Preferences#name()
+ */
+ public String name() {
+ return name;
+ }
+
+ /*
+ * @see org.osgi.service.prefs.Preferences#node(java.lang.String)
+ */
+ public Preferences node(String pathName) {
+ return internalNode(pathName, true, null);
+ }
+
+ protected void fireNodeEvent(final NodeChangeEvent event, final boolean added) {
+ if (nodeChangeListeners == null)
+ return;
+ Object[] listeners = nodeChangeListeners.getListeners();
+ for (int i = 0; i < listeners.length; i++) {
+ final INodeChangeListener listener = (INodeChangeListener) listeners[i];
+ ISafeRunnable job = new ISafeRunnable() {
+ public void handleException(Throwable exception) {
+ // already logged in Platform#run()
+ }
+
+ public void run() throws Exception {
+ if (added)
+ listener.added(event);
+ else
+ listener.removed(event);
+ }
+ };
+ SafeRunner.run(job);
+ }
+ }
+
+ /*
+ * @see org.osgi.service.prefs.Preferences#nodeExists(java.lang.String)
+ */
+ public boolean nodeExists(String path) throws BackingStoreException {
+ // short circuit for checking this node
+ if (path.length() == 0)
+ return !removed;
+
+ // illegal state if this node has been removed.
+ // do this AFTER checking for the empty string.
+ checkRemoved();
+
+ // use the root relative to this node instead of the global root
+ // in case we have a different hierarchy. (e.g. export)
+ if (path.charAt(0) == IPath.SEPARATOR)
+ return calculateRoot().nodeExists(path.substring(1));
+
+ int index = path.indexOf(IPath.SEPARATOR);
+ boolean noSlash = index == -1;
+
+ // if we are looking for a simple child then just look in the table and return
+ if (noSlash)
+ return childExists(path);
+
+ // otherwise load the parent of the child and then recursively ask
+ String childName = path.substring(0, index);
+ if (!childExists(childName))
+ return false;
+ IEclipsePreferences child = getChild(childName, null, true);
+ if (child == null)
+ return false;
+ return child.nodeExists(path.substring(index + 1));
+ }
+
+ /*
+ * @see org.osgi.service.prefs.Preferences#parent()
+ */
+ public Preferences parent() {
+ // illegal state if this node has been removed
+ checkRemoved();
+ return parent;
+ }
+
+ /*
+ * Convenience method for notifying preference change listeners.
+ */
+ protected void firePreferenceEvent(String key, Object oldValue, Object newValue) {
+ if (preferenceChangeListeners == null)
+ return;
+ Object[] listeners = preferenceChangeListeners.getListeners();
+ final PreferenceChangeEvent event = new PreferenceChangeEvent(this, key, oldValue, newValue);
+ for (int i = 0; i < listeners.length; i++) {
+ final IPreferenceChangeListener listener = (IPreferenceChangeListener) listeners[i];
+ ISafeRunnable job = new ISafeRunnable() {
+ public void handleException(Throwable exception) {
+ // already logged in Platform#run()
+ }
+
+ public void run() throws Exception {
+ listener.preferenceChange(event);
+ }
+ };
+ SafeRunner.run(job);
+ }
+ }
+
+ /*
+ * @see org.osgi.service.prefs.Preferences#put(java.lang.String, java.lang.String)
+ */
+ public void put(String key, String newValue) {
+ if (key == null || newValue == null)
+ throw new NullPointerException();
+ String oldValue = internalPut(key, newValue);
+ if (!newValue.equals(oldValue)) {
+ makeDirty();
+ firePreferenceEvent(key, oldValue, newValue);
+ }
+ }
+
+ /*
+ * @see org.osgi.service.prefs.Preferences#putBoolean(java.lang.String, boolean)
+ */
+ public void putBoolean(String key, boolean value) {
+ if (key == null)
+ throw new NullPointerException();
+ String newValue = value ? TRUE : FALSE;
+ String oldValue = internalPut(key, newValue);
+ if (!newValue.equals(oldValue)) {
+ makeDirty();
+ firePreferenceEvent(key, oldValue, newValue);
+ }
+ }
+
+ /*
+ * @see org.osgi.service.prefs.Preferences#putByteArray(java.lang.String, byte[])
+ */
+ public void putByteArray(String key, byte[] value) {
+ if (key == null || value == null)
+ throw new NullPointerException();
+ String newValue = new String(Base64.encode(value));
+ String oldValue = internalPut(key, newValue);
+ if (!newValue.equals(oldValue)) {
+ makeDirty();
+ firePreferenceEvent(key, oldValue, newValue);
+ }
+ }
+
+ /*
+ * @see org.osgi.service.prefs.Preferences#putDouble(java.lang.String, double)
+ */
+ public void putDouble(String key, double value) {
+ if (key == null)
+ throw new NullPointerException();
+ String newValue = Double.toString(value);
+ String oldValue = internalPut(key, newValue);
+ if (!newValue.equals(oldValue)) {
+ makeDirty();
+ firePreferenceEvent(key, oldValue, newValue);
+ }
+ }
+
+ /*
+ * @see org.osgi.service.prefs.Preferences#putFloat(java.lang.String, float)
+ */
+ public void putFloat(String key, float value) {
+ if (key == null)
+ throw new NullPointerException();
+ String newValue = Float.toString(value);
+ String oldValue = internalPut(key, newValue);
+ if (!newValue.equals(oldValue)) {
+ makeDirty();
+ firePreferenceEvent(key, oldValue, newValue);
+ }
+ }
+
+ /*
+ * @see org.osgi.service.prefs.Preferences#putInt(java.lang.String, int)
+ */
+ public void putInt(String key, int value) {
+ if (key == null)
+ throw new NullPointerException();
+ String newValue = Integer.toString(value);
+ String oldValue = internalPut(key, newValue);
+ if (!newValue.equals(oldValue)) {
+ makeDirty();
+ firePreferenceEvent(key, oldValue, newValue);
+ }
+ }
+
+ /*
+ * @see org.osgi.service.prefs.Preferences#putLong(java.lang.String, long)
+ */
+ public void putLong(String key, long value) {
+ if (key == null)
+ throw new NullPointerException();
+ String newValue = Long.toString(value);
+ String oldValue = internalPut(key, newValue);
+ if (!newValue.equals(oldValue)) {
+ makeDirty();
+ firePreferenceEvent(key, oldValue, newValue);
+ }
+ }
+
+ /*
+ * @see org.osgi.service.prefs.Preferences#remove(java.lang.String)
+ */
+ public void remove(String key) {
+ // illegal state if this node has been removed
+ checkRemoved();
+ String oldValue = properties.get(key);
+ if (oldValue == null)
+ return;
+ properties = properties.removeKey(key);
+ makeDirty();
+ firePreferenceEvent(key, oldValue, null);
+ }
+
+ /*
+ * @see org.osgi.service.prefs.Preferences#removeNode()
+ */
+ public void removeNode() throws BackingStoreException {
+ // illegal state if this node has been removed
+ checkRemoved();
+ // clear all the property values. do it "the long way" so
+ // everyone gets notification
+ String[] keys = keys();
+ for (int i = 0; i < keys.length; i++)
+ remove(keys[i]);
+ // don't remove the global root or the scope root from the
+ // parent but remove all its children
+ if (parent != null && !(parent instanceof RootPreferences)) {
+ // remove the node from the parent's collection and notify listeners
+ removed = true;
+ parent.removeNode(this);
+ }
+ IEclipsePreferences[] childNodes = getChildren(false);
+ for (int i = 0; i < childNodes.length; i++)
+ try {
+ childNodes[i].removeNode();
+ } catch (IllegalStateException e) {
+ // ignore since we only get this exception if we have already
+ // been removed. no work to do.
+ }
+ }
+
+ /*
+ * Remove the child from the collection and notify the listeners if something
+ * was actually removed.
+ */
+ protected void removeNode(IEclipsePreferences child) {
+ boolean wasRemoved = false;
+ synchronized (this) {
+ if (children != null) {
+ wasRemoved = children.remove(child.name()) != null;
+ if (wasRemoved)
+ makeDirty();
+ if (children.isEmpty())
+ children = null;
+ }
+ }
+ if (wasRemoved)
+ fireNodeEvent(new NodeChangeEvent(this, child), false);
+ }
+
+ /*
+ * Remove non-initialized node from the collection.
+ */
+ protected void removeNode(String key) {
+ synchronized (this) {
+ if (children != null) {
+ boolean wasRemoved = children.remove(key) != null;
+ if (wasRemoved)
+ makeDirty();
+ if (children.isEmpty())
+ children = null;
+ }
+ }
+ }
+
+ /*
+ * @see org.eclipse.core.runtime.IEclipsePreferences#removeNodeChangeListener(org.eclipse.core.runtime.IEclipsePreferences.removeNodeChangeListener)
+ */
+ public void removeNodeChangeListener(INodeChangeListener listener) {
+ checkRemoved();
+ if (nodeChangeListeners == null)
+ return;
+ nodeChangeListeners.remove(listener);
+ if (nodeChangeListeners.size() == 0)
+ nodeChangeListeners = null;
+ if (DEBUG_PREFERENCE_GENERAL)
+ PrefsMessages.message("Removed preference node change listener: " + listener + " from: " + absolutePath()); //$NON-NLS-1$ //$NON-NLS-2$
+ }
+
+ /*
+ * @see org.eclipse.core.runtime.IEclipsePreferences#removePreferenceChangeListener(org.eclipse.core.runtime.IEclipsePreferences.IPreferenceChangeListener)
+ */
+ public void removePreferenceChangeListener(IPreferenceChangeListener listener) {
+ checkRemoved();
+ if (preferenceChangeListeners == null)
+ return;
+ preferenceChangeListeners.remove(listener);
+ if (preferenceChangeListeners.size() == 0)
+ preferenceChangeListeners = null;
+ if (DEBUG_PREFERENCE_GENERAL)
+ PrefsMessages.message("Removed preference property change listener: " + listener + " from: " + absolutePath()); //$NON-NLS-1$ //$NON-NLS-2$
+ }
+
+ /**
+ * Saves the preference node. This method returns silently if the node does not exist
+ * in the backing store (for example non-existent project)
+ *
+ * @throws BackingStoreException if the node exists in the backing store but it
+ * could not be saved
+ */
+ protected void save() throws BackingStoreException {
+ save(getLocation());
+ }
+
+ protected void save(IPath location) throws BackingStoreException {
+ if (location == null) {
+ if (DEBUG_PREFERENCE_GENERAL)
+ PrefsMessages.message("Unable to determine location of preference file for node: " + absolutePath()); //$NON-NLS-1$
+ return;
+ }
+ if (DEBUG_PREFERENCE_GENERAL)
+ PrefsMessages.message("Saving preferences to file: " + location); //$NON-NLS-1$
+ Properties table = convertToProperties(new SortedProperties(), EMPTY_STRING);
+ if (table.isEmpty()) {
+ // nothing to save. delete existing file if one exists.
+ if (location.toFile().exists() && !location.toFile().delete()) {
+ String message = NLS.bind(PrefsMessages.preferences_failedDelete, location);
+ log(new Status(IStatus.WARNING, PrefsMessages.OWNER_NAME, IStatus.WARNING, message, null));
+ }
+ return;
+ }
+ table.put(VERSION_KEY, VERSION_VALUE);
+ write(table, location);
+ }
+
+ /**
+ * Traverses the preference hierarchy rooted at this node, and adds
+ * all preference key and value strings to the provided pool. If an added
+ * string was already in the pool, all references will be replaced with the
+ * canonical copy of the string.
+ *
+ * @param pool The pool to share strings in
+ */
+ public void shareStrings(StringPool pool) {
+ properties.shareStrings(pool);
+ IEclipsePreferences[] myChildren = getChildren(false);
+ for (int i = 0; i < myChildren.length; i++)
+ if (myChildren[i] instanceof EclipsePreferences)
+ ((EclipsePreferences) myChildren[i]).shareStrings(pool);
+ }
+
+ /*
+ * Encode the given path and key combo to a form which is suitable for
+ * persisting or using when searching. If the key contains a slash character
+ * then we must use a double-slash to indicate the end of the
+ * path/the beginning of the key.
+ */
+ public static String encodePath(String path, String key) {
+ String result;
+ int pathLength = path == null ? 0 : path.length();
+ if (key.indexOf(IPath.SEPARATOR) == -1) {
+ if (pathLength == 0)
+ result = key;
+ else
+ result = path + IPath.SEPARATOR + key;
+ } else {
+ if (pathLength == 0)
+ result = DOUBLE_SLASH + key;
+ else
+ result = path + DOUBLE_SLASH + key;
+ }
+ return result;
+ }
+
+ /*
+ * Return the segment from the given path or null.
+ * "segment" parameter is 0-based.
+ */
+ public static String getSegment(String path, int segment) {
+ int start = path.indexOf(IPath.SEPARATOR) == 0 ? 1 : 0;
+ int end = path.indexOf(IPath.SEPARATOR, start);
+ if (end == path.length() - 1)
+ end = -1;
+ for (int i = 0; i < segment; i++) {
+ if (end == -1)
+ return null;
+ start = end + 1;
+ end = path.indexOf(IPath.SEPARATOR, start);
+ }
+ if (end == -1)
+ end = path.length();
+ return path.substring(start, end);
+ }
+
+ public static int getSegmentCount(String path) {
+ StringTokenizer tokenizer = new StringTokenizer(path, String.valueOf(IPath.SEPARATOR));
+ return tokenizer.countTokens();
+ }
+
+ /*
+ * Return a relative path
+ */
+ public static String makeRelative(String path) {
+ String result = path;
+ if (path == null)
+ return EMPTY_STRING;
+ if (path.length() > 0 && path.charAt(0) == IPath.SEPARATOR)
+ result = path.length() == 0 ? EMPTY_STRING : path.substring(1);
+ return result;
+ }
+
+ /*
+ * Return a 2 element String array.
+ * element 0 - the path
+ * element 1 - the key
+ * The path may be null.
+ * The key is never null.
+ */
+ public static String[] decodePath(String fullPath) {
+ String key = null;
+ String path = null;
+
+ // check to see if we have an indicator which tells us where the path ends
+ int index = fullPath.indexOf(DOUBLE_SLASH);
+ if (index == -1) {
+ // we don't have a double-slash telling us where the path ends
+ // so the path is up to the last slash character
+ int lastIndex = fullPath.lastIndexOf(IPath.SEPARATOR);
+ if (lastIndex == -1) {
+ key = fullPath;
+ } else {
+ path = fullPath.substring(0, lastIndex);
+ key = fullPath.substring(lastIndex + 1);
+ }
+ } else {
+ // the child path is up to the double-slash and the key
+ // is the string after it
+ path = fullPath.substring(0, index);
+ key = fullPath.substring(index + 2);
+ }
+
+ // adjust if we have an absolute path
+ if (path != null)
+ if (path.length() == 0)
+ path = null;
+ else if (path.charAt(0) == IPath.SEPARATOR)
+ path = path.substring(1);
+
+ return new String[] {path, key};
+ }
+
+ /*
+ * @see org.osgi.service.prefs.Preferences#sync()
+ */
+
+ public void sync() throws BackingStoreException {
+ // illegal state if this node has been removed
+ checkRemoved();
+ IEclipsePreferences node = getLoadLevel();
+ if (node == null) {
+ if (DEBUG_PREFERENCE_GENERAL)
+ PrefsMessages.message("Preference node is not a load root: " + absolutePath()); //$NON-NLS-1$
+ return;
+ }
+ if (node instanceof EclipsePreferences) {
+ ((EclipsePreferences) node).load();
+ node.flush();
+ }
+ }
+
+ public String toDeepDebugString() {
+ final StringBuffer buffer = new StringBuffer();
+ IPreferenceNodeVisitor visitor = new IPreferenceNodeVisitor() {
+ public boolean visit(IEclipsePreferences node) throws BackingStoreException {
+ buffer.append(node);
+ buffer.append('\n');
+ String[] keys = node.keys();
+ for (int i = 0; i < keys.length; i++) {
+ buffer.append(node.absolutePath());
+ buffer.append(PATH_SEPARATOR);
+ buffer.append(keys[i]);
+ buffer.append('=');
+ buffer.append(node.get(keys[i], "*default*")); //$NON-NLS-1$
+ buffer.append('\n');
+ }
+ return true;
+ }
+ };
+ try {
+ accept(visitor);
+ } catch (BackingStoreException e) {
+ System.out.println("Exception while calling #toDeepDebugString()"); //$NON-NLS-1$
+ e.printStackTrace();
+ }
+ return buffer.toString();
+ }
+
+ public String toString() {
+ return absolutePath();
+ }
+}
diff --git a/bundles/org.eclipse.equinox.preferences/src/org/osgi/service/prefs/BackingStoreException.java b/bundles/org.eclipse.equinox.preferences/src/org/osgi/service/prefs/BackingStoreException.java
index 9f4bca221..86f6e3cc9 100644
--- a/bundles/org.eclipse.equinox.preferences/src/org/osgi/service/prefs/BackingStoreException.java
+++ b/bundles/org.eclipse.equinox.preferences/src/org/osgi/service/prefs/BackingStoreException.java
@@ -19,7 +19,7 @@ package org.osgi.service.prefs;
* Thrown to indicate that a preferences operation could not complete because of
* a failure in the backing store, or a failure to contact the backing store.
*
- * @version $Id: 86f6e3cc926b2ea3875e000e90b0700a75f2a7c7 $
+ * @version $Id$
*/
public class BackingStoreException extends Exception {
static final long serialVersionUID = -1415637364122829574L;
diff --git a/bundles/org.eclipse.equinox.preferences/src/org/osgi/service/prefs/Preferences.java b/bundles/org.eclipse.equinox.preferences/src/org/osgi/service/prefs/Preferences.java
index 513d6cd79..481de91d7 100644
--- a/bundles/org.eclipse.equinox.preferences/src/org/osgi/service/prefs/Preferences.java
+++ b/bundles/org.eclipse.equinox.preferences/src/org/osgi/service/prefs/Preferences.java
@@ -108,7 +108,7 @@ package org.osgi.service.prefs;
* preference data.
*
* @noimplement
- * @version $Id: 481de91d7ba8a3274ad7ded1ea26f254564baea0 $
+ * @version $Id$
*/
public interface Preferences {
/**
diff --git a/bundles/org.eclipse.equinox.preferences/src/org/osgi/service/prefs/PreferencesService.java b/bundles/org.eclipse.equinox.preferences/src/org/osgi/service/prefs/PreferencesService.java
index 6371dbf95..bcb430ac7 100644
--- a/bundles/org.eclipse.equinox.preferences/src/org/osgi/service/prefs/PreferencesService.java
+++ b/bundles/org.eclipse.equinox.preferences/src/org/osgi/service/prefs/PreferencesService.java
@@ -29,7 +29,7 @@ package org.osgi.service.prefs;
* {@code PreferencesService} object to that bundle.
*
* @noimplement
- * @version $Id: bcb430ac769863b4239575c1edeedc23fc5ab097 $
+ * @version $Id$
*/
public interface PreferencesService {
/**
diff --git a/bundles/org.eclipse.equinox.resolver/src/org/osgi/service/resolver/Resolver.java b/bundles/org.eclipse.equinox.resolver/src/org/osgi/service/resolver/Resolver.java
index cc84ddc3d..5735a30be 100644
--- a/bundles/org.eclipse.equinox.resolver/src/org/osgi/service/resolver/Resolver.java
+++ b/bundles/org.eclipse.equinox.resolver/src/org/osgi/service/resolver/Resolver.java
@@ -32,7 +32,7 @@ import org.osgi.framework.resource.Wire;
* specified {@link Resource resources} based on a supplied {@link Environment}.
*
* @ThreadSafe
- * @version $Id: 93375420122cbe48e6fba5af207af43826a508fa $
+ * @version $Id$
*/
public interface Resolver {
/**
diff --git a/bundles/org.eclipse.equinox.resolver/src/org/osgi/service/resolver/package-info.java b/bundles/org.eclipse.equinox.resolver/src/org/osgi/service/resolver/package-info.java
index be979c503..ffe26e5b9 100644
--- a/bundles/org.eclipse.equinox.resolver/src/org/osgi/service/resolver/package-info.java
+++ b/bundles/org.eclipse.equinox.resolver/src/org/osgi/service/resolver/package-info.java
@@ -32,7 +32,7 @@
* <p>
* {@code Import-Package: org.osgi.service.resolver; version="[1.0,1.1)"}
*
- * @version $Id: ffe26e5b960ebceb84699fd1cb8f211d9a386bf4 $
+ * @version $Id$
*/
package org.osgi.service.resolver; \ No newline at end of file

Back to the top