Download
Getting Started
Members
Projects
Community
Marketplace
Events
Planet Eclipse
Newsletter
Videos
Participate
Report a Bug
Forums
Mailing Lists
Wiki
IRC
How to Contribute
Working Groups
Automotive
Internet of Things
LocationTech
Long-Term Support
PolarSys
Science
OpenMDM
More
Community
Marketplace
Events
Planet Eclipse
Newsletter
Videos
Participate
Report a Bug
Forums
Mailing Lists
Wiki
IRC
How to Contribute
Working Groups
Automotive
Internet of Things
LocationTech
Long-Term Support
PolarSys
Science
OpenMDM
Toggle navigation
Bugzilla – Attachment 199393 Details for
Bug 349711
[metatype] Improve metatype implementation in equinox to allow better use of schema extensions
Home
|
New
|
Browse
|
Search
|
[?]
|
Reports
|
Requests
|
Help
|
Log In
[x]
|
Terms of Use
|
Copyright Agent
[patch]
work in progress patch
349711-20110710-1830.txt (text/plain), 264.21 KB, created by
John Ross
on 2011-07-10 19:39:14 EDT
(
hide
)
Description:
work in progress patch
Filename:
MIME Type:
Creator:
John Ross
Created:
2011-07-10 19:39:14 EDT
Size:
264.21 KB
patch
obsolete
>### Eclipse Workspace Patch 1.0 >#P org.eclipse.equinox.compendium.tests >Index: .classpath >=================================================================== >RCS file: /cvsroot/rt/org.eclipse.equinox/compendium/bundles/org.eclipse.equinox.compendium.tests/.classpath,v >retrieving revision 1.6 >diff -u -r1.6 .classpath >--- .classpath 25 Mar 2011 14:06:23 -0000 1.6 >+++ .classpath 10 Jul 2011 23:30:15 -0000 >@@ -10,5 +10,6 @@ > <classpathentry kind="src" output="bundle_tests/metatype/tb5" path="bundles_src/metatype/tb5"/> > <classpathentry kind="src" output="bundle_tests/metatype/tb6" path="bundles_src/metatype/tb6"/> > <classpathentry kind="src" output="bundle_tests/metatype/tb7" path="bundles_src/metatype/tb7"/> >+ <classpathentry kind="src" output="bundle_tests/metatype/extendable.tb1" path="bundles_src/metatype/extendable.tb1"/> > <classpathentry kind="output" path="bin"/> > </classpath> >Index: build.properties >=================================================================== >RCS file: /cvsroot/rt/org.eclipse.equinox/compendium/bundles/org.eclipse.equinox.compendium.tests/build.properties,v >retrieving revision 1.7 >diff -u -r1.7 build.properties >--- build.properties 2 May 2011 15:37:11 -0000 1.7 >+++ build.properties 10 Jul 2011 23:30:15 -0000 >@@ -29,6 +29,8 @@ > manifest.bundle_tests/metatype.tb6.jar = META-INF/MANIFEST.MF > source.bundle_tests/metatype.tb7.jar = bundles_src/metatype/tb7/ > manifest.bundle_tests/metatype.tb7.jar = META-INF/MANIFEST.MF >+source.bundle_tests/metatype.extendable.tb1.jar = bundles_src/metatype/extendable.tb1/ >+manifest.bundle_tests/metatype.extendable.tb1.jar = META-INF/MANIFEST.MF > > jars.compile.order = bundle_tests/metatype/metatype.tb1.jar,\ > bundle_tests/metatype/metatype.tb2.jar,\ >@@ -36,4 +38,5 @@ > bundle_tests/metatype/metatype.tb4.jar,\ > bundle_tests/metatype/metatype.tb5.jar,\ > bundle_tests/metatype/metatype.tb6.jar,\ >- bundle_tests/metatype/metatype.tb7.jar >+ bundle_tests/metatype/metatype.tb7.jar,\ >+ bundle_tests/metatype/metatype.extendable.tb1.jar >Index: META-INF/MANIFEST.MF >=================================================================== >RCS file: /cvsroot/rt/org.eclipse.equinox/compendium/bundles/org.eclipse.equinox.compendium.tests/META-INF/MANIFEST.MF,v >retrieving revision 1.2 >diff -u -r1.2 MANIFEST.MF >--- META-INF/MANIFEST.MF 19 Nov 2010 21:28:40 -0000 1.2 >+++ META-INF/MANIFEST.MF 10 Jul 2011 23:30:15 -0000 >@@ -2,11 +2,12 @@ > Bundle-ManifestVersion: 2 > Bundle-Name: %bundleName > Bundle-SymbolicName: org.eclipse.equinox.compendium.tests >-Bundle-Version: 1.1.0 >+Bundle-Version: 1.1.100 > Bundle-Activator: org.eclipse.equinox.compendium.tests.Activator > Require-Bundle: org.eclipse.core.runtime > Eclipse-LazyStart: true > Import-Package: junit.framework;version="3.8.2", >+ org.eclipse.equinox.metatype;version="1.2.0", > org.eclipse.osgi.tests.bundles, > org.osgi.framework;version="1.3.0", > org.osgi.service.event;version="1.1.0", >Index: bundles_src/metatype/extendable.tb1/META-INF/MANIFEST.MF >=================================================================== >RCS file: bundles_src/metatype/extendable.tb1/META-INF/MANIFEST.MF >diff -N bundles_src/metatype/extendable.tb1/META-INF/MANIFEST.MF >--- /dev/null 1 Jan 1970 00:00:00 -0000 >+++ bundles_src/metatype/extendable.tb1/META-INF/MANIFEST.MF 1 Jan 1970 00:00:00 -0000 >@@ -0,0 +1,8 @@ >+Manifest-Version: 1.0 >+Bundle-ManifestVersion: 2 >+Bundle-SymbolicName: metatype.extendable.tb1 >+Bundle-Version: 1.0.0 >+Import-Package: org.osgi.framework;version="1.3.0", >+ org.osgi.service.metatype;version="1.2" >+Bundle-RequiredExecutionEnvironment: J2SE-1.4 >+ >Index: bundles_src/metatype/extendable.tb1/OSGI-INF/metatype/metadata.xml >=================================================================== >RCS file: bundles_src/metatype/extendable.tb1/OSGI-INF/metatype/metadata.xml >diff -N bundles_src/metatype/extendable.tb1/OSGI-INF/metatype/metadata.xml >--- /dev/null 1 Jan 1970 00:00:00 -0000 >+++ bundles_src/metatype/extendable.tb1/OSGI-INF/metatype/metadata.xml 1 Jan 1970 00:00:00 -0000 >@@ -0,0 +1,14 @@ >+<?xml version="1.0" encoding="UTF-8"?> >+<md:MetaData >+ xmlns:md="http://www.org.osgi/xmlns/metatype/v1.2.0/md" >+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" >+ xsi:schemaLocation="http://www.org.osgi/xmlns/metatype/v1.2.0/md metatype.xsd" >+ xmlns:validation="urn:xmlns:validation" >+ xmlns:foo="urn:xmlns:foo"> >+ <OCD id="ocd1" name="ocd1" foo:foo="bar" validation:enabled="true"> >+ <AD name="ad1" id="ad1" type="String" validation:regexp="[a-zA-Z0-9]" validation:validation="validation" foo:bar="foo"/> >+ </OCD> >+ <Designate pid="metatype.extendable.tb1.1"> >+ <Object ocdref="ocd1"/> >+ </Designate> >+</md:MetaData> >Index: src/org/eclipse/equinox/compendium/tests/AllTests.java >=================================================================== >RCS file: /cvsroot/rt/org.eclipse.equinox/compendium/bundles/org.eclipse.equinox.compendium.tests/src/org/eclipse/equinox/compendium/tests/AllTests.java,v >retrieving revision 1.4 >diff -u -r1.4 AllTests.java >--- src/org/eclipse/equinox/compendium/tests/AllTests.java 2 May 2011 15:37:11 -0000 1.4 >+++ src/org/eclipse/equinox/compendium/tests/AllTests.java 10 Jul 2011 23:30:16 -0000 >@@ -1,5 +1,5 @@ > /******************************************************************************* >- * Copyright (c) 2008, 2010 IBM Corporation and others >+ * Copyright (c) 2008, 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 >@@ -18,6 +18,8 @@ > public static Test suite() { > TestSuite suite = new TestSuite("Tests for Equinox Compendium"); //$NON-NLS-1$ > suite.addTest(org.eclipse.equinox.metatype.tests.AllTests.suite()); >+ // Second run for EquinoxMetaTypeService. >+ suite.addTest(org.eclipse.equinox.metatype.tests.AllTests.suite()); > suite.addTest(org.eclipse.equinox.useradmin.tests.AllTests.suite()); > suite.addTest(org.eclipse.equinox.event.tests.AllTests.suite()); > return suite; >Index: src/org/eclipse/equinox/metatype/tests/AbstractTest.java >=================================================================== >RCS file: /cvsroot/rt/org.eclipse.equinox/compendium/bundles/org.eclipse.equinox.compendium.tests/src/org/eclipse/equinox/metatype/tests/AbstractTest.java,v >retrieving revision 1.1 >diff -u -r1.1 AbstractTest.java >--- src/org/eclipse/equinox/metatype/tests/AbstractTest.java 18 Mar 2011 19:37:21 -0000 1.1 >+++ src/org/eclipse/equinox/metatype/tests/AbstractTest.java 10 Jul 2011 23:30:16 -0000 >@@ -10,18 +10,18 @@ > *******************************************************************************/ > package org.eclipse.equinox.metatype.tests; > >+import org.eclipse.equinox.metatype.EquinoxMetaTypeService; >+ > import junit.framework.TestCase; > import org.eclipse.equinox.compendium.tests.Activator; > import org.eclipse.osgi.tests.bundles.BundleInstaller; > import org.osgi.framework.ServiceReference; > import org.osgi.service.metatype.AttributeDefinition; >-import org.osgi.service.metatype.MetaTypeService; > > public abstract class AbstractTest extends TestCase { > protected BundleInstaller bundleInstaller; >- protected MetaTypeService metatype; >- >- private ServiceReference metaTypeReference; >+ protected EquinoxMetaTypeService metatype; >+ protected ServiceReference metaTypeReference; > > protected void assertValidationFail(String value, AttributeDefinition ad) { > String result = assertValidationPresent(value, ad); >@@ -75,9 +75,9 @@ > > protected void setUp() throws Exception { > Activator.getBundle(Activator.BUNDLE_METATYPE).start(); >- metaTypeReference = Activator.getBundleContext().getServiceReference(MetaTypeService.class.getName()); >+ metaTypeReference = Activator.getBundleContext().getServiceReference(EquinoxMetaTypeService.class.getName()); > assertNotNull("Metatype service reference not found", metaTypeReference); //$NON-NLS-1$ >- metatype = (MetaTypeService) Activator.getBundleContext().getService(metaTypeReference); >+ metatype = (EquinoxMetaTypeService) Activator.getBundleContext().getService(metaTypeReference); > assertNotNull("Metatype service not found", metatype); //$NON-NLS-1$ > bundleInstaller = new BundleInstaller("bundle_tests/metatype", Activator.getBundleContext()); //$NON-NLS-1$ > } >Index: src/org/eclipse/equinox/metatype/tests/AllTests.java >=================================================================== >RCS file: /cvsroot/rt/org.eclipse.equinox/compendium/bundles/org.eclipse.equinox.compendium.tests/src/org/eclipse/equinox/metatype/tests/AllTests.java,v >retrieving revision 1.4 >diff -u -r1.4 AllTests.java >--- src/org/eclipse/equinox/metatype/tests/AllTests.java 25 Mar 2011 14:06:23 -0000 1.4 >+++ src/org/eclipse/equinox/metatype/tests/AllTests.java 10 Jul 2011 23:30:16 -0000 >@@ -21,6 +21,7 @@ > suite.addTestSuite(Bug340899Test.class); > suite.addTestSuite(BugTests.class); > suite.addTestSuite(SameOcdPidFactoryPidTest.class); >+ suite.addTestSuite(ExtendableTest.class); > return suite; > } > } >Index: src/org/eclipse/equinox/metatype/tests/ExtendableTest.java >=================================================================== >RCS file: src/org/eclipse/equinox/metatype/tests/ExtendableTest.java >diff -N src/org/eclipse/equinox/metatype/tests/ExtendableTest.java >--- /dev/null 1 Jan 1970 00:00:00 -0000 >+++ src/org/eclipse/equinox/metatype/tests/ExtendableTest.java 1 Jan 1970 00:00:00 -0000 >@@ -0,0 +1,65 @@ >+/******************************************************************************* >+ * 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.tests; >+ >+import org.eclipse.equinox.metatype.*; >+ >+import java.util.Map; >+import java.util.Set; >+import org.osgi.framework.Bundle; >+import org.osgi.service.metatype.ObjectClassDefinition; >+ >+public class ExtendableTest extends AbstractTest { >+ private Bundle bundle; >+ >+ protected void setUp() throws Exception { >+ super.setUp(); >+ bundle = bundleInstaller.installBundle("extendable.tb1"); //$NON-NLS-1$ >+ bundle.start(); >+ } >+ >+ public void testExtensions() { >+ EquinoxMetaTypeInformation mti = metatype.getMetaTypeInformation(bundle); >+ EquinoxObjectClassDefinition ocd = mti.getObjectClassDefinition("metatype.extendable.tb1.1", null); //$NON-NLS-1$ >+ Set schemas = ocd.getExtensionUris(); >+ assertNotNull("Null extension schemas", schemas); //$NON-NLS-1$ >+ assertEquals("Wrong schemas size", 2, schemas.size()); //$NON-NLS-1$ >+ assertTrue("Missing schema", schemas.contains("urn:xmlns:foo")); //$NON-NLS-1$ //$NON-NLS-2$ >+ assertTrue("Missing schema", schemas.contains("urn:xmlns:validation")); //$NON-NLS-1$ //$NON-NLS-2$ >+ Map attributes = ocd.getExtensionAttributes("urn:xmlns:foo"); //$NON-NLS-1$ >+ assertNotNull("Null attributes", attributes); //$NON-NLS-1$ >+ assertEquals("Wrong attributes size", 1, attributes.size()); //$NON-NLS-1$ >+ assertEquals("Wrong value", "bar", attributes.get("foo")); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ >+ attributes = ocd.getExtensionAttributes("urn:xmlns:validation"); //$NON-NLS-1$ >+ assertNotNull("Null attributes", attributes); //$NON-NLS-1$ >+ assertEquals("Wrong attributes size", 1, attributes.size()); //$NON-NLS-1$ >+ assertEquals("Wrong value", "true", attributes.get("enabled")); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ >+ EquinoxAttributeDefinition[] ads = ocd.getAttributeDefinitions(ObjectClassDefinition.ALL); >+ for (int i = 0; i < ads.length; i++) { >+ if (ads[i].getID().equals("ad1")) { //$NON-NLS-1$ >+ schemas = ads[i].getExtensionUris(); >+ assertNotNull("Null extension schemas", schemas); //$NON-NLS-1$ >+ assertEquals("Wrong schemas size", 2, schemas.size()); //$NON-NLS-1$ >+ assertTrue("Missing schema", schemas.contains("urn:xmlns:foo")); //$NON-NLS-1$ //$NON-NLS-2$ >+ assertTrue("Missing schema", schemas.contains("urn:xmlns:validation")); //$NON-NLS-1$ //$NON-NLS-2$ >+ attributes = ads[i].getExtensionAttributes("urn:xmlns:foo"); //$NON-NLS-1$ >+ assertNotNull("Null attributes", attributes); //$NON-NLS-1$ >+ assertEquals("Wrong attributes size", 1, attributes.size()); //$NON-NLS-1$ >+ assertEquals("Wrong value", "foo", attributes.get("bar")); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ >+ attributes = ads[i].getExtensionAttributes("urn:xmlns:validation"); //$NON-NLS-1$ >+ assertNotNull("Null attributes", attributes); //$NON-NLS-1$ >+ assertEquals("Wrong attributes size", 2, attributes.size()); //$NON-NLS-1$ >+ assertEquals("Wrong value", "[a-zA-Z0-9]", attributes.get("regexp")); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ >+ assertEquals("Wrong value", "validation", attributes.get("validation")); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ >+ } >+ } >+ } >+} >#P org.eclipse.equinox.metatype >Index: .settings/.api_filters >=================================================================== >RCS file: .settings/.api_filters >diff -N .settings/.api_filters >--- .settings/.api_filters 18 Mar 2011 19:37:21 -0000 1.1 >+++ /dev/null 1 Jan 1970 00:00:00 -0000 >@@ -1,11 +0,0 @@ >-<?xml version="1.0" encoding="UTF-8" standalone="no"?> >-<component id="org.eclipse.equinox.metatype" version="2"> >- <resource path="src/org/eclipse/equinox/metatype/LogTracker.java" type="org.eclipse.equinox.metatype.LogTracker"> >- <filter id="574619656"> >- <message_arguments> >- <message_argument value="LogService"/> >- <message_argument value="LogTracker"/> >- </message_arguments> >- </filter> >- </resource> >-</component> >Index: META-INF/MANIFEST.MF >=================================================================== >RCS file: /cvsroot/rt/org.eclipse.equinox/compendium/bundles/org.eclipse.equinox.metatype/META-INF/MANIFEST.MF,v >retrieving revision 1.13 >diff -u -r1.13 MANIFEST.MF >--- META-INF/MANIFEST.MF 1 Jul 2011 19:25:52 -0000 1.13 >+++ META-INF/MANIFEST.MF 10 Jul 2011 23:30:16 -0000 >@@ -1,8 +1,8 @@ > Bundle-ManifestVersion: 2 > Bundle-Name: %bundleName >-Bundle-Version: 1.1.100.qualifier >+Bundle-Version: 1.2.0.qualifier > Bundle-SymbolicName: org.eclipse.equinox.metatype >-Bundle-Activator: org.eclipse.equinox.metatype.Activator >+Bundle-Activator: org.eclipse.equinox.metatype.impl.Activator > Import-Package: javax.xml.parsers, > org.eclipse.osgi.util;version="[1.1,2.0)", > org.osgi.framework;version="[1.6,2.0)", >@@ -13,7 +13,8 @@ > org.osgi.util.tracker;version="[1.5,2.0)", > org.xml.sax, > org.xml.sax.helpers >-Export-Package: org.eclipse.equinox.metatype;x-internal:=true >+Export-Package: org.eclipse.equinox.metatype;version="1.2.0", >+ org.eclipse.equinox.metatype.impl;version="1.2.0";x-internal:=true > Bundle-Vendor: %bundleVendor > Bundle-Localization: plugin > Bundle-RequiredExecutionEnvironment: J2SE-1.5, >Index: src/org/eclipse/equinox/metatype/Activator.java >=================================================================== >RCS file: src/org/eclipse/equinox/metatype/Activator.java >diff -N src/org/eclipse/equinox/metatype/Activator.java >--- src/org/eclipse/equinox/metatype/Activator.java 25 Oct 2010 18:04:37 -0000 1.7 >+++ /dev/null 1 Jan 1970 00:00:00 -0000 >@@ -1,188 +0,0 @@ >-/******************************************************************************* >- * Copyright (c) 2005, 2010 IBM Corporation and others. >- * All rights reserved. This program and the accompanying materials >- * are made available under the terms of the Eclipse Public License v1.0 >- * which accompanies this distribution, and is available at >- * http://www.eclipse.org/legal/epl-v10.html >- * >- * Contributors: >- * IBM Corporation - initial API and implementation >- *******************************************************************************/ >-package org.eclipse.equinox.metatype; >- >-import java.util.Dictionary; >-import java.util.Hashtable; >-import javax.xml.parsers.SAXParserFactory; >-import org.osgi.framework.*; >-import org.osgi.service.cm.ManagedService; >-import org.osgi.service.log.LogService; >-import org.osgi.service.metatype.MetaTypeProvider; >-import org.osgi.service.metatype.MetaTypeService; >-import org.osgi.util.tracker.ServiceTracker; >-import org.osgi.util.tracker.ServiceTrackerCustomizer; >- >-/** >- * MetaType Activator >- */ >-public class Activator implements BundleActivator { >- /* >- * The following filter guarantees only services meeting the following >- * criteria will be tracked. >- * >- * (1) A ManagedService or ManagedServiceFactory registered with a >- * SERVICE_PID property. May also be registered as a MetaTypeProvider. >- * (2) A MetaTypeProvider registered with a METATYPE_PID or >- * METATYPE_FACTORY_PID property. >- * >- * Note that it's still necessary to inspect a ManagedService or >- * ManagedServiceFactory to ensure it also implements MetaTypeProvider. >- */ >- private static final String FILTER = "(|(&(" + Constants.OBJECTCLASS + '=' + ManagedService.class.getName() + "*)(" + Constants.SERVICE_PID + "=*))(&(" + Constants.OBJECTCLASS + '=' + MetaTypeProvider.class.getName() + ")(|(" + MetaTypeProvider.METATYPE_PID + "=*)(" + MetaTypeProvider.METATYPE_FACTORY_PID + "=*))))"; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ //$NON-NLS-5$ //$NON-NLS-6$ >- private static final String SERVICE_PID = "org.osgi.impl.service.metatype.MetaTypeService"; //$NON-NLS-1$ >- >- private LogTracker logServiceTracker; >- // Could be ManagedService, ManagedServiceFactory, or MetaTypeProvider. >- // The tracker tracks all services regardless of bundle. Services are >- // filtered by bundle later in the MetaTypeProviderTracker class. It may >- // therefore be shared among multiple instances of that class. >- private ServiceTracker<Object, Object> metaTypeProviderTracker; >- private ServiceTracker<SAXParserFactory, SAXParserFactory> saxParserFactoryTracker; >- >- public void start(BundleContext context) throws InvalidSyntaxException { >- LogTracker lsTracker; >- ServiceTracker<Object, Object> mtpTracker; >- ServiceTracker<SAXParserFactory, SAXParserFactory> spfTracker; >- Filter filter = context.createFilter(FILTER); >- synchronized (this) { >- lsTracker = logServiceTracker = new LogTracker(context, System.out); >- mtpTracker = metaTypeProviderTracker = new ServiceTracker<Object, Object>(context, filter, null); >- spfTracker = saxParserFactoryTracker = new ServiceTracker<SAXParserFactory, SAXParserFactory>(context, SAXParserFactory.class, new SAXParserFactoryTrackerCustomizer(context, lsTracker, mtpTracker)); >- } >- // Do this first to make logging available as early as possible. >- lsTracker.open(); >- lsTracker.log(LogService.LOG_DEBUG, "====== Meta Type Service starting ! ====="); //$NON-NLS-1$ >- // Do this next to make MetaTypeProviders available as early as possible. >- mtpTracker.open(); >- // Do this last because it may result in the MetaTypeService being registered. >- spfTracker.open(); >- } >- >- public void stop(BundleContext context) { >- ServiceTracker<SAXParserFactory, SAXParserFactory> spfTracker; >- ServiceTracker<Object, Object> mtpTracker; >- LogTracker lsTracker; >- synchronized (this) { >- spfTracker = saxParserFactoryTracker; >- // Set this to null so the SAXParserFactoryTrackerCustomizer knows >- // not to register a new MetaTypeService when removedService() is >- // called while the tracker is closing. >- saxParserFactoryTracker = null; >- mtpTracker = metaTypeProviderTracker; >- lsTracker = logServiceTracker; >- } >- lsTracker.log(LogService.LOG_DEBUG, "====== Meta Type Service stopping ! ====="); //$NON-NLS-1$ >- spfTracker.close(); >- mtpTracker.close(); >- // Do this last to leave logging available as long as possible. >- lsTracker.close(); >- } >- >- synchronized ServiceTracker<SAXParserFactory, SAXParserFactory> getSAXParserFactoryTracker() { >- return saxParserFactoryTracker; >- } >- >- private class SAXParserFactoryTrackerCustomizer implements ServiceTrackerCustomizer<SAXParserFactory, SAXParserFactory> { >- private final BundleContext bundleCtx; >- private final LogService logService; >- private final ServiceTracker<Object, Object> mtpTracker; >- >- private MetaTypeServiceImpl metaTypeService; >- private ServiceRegistration<MetaTypeService> metaTypeServiceRegistration; >- private SAXParserFactory saxParserFactory; >- >- public SAXParserFactoryTrackerCustomizer(BundleContext bundleContext, LogService logService, ServiceTracker<Object, Object> metaTypeProviderTracker) { >- this.bundleCtx = bundleContext; >- this.logService = logService; >- this.mtpTracker = metaTypeProviderTracker; >- } >- >- public SAXParserFactory addingService(ServiceReference<SAXParserFactory> ref) { >- SAXParserFactory parserFactory = bundleCtx.getService(ref); >- if (parserFactory == null) >- return null; >- boolean register = false; >- synchronized (this) { >- if (saxParserFactory == null) { >- // Save this parserFactory as the currently used parserFactory >- saxParserFactory = parserFactory; >- register = true; >- } >- } >- if (register) { >- registerMetaTypeService(); >- } >- return parserFactory; >- } >- >- public void modifiedService(ServiceReference<SAXParserFactory> ref, SAXParserFactory object) { >- // noop >- } >- >- public void removedService(ServiceReference<SAXParserFactory> ref, SAXParserFactory object) { >- ServiceRegistration<MetaTypeService> registration = null; >- MetaTypeServiceImpl service = null; >- synchronized (this) { >- if (object == saxParserFactory) { >- // This means that this SAXParserFactory was used to start the >- // MetaTypeService. Set to null to indicate a new MetaTypeService >- // needs to be registered. >- saxParserFactory = null; >- registration = metaTypeServiceRegistration; >- service = metaTypeService; >- } >- } >- if (registration != null) { >- registration.unregister(); >- bundleCtx.removeBundleListener(service); >- // See if another factory is available >- ServiceTracker<SAXParserFactory, SAXParserFactory> tracker = getSAXParserFactoryTracker(); >- // If the SAXParserFactory tracker is null, the bundle is stopping, and we >- // shouldn't register a new MetaTypeService to avoid unnecessary churn. >- if (tracker != null) { >- SAXParserFactory factory = tracker.getService(); >- if (factory != null) { >- // We have another parser so lets restart the MetaTypeService >- boolean register = false; >- synchronized (this) { >- if (saxParserFactory == null) { >- saxParserFactory = factory; >- register = true; >- } >- } >- if (register) { >- registerMetaTypeService(); >- } >- } >- } >- } >- bundleCtx.ungetService(ref); >- } >- >- private void registerMetaTypeService() { >- Dictionary<String, Object> properties = new Hashtable<String, Object>(7); >- properties = new Hashtable<String, Object>(7); >- properties.put(Constants.SERVICE_VENDOR, "IBM"); //$NON-NLS-1$ >- properties.put(Constants.SERVICE_DESCRIPTION, MetaTypeMsg.SERVICE_DESCRIPTION); >- properties.put(Constants.SERVICE_PID, SERVICE_PID); >- MetaTypeServiceImpl service; >- synchronized (this) { >- service = metaTypeService = new MetaTypeServiceImpl(saxParserFactory, logService, mtpTracker); >- } >- bundleCtx.addBundleListener(service); >- ServiceRegistration<MetaTypeService> registration = bundleCtx.registerService(MetaTypeService.class, service, properties); >- synchronized (this) { >- metaTypeServiceRegistration = registration; >- } >- } >- } >-} >Index: src/org/eclipse/equinox/metatype/AttributeDefinitionImpl.java >=================================================================== >RCS file: src/org/eclipse/equinox/metatype/AttributeDefinitionImpl.java >diff -N src/org/eclipse/equinox/metatype/AttributeDefinitionImpl.java >--- src/org/eclipse/equinox/metatype/AttributeDefinitionImpl.java 18 Mar 2011 19:37:21 -0000 1.9 >+++ /dev/null 1 Jan 1970 00:00:00 -0000 >@@ -1,298 +0,0 @@ >-/******************************************************************************* >- * Copyright (c) 2005, 2011 IBM Corporation and others. >- * All rights reserved. This program and the accompanying materials >- * are made available under the terms of the Eclipse Public License v1.0 >- * which accompanies this distribution, and is available at >- * http://www.eclipse.org/legal/epl-v10.html >- * >- * Contributors: >- * IBM Corporation - initial API and implementation >- *******************************************************************************/ >-package org.eclipse.equinox.metatype; >- >-import java.util.Enumeration; >-import java.util.Vector; >-import org.eclipse.osgi.util.NLS; >-import org.osgi.service.log.LogService; >-import org.osgi.service.metatype.AttributeDefinition; >- >-/** >- * Implementation of AttributeDefintion >- */ >-public class AttributeDefinitionImpl extends LocalizationElement implements AttributeDefinition, Cloneable { >- >- String _name; >- String _id; >- String _description; >- int _cardinality = 0; >- int _dataType; >- Object _minValue = null; >- Object _maxValue = null; >- boolean _isRequired = true; >- >- String[] _defaults = null; >- Vector<String> _values = new Vector<String>(7); >- Vector<String> _labels = new Vector<String>(7); >- >- private final LogService logger; >- >- /** >- * Constructor of class AttributeDefinitionImpl. >- */ >- public AttributeDefinitionImpl(String id, String name, String description, int type, int cardinality, Object min, Object max, boolean isRequired, String localization, LogService logger) { >- >- this._id = id; >- this._name = name; >- this._description = description; >- this._dataType = type; >- this._cardinality = cardinality; >- this._minValue = min; >- this._maxValue = max; >- this._isRequired = isRequired; >- this._localization = localization; >- this.logger = logger; >- } >- >- /* >- * >- */ >- public synchronized Object clone() { >- >- AttributeDefinitionImpl ad = new AttributeDefinitionImpl(_id, _name, _description, _dataType, _cardinality, _minValue, _maxValue, _isRequired, _localization, logger); >- >- if (_defaults != null) { >- ad.setDefaultValue(_defaults.clone()); >- } >- if ((_labels != null) && (_values != null)) { >- @SuppressWarnings("unchecked") >- Vector<String> labels = (Vector<String>) _labels.clone(); >- @SuppressWarnings("unchecked") >- Vector<String> values = (Vector<String>) _values.clone(); >- ad.setOption(labels, values, false); >- } >- >- return ad; >- } >- >- /* >- * (non-Javadoc) >- * >- * @see org.osgi.service.metatype.AttributeDefinition#getName() >- */ >- public String getName() { >- return getLocalized(_name); >- } >- >- /** >- * Method to set the name of AttributeDefinition. >- */ >- void setName(String name) { >- this._name = name; >- } >- >- /* >- * (non-Javadoc) >- * >- * @see org.osgi.service.metatype.AttributeDefinition#getID() >- */ >- public String getID() { >- return _id; >- } >- >- /** >- * Method to set the ID of AttributeDefinition. >- */ >- void setID(String id) { >- this._id = id; >- } >- >- /* >- * (non-Javadoc) >- * >- * @see org.osgi.service.metatype.AttributeDefinition#getDescription() >- */ >- public String getDescription() { >- return getLocalized(_description); >- } >- >- /** >- * Method to set the description of AttributeDefinition. >- */ >- void setDescription(String description) { >- this._description = description; >- } >- >- /* >- * (non-Javadoc) >- * >- * @see org.osgi.service.metatype.AttributeDefinition#getCardinality() >- */ >- public int getCardinality() { >- return _cardinality; >- } >- >- /** >- * Method to set the cardinality of AttributeDefinition. >- */ >- void setCardinality(int cardinality) { >- this._cardinality = cardinality; >- } >- >- /* >- * (non-Javadoc) >- * >- * @see org.osgi.service.metatype.AttributeDefinition#getType() >- */ >- public int getType() { >- return _dataType; >- } >- >- /** >- * Method to set the data type of AttributeDefinition. >- */ >- void setType(int type) { >- this._dataType = type; >- } >- >- /** >- * Method to get the required flag of AttributeDefinition. >- */ >- boolean isRequired() { >- return _isRequired; >- } >- >- /** >- * Method to set the required flag of AttributeDefinition. >- */ >- void setRequired(boolean isRequired) { >- this._isRequired = isRequired; >- } >- >- /* >- * (non-Javadoc) >- * >- * @see org.osgi.service.metatype.AttributeDefinition#getOptionLabels() >- */ >- public String[] getOptionLabels() { >- >- if ((_labels == null) || (_labels.size() == 0)) { >- return null; >- } >- >- String[] returnedLabels = new String[_labels.size()]; >- Enumeration<String> labelKeys = _labels.elements(); >- int i = 0; >- while (labelKeys.hasMoreElements()) { >- String labelKey = labelKeys.nextElement(); >- returnedLabels[i] = getLocalized(labelKey); >- i++; >- } >- return returnedLabels; >- } >- >- /* >- * (non-Javadoc) >- * >- * @see org.osgi.service.metatype.AttributeDefinition#getOptionValues() >- */ >- public String[] getOptionValues() { >- >- if ((_values == null) || (_values.size() == 0)) { >- return null; >- } >- >- return _values.toArray(new String[_values.size()]); >- } >- >- /** >- * Method to set the Option values of AttributeDefinition. >- */ >- void setOption(Vector<String> labels, Vector<String> values, boolean needValidation) { >- if ((labels == null) || (values == null)) { >- logger.log(LogService.LOG_ERROR, "AttributeDefinitionImpl.setOption(Vector, Vector, boolean) " + MetaTypeMsg.NULL_OPTIONS); //$NON-NLS-1$ >- return; >- } >- if (labels.size() != values.size()) { >- logger.log(LogService.LOG_ERROR, "AttributeDefinitionImpl.setOption(Vector, Vector, boolean) " + MetaTypeMsg.INCONSISTENT_OPTIONS); //$NON-NLS-1$ >- return; >- } >- _labels = labels; >- _values = values; >- if (needValidation) { >- for (int index = 0; index < _values.size(); index++) { >- ValueTokenizer vt = new ValueTokenizer(_values.get(index), logger); >- _values.set(index, vt.getValuesAsString()); >- String reason = vt.validate(this); >- if ((reason != null) && reason.length() > 0) { >- logger.log(LogService.LOG_WARNING, NLS.bind(MetaTypeMsg.INVALID_OPTIONS, _values.get(index), reason)); >- _labels.remove(index); >- _values.remove(index); >- index--; // Because this one has been removed. >- } >- } >- } >- } >- >- /* >- * (non-Javadoc) >- * >- * @see org.osgi.service.metatype.AttributeDefinition#getDefaultValue() >- */ >- public String[] getDefaultValue() { >- return _defaults; >- } >- >- /** >- * Method to set the default value of AttributeDefinition. >- * The given parameter is a comma delimited list needed to be parsed. >- */ >- void setDefaultValue(String defaults_str, boolean needValidation) { >- ValueTokenizer vt = new ValueTokenizer(defaults_str, logger); >- String reason = vt.validate(this); >- if ((reason != null) && reason.length() > 0) { >- logger.log(LogService.LOG_WARNING, NLS.bind(MetaTypeMsg.INVALID_DEFAULTS, vt.getValuesAsString(), reason)); >- return; >- } >- setDefaultValue(vt.getValuesAsArray()); >- } >- >- /** >- * Method to set the default value of AttributeDefinition. >- * The given parameter is a String array of multi values. >- */ >- void setDefaultValue(String[] defaults) { >- _defaults = defaults; >- } >- >- /** >- * Method to set the validation value - min of AttributeDefinition. >- */ >- void setMinValue(Object minValue) { >- this._minValue = minValue; >- } >- >- /** >- * Method to set the validation value - max of AttributeDefinition. >- */ >- void setMaxValue(Object maxValue) { >- this._maxValue = maxValue; >- } >- >- /* >- * (non-Javadoc) >- * In order to be valid, a value must pass all of the following tests. >- * (1) The value must not be null. >- * (2) The value must be convertible into the attribute definition's type. >- * (3) The following relation must hold: min <= value <= max, if either min or max was specified. >- * (4) If options were specified, the value must be equal to one of them. >- * >- * Note this method will never return null to indicate there's no validation >- * present. The type compatibility check can always be performed. >- * >- * @see org.osgi.service.metatype.AttributeDefinition#validate(java.lang.String) >- */ >- public String validate(String value) { >- ValueTokenizer vt = new ValueTokenizer(value, logger); >- return vt.validate(this); >- } >-} >Index: src/org/eclipse/equinox/metatype/DataParser.java >=================================================================== >RCS file: src/org/eclipse/equinox/metatype/DataParser.java >diff -N src/org/eclipse/equinox/metatype/DataParser.java >--- src/org/eclipse/equinox/metatype/DataParser.java 1 Jul 2011 19:27:21 -0000 1.20 >+++ /dev/null 1 Jan 1970 00:00:00 -0000 >@@ -1,841 +0,0 @@ >-/******************************************************************************* >- * Copyright (c) 2005, 2011 IBM Corporation and others. >- * All rights reserved. This program and the accompanying materials >- * are made available under the terms of the Eclipse Public License v1.0 >- * which accompanies this distribution, and is available at >- * http://www.eclipse.org/legal/epl-v10.html >- * >- * Contributors: >- * IBM Corporation - initial API and implementation >- *******************************************************************************/ >-package org.eclipse.equinox.metatype; >- >-import java.io.*; >-import java.math.BigDecimal; >-import java.math.BigInteger; >-import java.net.URL; >-import java.util.*; >-import javax.xml.parsers.*; >-import org.eclipse.osgi.util.NLS; >-import org.osgi.framework.Bundle; >-import org.osgi.service.log.LogService; >-import org.osgi.service.metatype.AttributeDefinition; >-import org.xml.sax.*; >-import org.xml.sax.helpers.DefaultHandler; >- >-/** >- * Meta XML Data Parser >- */ >-public class DataParser { >- private static final String METADATA = "MetaData"; //$NON-NLS-1$ >- private static final String LOCALIZATION = "localization"; //$NON-NLS-1$ >- private static final String OCD = "OCD"; //$NON-NLS-1$ >- private static final String ICON = "Icon"; //$NON-NLS-1$ >- private static final String AD = "AD"; //$NON-NLS-1$ >- private static final String CARDINALITY = "cardinality"; //$NON-NLS-1$ >- private static final String OPTION = "Option"; //$NON-NLS-1$ >- private static final String LABEL = "label"; //$NON-NLS-1$ >- private static final String VALUE = "value"; //$NON-NLS-1$ >- private static final String MIN = "min"; //$NON-NLS-1$ >- private static final String MAX = "max"; //$NON-NLS-1$ >- private static final String TYPE = "type"; //$NON-NLS-1$ >- private static final String SIZE = "size"; //$NON-NLS-1$ >- private static final String ID = "id"; //$NON-NLS-1$ >- private static final String NAME = "name"; //$NON-NLS-1$ >- private static final String DESCRIPTION = "description"; //$NON-NLS-1$ >- private static final String RESOURCE = "resource"; //$NON-NLS-1$ >- private static final String PID = "pid"; //$NON-NLS-1$ >- private static final String DEFAULT = "default"; //$NON-NLS-1$ >- private static final String ADREF = "adref"; //$NON-NLS-1$ >- private static final String CONTENT = "content"; //$NON-NLS-1$ >- private static final String FACTORY = "factoryPid"; //$NON-NLS-1$ >- private static final String BUNDLE = "bundle"; //$NON-NLS-1$ >- private static final String OPTIONAL = "optional"; //$NON-NLS-1$ >- private static final String OBJECT = "Object"; //$NON-NLS-1$ >- private static final String OCDREF = "ocdref"; //$NON-NLS-1$ >- private static final String ATTRIBUTE = "Attribute"; //$NON-NLS-1$ >- private static final String DESIGNATE = "Designate"; //$NON-NLS-1$ >- private static final String MERGE = "merge"; //$NON-NLS-1$ >- private static final String REQUIRED = "required"; //$NON-NLS-1$ >- >- private static final String INTEGER = "Integer"; //$NON-NLS-1$ >- private static final String STRING = "String"; //$NON-NLS-1$ >- private static final String FLOAT = "Float"; //$NON-NLS-1$ >- private static final String DOUBLE = "Double"; //$NON-NLS-1$ >- private static final String BYTE = "Byte"; //$NON-NLS-1$ >- private static final String LONG = "Long"; //$NON-NLS-1$ >- private static final String CHAR = "Char"; //$NON-NLS-1$ >- private static final String BOOLEAN = "Boolean"; //$NON-NLS-1$ >- private static final String SHORT = "Short"; //$NON-NLS-1$ >- private static final String PASSWORD = "Password"; //$NON-NLS-1$ >- >- protected Bundle _dp_bundle; >- protected URL _dp_url; >- protected SAXParserFactory _dp_parserFactory; >- protected XMLReader _dp_xmlReader; >- >- // DesignateHanders in DataParser class >- Vector<DesignateHandler> _dp_designateHandlers = new Vector<DesignateHandler>(7); >- // ObjectClassDefinitions in DataParser class w/ corresponding reference keys >- Hashtable<String, ObjectClassDefinitionImpl> _dp_OCDs = new Hashtable<String, ObjectClassDefinitionImpl>(7); >- // Localization in DataParser class >- String _dp_localization; >- >- // Default visibility to avoid a plethora of synthetic accessor method warnings. >- final LogService logger; >- final Collection<Designate> designates = new ArrayList<Designate>(7); >- >- /* >- * Constructor of class DataParser. >- */ >- public DataParser(Bundle bundle, URL url, SAXParserFactory parserFactory, LogService logger) { >- >- this._dp_bundle = bundle; >- this._dp_url = url; >- this._dp_parserFactory = parserFactory; >- parserFactory.setValidating(false); >- this.logger = logger; >- } >- >- /* >- * Main method to parse specific MetaData file. >- */ >- public Collection<Designate> doParse() throws IOException, ParserConfigurationException, SAXException { >- SAXParser saxParser = _dp_parserFactory.newSAXParser(); >- _dp_xmlReader = saxParser.getXMLReader(); >- _dp_xmlReader.setContentHandler(new RootHandler()); >- _dp_xmlReader.setErrorHandler(new MyErrorHandler(System.err)); >- InputStream is = _dp_url.openStream(); >- InputSource isource = new InputSource(is); >- logger.log(LogService.LOG_DEBUG, "Starting to parse " + _dp_url); //$NON-NLS-1$ >- _dp_xmlReader.parse(isource); >- return designates; >- } >- >- /* >- * Convert String for expected data type. >- */ >- static Object convert(String value, int type) { >- >- if (value == null) { >- return null; >- } >- >- switch (type) { >- // PASSWORD should be treated like STRING. >- case AttributeDefinition.PASSWORD : >- case AttributeDefinition.STRING : >- // Both the min and max of STRING are Integers. >- return new Integer(value); >- case AttributeDefinition.LONG : >- return new Long(value); >- case AttributeDefinition.INTEGER : >- return new Integer(value); >- case AttributeDefinition.SHORT : >- return new Short(value); >- case AttributeDefinition.CHARACTER : >- return new Character(value.charAt(0)); >- case AttributeDefinition.BYTE : >- return new Byte(value); >- case AttributeDefinition.DOUBLE : >- return new Double(value); >- case AttributeDefinition.FLOAT : >- return new Float(value); >- case AttributeDefinition.BIGINTEGER : >- return new BigInteger(value); >- case AttributeDefinition.BIGDECIMAL : >- return new BigDecimal(value); >- case AttributeDefinition.BOOLEAN : >- return new Boolean(value); >- default : >- // Unknown data type >- return null; >- } >- } >- >- /** >- * Abstract of all Handlers. >- */ >- private class AbstractHandler extends DefaultHandler { >- >- protected ContentHandler _doc_handler; >- protected boolean _isParsedDataValid = true; >- >- public AbstractHandler(ContentHandler parentHandler) { >- >- this._doc_handler = parentHandler; >- _dp_xmlReader.setContentHandler(this); >- } >- >- public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException { >- >- throw new SAXException(NLS.bind(MetaTypeMsg.UNEXPECTED_ELEMENT, qName)); >- } >- >- public void characters(char[] buf, int start, int end) throws SAXException { >- >- String s = new String(buf, start, end).trim(); >- if (s.length() > 0) { >- throw new SAXException(NLS.bind(MetaTypeMsg.UNEXPECTED_TEXT, s)); >- } >- } >- >- /** >- * Called when this element and all elements nested into it have been >- * handled. >- */ >- protected void finished() { >- // do nothing by default >- } >- >- public void endElement(String namespaceURI, String localName, String qName) { >- >- finished(); >- // Let parent resume handling SAX events >- _dp_xmlReader.setContentHandler(_doc_handler); >- } >- } >- >- /** >- * Handler for the root element. >- */ >- private class RootHandler extends DefaultHandler { >- >- public RootHandler() { >- super(); >- } >- >- public void startElement(String uri, String localName, String qName, Attributes attributes) { >- >- logger.log(LogService.LOG_DEBUG, "Here is AbstractHandler:startElement():" //$NON-NLS-1$ >- + qName); >- String name = getName(localName, qName); >- if (name.equalsIgnoreCase(METADATA)) { >- new MetaDataHandler(this).init(name, attributes); >- } else { >- logger.log(LogService.LOG_WARNING, NLS.bind(MetaTypeMsg.UNEXPECTED_ELEMENT, name)); >- } >- } >- >- public void setDocumentLocator(Locator locator) { >- // do nothing >- } >- } >- >- /** >- * Handler for the MetaData element. >- */ >- private class MetaDataHandler extends AbstractHandler { >- >- public MetaDataHandler(ContentHandler handler) { >- super(handler); >- } >- >- public void init(String name, Attributes attributes) { >- >- logger.log(LogService.LOG_DEBUG, "Here is MetaDataHandler():init()"); //$NON-NLS-1$ >- _dp_localization = attributes.getValue(LOCALIZATION); >- if (_dp_localization == null) { >- // Not a problem, because LOCALIZATION is an optional attribute. >- } >- // The global variable "_dp_localization" will be used within >- // OcdHandler and AttributeDefinitionHandler later. >- } >- >- public void startElement(String uri, String localName, String qName, Attributes atts) { >- >- logger.log(LogService.LOG_DEBUG, "Here is MetaDataHandler:startElement():" //$NON-NLS-1$ >- + qName); >- String name = getName(localName, qName); >- if (name.equalsIgnoreCase(DESIGNATE)) { >- DesignateHandler designateHandler = new DesignateHandler(this); >- designateHandler.init(name, atts); >- if (designateHandler._isParsedDataValid) { >- _dp_designateHandlers.addElement(designateHandler); >- } >- } else if (name.equalsIgnoreCase(OCD)) { >- OcdHandler ocdHandler = new OcdHandler(this); >- ocdHandler.init(name, atts, _dp_OCDs); >- } else { >- logger.log(LogService.LOG_WARNING, NLS.bind(MetaTypeMsg.UNEXPECTED_ELEMENT, name)); >- } >- } >- >- protected void finished() { >- >- logger.log(LogService.LOG_DEBUG, "Here is MetaDataHandler():finished()"); //$NON-NLS-1$ >- if (_dp_designateHandlers.size() == 0) { >- // Schema defines at least one DESIGNATE is required. >- _isParsedDataValid = false; >- logger.log(LogService.LOG_WARNING, "DataParser.finished() " + NLS.bind(MetaTypeMsg.MISSING_ELEMENT, DESIGNATE)); //$NON-NLS-1$ >- return; >- } >- Enumeration<DesignateHandler> designateHandlerKeys = _dp_designateHandlers.elements(); >- while (designateHandlerKeys.hasMoreElements()) { >- DesignateHandler dh = designateHandlerKeys.nextElement(); >- >- ObjectClassDefinitionImpl ocd = _dp_OCDs.get(dh._ocdref); >- if (ocd != null) { >- designates.add(new Designate.Builder(ocd).bundle(dh._bundle_val).factoryPid(dh._factory_val).merge(dh._merge_val).pid(dh._pid_val).optional(dh._optional_val).build()); >- } else { >- logger.log(LogService.LOG_ERROR, "DataParser.finished() " + NLS.bind(MetaTypeMsg.OCD_ID_NOT_FOUND, dh._ocdref)); //$NON-NLS-1$ >- >- } >- } >- } >- } >- >- /** >- * Handler for the ObjectClassDefinition element. >- */ >- private class OcdHandler extends AbstractHandler { >- >- Hashtable<String, ObjectClassDefinitionImpl> _parent_OCDs_hashtable; >- // This ID "_refID" is only used for reference by Designate element, >- // not the PID or FPID of this OCD. >- String _refID; >- ObjectClassDefinitionImpl _ocd; >- Vector<AttributeDefinitionImpl> _ad_vector = new Vector<AttributeDefinitionImpl>(7); >- >- public OcdHandler(ContentHandler handler) { >- super(handler); >- } >- >- public void init(String name, Attributes atts, Hashtable<String, ObjectClassDefinitionImpl> ocds_hashtable) { >- >- logger.log(LogService.LOG_DEBUG, "Here is OcdHandler():init()"); //$NON-NLS-1$ >- _parent_OCDs_hashtable = ocds_hashtable; >- >- String ocd_name_val = atts.getValue(NAME); >- if (ocd_name_val == null) { >- _isParsedDataValid = false; >- logger.log(LogService.LOG_ERROR, "DataParser.init(String, Attributes, Hashtable) " + NLS.bind(MetaTypeMsg.MISSING_ATTRIBUTE, NAME, name)); //$NON-NLS-1$ >- return; >- } >- >- String ocd_description_val = atts.getValue(DESCRIPTION); >- if (ocd_description_val == null) { >- // Not a problem, because DESCRIPTION is an optional attribute. >- } >- >- _refID = atts.getValue(ID); >- if (_refID == null) { >- _isParsedDataValid = false; >- logger.log(LogService.LOG_ERROR, "DataParser.init(String, Attributes, Hashtable) " + NLS.bind(MetaTypeMsg.MISSING_ATTRIBUTE, ID, name)); //$NON-NLS-1$ >- return; >- } >- >- _ocd = new ObjectClassDefinitionImpl(ocd_name_val, ocd_description_val, _refID, _dp_localization); >- } >- >- public void startElement(String uri, String localName, String qName, Attributes atts) { >- >- logger.log(LogService.LOG_DEBUG, "Here is OcdHandler:startElement():" //$NON-NLS-1$ >- + qName); >- if (!_isParsedDataValid) >- return; >- >- String name = getName(localName, qName); >- if (name.equalsIgnoreCase(AD)) { >- AttributeDefinitionHandler attributeDefHandler = new AttributeDefinitionHandler(this); >- attributeDefHandler.init(name, atts, _ad_vector); >- } else if (name.equalsIgnoreCase(ICON)) { >- IconHandler iconHandler = new IconHandler(this); >- iconHandler.init(name, atts); >- if (iconHandler._isParsedDataValid) { >- // Because XML schema allows at most one icon for >- // one OCD, if more than one icons are read from >- // MetaData, then only the final icon will be kept. >- _ocd.setIcon(iconHandler._icon); >- } >- } else { >- logger.log(LogService.LOG_WARNING, NLS.bind(MetaTypeMsg.UNEXPECTED_ELEMENT, name)); >- } >- } >- >- protected void finished() { >- >- logger.log(LogService.LOG_DEBUG, "Here is OcdHandler():finished()"); //$NON-NLS-1$ >- if (!_isParsedDataValid) >- return; >- >- if (_ad_vector.size() == 0) { >- // Schema defines at least one AD is required. >- _isParsedDataValid = false; >- logger.log(LogService.LOG_ERROR, "DataParser.finished() " + NLS.bind(MetaTypeMsg.MISSING_ELEMENT, AD, _refID)); //$NON-NLS-1$ >- return; >- } >- // OCD gets all parsed ADs. >- Enumeration<AttributeDefinitionImpl> adKey = _ad_vector.elements(); >- while (adKey.hasMoreElements()) { >- AttributeDefinitionImpl ad = adKey.nextElement(); >- _ocd.addAttributeDefinition(ad, ad._isRequired); >- } >- >- _parent_OCDs_hashtable.put(_refID, _ocd); >- } >- } >- >- /** >- * Handler for the Icon element. >- */ >- private class IconHandler extends AbstractHandler { >- >- Icon _icon; >- >- public IconHandler(ContentHandler handler) { >- super(handler); >- } >- >- public void init(String name, Attributes atts) { >- >- logger.log(LogService.LOG_DEBUG, "Here is IconHandler:init()"); //$NON-NLS-1$ >- String icon_resource_val = atts.getValue(RESOURCE); >- if (icon_resource_val == null) { >- _isParsedDataValid = false; >- logger.log(LogService.LOG_ERROR, "DataParser.init(String, Attributes) " + NLS.bind(MetaTypeMsg.MISSING_ATTRIBUTE, RESOURCE, name)); //$NON-NLS-1$ >- return; >- } >- >- String icon_size_val = atts.getValue(SIZE); >- if (icon_size_val == null) { >- // Not a problem, because SIZE is an optional attribute. >- icon_size_val = "0"; //$NON-NLS-1$ >- } else if (icon_size_val.equalsIgnoreCase("")) { //$NON-NLS-1$ >- icon_size_val = "0"; //$NON-NLS-1$ >- } >- >- _icon = new Icon(icon_resource_val, Integer.parseInt(icon_size_val), _dp_bundle); >- } >- } >- >- /** >- * Handler for the Attribute element. >- */ >- private class AttributeDefinitionHandler extends AbstractHandler { >- >- AttributeDefinitionImpl _ad; >- int _dataType; >- >- Vector<AttributeDefinitionImpl> _parent_ADs_vector; >- Vector<String> _optionLabel_vector = new Vector<String>(7); >- Vector<String> _optionValue_vector = new Vector<String>(7); >- >- public AttributeDefinitionHandler(ContentHandler handler) { >- super(handler); >- } >- >- public void init(String name, Attributes atts, Vector<AttributeDefinitionImpl> ad_vector) { >- >- logger.log(LogService.LOG_DEBUG, "Here is AttributeDefinitionHandler():init()"); //$NON-NLS-1$ >- _parent_ADs_vector = ad_vector; >- >- String ad_name_val = atts.getValue(NAME); >- if (ad_name_val == null) { >- // Not a problem, because NAME is an optional attribute. >- } >- >- String ad_description_val = atts.getValue(DESCRIPTION); >- if (ad_description_val == null) { >- // Not a problem, because DESCRIPTION is an optional attribute. >- } >- >- String ad_id_val = atts.getValue(ID); >- if (ad_id_val == null) { >- _isParsedDataValid = false; >- logger.log(LogService.LOG_ERROR, "DataParser.init(String, Attributes, Vector) " + NLS.bind(MetaTypeMsg.MISSING_ATTRIBUTE, ID, name)); //$NON-NLS-1$ >- return; >- } >- >- String ad_type_val = atts.getValue(TYPE); >- if (ad_type_val == null) { >- _isParsedDataValid = false; >- logger.log(LogService.LOG_ERROR, "DataParser.init(String, Attributes, Vector) " + NLS.bind(MetaTypeMsg.MISSING_ATTRIBUTE, TYPE, name)); //$NON-NLS-1$ >- return; >- } >- if (ad_type_val.equalsIgnoreCase(STRING)) { >- _dataType = AttributeDefinition.STRING; >- } else if (ad_type_val.equalsIgnoreCase(LONG)) { >- _dataType = AttributeDefinition.LONG; >- } else if (ad_type_val.equalsIgnoreCase(DOUBLE)) { >- _dataType = AttributeDefinition.DOUBLE; >- } else if (ad_type_val.equalsIgnoreCase(FLOAT)) { >- _dataType = AttributeDefinition.FLOAT; >- } else if (ad_type_val.equalsIgnoreCase(INTEGER)) { >- _dataType = AttributeDefinition.INTEGER; >- } else if (ad_type_val.equalsIgnoreCase(BYTE)) { >- _dataType = AttributeDefinition.BYTE; >- } else if (ad_type_val.equalsIgnoreCase(CHAR)) { >- _dataType = AttributeDefinition.CHARACTER; >- } else if (ad_type_val.equalsIgnoreCase(BOOLEAN)) { >- _dataType = AttributeDefinition.BOOLEAN; >- } else if (ad_type_val.equalsIgnoreCase(SHORT)) { >- _dataType = AttributeDefinition.SHORT; >- } else if (ad_type_val.equalsIgnoreCase(PASSWORD)) { >- _dataType = AttributeDefinition.PASSWORD; >- } else { >- _isParsedDataValid = false; >- logger.log(LogService.LOG_ERROR, "DataParser.init(String, Attributes, Vector) " + NLS.bind(MetaTypeMsg.INVALID_TYPE, new Object[] {ad_type_val, _dp_url, _dp_bundle.getBundleId()})); //$NON-NLS-1$ >- return; >- } >- >- String ad_cardinality_str = atts.getValue(CARDINALITY); >- int ad_cardinality_val = 0; >- if (ad_cardinality_str == null) { >- // Not a problem, because CARDINALITY is an optional attribute. >- // And the default value is 0. >- } else { >- ad_cardinality_val = Integer.parseInt(ad_cardinality_str); >- } >- >- String ad_min_val = atts.getValue(MIN); >- if (ad_min_val == null) { >- // Not a problem, because MIN is an optional attribute. >- } >- >- String ad_max_val = atts.getValue(MAX); >- if (ad_max_val == null) { >- // Not a problem, because MAX is an optional attribute. >- } >- >- String ad_defaults_str = atts.getValue(DEFAULT); >- if (ad_defaults_str == null) { >- // Not a problem, because DEFAULT is an optional attribute. >- } >- >- String ad_required_val = atts.getValue(REQUIRED); >- if (ad_required_val == null) { >- // Not a problem, because REQUIRED is an optional attribute. >- // And the default value is 'true'. >- ad_required_val = Boolean.TRUE.toString(); >- } >- >- _ad = new AttributeDefinitionImpl(ad_id_val, ad_name_val, ad_description_val, _dataType, ad_cardinality_val, convert(ad_min_val, _dataType), convert(ad_max_val, _dataType), Boolean.valueOf(ad_required_val).booleanValue(), _dp_localization, logger); >- >- if (ad_defaults_str != null) { >- _ad.setDefaultValue(ad_defaults_str, true); >- } >- } >- >- public void startElement(String uri, String localName, String qName, Attributes atts) { >- >- logger.log(LogService.LOG_DEBUG, "Here is AttributeDefinitionHandler:startElement():" //$NON-NLS-1$ >- + qName); >- if (!_isParsedDataValid) >- return; >- >- String name = getName(localName, qName); >- if (name.equalsIgnoreCase(OPTION)) { >- OptionHandler optionHandler = new OptionHandler(this); >- optionHandler.init(name, atts); >- if (optionHandler._isParsedDataValid) { >- // Only add valid Option >- _optionLabel_vector.addElement(optionHandler._label_val); >- _optionValue_vector.addElement(optionHandler._value_val); >- } >- } else { >- logger.log(LogService.LOG_WARNING, NLS.bind(MetaTypeMsg.UNEXPECTED_ELEMENT, name)); >- } >- } >- >- protected void finished() { >- >- logger.log(LogService.LOG_DEBUG, "Here is AttributeDefinitionHandler():finished()"); //$NON-NLS-1$ >- if (!_isParsedDataValid) >- return; >- >- _ad.setOption(_optionLabel_vector, _optionValue_vector, true); >- _parent_ADs_vector.addElement(_ad); >- } >- } >- >- /** >- * Handler for the Option element. >- */ >- private class OptionHandler extends AbstractHandler { >- >- String _label_val; >- String _value_val; >- >- public OptionHandler(ContentHandler handler) { >- super(handler); >- } >- >- public void init(String name, Attributes atts) { >- >- logger.log(LogService.LOG_DEBUG, "Here is OptionHandler:init()"); //$NON-NLS-1$ >- _label_val = atts.getValue(LABEL); >- if (_label_val == null) { >- _isParsedDataValid = false; >- logger.log(LogService.LOG_ERROR, "DataParser.init(String, Attributes) " + NLS.bind(MetaTypeMsg.MISSING_ATTRIBUTE, LABEL, name)); //$NON-NLS-1$ >- return; >- } >- >- _value_val = atts.getValue(VALUE); >- if (_value_val == null) { >- _isParsedDataValid = false; >- logger.log(LogService.LOG_ERROR, "DataParser.init(String, Attributes) " + NLS.bind(MetaTypeMsg.MISSING_ATTRIBUTE, VALUE, name)); //$NON-NLS-1$ >- return; >- } >- } >- } >- >- // /** >- // * Handler for the Simple Value element. >- // */ >- // private class SimpleValueHandler extends AbstractHandler { >- // >- // StringBuffer _buffer = new StringBuffer(); >- // Vector _parent_value_vector; >- // String _elementName; >- // >- // public SimpleValueHandler(ContentHandler handler) { >- // super(handler); >- // } >- // >- // public void init(String name, Attributes atts, Vector value_vector) >- // throws SAXException { >- // >- // Logging.log(LogService.LOG_DEBUG, >- // "Here is SimpleValueHandler():init()"); //$NON-NLS-1$ >- // _elementName = name; >- // _parent_value_vector = value_vector; >- // } >- // >- // protected void finished() throws SAXException { >- // >- // Logging.log(LogService.LOG_DEBUG, >- // "Here is SimpleValueHandler():finished()"); //$NON-NLS-1$ >- // if (_parent_value_vector != null) { >- // _parent_value_vector.addElement(_buffer.toString()); >- // } >- // } >- // >- // public void characters(char buf[], int offset, int len) >- // throws SAXException { >- // >- // Logging.log(LogService.LOG_DEBUG, >- // "Here is SimpleValueHandler(" //$NON-NLS-1$ >- // + _elementName >- // + "):characters():[" //$NON-NLS-1$ >- // + new String(buf, offset, len) >- // + "]"); //$NON-NLS-1$ >- // _buffer.append(new String(buf, offset, len)); >- // } >- // } >- >- /** >- * Handler for the Designate element. >- */ >- class DesignateHandler extends AbstractHandler { >- >- String _pid_val = null; >- String _factory_val = null; >- String _bundle_val = null; // Only used by RFC94 >- boolean _optional_val = false; // Only used by RFC94 >- boolean _merge_val = false; // Only used by RFC94 >- >- // Referenced OCD ID >- String _ocdref; >- >- public DesignateHandler(ContentHandler handler) { >- super(handler); >- } >- >- public void init(String name, Attributes atts) { >- >- logger.log(LogService.LOG_DEBUG, "Here is DesignateHandler():init()"); //$NON-NLS-1$ >- _pid_val = atts.getValue(PID); >- _factory_val = atts.getValue(FACTORY); >- if (_pid_val == null && _factory_val == null) { >- _isParsedDataValid = false; >- logger.log(LogService.LOG_ERROR, MetaTypeMsg.MISSING_DESIGNATE_PID_AND_FACTORYPID); >- return; >- } >- >- _bundle_val = atts.getValue(BUNDLE); >- if (_bundle_val == null) { >- // Not a problem because BUNDLE is an optional attribute. >- } >- >- String optional_str = atts.getValue(OPTIONAL); >- if (optional_str == null) { >- // Not a problem, because OPTIONAL is an optional attribute. >- // The default value is "false". >- _optional_val = false; >- } else { >- _optional_val = Boolean.valueOf(optional_str).booleanValue(); >- } >- >- String merge_str = atts.getValue(MERGE); >- if (merge_str == null) { >- // Not a problem, because MERGE is an optional attribute. >- // The default value is "false". >- _merge_val = false; >- } else { >- _merge_val = Boolean.valueOf(merge_str).booleanValue(); >- } >- } >- >- public void startElement(String uri, String localName, String qName, Attributes atts) { >- >- logger.log(LogService.LOG_DEBUG, "Here is DesignateHandler:startElement():" //$NON-NLS-1$ >- + qName); >- if (!_isParsedDataValid) >- return; >- >- String name = getName(localName, qName); >- if (name.equalsIgnoreCase(OBJECT)) { >- ObjectHandler objectHandler = new ObjectHandler(this); >- objectHandler.init(name, atts); >- if (objectHandler._isParsedDataValid) { >- _ocdref = objectHandler._ocdref; >- } >- } else { >- logger.log(LogService.LOG_WARNING, NLS.bind(MetaTypeMsg.UNEXPECTED_ELEMENT, name)); >- } >- } >- >- protected void finished() { >- >- logger.log(LogService.LOG_DEBUG, "Here is DesignateHandler():finished()"); //$NON-NLS-1$ >- if (!_isParsedDataValid) >- return; >- >- if (_ocdref == null) { >- _isParsedDataValid = false; >- // Schema defines at least one OBJECT is required. >- logger.log(LogService.LOG_ERROR, "DataParser.finished() " + NLS.bind(MetaTypeMsg.MISSING_ELEMENT, OBJECT, _pid_val)); //$NON-NLS-1$ >- return; >- >- } >- } >- } >- >- /** >- * Handler for the Object element. >- */ >- private class ObjectHandler extends AbstractHandler { >- >- String _ocdref; >- >- public ObjectHandler(ContentHandler handler) { >- super(handler); >- } >- >- public void init(String name, Attributes atts) { >- >- logger.log(LogService.LOG_DEBUG, "Here is ObjectHandler():init()"); //$NON-NLS-1$ >- _ocdref = atts.getValue(OCDREF); >- if (_ocdref == null) { >- _isParsedDataValid = false; >- logger.log(LogService.LOG_ERROR, "DataParser.init(String, Attributes) " + NLS.bind(MetaTypeMsg.MISSING_ATTRIBUTE, OCDREF, name)); //$NON-NLS-1$ >- return; >- } >- } >- >- public void startElement(String uri, String localName, String qName, Attributes atts) { >- >- logger.log(LogService.LOG_DEBUG, "Here is ObjectHandler:startElement():" //$NON-NLS-1$ >- + qName); >- if (!_isParsedDataValid) >- return; >- >- String name = getName(localName, qName); >- if (name.equalsIgnoreCase(ATTRIBUTE)) { >- AttributeHandler attributeHandler = new AttributeHandler(this); >- attributeHandler.init(name, atts); >- // The ATTRIBUTE element is only used by RFC94, do nothing for it here. >- } else { >- logger.log(LogService.LOG_WARNING, NLS.bind(MetaTypeMsg.UNEXPECTED_ELEMENT, name)); >- } >- } >- } >- >- /** >- * Handler for the Attribute element. >- * >- * This Handler is only used by RFC94. >- */ >- private class AttributeHandler extends AbstractHandler { >- >- String _adref_val; >- String _content_val; >- >- public AttributeHandler(ContentHandler handler) { >- super(handler); >- } >- >- public void init(String name, Attributes atts) { >- >- logger.log(LogService.LOG_DEBUG, "Here is AttributeHandler():init()"); //$NON-NLS-1$ >- _adref_val = atts.getValue(ADREF); >- if (_adref_val == null) { >- _isParsedDataValid = false; >- logger.log(LogService.LOG_ERROR, "DataParser.init(String, Attributes) " + NLS.bind(MetaTypeMsg.MISSING_ATTRIBUTE, ADREF, name)); //$NON-NLS-1$ >- return; >- } >- >- _content_val = atts.getValue(CONTENT); >- if (_content_val == null) { >- _isParsedDataValid = false; >- logger.log(LogService.LOG_ERROR, "DataParser.init(String, Attributes) " + NLS.bind(MetaTypeMsg.MISSING_ATTRIBUTE, CONTENT, name)); //$NON-NLS-1$ >- return; >- } >- } >- } >- >- /** >- * Error Handler to report errors and warnings >- */ >- private static class MyErrorHandler implements ErrorHandler { >- >- /** Error handler output goes here */ >- private PrintStream _out; >- >- MyErrorHandler(PrintStream out) { >- this._out = out; >- } >- >- /** >- * Returns a string describing parse exception details >- */ >- private String getParseExceptionInfo(SAXParseException spe) { >- String systemId = spe.getSystemId(); >- if (systemId == null) { >- systemId = "null"; //$NON-NLS-1$ >- } >- String info = "URI=" + systemId + //$NON-NLS-1$ >- " Line=" + spe.getLineNumber() + //$NON-NLS-1$ >- ": " + spe.getMessage(); //$NON-NLS-1$ >- >- return info; >- } >- >- // The following methods are standard SAX ErrorHandler methods. >- // See SAX documentation for more info. >- >- public void warning(SAXParseException spe) { >- _out.println("Warning: " + getParseExceptionInfo(spe)); //$NON-NLS-1$ >- } >- >- public void error(SAXParseException spe) throws SAXException { >- String message = "Error: " + getParseExceptionInfo(spe); //$NON-NLS-1$ >- throw new SAXException(message); >- } >- >- public void fatalError(SAXParseException spe) throws SAXException { >- String message = "Fatal Error: " + getParseExceptionInfo(spe); //$NON-NLS-1$ >- throw new SAXException(message); >- } >- } >- >- public static String getName(String localName, String qName) { >- if (localName != null && localName.length() > 0) { >- return localName; >- } >- >- int nameSpaceIndex = qName.indexOf(":"); //$NON-NLS-1$ >- return nameSpaceIndex == -1 ? qName : qName.substring(nameSpaceIndex + 1); >- } >-} >Index: src/org/eclipse/equinox/metatype/Designate.java >=================================================================== >RCS file: src/org/eclipse/equinox/metatype/Designate.java >diff -N src/org/eclipse/equinox/metatype/Designate.java >--- src/org/eclipse/equinox/metatype/Designate.java 6 Apr 2011 16:32:54 -0000 1.3 >+++ /dev/null 1 Jan 1970 00:00:00 -0000 >@@ -1,104 +0,0 @@ >-/******************************************************************************* >- * Copyright (c) 2011 IBM Corporation and others. >- * All rights reserved. This program and the accompanying materials >- * are made available under the terms of the Eclipse Public License v1.0 >- * which accompanies this distribution, and is available at >- * http://www.eclipse.org/legal/epl-v10.html >- * >- * Contributors: >- * IBM Corporation - initial API and implementation >- *******************************************************************************/ >-package org.eclipse.equinox.metatype; >- >-import org.eclipse.osgi.util.NLS; >- >-public class Designate { >- public static class Builder { >- String bundle; >- String factoryPid; >- boolean merge; >- ObjectClassDefinitionImpl ocd; >- boolean optional; >- String pid; >- >- public Builder(ObjectClassDefinitionImpl ocd) { >- if (ocd == null) { >- throw new IllegalArgumentException(NLS.bind(MetaTypeMsg.MISSING_REQUIRED_PARAMETER, "ocd")); //$NON-NLS-1$ >- } >- this.ocd = ocd; >- } >- >- public Designate build() { >- return new Designate(this); >- } >- >- public Builder bundle(String value) { >- bundle = value; >- return this; >- } >- >- public Builder factoryPid(String value) { >- factoryPid = value; >- return this; >- } >- >- public Builder merge(boolean value) { >- merge = value; >- return this; >- } >- >- public Builder optional(boolean value) { >- optional = value; >- return this; >- } >- >- public Builder pid(String value) { >- pid = value; >- return this; >- } >- } >- >- private final String bundle; >- private final String factoryPid; >- private final boolean merge; >- private final ObjectClassDefinitionImpl ocd; >- private final boolean optional; >- private final String pid; >- >- Designate(Builder b) { >- bundle = b.bundle; >- factoryPid = b.factoryPid; >- merge = b.merge; >- ocd = b.ocd; >- optional = b.optional; >- pid = b.pid; >- } >- >- public String getBundle() { >- return bundle; >- } >- >- public String getFactoryPid() { >- return factoryPid; >- } >- >- public boolean isFactory() { >- return factoryPid != null && factoryPid.length() != 0; >- } >- >- public boolean isMerge() { >- return merge; >- } >- >- public ObjectClassDefinitionImpl getObjectClassDefinition() { >- return ocd; >- } >- >- public boolean isOptional() { >- return optional; >- } >- >- public String getPid() { >- return pid; >- } >-} >Index: src/org/eclipse/equinox/metatype/EquinoxAttributeDefinition.java >=================================================================== >RCS file: src/org/eclipse/equinox/metatype/EquinoxAttributeDefinition.java >diff -N src/org/eclipse/equinox/metatype/EquinoxAttributeDefinition.java >--- /dev/null 1 Jan 1970 00:00:00 -0000 >+++ src/org/eclipse/equinox/metatype/EquinoxAttributeDefinition.java 1 Jan 1970 00:00:00 -0000 >@@ -0,0 +1,19 @@ >+/******************************************************************************* >+ * Copyright (c) 2011 IBM Corporation and others >+ * All rights reserved. This program and the accompanying materials are made >+ * available under the terms of the Eclipse Public License v1.0 which >+ * accompanies this distribution, and is available at >+ * http://www.eclipse.org/legal/epl-v10.html >+ ******************************************************************************/ >+package org.eclipse.equinox.metatype; >+ >+import org.osgi.service.metatype.AttributeDefinition; >+ >+/** >+ * >+ * @since 1.2 >+ * >+ */ >+public interface EquinoxAttributeDefinition extends AttributeDefinition, Extendable { >+ // Empty interface to support extendable attribute definitions. >+} >Index: src/org/eclipse/equinox/metatype/EquinoxMetaTypeInformation.java >=================================================================== >RCS file: src/org/eclipse/equinox/metatype/EquinoxMetaTypeInformation.java >diff -N src/org/eclipse/equinox/metatype/EquinoxMetaTypeInformation.java >--- /dev/null 1 Jan 1970 00:00:00 -0000 >+++ src/org/eclipse/equinox/metatype/EquinoxMetaTypeInformation.java 1 Jan 1970 00:00:00 -0000 >@@ -0,0 +1,19 @@ >+/******************************************************************************* >+ * Copyright (c) 2011 IBM Corporation and others >+ * All rights reserved. This program and the accompanying materials are made >+ * available under the terms of the Eclipse Public License v1.0 which >+ * accompanies this distribution, and is available at >+ * http://www.eclipse.org/legal/epl-v10.html >+ ******************************************************************************/ >+package org.eclipse.equinox.metatype; >+ >+import org.osgi.service.metatype.MetaTypeInformation; >+ >+/** >+ * >+ * @since 1.2 >+ * >+ */ >+public interface EquinoxMetaTypeInformation extends MetaTypeInformation { >+ EquinoxObjectClassDefinition getObjectClassDefinition(String id, String locale); >+} >Index: src/org/eclipse/equinox/metatype/EquinoxMetaTypeService.java >=================================================================== >RCS file: src/org/eclipse/equinox/metatype/EquinoxMetaTypeService.java >diff -N src/org/eclipse/equinox/metatype/EquinoxMetaTypeService.java >--- /dev/null 1 Jan 1970 00:00:00 -0000 >+++ src/org/eclipse/equinox/metatype/EquinoxMetaTypeService.java 1 Jan 1970 00:00:00 -0000 >@@ -0,0 +1,20 @@ >+/******************************************************************************* >+ * Copyright (c) 2011 IBM Corporation and others >+ * All rights reserved. This program and the accompanying materials are made >+ * available under the terms of the Eclipse Public License v1.0 which >+ * accompanies this distribution, and is available at >+ * http://www.eclipse.org/legal/epl-v10.html >+ ******************************************************************************/ >+package org.eclipse.equinox.metatype; >+ >+import org.osgi.framework.Bundle; >+import org.osgi.service.metatype.MetaTypeService; >+ >+/** >+ * >+ * @since 1.2 >+ * >+ */ >+public interface EquinoxMetaTypeService extends MetaTypeService { >+ EquinoxMetaTypeInformation getMetaTypeInformation(Bundle bundle); >+} >Index: src/org/eclipse/equinox/metatype/EquinoxObjectClassDefinition.java >=================================================================== >RCS file: src/org/eclipse/equinox/metatype/EquinoxObjectClassDefinition.java >diff -N src/org/eclipse/equinox/metatype/EquinoxObjectClassDefinition.java >--- /dev/null 1 Jan 1970 00:00:00 -0000 >+++ src/org/eclipse/equinox/metatype/EquinoxObjectClassDefinition.java 1 Jan 1970 00:00:00 -0000 >@@ -0,0 +1,19 @@ >+/******************************************************************************* >+ * Copyright (c) 2011 IBM Corporation and others >+ * All rights reserved. This program and the accompanying materials are made >+ * available under the terms of the Eclipse Public License v1.0 which >+ * accompanies this distribution, and is available at >+ * http://www.eclipse.org/legal/epl-v10.html >+ ******************************************************************************/ >+package org.eclipse.equinox.metatype; >+ >+import org.osgi.service.metatype.ObjectClassDefinition; >+ >+/** >+ * >+ * @since 1.2 >+ * >+ */ >+public interface EquinoxObjectClassDefinition extends ObjectClassDefinition, Extendable { >+ EquinoxAttributeDefinition[] getAttributeDefinitions(int filter); >+} >Index: src/org/eclipse/equinox/metatype/Extendable.java >=================================================================== >RCS file: src/org/eclipse/equinox/metatype/Extendable.java >diff -N src/org/eclipse/equinox/metatype/Extendable.java >--- /dev/null 1 Jan 1970 00:00:00 -0000 >+++ src/org/eclipse/equinox/metatype/Extendable.java 1 Jan 1970 00:00:00 -0000 >@@ -0,0 +1,22 @@ >+/******************************************************************************* >+ * Copyright (c) 2011 IBM Corporation and others >+ * All rights reserved. This program and the accompanying materials are made >+ * available under the terms of the Eclipse Public License v1.0 which >+ * accompanies this distribution, and is available at >+ * http://www.eclipse.org/legal/epl-v10.html >+ ******************************************************************************/ >+package org.eclipse.equinox.metatype; >+ >+import java.util.Map; >+import java.util.Set; >+ >+/** >+ * >+ * @since 1.2 >+ * >+ */ >+public interface Extendable { >+ Map<String, String> getExtensionAttributes(String uri); >+ >+ Set<String> getExtensionUris(); >+} >Index: src/org/eclipse/equinox/metatype/ExternalMessages.properties >=================================================================== >RCS file: src/org/eclipse/equinox/metatype/ExternalMessages.properties >diff -N src/org/eclipse/equinox/metatype/ExternalMessages.properties >--- src/org/eclipse/equinox/metatype/ExternalMessages.properties 1 Jul 2011 19:25:52 -0000 1.8 >+++ /dev/null 1 Jan 1970 00:00:00 -0000 >@@ -1,37 +0,0 @@ >-############################################################################### >-# 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 >Index: src/org/eclipse/equinox/metatype/FragmentUtils.java >=================================================================== >RCS file: src/org/eclipse/equinox/metatype/FragmentUtils.java >diff -N src/org/eclipse/equinox/metatype/FragmentUtils.java >--- src/org/eclipse/equinox/metatype/FragmentUtils.java 16 Feb 2011 20:45:47 -0000 1.3 >+++ /dev/null 1 Jan 1970 00:00:00 -0000 >@@ -1,58 +0,0 @@ >-/******************************************************************************* >- * Copyright (c) 2005, 2011 IBM Corporation. >- * All rights reserved. This program and the accompanying materials >- * are made available under the terms of the Eclipse Public License v1.0 >- * which accompanies this distribution, and is available at >- * http://www.eclipse.org/legal/epl-v10.html >- * >- * Contributors: >- * IBM Corporation - initial API and implementation >- *******************************************************************************/ >-package org.eclipse.equinox.metatype; >- >-import java.net.URL; >-import java.util.List; >-import org.osgi.framework.Bundle; >-import org.osgi.framework.wiring.BundleRevision; >-import org.osgi.framework.wiring.BundleWiring; >- >-/* >- * Fragment Utilities >- */ >-public class FragmentUtils { >- >- /* >- * >- */ >- public static boolean isFragment(Bundle bundle) { >- return (bundle.adapt(BundleRevision.class).getTypes() & BundleRevision.TYPE_FRAGMENT) != 0; >- } >- >- /* >- * Find all the URLs to entries for the bundle and its fragments. >- */ >- public static URL[] findEntries(Bundle bundle, String path) { >- BundleWiring wiring = bundle.adapt(BundleWiring.class); >- if (wiring == null) >- return null; >- String directory = "/"; //$NON-NLS-1$ >- String file = "*"; //$NON-NLS-1$ >- int index = path.lastIndexOf(MetaTypeProviderImpl.DIRECTORY_SEP); >- switch (index) { >- case -1 : >- file = path; >- break; >- case 0 : >- if (path.length() > 1) >- file = path.substring(1); >- break; >- default : >- directory = path.substring(0, index); >- file = path.substring(index + 1); >- } >- List<URL> entries = wiring.findEntries(directory, file, 0); >- if (entries == null) >- return null; >- return entries.toArray(new URL[entries.size()]); >- } >-} >Index: src/org/eclipse/equinox/metatype/Icon.java >=================================================================== >RCS file: src/org/eclipse/equinox/metatype/Icon.java >diff -N src/org/eclipse/equinox/metatype/Icon.java >--- src/org/eclipse/equinox/metatype/Icon.java 15 Dec 2005 20:25:22 -0000 1.1 >+++ /dev/null 1 Jan 1970 00:00:00 -0000 >@@ -1,72 +0,0 @@ >-/******************************************************************************* >- * Copyright (c) 2005 IBM Corporation. >- * All rights reserved. This program and the accompanying materials >- * are made available under the terms of the Eclipse Public License v1.0 >- * which accompanies this distribution, and is available at >- * http://www.eclipse.org/legal/epl-v10.html >- * >- * Contributors: >- * IBM Corporation - initial API and implementation >- *******************************************************************************/ >-package org.eclipse.equinox.metatype; >- >-import org.osgi.framework.Bundle; >- >-/** >- * Represents an Icon with a name and a size >- */ >-class Icon implements Cloneable { >- >- private String _fileName; >- private int _size; >- private Bundle _bundle; >- >- /** >- * Constructor of class Icon. >- */ >- public Icon(String fileName, int size, Bundle bundle) { >- >- this._fileName = fileName; >- this._size = size; >- this._bundle = bundle; >- } >- >- /** >- * Constructor of class Icon. >- */ >- public Icon(String fileName, Bundle bundle) { >- >- // Integer.MIN_VALUE signifies size was not specified >- this(fileName, Integer.MIN_VALUE, bundle); >- } >- >- /* >- * >- */ >- public synchronized Object clone() { >- return new Icon(this._fileName, this._size, this._bundle); >- } >- >- /** >- * Method to get the icon's file name. >- */ >- String getIconName() { >- return _fileName; >- } >- >- /** >- * returns the size specified when the icon was created >- * >- * @return size or Integer.MIN_VALUE if no size was specified >- */ >- int getIconSize() { >- return _size; >- } >- >- /** >- * Method to get the bundle having this Icon. >- */ >- Bundle getIconBundle() { >- return _bundle; >- } >-} >Index: src/org/eclipse/equinox/metatype/LocalizationElement.java >=================================================================== >RCS file: src/org/eclipse/equinox/metatype/LocalizationElement.java >diff -N src/org/eclipse/equinox/metatype/LocalizationElement.java >--- src/org/eclipse/equinox/metatype/LocalizationElement.java 6 Apr 2011 16:35:32 -0000 1.4 >+++ /dev/null 1 Jan 1970 00:00:00 -0000 >@@ -1,55 +0,0 @@ >-/******************************************************************************* >- * Copyright (c) 2005, 2011 IBM Corporation and others. >- * All rights reserved. This program and the accompanying materials >- * are made available under the terms of the Eclipse Public License v1.0 >- * which accompanies this distribution, and is available at >- * http://www.eclipse.org/legal/epl-v10.html >- * >- * Contributors: >- * IBM Corporation - initial API and implementation >- *******************************************************************************/ >-package org.eclipse.equinox.metatype; >- >-import java.util.MissingResourceException; >-import java.util.ResourceBundle; >- >-public class LocalizationElement { >- >- public static final char KEY_SIGN = '%'; >- String _localization = null; >- ResourceBundle _rb; >- >- /** >- * Internal method >- */ >- void setResourceBundle(ResourceBundle rb) { >- this._rb = rb; >- } >- >- /** >- * Method to get the localized text of inputed String. >- */ >- String getLocalized(String key) { >- >- if (key == null) { >- return null; >- } >- >- if ((key.length() > 1) && (key.charAt(0) == KEY_SIGN)) { >- if (_rb != null) { >- try { >- String transfered = _rb.getString(key.substring(1)); >- if (transfered != null) { >- return transfered; >- } >- } catch (MissingResourceException mre) { >- // Nothing found for this key. >- } >- } >- // If no localization file available or no localized value found >- // for the key, then return the raw data without the key-sign. >- return key.substring(1); >- } >- return key; >- } >-} >Index: src/org/eclipse/equinox/metatype/LogMessages.properties >=================================================================== >RCS file: src/org/eclipse/equinox/metatype/LogMessages.properties >diff -N src/org/eclipse/equinox/metatype/LogMessages.properties >--- src/org/eclipse/equinox/metatype/LogMessages.properties 11 Oct 2010 20:29:13 -0000 1.1 >+++ /dev/null 1 Jan 1970 00:00:00 -0000 >@@ -1,17 +0,0 @@ >-############################################################################### >-# 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 >Index: src/org/eclipse/equinox/metatype/LogTracker.java >=================================================================== >RCS file: src/org/eclipse/equinox/metatype/LogTracker.java >diff -N src/org/eclipse/equinox/metatype/LogTracker.java >--- src/org/eclipse/equinox/metatype/LogTracker.java 8 Dec 2010 14:23:53 -0000 1.3 >+++ /dev/null 1 Jan 1970 00:00:00 -0000 >@@ -1,177 +0,0 @@ >-/******************************************************************************* >- * Copyright (c) 1998, 2010 IBM Corporation and others. >- * All rights reserved. This program and the accompanying materials >- * are made available under the terms of the Eclipse Public License v1.0 >- * which accompanies this distribution, and is available at >- * http://www.eclipse.org/legal/epl-v10.html >- * >- * Contributors: >- * IBM Corporation - initial API and implementation >- *******************************************************************************/ >-package org.eclipse.equinox.metatype; >- >-import java.io.PrintStream; >-import java.util.Calendar; >-import java.util.Date; >-import org.osgi.framework.BundleContext; >-import org.osgi.framework.ServiceReference; >-import org.osgi.service.log.LogService; >-import org.osgi.util.tracker.ServiceTracker; >- >-/** >- * LogTracker class. This class encapsulates the LogService >- * and handles all issues such as the service coming and going. >- */ >- >-public class LogTracker extends ServiceTracker<LogService, LogService> implements LogService { >- /** LogService interface class name */ >- protected final static String clazz = "org.osgi.service.log.LogService"; //$NON-NLS-1$ >- >- /** PrintStream to use if LogService is unavailable */ >- private final PrintStream out; >- >- /** >- * Create new LogTracker. >- * >- * @param context BundleContext of parent bundle. >- * @param out Default PrintStream to use if LogService is unavailable. >- */ >- public LogTracker(BundleContext context, PrintStream out) { >- super(context, clazz, null); >- this.out = out; >- } >- >- /* >- * ---------------------------------------------------------------------- >- * LogService Interface implementation >- * ---------------------------------------------------------------------- >- */ >- >- public void log(int level, String message) { >- log(null, level, message, null); >- } >- >- public void log(int level, String message, Throwable exception) { >- log(null, level, message, exception); >- } >- >- // Must suppress warnings here because the log service is not >- @SuppressWarnings("rawtypes") >- public void log(ServiceReference reference, int level, String message) { >- log(reference, level, message, null); >- } >- >- // Must suppress warnings here because the log service is not >- @SuppressWarnings("rawtypes") >- public synchronized void log(ServiceReference reference, int level, String message, Throwable exception) { >- ServiceReference<LogService>[] references = getServiceReferences(); >- >- if (references != null) { >- int size = references.length; >- >- for (int i = 0; i < size; i++) { >- LogService service = getService(references[i]); >- if (service != null) { >- try { >- service.log(reference, level, message, exception); >- } catch (Exception e) { >- // TODO: consider printing to System Error >- } >- } >- } >- >- return; >- } >- >- noLogService(level, message, exception, reference); >- } >- >- /** >- * The LogService is not available so we write the message to a PrintStream. >- * >- * @param level Logging level >- * @param message Log message. >- * @param throwable Log exception or null if none. >- * @param reference ServiceReference associated with message or null if none. >- */ >- protected void noLogService(int level, String message, Throwable throwable, ServiceReference<?> reference) { >- if (out != null) { >- synchronized (out) { >- // Bug #113286. If no log service present and messages are being >- // printed to stdout, prepend message with a timestamp. >- String timestamp = getDate(new Date()); >- out.print(timestamp + " "); //$NON-NLS-1$ >- >- switch (level) { >- case LOG_DEBUG : { >- out.print(LogTrackerMsg.Debug); >- >- break; >- } >- case LOG_INFO : { >- out.print(LogTrackerMsg.Info); >- >- break; >- } >- case LOG_WARNING : { >- out.print(LogTrackerMsg.Warning); >- >- break; >- } >- case LOG_ERROR : { >- out.print(LogTrackerMsg.Error); >- >- break; >- } >- default : { >- out.print("["); //$NON-NLS-1$ >- out.print(LogTrackerMsg.Unknown_Log_level); >- out.print("]: "); //$NON-NLS-1$ >- >- break; >- } >- } >- >- out.println(message); >- >- if (reference != null) { >- out.println(reference); >- } >- >- if (throwable != null) { >- throwable.printStackTrace(out); >- } >- } >- } >- } >- >- // from EclipseLog to avoid using DateFormat -- see bug 149892#c10 >- private String getDate(Date date) { >- Calendar c = Calendar.getInstance(); >- c.setTime(date); >- StringBuffer sb = new StringBuffer(); >- appendPaddedInt(c.get(Calendar.YEAR), 4, sb).append('-'); >- appendPaddedInt(c.get(Calendar.MONTH) + 1, 2, sb).append('-'); >- appendPaddedInt(c.get(Calendar.DAY_OF_MONTH), 2, sb).append(' '); >- appendPaddedInt(c.get(Calendar.HOUR_OF_DAY), 2, sb).append(':'); >- appendPaddedInt(c.get(Calendar.MINUTE), 2, sb).append(':'); >- appendPaddedInt(c.get(Calendar.SECOND), 2, sb).append('.'); >- appendPaddedInt(c.get(Calendar.MILLISECOND), 3, sb); >- return sb.toString(); >- } >- >- private StringBuffer appendPaddedInt(int value, int pad, StringBuffer buffer) { >- pad = pad - 1; >- if (pad == 0) >- return buffer.append(Integer.toString(value)); >- int padding = (int) Math.pow(10, pad); >- if (value >= padding) >- return buffer.append(Integer.toString(value)); >- while (padding > value && padding > 1) { >- buffer.append('0'); >- padding = padding / 10; >- } >- buffer.append(value); >- return buffer; >- } >-} >Index: src/org/eclipse/equinox/metatype/LogTrackerMsg.java >=================================================================== >RCS file: src/org/eclipse/equinox/metatype/LogTrackerMsg.java >diff -N src/org/eclipse/equinox/metatype/LogTrackerMsg.java >--- src/org/eclipse/equinox/metatype/LogTrackerMsg.java 11 Oct 2010 20:29:13 -0000 1.1 >+++ /dev/null 1 Jan 1970 00:00:00 -0000 >@@ -1,28 +0,0 @@ >-/******************************************************************************* >- * Copyright (c) 2005, 2010 IBM Corporation and others. >- * All rights reserved. This program and the accompanying materials >- * are made available under the terms of the Eclipse Public License v1.0 >- * which accompanies this distribution, and is available at >- * http://www.eclipse.org/legal/epl-v10.html >- * >- * Contributors: >- * IBM Corporation - initial API and implementation >- *******************************************************************************/ >-package org.eclipse.equinox.metatype; >- >-import org.eclipse.osgi.util.NLS; >- >-public class LogTrackerMsg extends NLS { >- private static final String BUNDLE_NAME = "org.eclipse.equinox.metatype.LogMessages"; //$NON-NLS-1$ >- >- public static String Unknown_Log_level; >- public static String Info; >- public static String Warning; >- public static String Error; >- public static String Debug; >- >- static { >- // initialize resource bundles >- NLS.initializeMessages(BUNDLE_NAME, LogTrackerMsg.class); >- } >-} >Index: src/org/eclipse/equinox/metatype/MetaTypeInformationImpl.java >=================================================================== >RCS file: src/org/eclipse/equinox/metatype/MetaTypeInformationImpl.java >diff -N src/org/eclipse/equinox/metatype/MetaTypeInformationImpl.java >--- src/org/eclipse/equinox/metatype/MetaTypeInformationImpl.java 1 Jul 2011 19:25:52 -0000 1.7 >+++ /dev/null 1 Jan 1970 00:00:00 -0000 >@@ -1,88 +0,0 @@ >-/******************************************************************************* >- * Copyright (c) 2005, 2011 IBM Corporation and others. >- * All rights reserved. This program and the accompanying materials >- * are made available under the terms of the Eclipse Public License v1.0 >- * which accompanies this distribution, and is available at >- * http://www.eclipse.org/legal/epl-v10.html >- * >- * Contributors: >- * IBM Corporation - initial API and implementation >- *******************************************************************************/ >-package org.eclipse.equinox.metatype; >- >-import java.util.Enumeration; >-import java.util.Vector; >-import javax.xml.parsers.SAXParserFactory; >-import org.osgi.framework.Bundle; >-import org.osgi.service.log.LogService; >-import org.osgi.service.metatype.MetaTypeInformation; >- >-/** >- * Implementation of MetaTypeProvider >- * <p> >- * Extension of MetaTypeProvider >- * <p> >- * Provides methods to: >- * <p> - getPids() get the Pids for a given Locale >- * <p> - getFactoryPids() get the Factory Pids for a given Locale >- * <p> >- */ >-public class MetaTypeInformationImpl extends MetaTypeProviderImpl implements MetaTypeInformation { >- >- /** >- * Constructor of class MetaTypeInformationImpl. >- */ >- MetaTypeInformationImpl(Bundle bundle, SAXParserFactory parserFactory, LogService logger) { >- super(bundle, parserFactory, logger); >- } >- >- /* >- * (non-Javadoc) >- * >- * @see org.osgi.service.metatype.MetaTypeInformation#getPids() >- */ >- public String[] getPids() { >- >- if (_allPidOCDs.size() == 0) { >- return new String[0]; >- } >- >- Vector<String> pids = new Vector<String>(7); >- Enumeration<String> e = _allPidOCDs.keys(); >- while (e.hasMoreElements()) { >- pids.addElement(e.nextElement()); >- } >- >- String[] retvalue = new String[pids.size()]; >- pids.toArray(retvalue); >- return retvalue; >- } >- >- /* >- * (non-Javadoc) >- * >- * @see org.osgi.service.metatype.MetaTypeInformation#getFactoryPids() >- */ >- public String[] getFactoryPids() { >- if (_allFPidOCDs.size() == 0) { >- return new String[0]; >- } >- Vector<String> fpids = new Vector<String>(7); >- Enumeration<String> e = _allFPidOCDs.keys(); >- while (e.hasMoreElements()) { >- fpids.addElement(e.nextElement()); >- } >- String[] retvalue = new String[fpids.size()]; >- fpids.toArray(retvalue); >- return retvalue; >- } >- >- /* >- * (non-Javadoc) >- * >- * @see org.osgi.service.metatype.MetaTypeInformation#getBundle() >- */ >- public Bundle getBundle() { >- return this._bundle; >- } >-} >Index: src/org/eclipse/equinox/metatype/MetaTypeMsg.java >=================================================================== >RCS file: src/org/eclipse/equinox/metatype/MetaTypeMsg.java >diff -N src/org/eclipse/equinox/metatype/MetaTypeMsg.java >--- src/org/eclipse/equinox/metatype/MetaTypeMsg.java 1 Jul 2011 19:25:52 -0000 1.8 >+++ /dev/null 1 Jan 1970 00:00:00 -0000 >@@ -1,46 +0,0 @@ >-/******************************************************************************* >- * Copyright (c) 2005, 2011 IBM Corporation. >- * All rights reserved. This program and the accompanying materials >- * are made available under the terms of the Eclipse Public License v1.0 >- * which accompanies this distribution, and is available at >- * http://www.eclipse.org/legal/epl-v10.html >- * >- * Contributors: >- * IBM Corporation - initial API and implementation >- *******************************************************************************/ >-package org.eclipse.equinox.metatype; >- >-import org.eclipse.osgi.util.NLS; >- >-public class MetaTypeMsg extends NLS { >- private static final String BUNDLE_NAME = "org.eclipse.equinox.metatype.ExternalMessages"; //$NON-NLS-1$ >- >- public static String SERVICE_DESCRIPTION; >- public static String UNEXPECTED_ELEMENT; >- public static String UNEXPECTED_TEXT; >- public static String MISSING_ATTRIBUTE; >- public static String INVALID_TYPE; >- public static String MISSING_DESIGNATE_PID_AND_FACTORYPID; >- public static String OCD_ID_NOT_FOUND; >- public static String MISSING_ELEMENT; >- public static String EXCEPTION_MESSAGE; >- public static String NULL_IS_INVALID; >- public static String VALUE_OUT_OF_RANGE; >- public static String VALUE_OUT_OF_OPTION; >- public static String CARDINALITY_VIOLATION; >- public static String NULL_OPTIONS; >- public static String INCONSISTENT_OPTIONS; >- public static String INVALID_OPTIONS; >- public static String INVALID_DEFAULTS; >- public static String METADATA_NOT_FOUND; >- public static String ASK_INVALID_LOCALE; >- public static String MISSING_REQUIRED_PARAMETER; >- public static String TOKENIZER_GOT_INVALID_DATA; >- public static String INVALID_PID_METATYPE_PROVIDER_IGNORED; >- public static String METADATA_PARSE_ERROR; >- >- static { >- // initialize resource bundles >- NLS.initializeMessages(BUNDLE_NAME, MetaTypeMsg.class); >- } >-} >\ No newline at end of file >Index: src/org/eclipse/equinox/metatype/MetaTypeProviderImpl.java >=================================================================== >RCS file: src/org/eclipse/equinox/metatype/MetaTypeProviderImpl.java >diff -N src/org/eclipse/equinox/metatype/MetaTypeProviderImpl.java >--- src/org/eclipse/equinox/metatype/MetaTypeProviderImpl.java 1 Jul 2011 22:28:43 -0000 1.14 >+++ /dev/null 1 Jan 1970 00:00:00 -0000 >@@ -1,236 +0,0 @@ >-/******************************************************************************* >- * Copyright (c) 2005, 2011 IBM Corporation and others. >- * All rights reserved. This program and the accompanying materials >- * are made available under the terms of the Eclipse Public License v1.0 >- * which accompanies this distribution, and is available at >- * http://www.eclipse.org/legal/epl-v10.html >- * >- * Contributors: >- * IBM Corporation - initial API and implementation >- *******************************************************************************/ >-package org.eclipse.equinox.metatype; >- >-import java.io.IOException; >-import java.net.URL; >-import java.util.*; >-import javax.xml.parsers.SAXParserFactory; >-import org.eclipse.osgi.util.NLS; >-import org.osgi.framework.Bundle; >-import org.osgi.framework.Constants; >-import org.osgi.framework.wiring.BundleWiring; >-import org.osgi.service.log.LogService; >-import org.osgi.service.metatype.*; >- >-/** >- * Implementation of MetaTypeProvider >- */ >-public class MetaTypeProviderImpl implements MetaTypeProvider { >- >- public static final String METADATA_NOT_FOUND = "METADATA_NOT_FOUND"; //$NON-NLS-1$ >- public static final String OCD_ID_NOT_FOUND = "OCD_ID_NOT_FOUND"; //$NON-NLS-1$ >- public static final String ASK_INVALID_LOCALE = "ASK_INVALID_LOCALE"; //$NON-NLS-1$ >- >- public static final String META_FILE_EXT = ".XML"; //$NON-NLS-1$ >- public static final String RESOURCE_FILE_CONN = "_"; //$NON-NLS-1$ >- public static final String RESOURCE_FILE_EXT = ".properties"; //$NON-NLS-1$ >- public static final char DIRECTORY_SEP = '/'; >- >- Bundle _bundle; >- >- Hashtable<String, ObjectClassDefinitionImpl> _allPidOCDs = new Hashtable<String, ObjectClassDefinitionImpl>(7); >- Hashtable<String, ObjectClassDefinitionImpl> _allFPidOCDs = new Hashtable<String, ObjectClassDefinitionImpl>(7); >- >- String[] _locales; >- boolean _isThereMeta = false; >- >- // Give access to subclasses. >- protected final LogService logger; >- >- /** >- * Constructor of class MetaTypeProviderImpl. >- */ >- MetaTypeProviderImpl(Bundle bundle, SAXParserFactory parserFactory, LogService logger) { >- >- this._bundle = bundle; >- this.logger = logger; >- >- // read all bundle's metadata files and build internal data structures >- _isThereMeta = readMetaFiles(bundle, parserFactory); >- >- if (!_isThereMeta) { >- logger.log(LogService.LOG_DEBUG, NLS.bind(MetaTypeMsg.METADATA_NOT_FOUND, new Long(bundle.getBundleId()), bundle.getSymbolicName())); >- } >- } >- >- /** >- * This method should do the following: >- * <p> - Obtain a SAX parser from the XML Parser Service: >- * <p> >- * >- * <pre> </pre> >- * >- * The parser may be SAX 1 (eXML) or SAX 2 (XML4J). It should attempt to use >- * a SAX2 parser by instantiating an XMLReader and extending DefaultHandler >- * BUT if that fails it should fall back to instantiating a SAX1 Parser and >- * extending HandlerBase. >- * <p> - Pass the parser the URL for the bundle's METADATA.XML file >- * <p> - Handle the callbacks from the parser and build the appropriate >- * MetaType objects - ObjectClassDefinitions & AttributeDefinitions >- * >- * @param bundle The bundle object for which the metadata should be read >- * @param parserFactory The bundle object for which the metadata should be >- * read >- * @return void >- * @throws IOException If there are errors accessing the metadata.xml file >- */ >- private boolean readMetaFiles(Bundle bundle, SAXParserFactory parserFactory) { >- BundleWiring wiring = bundle.adapt(BundleWiring.class); >- if (wiring == null) >- return false; >- List<URL> entries = wiring.findEntries(MetaTypeService.METATYPE_DOCUMENTS_LOCATION, "*", 0); //$NON-NLS-1$ >- if (entries == null) >- return false; >- boolean result = false; >- for (URL entry : entries) { >- if (entry.getPath().endsWith("/")) >- continue; >- DataParser parser = new DataParser(bundle, entry, parserFactory, logger); >- try { >- Collection<Designate> designates = parser.doParse(); >- if (!designates.isEmpty()) { >- result = true; >- } >- for (Designate designate : designates) { >- if (designate.isFactory()) { >- _allFPidOCDs.put(designate.getFactoryPid(), designate.getObjectClassDefinition()); >- } else { >- _allPidOCDs.put(designate.getPid(), designate.getObjectClassDefinition()); >- } >- } >- } catch (Exception e) { >- logger.log(LogService.LOG_ERROR, NLS.bind(MetaTypeMsg.METADATA_PARSE_ERROR, new Object[] {entry, bundle.getBundleId()}), e); >- } >- } >- return result; >- } >- >- /* >- * (non-Javadoc) >- * >- * @see org.osgi.service.metatype.MetaTypeProvider#getObjectClassDefinition(java.lang.String, >- * java.lang.String) >- */ >- public ObjectClassDefinition getObjectClassDefinition(String pid, String locale) { >- >- if (isInvalidLocale(locale)) { >- throw new IllegalArgumentException(NLS.bind(MetaTypeMsg.ASK_INVALID_LOCALE, pid, locale)); >- } >- >- ObjectClassDefinitionImpl ocd; >- if (_allPidOCDs.containsKey(pid)) { >- ocd = (ObjectClassDefinitionImpl) (_allPidOCDs.get(pid)).clone(); >- ocd.setResourceBundle(locale, _bundle); >- return ocd; >- } else if (_allFPidOCDs.containsKey(pid)) { >- ocd = (ObjectClassDefinitionImpl) (_allFPidOCDs.get(pid)).clone(); >- ocd.setResourceBundle(locale, _bundle); >- return ocd; >- } else { >- throw new IllegalArgumentException(NLS.bind(MetaTypeMsg.OCD_ID_NOT_FOUND, pid)); >- } >- } >- >- /** >- * Internal Method - Check if the locale is invalid. >- */ >- public boolean isInvalidLocale(String locale) { >- >- // Just a simple and quick check here. >- if (locale == null || locale.length() == 0) >- return false; >- >- int idx_first = locale.indexOf(ObjectClassDefinitionImpl.LOCALE_SEP); >- int idx_second = locale.lastIndexOf(ObjectClassDefinitionImpl.LOCALE_SEP); >- if (idx_first == -1 && locale.length() == 2) >- // It is format of only language. >- return false; >- if ((idx_first == 2) && (idx_second == 5 || idx_second == 2)) >- // It is format of language + "_" + country [ + "_" + variation ]. >- return false; >- return true; >- } >- >- /* >- * (non-Javadoc) >- * >- * @see org.osgi.service.metatype.MetaTypeProvider#getLocales() >- */ >- public synchronized String[] getLocales() { >- >- if (_locales != null) >- return checkForDefault(_locales); >- BundleWiring wiring = _bundle.adapt(BundleWiring.class); >- if (wiring == null) >- return null; >- Vector<String> localizationFiles = new Vector<String>(7); >- // get all the localization resources for PIDS >- Enumeration<ObjectClassDefinitionImpl> ocds = _allPidOCDs.elements(); >- while (ocds.hasMoreElements()) { >- ObjectClassDefinitionImpl ocd = ocds.nextElement(); >- if (ocd._localization != null && !localizationFiles.contains(ocd._localization)) >- localizationFiles.add(ocd._localization); >- } >- // get all the localization resources for FPIDS >- ocds = _allFPidOCDs.elements(); >- while (ocds.hasMoreElements()) { >- ObjectClassDefinitionImpl ocd = ocds.nextElement(); >- if (ocd._localization != null && !localizationFiles.contains(ocd._localization)) >- localizationFiles.add(ocd._localization); >- } >- if (localizationFiles.size() == 0) >- localizationFiles.add(getBundleLocalization(_bundle)); >- Vector<String> locales = new Vector<String>(7); >- Enumeration<String> eLocalizationFiles = localizationFiles.elements(); >- while (eLocalizationFiles.hasMoreElements()) { >- String localizationFile = eLocalizationFiles.nextElement(); >- int iSlash = localizationFile.lastIndexOf(DIRECTORY_SEP); >- String baseDir; >- String baseFileName; >- if (iSlash < 0) { >- baseDir = ""; //$NON-NLS-1$ >- } else { >- baseDir = localizationFile.substring(0, iSlash); >- } >- baseFileName = '/' + localizationFile + RESOURCE_FILE_CONN; >- List<URL> entries = wiring.findEntries(baseDir, "*.properties", 0); //$NON-NLS-1$ >- if (entries == null) >- continue; >- for (URL entry : entries) { >- String resource = entry.getPath(); >- if (resource.startsWith(baseFileName) && resource.toLowerCase().endsWith(RESOURCE_FILE_EXT)) >- locales.add(resource.substring(baseFileName.length(), resource.length() - RESOURCE_FILE_EXT.length())); >- } >- } >- _locales = locales.toArray(new String[locales.size()]); >- return checkForDefault(_locales); >- } >- >- static String getBundleLocalization(Bundle bundle) { >- // Use the Bundle-Localization manifest header value if it exists. >- String baseName = bundle.getHeaders("").get(Constants.BUNDLE_LOCALIZATION); //$NON-NLS-1$ >- if (baseName == null) >- // If the manifest header does not exist, use the default. >- baseName = Constants.BUNDLE_LOCALIZATION_DEFAULT_BASENAME; >- return baseName; >- } >- >- /** >- * Internal Method - checkForDefault >- */ >- private String[] checkForDefault(String[] locales) { >- >- if (locales == null || locales.length == 0 || (locales.length == 1 && Locale.getDefault().toString().equals(locales[0]))) >- return null; >- return locales; >- } >-} >Index: src/org/eclipse/equinox/metatype/MetaTypeProviderTracker.java >=================================================================== >RCS file: src/org/eclipse/equinox/metatype/MetaTypeProviderTracker.java >diff -N src/org/eclipse/equinox/metatype/MetaTypeProviderTracker.java >--- src/org/eclipse/equinox/metatype/MetaTypeProviderTracker.java 25 Oct 2010 18:04:37 -0000 1.5 >+++ /dev/null 1 Jan 1970 00:00:00 -0000 >@@ -1,189 +0,0 @@ >-/******************************************************************************* >- * Copyright (c) 2005, 2010 IBM Corporation and others. >- * All rights reserved. This program and the accompanying materials >- * are made available under the terms of the Eclipse Public License v1.0 >- * which accompanies this distribution, and is available at >- * http://www.eclipse.org/legal/epl-v10.html >- * >- * Contributors: >- * IBM Corporation - initial API and implementation >- *******************************************************************************/ >-package org.eclipse.equinox.metatype; >- >-import java.util.*; >-import org.eclipse.osgi.util.NLS; >-import org.osgi.framework.*; >-import org.osgi.service.cm.ManagedService; >-import org.osgi.service.cm.ManagedServiceFactory; >-import org.osgi.service.log.LogService; >-import org.osgi.service.metatype.*; >-import org.osgi.util.tracker.ServiceTracker; >- >-public class MetaTypeProviderTracker implements MetaTypeInformation { >- private final Bundle _bundle; >- private final LogService log; >- private final ServiceTracker<Object, Object> _tracker; >- >- /** >- * Constructs a MetaTypeProviderTracker which tracks all MetaTypeProviders >- * registered by the specified bundle. >- * @param context The BundleContext of the MetaTypeService implementation >- * @param bundle The bundle to track all MetaTypeProviders for. >- * @param log The {@code LogService} to use for logging messages. >- */ >- public MetaTypeProviderTracker(Bundle bundle, LogService log, ServiceTracker<Object, Object> tracker) { >- this._bundle = bundle; >- this._tracker = tracker; >- this.log = log; >- } >- >- private String[] getPids(boolean factory) { >- if (_bundle.getState() != Bundle.ACTIVE) >- return new String[0]; // return none if not active >- MetaTypeProviderWrapper[] wrappers = getMetaTypeProviders(); >- ArrayList<String> results = new ArrayList<String>(); >- for (int i = 0; i < wrappers.length; i++) { >- // return only the correct type of pids (regular or factory) >- if (factory == wrappers[i].factory) >- results.add(wrappers[i].pid); >- } >- return results.toArray(new String[results.size()]); >- } >- >- public String[] getPids() { >- return getPids(false); >- } >- >- public String[] getFactoryPids() { >- return getPids(true); >- } >- >- public Bundle getBundle() { >- return _bundle; >- } >- >- public ObjectClassDefinition getObjectClassDefinition(String id, String locale) { >- if (_bundle.getState() != Bundle.ACTIVE) >- return null; // return none if not active >- MetaTypeProviderWrapper[] wrappers = getMetaTypeProviders(); >- for (int i = 0; i < wrappers.length; i++) { >- if (id.equals(wrappers[i].pid)) >- // found a matching pid now call the actual provider >- return wrappers[i].provider.getObjectClassDefinition(id, locale); >- } >- return null; >- } >- >- public String[] getLocales() { >- if (_bundle.getState() != Bundle.ACTIVE) >- return new String[0]; // return none if not active >- MetaTypeProviderWrapper[] wrappers = getMetaTypeProviders(); >- ArrayList<String> locales = new ArrayList<String>(); >- // collect all the unique locales from all providers we found >- for (int i = 0; i < wrappers.length; i++) { >- String[] wrappedLocales = wrappers[i].provider.getLocales(); >- if (wrappedLocales == null) >- continue; >- for (int j = 0; j < wrappedLocales.length; j++) >- if (!locales.contains(wrappedLocales[j])) >- locales.add(wrappedLocales[j]); >- } >- return locales.toArray(new String[locales.size()]); >- } >- >- private MetaTypeProviderWrapper[] getMetaTypeProviders() { >- Map<ServiceReference<Object>, Object> services = _tracker.getTracked(); >- if (services.isEmpty()) >- return new MetaTypeProviderWrapper[0]; >- Set<ServiceReference<Object>> serviceReferences = services.keySet(); >- Set<MetaTypeProviderWrapper> result = new HashSet<MetaTypeProviderWrapper>(); >- for (ServiceReference<Object> serviceReference : serviceReferences) { >- if (serviceReference.getBundle() == _bundle) { >- Object service = services.get(serviceReference); >- // If the service is not a MetaTypeProvider, we're not interested in it. >- if (service instanceof MetaTypeProvider) { >- // Include the METATYPE_PID, if present, to return as part of getPids(). Also, include the >- // METATYPE_FACTORY_PID, if present, to return as part of getFactoryPids(). >- // The filter ensures at least one of these properties was set for a standalone MetaTypeProvider. >- addMetaTypeProviderWrappers(MetaTypeProvider.METATYPE_PID, serviceReference, (MetaTypeProvider) service, false, result); >- addMetaTypeProviderWrappers(MetaTypeProvider.METATYPE_FACTORY_PID, serviceReference, (MetaTypeProvider) service, true, result); >- // If the service is a ManagedService, include the SERVICE_PID to return as part of getPids(). >- // The filter ensures the SERVICE_PID property was set. >- if (service instanceof ManagedService) { >- addMetaTypeProviderWrappers(Constants.SERVICE_PID, serviceReference, (MetaTypeProvider) service, false, result); >- } >- // If the service is a ManagedServiceFactory, include the SERVICE_PID to return as part of getFactoryPids(). >- // The filter ensures the SERVICE_PID property was set. >- else if (service instanceof ManagedServiceFactory) { >- addMetaTypeProviderWrappers(Constants.SERVICE_PID, serviceReference, (MetaTypeProvider) service, true, result); >- } >- } >- } >- } >- return result.toArray(new MetaTypeProviderWrapper[result.size()]); >- } >- >- private void addMetaTypeProviderWrappers(String servicePropertyName, ServiceReference<Object> serviceReference, MetaTypeProvider service, boolean factory, Set<MetaTypeProviderWrapper> wrappers) { >- String[] pids = getStringProperty(servicePropertyName, serviceReference.getProperty(servicePropertyName)); >- for (String pid : pids) { >- wrappers.add(new MetaTypeProviderWrapper(service, pid, factory)); >- } >- } >- >- private String[] getStringProperty(String name, Object value) { >- // Don't log a warning if the value is null. The filter guarantees at least one of the necessary properties >- // is there. If others are not, this method will get called with value equal to null. >- if (value == null) >- return new String[0]; >- if (value instanceof String) { >- return new String[] {(String) value}; >- } >- if (value instanceof String[]) { >- return (String[]) value; >- } >- Exception e = null; >- if (value instanceof Collection) { >- @SuppressWarnings("unchecked") >- Collection<String> temp = (Collection<String>) value; >- try { >- return temp.toArray(new String[temp.size()]); >- } catch (ArrayStoreException ase) { >- e = ase; >- } >- } >- log.log(LogService.LOG_WARNING, NLS.bind(MetaTypeMsg.INVALID_PID_METATYPE_PROVIDER_IGNORED, new Object[] {_bundle.getSymbolicName(), _bundle.getBundleId(), name, value}), e); >- return new String[0]; >- } >- >- // this is a simple class just used to temporarily store information about a provider >- public class MetaTypeProviderWrapper { >- MetaTypeProvider provider; >- String pid; >- boolean factory; >- >- MetaTypeProviderWrapper(MetaTypeProvider provider, String pid, boolean factory) { >- this.provider = provider; >- this.pid = pid; >- this.factory = factory; >- } >- >- @Override >- public boolean equals(Object object) { >- if (object == this) >- return true; >- if (!(object instanceof MetaTypeProviderWrapper)) >- return false; >- MetaTypeProviderWrapper that = (MetaTypeProviderWrapper) object; >- return this.provider.equals(that.provider) && this.pid.equals(that.pid) && this.factory == that.factory; >- } >- >- @Override >- public int hashCode() { >- int result = 17; >- result = 31 * result + provider.hashCode(); >- result = 31 * result + pid.hashCode(); >- result = 31 * result + (factory ? 1 : 0); >- return result; >- } >- } >-} >Index: src/org/eclipse/equinox/metatype/MetaTypeServiceImpl.java >=================================================================== >RCS file: src/org/eclipse/equinox/metatype/MetaTypeServiceImpl.java >diff -N src/org/eclipse/equinox/metatype/MetaTypeServiceImpl.java >--- src/org/eclipse/equinox/metatype/MetaTypeServiceImpl.java 1 Jul 2011 19:25:52 -0000 1.7 >+++ /dev/null 1 Jan 1970 00:00:00 -0000 >@@ -1,107 +0,0 @@ >-/******************************************************************************* >- * Copyright (c) 2005, 2011 IBM Corporation and others. >- * All rights reserved. This program and the accompanying materials >- * are made available under the terms of the Eclipse Public License v1.0 >- * which accompanies this distribution, and is available at >- * http://www.eclipse.org/legal/epl-v10.html >- * >- * Contributors: >- * IBM Corporation - initial API and implementation >- *******************************************************************************/ >-package org.eclipse.equinox.metatype; >- >-import java.security.AccessController; >-import java.security.PrivilegedExceptionAction; >-import java.util.Hashtable; >-import javax.xml.parsers.SAXParserFactory; >-import org.eclipse.osgi.util.NLS; >-import org.osgi.framework.*; >-import org.osgi.service.log.LogService; >-import org.osgi.service.metatype.MetaTypeInformation; >-import org.osgi.service.metatype.MetaTypeService; >-import org.osgi.util.tracker.ServiceTracker; >- >-/** >- * Implementation of MetaTypeService >- */ >-public class MetaTypeServiceImpl implements MetaTypeService, SynchronousBundleListener { >- >- SAXParserFactory _parserFactory; >- private Hashtable<Long, MetaTypeInformation> _mtps = new Hashtable<Long, MetaTypeInformation>(7); >- >- private final LogService logger; >- private final ServiceTracker<Object, Object> metaTypeProviderTracker; >- >- /** >- * Constructor of class MetaTypeServiceImpl. >- */ >- public MetaTypeServiceImpl(SAXParserFactory parserFactory, LogService logger, ServiceTracker<Object, Object> metaTypeProviderTracker) { >- this._parserFactory = parserFactory; >- this.logger = logger; >- this.metaTypeProviderTracker = metaTypeProviderTracker; >- } >- >- /* >- * (non-Javadoc) >- * >- * @see org.osgi.service.metatype.MetaTypeService#getMetaTypeInformation(org.osgi.framework.Bundle) >- */ >- public MetaTypeInformation getMetaTypeInformation(Bundle bundle) { >- return getMetaTypeProvider(bundle); >- } >- >- /** >- * Internal Method - to get MetaTypeProvider object. >- */ >- private MetaTypeInformation getMetaTypeProvider(final Bundle b) { >- final LogService loggerTemp = this.logger; >- final ServiceTracker<Object, Object> tracker = this.metaTypeProviderTracker; >- try { >- Long bID = new Long(b.getBundleId()); >- synchronized (_mtps) { >- if (_mtps.containsKey(bID)) >- return _mtps.get(bID); >- // Avoid synthetic accessor method warnings. >- >- MetaTypeInformation mti = AccessController.doPrivileged(new PrivilegedExceptionAction<MetaTypeInformation>() { >- public MetaTypeInformation run() { >- MetaTypeInformationImpl impl = new MetaTypeInformationImpl(b, _parserFactory, loggerTemp); >- if (!impl._isThereMeta) >- return new MetaTypeProviderTracker(b, loggerTemp, tracker); >- return impl; >- } >- }); >- _mtps.put(bID, mti); >- return mti; >- } >- } catch (Exception e) { >- logger.log(LogService.LOG_ERROR, NLS.bind(MetaTypeMsg.EXCEPTION_MESSAGE, e.getMessage()), e); >- return new MetaTypeProviderTracker(b, loggerTemp, tracker); >- } >- } >- >- /* >- * (non-Javadoc) >- * >- * @see org.osgi.framework.BundleListener#bundleChanged(org.osgi.framework.BundleEvent) >- */ >- public void bundleChanged(BundleEvent event) { >- >- int type = event.getType(); >- Long bID = new Long(event.getBundle().getBundleId()); >- >- switch (type) { >- case BundleEvent.UPDATED : >- case BundleEvent.UNINSTALLED : >- _mtps.remove(bID); >- break; >- case BundleEvent.INSTALLED : >- case BundleEvent.RESOLVED : >- case BundleEvent.STARTED : >- case BundleEvent.STOPPED : >- case BundleEvent.UNRESOLVED : >- default : >- break; >- } >- } >-} >Index: src/org/eclipse/equinox/metatype/ObjectClassDefinitionImpl.java >=================================================================== >RCS file: src/org/eclipse/equinox/metatype/ObjectClassDefinitionImpl.java >diff -N src/org/eclipse/equinox/metatype/ObjectClassDefinitionImpl.java >--- src/org/eclipse/equinox/metatype/ObjectClassDefinitionImpl.java 29 Apr 2011 15:41:04 -0000 1.10 >+++ /dev/null 1 Jan 1970 00:00:00 -0000 >@@ -1,313 +0,0 @@ >-/******************************************************************************* >- * Copyright (c) 2005, 2011 IBM Corporation and others. >- * All rights reserved. This program and the accompanying materials >- * are made available under the terms of the Eclipse Public License v1.0 >- * which accompanies this distribution, and is available at >- * http://www.eclipse.org/legal/epl-v10.html >- * >- * Contributors: >- * IBM Corporation - initial API and implementation >- *******************************************************************************/ >-package org.eclipse.equinox.metatype; >- >-import java.io.IOException; >-import java.io.InputStream; >-import java.net.URL; >-import java.util.*; >-import org.osgi.framework.Bundle; >-import org.osgi.service.metatype.AttributeDefinition; >-import org.osgi.service.metatype.ObjectClassDefinition; >- >-/** >- * Implementation of ObjectClassDefinition >- */ >-public class ObjectClassDefinitionImpl extends LocalizationElement implements ObjectClassDefinition, Cloneable { >- >- public static final char LOCALE_SEP = '_'; >- >- String _name; >- String _id; >- String _description; >- >- int _type; >- Vector<AttributeDefinitionImpl> _required = new Vector<AttributeDefinitionImpl>(7); >- Vector<AttributeDefinitionImpl> _optional = new Vector<AttributeDefinitionImpl>(7); >- Icon _icon; >- >- /* >- * Constructor of class ObjectClassDefinitionImpl. >- */ >- public ObjectClassDefinitionImpl(String name, String description, String id, String localization) { >- >- this._name = name; >- this._description = description; >- this._id = id; >- this._localization = localization; >- } >- >- /* >- * Constructor of class ObjectClassDefinitionImpl. >- */ >- public ObjectClassDefinitionImpl(String name, String description, String id, int type, String localization) { >- >- this._name = name; >- this._id = id; >- this._description = description; >- this._type = type; >- this._localization = localization; >- } >- >- /* >- * >- */ >- public synchronized Object clone() { >- >- ObjectClassDefinitionImpl ocd = new ObjectClassDefinitionImpl(_name, _description, _id, _type, _localization); >- for (int i = 0; i < _required.size(); i++) { >- AttributeDefinitionImpl ad = _required.elementAt(i); >- ocd.addAttributeDefinition((AttributeDefinitionImpl) ad.clone(), true); >- } >- for (int i = 0; i < _optional.size(); i++) { >- AttributeDefinitionImpl ad = _optional.elementAt(i); >- ocd.addAttributeDefinition((AttributeDefinitionImpl) ad.clone(), false); >- } >- if (_icon != null) { >- ocd.setIcon((Icon) _icon.clone()); >- } >- return ocd; >- } >- >- /* >- * (non-Javadoc) >- * >- * @see org.osgi.service.metatype.ObjectClassDefinition#getName() >- */ >- public String getName() { >- return getLocalized(_name); >- } >- >- /** >- * Method to set the name of ObjectClassDefinition. >- */ >- void setName(String name) { >- this._name = name; >- } >- >- /* >- * (non-Javadoc) >- * >- * @see org.osgi.service.metatype.ObjectClassDefinition#getID() >- */ >- public String getID() { >- return _id; >- } >- >- /* >- * (non-Javadoc) >- * >- * @see org.osgi.service.metatype.ObjectClassDefinition#getDescription() >- */ >- public String getDescription() { >- return getLocalized(_description); >- } >- >- /* >- * Method to set the description of ObjectClassDefinition. >- */ >- void setDescription(String description) { >- this._description = description; >- } >- >- /* >- * (non-Javadoc) >- * >- * @see org.osgi.service.metatype.ObjectClassDefinition#getAttributeDefinitions(int) >- */ >- public AttributeDefinition[] getAttributeDefinitions(int filter) { >- >- AttributeDefinition[] atts; >- switch (filter) { >- case REQUIRED : >- atts = new AttributeDefinition[_required.size()]; >- _required.toArray(atts); >- return atts; >- case OPTIONAL : >- atts = new AttributeDefinition[_optional.size()]; >- _optional.toArray(atts); >- return atts; >- case ALL : >- default : >- atts = new AttributeDefinition[_required.size() + _optional.size()]; >- Enumeration<AttributeDefinitionImpl> e = _required.elements(); >- int i = 0; >- while (e.hasMoreElements()) { >- atts[i] = e.nextElement(); >- i++; >- } >- e = _optional.elements(); >- while (e.hasMoreElements()) { >- atts[i] = e.nextElement(); >- i++; >- } >- return atts; >- } >- } >- >- /* >- * Method to add one new AD to ObjectClassDefinition. >- */ >- void addAttributeDefinition(AttributeDefinitionImpl ad, boolean isRequired) { >- >- if (isRequired) { >- _required.addElement(ad); >- } else { >- _optional.addElement(ad); >- } >- } >- >- /* >- * (non-Javadoc) >- * >- * @see org.osgi.service.metatype.ObjectClassDefinition#getIcon(int) >- */ >- public InputStream getIcon(int sizeHint) throws IOException { >- // The parameter simply represents a requested size. This method should never return null if an >- // icon exists. >- // TODO This method may change further depending on the outcome of certain ongoing CPEG discussions. >- // It is thought that users should be able to specify the same icon multiple times but of different >- // sizes. This would require a change to the XML schema. This method would then return the icon with >- // a size closest to the requested size. >- if ((_icon == null)) { >- return null; >- } >- Bundle b = _icon.getIconBundle(); >- URL[] urls = FragmentUtils.findEntries(b, getLocalized(_icon.getIconName())); >- if (urls != null && urls.length > 0) { >- return urls[0].openStream(); >- } >- return null; >- } >- >- /** >- * Method to set the icon of ObjectClassDefinition. >- */ >- void setIcon(Icon icon) { >- this._icon = icon; >- } >- >- /** >- * Method to set the resource bundle for this OCD and all its ADs. >- */ >- void setResourceBundle(String assignedLocale, Bundle bundle) { >- >- _rb = getResourceBundle(assignedLocale, bundle); >- >- Enumeration<AttributeDefinitionImpl> allADReqs = _required.elements(); >- while (allADReqs.hasMoreElements()) { >- AttributeDefinitionImpl ad = allADReqs.nextElement(); >- ad.setResourceBundle(_rb); >- } >- >- Enumeration<AttributeDefinitionImpl> allADOpts = _optional.elements(); >- while (allADOpts.hasMoreElements()) { >- AttributeDefinitionImpl ad = allADOpts.nextElement(); >- ad.setResourceBundle(_rb); >- } >- } >- >- /* >- * Internal Method - to get resource bundle. >- */ >- private ResourceBundle getResourceBundle(String locale, final Bundle bundle) { >- // Determine the base name of the bundle localization property files. >- // If the <MetaData> 'localization' attribute was not specified, >- // use the Bundle-Localization manifest header value instead if it exists. >- String resourceBase = _localization != null ? _localization : MetaTypeProviderImpl.getBundleLocalization(bundle); >- >- // There are seven searching candidates possible: >- // baseName + >- // "_" + language1 + "_" + country1 + "_" + variation1 + ".properties" >- // or "_" + language1 + "_" + country1 + ".properties" >- // or "_" + language1 + ".properties" >- // or "_" + language2 + "_" + country2 + "_" + variation2 + ".properties" >- // or "_" + language2 + "_" + country2 + ".properties" >- // or "_" + language2 + ".properties" >- // or "" + ".properties" >- // >- // Where language1[_country1[_variation1]] is the requested locale, >- // and language2[_country2[_variation2]] is the default locale. >- >- String[] searchCandidates = new String[7]; >- >- // Candidates from passed locale: >- if (locale != null && locale.length() > 0) { >- int idx1_first = locale.indexOf(LOCALE_SEP); >- if (idx1_first == -1) { >- // locale has only language. >- searchCandidates[2] = MetaTypeProviderImpl.RESOURCE_FILE_CONN + locale; >- } else { >- // locale has at least language and country. >- searchCandidates[2] = MetaTypeProviderImpl.RESOURCE_FILE_CONN + locale.substring(0, idx1_first); >- int idx1_second = locale.indexOf(LOCALE_SEP, idx1_first + 1); >- if (idx1_second == -1) { >- // locale just has both language and country. >- searchCandidates[1] = MetaTypeProviderImpl.RESOURCE_FILE_CONN + locale; >- } else { >- // locale has language, country, and variation all. >- searchCandidates[1] = MetaTypeProviderImpl.RESOURCE_FILE_CONN + locale.substring(0, idx1_second); >- searchCandidates[0] = MetaTypeProviderImpl.RESOURCE_FILE_CONN + locale; >- } >- } >- } >- >- // Candidates from Locale.getDefault(): >- String defaultLocale = Locale.getDefault().toString(); >- int idx2_first = defaultLocale.indexOf(LOCALE_SEP); >- int idx2_second = defaultLocale.indexOf(LOCALE_SEP, idx2_first + 1); >- if (idx2_second != -1) { >- // default-locale is format of [language]_[country]_variation. >- searchCandidates[3] = MetaTypeProviderImpl.RESOURCE_FILE_CONN + defaultLocale; >- if (searchCandidates[3].equalsIgnoreCase(searchCandidates[0])) { >- searchCandidates[3] = null; >- } >- } >- if ((idx2_first != -1) && (idx2_second != idx2_first + 1)) { >- // default-locale is format of [language]_country[_variation]. >- searchCandidates[4] = MetaTypeProviderImpl.RESOURCE_FILE_CONN + ((idx2_second == -1) ? defaultLocale : defaultLocale.substring(0, idx2_second)); >- if (searchCandidates[4].equalsIgnoreCase(searchCandidates[1])) { >- searchCandidates[4] = null; >- } >- } >- if ((idx2_first == -1) && (defaultLocale.length() > 0)) { >- // default-locale has only language. >- searchCandidates[5] = MetaTypeProviderImpl.RESOURCE_FILE_CONN + defaultLocale; >- } else if (idx2_first > 0) { >- // default-locale is format of language_[...]. >- searchCandidates[5] = MetaTypeProviderImpl.RESOURCE_FILE_CONN + defaultLocale.substring(0, idx2_first); >- } >- if (searchCandidates[5] != null && searchCandidates[5].equalsIgnoreCase(searchCandidates[2])) { >- searchCandidates[5] = null; >- } >- >- // The final candidate. >- searchCandidates[6] = ""; //$NON-NLS-1$ >- >- URL resourceUrl = null; >- URL[] urls = null; >- >- for (int idx = 0; (idx < searchCandidates.length) && (resourceUrl == null); idx++) { >- urls = (searchCandidates[idx] == null ? null : FragmentUtils.findEntries(bundle, resourceBase + searchCandidates[idx] + MetaTypeProviderImpl.RESOURCE_FILE_EXT)); >- if (urls != null && urls.length > 0) >- resourceUrl = urls[0]; >- } >- >- if (resourceUrl != null) { >- try { >- return new PropertyResourceBundle(resourceUrl.openStream()); >- } catch (IOException ioe) { >- // Exception when creating PropertyResourceBundle object. >- } >- } >- return null; >- } >-} >Index: src/org/eclipse/equinox/metatype/ValueTokenizer.java >=================================================================== >RCS file: src/org/eclipse/equinox/metatype/ValueTokenizer.java >diff -N src/org/eclipse/equinox/metatype/ValueTokenizer.java >--- src/org/eclipse/equinox/metatype/ValueTokenizer.java 18 Mar 2011 19:37:21 -0000 1.6 >+++ /dev/null 1 Jan 1970 00:00:00 -0000 >@@ -1,274 +0,0 @@ >-/******************************************************************************* >- * Copyright (c) 2005, 2011 IBM Corporation and others. >- * All rights reserved. This program and the accompanying materials >- * are made available under the terms of the Eclipse Public License v1.0 >- * which accompanies this distribution, and is available at >- * http://www.eclipse.org/legal/epl-v10.html >- * >- * Contributors: >- * IBM Corporation - initial API and implementation >- *******************************************************************************/ >-package org.eclipse.equinox.metatype; >- >-import java.math.BigDecimal; >-import java.math.BigInteger; >-import java.util.*; >-import org.eclipse.osgi.util.NLS; >-import org.osgi.service.log.LogService; >-import org.osgi.service.metatype.AttributeDefinition; >- >-public class ValueTokenizer { >- private static final char DELIMITER = ','; >- private static final char ESCAPE = '\\'; >- >- private final LogService logger; >- private final List<String> values = new ArrayList<String>(); >- >- /* >- * Constructor of class ValueTokenizer >- */ >- public ValueTokenizer(String values_str, LogService logger) { >- this.logger = logger; >- if (values_str == null) >- return; >- // The trick is to strip out unescaped whitespace characters before and >- // after the input string as well as before and after each >- // individual token within the input string without losing any escaped >- // whitespace characters. Whitespace between two non-whitespace >- // characters may or may not be escaped. Also, any character may be >- // escaped. The escape character is '\'. The delimiter is ','. >- StringBuffer buffer = new StringBuffer(); >- // Loop over the characters within the input string and extract each >- // value token. >- for (int i = 0; i < values_str.length(); i++) { >- char c1 = values_str.charAt(i); >- switch (c1) { >- case DELIMITER : >- // When the delimiter is encountered, add the extracted >- // token to the result and prepare the buffer to receive the >- // next token. >- values.add(buffer.toString()); >- buffer.delete(0, buffer.length()); >- break; >- case ESCAPE : >- // When the escape is encountered, add the immediately >- // following character to the token, unless the end of the >- // input has been reached. Note this will result in loop >- // counter 'i' being incremented twice, once here and once >- // at the end of the loop. >- if (i + 1 < values_str.length()) { >- buffer.append(values_str.charAt(++i)); >- } else { >- // If the ESCAPE character occurs as the last character >- // of the string, log the error and ignore it. >- logger.log(LogService.LOG_ERROR, "ValueTokenizer.ValueTokenizer(String) " + MetaTypeMsg.TOKENIZER_GOT_INVALID_DATA); //$NON-NLS-1$ >- } >- break; >- default : >- // For all other characters, add them to the current token >- // unless dealing with unescaped whitespace at the beginning >- // or end. We know the whitespace is unescaped because it >- // would have been handled in the ESCAPE case otherwise. >- if (Character.isWhitespace(c1)) { >- // Ignore unescaped whitespace at the beginning of the >- // token. >- if (buffer.length() == 0) { >- continue; >- } >- // If the whitespace is not at the beginning, look >- // forward, starting with the next character, to see if >- // it's in the middle or at the end. Unescaped >- // whitespace in the middle is okay. >- for (int j = i + 1; j < values_str.length(); j++) { >- // Keep looping until the end of the string is >- // reached or a non-whitespace character other than >- // the escape is seen. >- char c2 = values_str.charAt(j); >- if (!Character.isWhitespace(c2)) { >- // If the current character is not the DELIMITER, all whitespace >- // characters are significant and should be added to the token. >- // Otherwise, they're at the end and should be ignored. But watch >- // out for an escape character at the end of the input. Ignore it >- // and any previous insignificant whitespace if it exists. >- if (c2 == ESCAPE && j + 1 >= values_str.length()) { >- continue; >- } >- if (c2 != DELIMITER) { >- buffer.append(values_str.substring(i, j)); >- } >- // Let loop counter i catch up with the inner loop but keep in >- // mind it will still be incremented at the end of the outer loop. >- i = j - 1; >- break; >- } >- } >- } else { >- // For non-whitespace characters. >- buffer.append(c1); >- } >- } >- } >- // Don't forget to add the last token. >- values.add(buffer.toString()); >- } >- >- /* >- * Method to return values as Vector. >- */ >- public Collection<String> getValues() { >- return Collections.unmodifiableList(values); >- } >- >- /* >- * Method to return values as String[] or null. >- */ >- public String[] getValuesAsArray() { >- if (values.isEmpty()) { >- return null; >- } >- return values.toArray(new String[values.size()]); >- } >- >- public String getValuesAsString() { >- if (values.isEmpty()) { >- return null; >- } >- if (values.size() == 1) { >- return values.get(0); >- } >- StringBuffer buffer = new StringBuffer(values.get(0)); >- for (int i = 1; i < values.size(); i++) { >- buffer.append(','); >- buffer.append(values.get(i)); >- } >- return buffer.toString(); >- } >- >- public String validate(AttributeDefinitionImpl ad) { >- // An empty list means the original value was null. Null is never valid. >- if (values.isEmpty()) { >- return MetaTypeMsg.NULL_IS_INVALID; >- } >- try { >- // A value must match the cardinality. >- int cardinality = Math.abs(ad.getCardinality()); >- // If the cardinality is zero, the value must contain one and only one token. >- if (cardinality == 0) { >- if (values.size() != 1) { >- return NLS.bind(MetaTypeMsg.CARDINALITY_VIOLATION, new Object[] {getValuesAsString(), values.size(), 1, 1}); >- } >- } >- // Otherwise, the number of tokens must be between 0 and cardinality, inclusive. >- else if (values.size() > cardinality) { >- return NLS.bind(MetaTypeMsg.CARDINALITY_VIOLATION, new Object[] {getValuesAsString(), values.size(), 0, cardinality}); >- } >- // Now inspect each token. >- for (Iterator<String> i = values.iterator(); i.hasNext();) { >- String s = i.next(); >- // If options were declared and the value does not match one of them, the value is not valid. >- if (!ad._values.isEmpty() && !ad._values.contains(s)) { >- return NLS.bind(MetaTypeMsg.VALUE_OUT_OF_OPTION, s); >- } >- // Check the type. Also check the range if min or max were declared. >- boolean rangeError = false; >- switch (ad._dataType) { >- case AttributeDefinition.PASSWORD : >- case AttributeDefinition.STRING : >- if (ad._minValue != null && s.length() < (Integer) ad._minValue) { >- rangeError = true; >- } else if (ad._maxValue != null && s.length() > (Integer) ad._maxValue) { >- rangeError = true; >- } >- break; >- case AttributeDefinition.INTEGER : >- Integer intVal = new Integer(s); >- if (ad._minValue != null && intVal.compareTo((Integer) ad._minValue) < 0) { >- rangeError = true; >- } else if (ad._maxValue != null && intVal.compareTo((Integer) ad._maxValue) > 0) { >- rangeError = true; >- } >- break; >- case AttributeDefinition.LONG : >- Long longVal = new Long(s); >- if (ad._minValue != null && longVal.compareTo((Long) ad._minValue) < 0) { >- rangeError = true; >- } else if (ad._maxValue != null && longVal.compareTo((Long) ad._maxValue) > 0) { >- rangeError = true; >- } >- break; >- case AttributeDefinition.DOUBLE : >- Double doubleVal = new Double(s); >- if (ad._minValue != null && doubleVal.compareTo((Double) ad._minValue) < 0) { >- rangeError = true; >- } else if (ad._maxValue != null && doubleVal.compareTo((Double) ad._maxValue) > 0) { >- rangeError = true; >- } >- break; >- case AttributeDefinition.BOOLEAN : >- // Any string can be converted into a boolean via Boolean.valueOf(String). >- // Seems unnecessary to impose any further restrictions. >- break; >- case AttributeDefinition.CHARACTER : >- Character charVal = new Character(s.charAt(0)); >- if (ad._minValue != null && charVal.compareTo((Character) ad._minValue) < 0) { >- rangeError = true; >- } else if (ad._maxValue != null && charVal.compareTo((Character) ad._maxValue) > 0) { >- rangeError = true; >- } >- break; >- case AttributeDefinition.FLOAT : >- Float floatVal = new Float(s); >- if (ad._minValue != null && floatVal.compareTo((Float) ad._minValue) < 0) { >- rangeError = true; >- } else if (ad._maxValue != null && floatVal.compareTo((Float) ad._maxValue) > 0) { >- rangeError = true; >- } >- break; >- case AttributeDefinition.SHORT : >- Short shortVal = new Short(s); >- if (ad._minValue != null && shortVal.compareTo((Short) ad._minValue) < 0) { >- rangeError = true; >- } else if (ad._maxValue != null && shortVal.compareTo((Short) ad._maxValue) > 0) { >- rangeError = true; >- } >- break; >- case AttributeDefinition.BYTE : >- Byte byteVal = new Byte(s); >- if (ad._minValue != null && byteVal.compareTo((Byte) ad._minValue) < 0) { >- rangeError = true; >- } else if (ad._maxValue != null && byteVal.compareTo((Byte) ad._maxValue) > 0) { >- rangeError = true; >- } >- break; >- case AttributeDefinition.BIGDECIMAL : >- BigDecimal bigDecVal = new BigDecimal(s); >- if (ad._minValue != null && bigDecVal.compareTo((BigDecimal) ad._minValue) < 0) { >- rangeError = true; >- } else if (ad._maxValue != null && bigDecVal.compareTo((BigDecimal) ad._maxValue) > 0) { >- rangeError = true; >- } >- break; >- case AttributeDefinition.BIGINTEGER : >- BigInteger bigIntVal = new BigInteger(s); >- if (ad._minValue != null && bigIntVal.compareTo((BigInteger) ad._minValue) < 0) { >- rangeError = true; >- } else if (ad._maxValue != null && bigIntVal.compareTo((BigInteger) ad._maxValue) > 0) { >- rangeError = true; >- } >- break; >- default : >- throw new IllegalStateException(); >- } >- if (rangeError) { >- return (NLS.bind(MetaTypeMsg.VALUE_OUT_OF_RANGE, s)); >- } >- } >- // No problems detected >- return ""; //$NON-NLS-1$ >- } catch (Throwable t) { >- String message = NLS.bind(MetaTypeMsg.EXCEPTION_MESSAGE, t.getClass().getName(), t.getMessage()); >- logger.log(LogService.LOG_DEBUG, message, t); >- return message; >- } >- } >-} >Index: src/org/eclipse/equinox/metatype/impl/Activator.java >=================================================================== >RCS file: src/org/eclipse/equinox/metatype/impl/Activator.java >diff -N src/org/eclipse/equinox/metatype/impl/Activator.java >--- /dev/null 1 Jan 1970 00:00:00 -0000 >+++ src/org/eclipse/equinox/metatype/impl/Activator.java 1 Jan 1970 00:00:00 -0000 >@@ -0,0 +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); >+ } >+ } >+} >Index: src/org/eclipse/equinox/metatype/impl/AttributeDefinitionImpl.java >=================================================================== >RCS file: src/org/eclipse/equinox/metatype/impl/AttributeDefinitionImpl.java >diff -N src/org/eclipse/equinox/metatype/impl/AttributeDefinitionImpl.java >--- /dev/null 1 Jan 1970 00:00:00 -0000 >+++ src/org/eclipse/equinox/metatype/impl/AttributeDefinitionImpl.java 1 Jan 1970 00:00:00 -0000 >@@ -0,0 +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(); >+ } >+} >Index: src/org/eclipse/equinox/metatype/impl/DataParser.java >=================================================================== >RCS file: src/org/eclipse/equinox/metatype/impl/DataParser.java >diff -N src/org/eclipse/equinox/metatype/impl/DataParser.java >--- /dev/null 1 Jan 1970 00:00:00 -0000 >+++ src/org/eclipse/equinox/metatype/impl/DataParser.java 1 Jan 1970 00:00:00 -0000 >@@ -0,0 +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); >+ } >+} >Index: src/org/eclipse/equinox/metatype/impl/Designate.java >=================================================================== >RCS file: src/org/eclipse/equinox/metatype/impl/Designate.java >diff -N src/org/eclipse/equinox/metatype/impl/Designate.java >--- /dev/null 1 Jan 1970 00:00:00 -0000 >+++ src/org/eclipse/equinox/metatype/impl/Designate.java 1 Jan 1970 00:00:00 -0000 >@@ -0,0 +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; >+ } >+} >Index: src/org/eclipse/equinox/metatype/impl/ExtendableHelper.java >=================================================================== >RCS file: src/org/eclipse/equinox/metatype/impl/ExtendableHelper.java >diff -N src/org/eclipse/equinox/metatype/impl/ExtendableHelper.java >--- /dev/null 1 Jan 1970 00:00:00 -0000 >+++ src/org/eclipse/equinox/metatype/impl/ExtendableHelper.java 1 Jan 1970 00:00:00 -0000 >@@ -0,0 +1,39 @@ >+/******************************************************************************* >+ * Copyright (c) 2011 IBM Corporation and others >+ * All rights reserved. This program and the accompanying materials >+ * are made available under the terms of the Eclipse Public License v1.0 >+ * which accompanies this distribution, and is available at >+ * http://www.eclipse.org/legal/epl-v10.html >+ * >+ * Contributors: >+ * IBM Corporation - initial API and implementation >+ *******************************************************************************/ >+package org.eclipse.equinox.metatype.impl; >+ >+import org.eclipse.equinox.metatype.Extendable; >+ >+import java.util.*; >+ >+public class ExtendableHelper implements Extendable { >+ private final Map<String, Map<String, String>> attributes; >+ >+ @SuppressWarnings("unchecked") >+ public ExtendableHelper() { >+ this(Collections.EMPTY_MAP); >+ } >+ >+ public ExtendableHelper(Map<String, Map<String, String>> attributes) { >+ if (attributes == null) >+ throw new NullPointerException(); >+ this.attributes = attributes; >+ } >+ >+ public Map<String, String> getExtensionAttributes(String schema) { >+ return Collections.unmodifiableMap(attributes.get(schema)); >+ } >+ >+ public Set<String> getExtensionUris() { >+ return Collections.unmodifiableSet(attributes.keySet()); >+ } >+ >+} >Index: src/org/eclipse/equinox/metatype/impl/ExternalMessages.properties >=================================================================== >RCS file: src/org/eclipse/equinox/metatype/impl/ExternalMessages.properties >diff -N src/org/eclipse/equinox/metatype/impl/ExternalMessages.properties >--- /dev/null 1 Jan 1970 00:00:00 -0000 >+++ src/org/eclipse/equinox/metatype/impl/ExternalMessages.properties 1 Jan 1970 00:00:00 -0000 >@@ -0,0 +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. >+METADATA_PARSE_ERROR=Unable to parse metadata XML at {0} for bundle ID {1}. >\ No newline at end of file >Index: src/org/eclipse/equinox/metatype/impl/FragmentUtils.java >=================================================================== >RCS file: src/org/eclipse/equinox/metatype/impl/FragmentUtils.java >diff -N src/org/eclipse/equinox/metatype/impl/FragmentUtils.java >--- /dev/null 1 Jan 1970 00:00:00 -0000 >+++ src/org/eclipse/equinox/metatype/impl/FragmentUtils.java 1 Jan 1970 00:00:00 -0000 >@@ -0,0 +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()]); >+ } >+} >Index: src/org/eclipse/equinox/metatype/impl/Icon.java >=================================================================== >RCS file: src/org/eclipse/equinox/metatype/impl/Icon.java >diff -N src/org/eclipse/equinox/metatype/impl/Icon.java >--- /dev/null 1 Jan 1970 00:00:00 -0000 >+++ src/org/eclipse/equinox/metatype/impl/Icon.java 1 Jan 1970 00:00:00 -0000 >@@ -0,0 +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; >+ } >+} >Index: src/org/eclipse/equinox/metatype/impl/LocalizationElement.java >=================================================================== >RCS file: src/org/eclipse/equinox/metatype/impl/LocalizationElement.java >diff -N src/org/eclipse/equinox/metatype/impl/LocalizationElement.java >--- /dev/null 1 Jan 1970 00:00:00 -0000 >+++ src/org/eclipse/equinox/metatype/impl/LocalizationElement.java 1 Jan 1970 00:00:00 -0000 >@@ -0,0 +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; >+ } >+} >Index: src/org/eclipse/equinox/metatype/impl/LogMessages.properties >=================================================================== >RCS file: src/org/eclipse/equinox/metatype/impl/LogMessages.properties >diff -N src/org/eclipse/equinox/metatype/impl/LogMessages.properties >--- /dev/null 1 Jan 1970 00:00:00 -0000 >+++ src/org/eclipse/equinox/metatype/impl/LogMessages.properties 1 Jan 1970 00:00:00 -0000 >@@ -0,0 +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 >Index: src/org/eclipse/equinox/metatype/impl/LogTracker.java >=================================================================== >RCS file: src/org/eclipse/equinox/metatype/impl/LogTracker.java >diff -N src/org/eclipse/equinox/metatype/impl/LogTracker.java >--- /dev/null 1 Jan 1970 00:00:00 -0000 >+++ src/org/eclipse/equinox/metatype/impl/LogTracker.java 1 Jan 1970 00:00:00 -0000 >@@ -0,0 +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; >+ } >+} >Index: src/org/eclipse/equinox/metatype/impl/LogTrackerMsg.java >=================================================================== >RCS file: src/org/eclipse/equinox/metatype/impl/LogTrackerMsg.java >diff -N src/org/eclipse/equinox/metatype/impl/LogTrackerMsg.java >--- /dev/null 1 Jan 1970 00:00:00 -0000 >+++ src/org/eclipse/equinox/metatype/impl/LogTrackerMsg.java 1 Jan 1970 00:00:00 -0000 >@@ -0,0 +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.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); >+ } >+} >Index: src/org/eclipse/equinox/metatype/impl/MetaTypeInformationImpl.java >=================================================================== >RCS file: src/org/eclipse/equinox/metatype/impl/MetaTypeInformationImpl.java >diff -N src/org/eclipse/equinox/metatype/impl/MetaTypeInformationImpl.java >--- /dev/null 1 Jan 1970 00:00:00 -0000 >+++ src/org/eclipse/equinox/metatype/impl/MetaTypeInformationImpl.java 1 Jan 1970 00:00:00 -0000 >@@ -0,0 +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; >+ } >+} >Index: src/org/eclipse/equinox/metatype/impl/MetaTypeMsg.java >=================================================================== >RCS file: src/org/eclipse/equinox/metatype/impl/MetaTypeMsg.java >diff -N src/org/eclipse/equinox/metatype/impl/MetaTypeMsg.java >--- /dev/null 1 Jan 1970 00:00:00 -0000 >+++ src/org/eclipse/equinox/metatype/impl/MetaTypeMsg.java 1 Jan 1970 00:00:00 -0000 >@@ -0,0 +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.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 >Index: src/org/eclipse/equinox/metatype/impl/MetaTypeProviderImpl.java >=================================================================== >RCS file: src/org/eclipse/equinox/metatype/impl/MetaTypeProviderImpl.java >diff -N src/org/eclipse/equinox/metatype/impl/MetaTypeProviderImpl.java >--- /dev/null 1 Jan 1970 00:00:00 -0000 >+++ src/org/eclipse/equinox/metatype/impl/MetaTypeProviderImpl.java 1 Jan 1970 00:00:00 -0000 >@@ -0,0 +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; >+ } >+} >Index: src/org/eclipse/equinox/metatype/impl/MetaTypeProviderTracker.java >=================================================================== >RCS file: src/org/eclipse/equinox/metatype/impl/MetaTypeProviderTracker.java >diff -N src/org/eclipse/equinox/metatype/impl/MetaTypeProviderTracker.java >--- /dev/null 1 Jan 1970 00:00:00 -0000 >+++ src/org/eclipse/equinox/metatype/impl/MetaTypeProviderTracker.java 1 Jan 1970 00:00:00 -0000 >@@ -0,0 +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(); >+ } >+ } >+} >Index: src/org/eclipse/equinox/metatype/impl/MetaTypeServiceImpl.java >=================================================================== >RCS file: src/org/eclipse/equinox/metatype/impl/MetaTypeServiceImpl.java >diff -N src/org/eclipse/equinox/metatype/impl/MetaTypeServiceImpl.java >--- /dev/null 1 Jan 1970 00:00:00 -0000 >+++ src/org/eclipse/equinox/metatype/impl/MetaTypeServiceImpl.java 1 Jan 1970 00:00:00 -0000 >@@ -0,0 +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; >+ } >+ } >+} >Index: src/org/eclipse/equinox/metatype/impl/ObjectClassDefinitionImpl.java >=================================================================== >RCS file: src/org/eclipse/equinox/metatype/impl/ObjectClassDefinitionImpl.java >diff -N src/org/eclipse/equinox/metatype/impl/ObjectClassDefinitionImpl.java >--- /dev/null 1 Jan 1970 00:00:00 -0000 >+++ src/org/eclipse/equinox/metatype/impl/ObjectClassDefinitionImpl.java 1 Jan 1970 00:00:00 -0000 >@@ -0,0 +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(); >+ } >+} >Index: src/org/eclipse/equinox/metatype/impl/ValueTokenizer.java >=================================================================== >RCS file: src/org/eclipse/equinox/metatype/impl/ValueTokenizer.java >diff -N src/org/eclipse/equinox/metatype/impl/ValueTokenizer.java >--- /dev/null 1 Jan 1970 00:00:00 -0000 >+++ src/org/eclipse/equinox/metatype/impl/ValueTokenizer.java 1 Jan 1970 00:00:00 -0000 >@@ -0,0 +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; >+ } >+ } >+}
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Diff
View Attachment As Raw
Actions:
View
|
Diff
Attachments on
bug 349711
:
199144
|
199217
| 199393 |
199394