From 19cf1c68d5c5862b4f9681f3645de747779a3696 Mon Sep 17 00:00:00 2001 From: Thomas Watson Date: Thu, 29 Sep 2016 09:12:52 -0500 Subject: Bug 501950 - [ds] replace Equinox DS implementation with Felix SCR (DS) implementation Gut the Equinox implementation and have it require the felix impl and manage the activation and start-level of felix scr. Change-Id: Idbbb73af5edf2871f4df5edd8329039b342c5995 Signed-off-by: Thomas Watson --- .../All DS Tests.launch | 877 ++++++------- .../ds/tests/tb25/ServicePropertiesComp.java | 5 +- .../eclipse/equinox/ds/tests/tb25/components.xml | 22 +- .../equinox/ds/tests/tb7/StaticCircuit1.java | 9 + .../eclipse/equinox/ds/tests/tb7/components.xml | 2 + .../org/eclipse/equinox/ds/tests/tbc/DSTest.java | 165 +-- bundles/org.eclipse.equinox.ds/.classpath | 4 +- bundles/org.eclipse.equinox.ds/.options | 16 - .../org.eclipse.equinox.ds/.settings/.api_filters | 35 + .../.settings/org.eclipse.jdt.core.prefs | 20 +- .../org.eclipse.equinox.ds/META-INF/MANIFEST.MF | 44 +- bundles/org.eclipse.equinox.ds/build.properties | 1 - bundles/org.eclipse.equinox.ds/pom.xml | 2 +- .../src/org/apache/felix/scr/Component.java | 332 ----- .../src/org/apache/felix/scr/Reference.java | 119 -- .../src/org/apache/felix/scr/ScrService.java | 83 -- .../src/org/apache/felix/scr/package.html | 15 - .../org/eclipse/equinox/internal/ds/Activator.java | 435 +------ .../equinox/internal/ds/CircularityException.java | 35 - .../equinox/internal/ds/ComponentStorage.java | 126 -- .../eclipse/equinox/internal/ds/FactoryReg.java | 67 - .../equinox/internal/ds/InstanceProcess.java | 838 ------------ .../org/eclipse/equinox/internal/ds/Messages.java | 183 --- .../org/eclipse/equinox/internal/ds/Reference.java | 493 -------- .../org/eclipse/equinox/internal/ds/Resolver.java | 1245 ------------------ .../equinox/internal/ds/SCRCommandProvider.java | 810 ------------ .../eclipse/equinox/internal/ds/SCRManager.java | 977 -------------- .../org/eclipse/equinox/internal/ds/SCRUtil.java | 279 ---- .../equinox/internal/ds/SCRmessages.properties | 168 --- .../equinox/internal/ds/ScrServiceImpl.java | 54 - .../eclipse/equinox/internal/ds/ServiceReg.java | 120 -- .../eclipse/equinox/internal/ds/WorkPerformer.java | 37 - .../eclipse/equinox/internal/ds/WorkThread.java | 111 -- .../internal/ds/impl/ComponentContextImpl.java | 328 ----- .../internal/ds/impl/ComponentFactoryImpl.java | 117 -- .../internal/ds/impl/ComponentInstanceImpl.java | 107 -- .../internal/ds/impl/ReadOnlyDictionary.java | 139 -- .../internal/ds/model/ComponentReference.java | 800 ------------ .../internal/ds/model/DeclarationParser.java | 885 ------------- .../internal/ds/model/ServiceComponent.java | 971 -------------- .../internal/ds/model/ServiceComponentProp.java | 928 -------------- .../equinox/internal/ds/storage/file/DBObject.java | 70 -- .../internal/ds/storage/file/FileStorage.java | 258 ---- .../equinox/internal/util/io/Externalizable.java | 37 - .../internal/util/io/ExternalizableDictionary.java | 759 ----------- .../equinox/internal/util/io/PDataStream.java | 236 ---- .../eclipse/equinox/internal/util/io/package.html | 9 - .../equinox/internal/util/string/CharBuffer.java | 163 --- .../equinox/internal/util/string/package.html | 18 - .../equinox/internal/util/xml/ExTagListener.java | 43 - .../org/eclipse/equinox/internal/util/xml/Tag.java | 109 -- .../equinox/internal/util/xml/TagClass.java | 296 ----- .../equinox/internal/util/xml/TagListener.java | 34 - .../equinox/internal/util/xml/XMLParser.java | 121 -- .../equinox/internal/util/xml/XMLReader.java | 1329 -------------------- .../eclipse/equinox/internal/util/xml/XMLUtil.java | 363 ------ .../equinox/internal/util/xml/XmlSerializer.java | 444 ------- .../equinox/internal/util/xml/impl/TagImpl.java | 381 ------ .../internal/util/xml/impl/XMLParserImpl.java | 1219 ------------------ .../eclipse/equinox/internal/util/xml/package.html | 12 - 60 files changed, 648 insertions(+), 17257 deletions(-) delete mode 100644 bundles/org.eclipse.equinox.ds/.options create mode 100644 bundles/org.eclipse.equinox.ds/.settings/.api_filters delete mode 100644 bundles/org.eclipse.equinox.ds/src/org/apache/felix/scr/Component.java delete mode 100644 bundles/org.eclipse.equinox.ds/src/org/apache/felix/scr/Reference.java delete mode 100644 bundles/org.eclipse.equinox.ds/src/org/apache/felix/scr/ScrService.java delete mode 100644 bundles/org.eclipse.equinox.ds/src/org/apache/felix/scr/package.html delete mode 100644 bundles/org.eclipse.equinox.ds/src/org/eclipse/equinox/internal/ds/CircularityException.java delete mode 100644 bundles/org.eclipse.equinox.ds/src/org/eclipse/equinox/internal/ds/ComponentStorage.java delete mode 100644 bundles/org.eclipse.equinox.ds/src/org/eclipse/equinox/internal/ds/FactoryReg.java delete mode 100644 bundles/org.eclipse.equinox.ds/src/org/eclipse/equinox/internal/ds/InstanceProcess.java delete mode 100644 bundles/org.eclipse.equinox.ds/src/org/eclipse/equinox/internal/ds/Messages.java delete mode 100644 bundles/org.eclipse.equinox.ds/src/org/eclipse/equinox/internal/ds/Reference.java delete mode 100644 bundles/org.eclipse.equinox.ds/src/org/eclipse/equinox/internal/ds/Resolver.java delete mode 100644 bundles/org.eclipse.equinox.ds/src/org/eclipse/equinox/internal/ds/SCRCommandProvider.java delete mode 100644 bundles/org.eclipse.equinox.ds/src/org/eclipse/equinox/internal/ds/SCRManager.java delete mode 100644 bundles/org.eclipse.equinox.ds/src/org/eclipse/equinox/internal/ds/SCRUtil.java delete mode 100644 bundles/org.eclipse.equinox.ds/src/org/eclipse/equinox/internal/ds/SCRmessages.properties delete mode 100644 bundles/org.eclipse.equinox.ds/src/org/eclipse/equinox/internal/ds/ScrServiceImpl.java delete mode 100644 bundles/org.eclipse.equinox.ds/src/org/eclipse/equinox/internal/ds/ServiceReg.java delete mode 100644 bundles/org.eclipse.equinox.ds/src/org/eclipse/equinox/internal/ds/WorkPerformer.java delete mode 100644 bundles/org.eclipse.equinox.ds/src/org/eclipse/equinox/internal/ds/WorkThread.java delete mode 100644 bundles/org.eclipse.equinox.ds/src/org/eclipse/equinox/internal/ds/impl/ComponentContextImpl.java delete mode 100644 bundles/org.eclipse.equinox.ds/src/org/eclipse/equinox/internal/ds/impl/ComponentFactoryImpl.java delete mode 100644 bundles/org.eclipse.equinox.ds/src/org/eclipse/equinox/internal/ds/impl/ComponentInstanceImpl.java delete mode 100644 bundles/org.eclipse.equinox.ds/src/org/eclipse/equinox/internal/ds/impl/ReadOnlyDictionary.java delete mode 100644 bundles/org.eclipse.equinox.ds/src/org/eclipse/equinox/internal/ds/model/ComponentReference.java delete mode 100644 bundles/org.eclipse.equinox.ds/src/org/eclipse/equinox/internal/ds/model/DeclarationParser.java delete mode 100644 bundles/org.eclipse.equinox.ds/src/org/eclipse/equinox/internal/ds/model/ServiceComponent.java delete mode 100644 bundles/org.eclipse.equinox.ds/src/org/eclipse/equinox/internal/ds/model/ServiceComponentProp.java delete mode 100644 bundles/org.eclipse.equinox.ds/src/org/eclipse/equinox/internal/ds/storage/file/DBObject.java delete mode 100644 bundles/org.eclipse.equinox.ds/src/org/eclipse/equinox/internal/ds/storage/file/FileStorage.java delete mode 100644 bundles/org.eclipse.equinox.ds/src/org/eclipse/equinox/internal/util/io/Externalizable.java delete mode 100644 bundles/org.eclipse.equinox.ds/src/org/eclipse/equinox/internal/util/io/ExternalizableDictionary.java delete mode 100644 bundles/org.eclipse.equinox.ds/src/org/eclipse/equinox/internal/util/io/PDataStream.java delete mode 100644 bundles/org.eclipse.equinox.ds/src/org/eclipse/equinox/internal/util/io/package.html delete mode 100644 bundles/org.eclipse.equinox.ds/src/org/eclipse/equinox/internal/util/string/CharBuffer.java delete mode 100644 bundles/org.eclipse.equinox.ds/src/org/eclipse/equinox/internal/util/string/package.html delete mode 100644 bundles/org.eclipse.equinox.ds/src/org/eclipse/equinox/internal/util/xml/ExTagListener.java delete mode 100644 bundles/org.eclipse.equinox.ds/src/org/eclipse/equinox/internal/util/xml/Tag.java delete mode 100644 bundles/org.eclipse.equinox.ds/src/org/eclipse/equinox/internal/util/xml/TagClass.java delete mode 100644 bundles/org.eclipse.equinox.ds/src/org/eclipse/equinox/internal/util/xml/TagListener.java delete mode 100644 bundles/org.eclipse.equinox.ds/src/org/eclipse/equinox/internal/util/xml/XMLParser.java delete mode 100644 bundles/org.eclipse.equinox.ds/src/org/eclipse/equinox/internal/util/xml/XMLReader.java delete mode 100644 bundles/org.eclipse.equinox.ds/src/org/eclipse/equinox/internal/util/xml/XMLUtil.java delete mode 100644 bundles/org.eclipse.equinox.ds/src/org/eclipse/equinox/internal/util/xml/XmlSerializer.java delete mode 100644 bundles/org.eclipse.equinox.ds/src/org/eclipse/equinox/internal/util/xml/impl/TagImpl.java delete mode 100644 bundles/org.eclipse.equinox.ds/src/org/eclipse/equinox/internal/util/xml/impl/XMLParserImpl.java delete mode 100644 bundles/org.eclipse.equinox.ds/src/org/eclipse/equinox/internal/util/xml/package.html diff --git a/bundles/org.eclipse.equinox.ds.tests/All DS Tests.launch b/bundles/org.eclipse.equinox.ds.tests/All DS Tests.launch index 3a5b9a7b1..af7178b29 100644 --- a/bundles/org.eclipse.equinox.ds.tests/All DS Tests.launch +++ b/bundles/org.eclipse.equinox.ds.tests/All DS Tests.launch @@ -1,436 +1,441 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/bundles/org.eclipse.equinox.ds.tests/bundles_src/tb25/org/eclipse/equinox/ds/tests/tb25/ServicePropertiesComp.java b/bundles/org.eclipse.equinox.ds.tests/bundles_src/tb25/org/eclipse/equinox/ds/tests/tb25/ServicePropertiesComp.java index 236dd5a6c..ecef4eb56 100644 --- a/bundles/org.eclipse.equinox.ds.tests/bundles_src/tb25/org/eclipse/equinox/ds/tests/tb25/ServicePropertiesComp.java +++ b/bundles/org.eclipse.equinox.ds.tests/bundles_src/tb25/org/eclipse/equinox/ds/tests/tb25/ServicePropertiesComp.java @@ -32,7 +32,10 @@ public class ServicePropertiesComp implements PropertiesProvider { } - public void bindRef(PropertiesProvider service, Map properties) { + public void bindDynamicRef(PropertiesProvider service, Map properties) { + } + + public void bindStaticRef(PropertiesProvider service, Map properties) { } public synchronized void serviceUpdatedStatic(PropertiesProvider service, Map properties) { diff --git a/bundles/org.eclipse.equinox.ds.tests/bundles_src/tb25/org/eclipse/equinox/ds/tests/tb25/components.xml b/bundles/org.eclipse.equinox.ds.tests/bundles_src/tb25/org/eclipse/equinox/ds/tests/tb25/components.xml index 32a308be3..9b060e7fb 100644 --- a/bundles/org.eclipse.equinox.ds.tests/bundles_src/tb25/org/eclipse/equinox/ds/tests/tb25/components.xml +++ b/bundles/org.eclipse.equinox.ds.tests/bundles_src/tb25/org/eclipse/equinox/ds/tests/tb25/components.xml @@ -11,13 +11,15 @@ @@ -35,24 +37,28 @@ interface="org.eclipse.equinox.ds.tests.tbc.PropertiesProvider" target="(service.provider=reluctant.policy.option.test)" cardinality="0..1" + name="bind01" bind="bind01" policy-option="reluctant"/> @@ -71,6 +77,7 @@ interface="org.eclipse.equinox.ds.tests.tbc.PropertiesProvider" target="(service.provider=reluctant.policy.option.test)" cardinality="0..1" + name="bind01" bind="bind01" policy="dynamic" policy-option="reluctant"/> @@ -78,6 +85,7 @@ interface="org.eclipse.equinox.ds.tests.tbc.PropertiesProvider" target="(service.provider=reluctant.policy.option.test)" cardinality="1..1" + name="bind11" bind="bind11" policy="dynamic" policy-option="reluctant"/> @@ -85,6 +93,7 @@ interface="org.eclipse.equinox.ds.tests.tbc.PropertiesProvider" target="(service.provider=reluctant.policy.option.test)" cardinality="0..n" + name="bind0n" bind="bind0n" policy="dynamic" policy-option="reluctant"/> @@ -92,6 +101,7 @@ interface="org.eclipse.equinox.ds.tests.tbc.PropertiesProvider" target="(service.provider=reluctant.policy.option.test)" cardinality="1..n" + name="bind1n" bind="bind1n" policy="dynamic" policy-option="reluctant"/> @@ -111,24 +121,28 @@ interface="org.eclipse.equinox.ds.tests.tbc.PropertiesProvider" target="(service.provider=greedy.policy.option.test)" cardinality="0..1" + name="bind01" bind="bind01" policy-option="greedy"/> @@ -147,6 +161,7 @@ interface="org.eclipse.equinox.ds.tests.tbc.PropertiesProvider" target="(service.provider=greedy.policy.option.test)" cardinality="0..1" + name="bind01" bind="bind01" policy="dynamic" policy-option="greedy"/> @@ -154,6 +169,7 @@ interface="org.eclipse.equinox.ds.tests.tbc.PropertiesProvider" target="(service.provider=greedy.policy.option.test)" cardinality="1..1" + name="bind11" bind="bind11" policy="dynamic" policy-option="greedy"/> @@ -161,6 +177,7 @@ interface="org.eclipse.equinox.ds.tests.tbc.PropertiesProvider" target="(service.provider=greedy.policy.option.test)" cardinality="0..n" + name="bind0n" bind="bind0n" policy="dynamic" policy-option="greedy"/> @@ -168,6 +185,7 @@ interface="org.eclipse.equinox.ds.tests.tbc.PropertiesProvider" target="(service.provider=greedy.policy.option.test)" cardinality="1..n" + name="bind1n" bind="bind1n" policy="dynamic" policy-option="greedy"/> diff --git a/bundles/org.eclipse.equinox.ds.tests/bundles_src/tb7/org/eclipse/equinox/ds/tests/tb7/StaticCircuit1.java b/bundles/org.eclipse.equinox.ds.tests/bundles_src/tb7/org/eclipse/equinox/ds/tests/tb7/StaticCircuit1.java index fb11abedd..a9b04839f 100644 --- a/bundles/org.eclipse.equinox.ds.tests/bundles_src/tb7/org/eclipse/equinox/ds/tests/tb7/StaticCircuit1.java +++ b/bundles/org.eclipse.equinox.ds.tests/bundles_src/tb7/org/eclipse/equinox/ds/tests/tb7/StaticCircuit1.java @@ -12,5 +12,14 @@ package org.eclipse.equinox.ds.tests.tb7; public class StaticCircuit1 { + private StaticCircuit2 mate = null; + public void bind(StaticCircuit2 mate) { + this.mate = mate; + } + public void unbind(StaticCircuit2 mate) { + if (this.mate == mate) { + this.mate = null; + } + } } diff --git a/bundles/org.eclipse.equinox.ds.tests/bundles_src/tb7/org/eclipse/equinox/ds/tests/tb7/components.xml b/bundles/org.eclipse.equinox.ds.tests/bundles_src/tb7/org/eclipse/equinox/ds/tests/tb7/components.xml index dc289e7e2..e62aabb3b 100644 --- a/bundles/org.eclipse.equinox.ds.tests/bundles_src/tb7/org/eclipse/equinox/ds/tests/tb7/components.xml +++ b/bundles/org.eclipse.equinox.ds.tests/bundles_src/tb7/org/eclipse/equinox/ds/tests/tb7/components.xml @@ -66,6 +66,8 @@ diff --git a/bundles/org.eclipse.equinox.ds.tests/src/org/eclipse/equinox/ds/tests/tbc/DSTest.java b/bundles/org.eclipse.equinox.ds.tests/src/org/eclipse/equinox/ds/tests/tbc/DSTest.java index 0350c010d..b08b45a62 100644 --- a/bundles/org.eclipse.equinox.ds.tests/src/org/eclipse/equinox/ds/tests/tbc/DSTest.java +++ b/bundles/org.eclipse.equinox.ds.tests/src/org/eclipse/equinox/ds/tests/tbc/DSTest.java @@ -477,23 +477,15 @@ public class DSTest { assertNotNull("The Worker should be available before we disable it", trackerSC.getServiceReferences()); assertTrue("The Worker should be available before we disable it", trackerSC.getServiceReferences().length > 0); - // *** test disableComponent() method - boolean exceptionThrown = false; try { ((ComponentManager) extendedClass).enableComponent("InvalidParameter", true); // test // for // disabling // unexistent - } catch (IllegalArgumentException iae) { - // expected exception - exceptionThrown = true; } catch (Exception e) { // unexpected exception fail("Unexpected exception " + e.getMessage()); } - if (!exceptionThrown) { - fail("Expected IllegalArgumentException but not thrown"); - } ((ComponentManager) extendedClass).enableComponent(SAC_CLASS, false); Thread.sleep(timeout); // let the SCR to unregister the service @@ -634,8 +626,9 @@ public class DSTest { ctxt.getBundleContext().ungetService(sr1); } - assertNull("locateService() must return null when passed ServiceReference is null", ctxt.locateService( - "StandAloneComp", null)); +// null is not allowed for ServiceReference +// assertNull("locateService() must return null when passed ServiceReference is null", ctxt.locateService( +// "StandAloneComp", null)); assertNull("locateService() must return null when passed ServiceReference isn't bound to the component", ctxt .locateService("StandAloneComp", trackerExtendedClass.getServiceReference())); @@ -663,7 +656,7 @@ public class DSTest { // the line below will create the configuration if it doesn't exists! // see CM api for details - Configuration config = cm.getConfiguration(SAC_CLASS); + Configuration config = cm.getConfiguration(SAC_CLASS, null); assertNotNull("The Configuration object should be created if don't exist", config); config.update(props); @@ -692,7 +685,7 @@ public class DSTest { bundle.start(); waitBundleStart(); - Configuration c = cm.getConfiguration(NAMED_CLASS); + Configuration c = cm.getConfiguration(NAMED_CLASS, null); assertNotNull("The Configuration should be created properly", c); Hashtable cmProps = new Hashtable(); cmProps.put("override.property.3", "setFromCM"); @@ -712,8 +705,16 @@ public class DSTest { newProps.put(ComponentConstants.COMPONENT_ID, Long.valueOf(-1)); newProps.put("name", "test"); + List cis = new ArrayList(); ComponentInstance ci = factory.newInstance(newProps); assertNotNull("newInstance() method shouldn't return null", ci); + cis.add(ci); + ci = factory.newInstance(newProps); + assertNotNull("newInstance() method shouldn't return null", ci); + cis.add(ci); + ci = factory.newInstance(newProps); + assertNotNull("newInstance() method shouldn't return null", ci); + cis.add(ci); ServiceReference[] refs = trackerNamedService.getServiceReferences(); boolean serviceFound = false; @@ -735,12 +736,18 @@ public class DSTest { } assertTrue("Must have found service", serviceFound); - ci.dispose(); + for (ComponentInstance i :cis) { + i.dispose(); + } c.delete(); - bundle.stop(); + //bundle.stop(); + + factory = (ComponentFactory) trackerNamedServiceFactory.getService(); + ci = factory.newInstance(newProps); + assertNotNull("newInstance() method shouldn't return null", ci); // test the conflict between factory and factoryPID - c = cm.createFactoryConfiguration(NAMED_CLASS); + c = cm.createFactoryConfiguration(NAMED_CLASS, null); assertNotNull("CM should not return null Configuration from createFactoryConfiguration()", c); c.update(cmProps); Thread.sleep(timeout); @@ -748,19 +755,22 @@ public class DSTest { bundle.start(); waitBundleStart(); - assertNull("The named service shouldn't be available when there is factory configuration for it", + // TODO Equinox DS behaves differently than Felix SCR here. The specification is vague + // Equinox DS will disable the component factory in this error case + // Felix will keep the component factory enabled and ignore the CM factory configuration + assertNotNull("The named service ComponentFactory should be available even when there is factory configuration for it", trackerNamedServiceFactory.getService()); c.delete(); Thread.sleep(timeout * 2); // create factory configs for Worker - Configuration scConfig1 = cm.createFactoryConfiguration(SC_CLASS); + Configuration scConfig1 = cm.createFactoryConfiguration(SC_CLASS, null); Hashtable scProps1 = new Hashtable(); scProps1.put("name", "instance1"); scConfig1.update(scProps1); - Configuration scConfig2 = cm.createFactoryConfiguration(SC_CLASS); + Configuration scConfig2 = cm.createFactoryConfiguration(SC_CLASS, null); Hashtable scProps2 = new Hashtable(); scProps2.put("name", "instance2"); scConfig2.update(scProps2); @@ -1419,7 +1429,8 @@ public class DSTest { } // tests namespace handling in xml component description parser - @Test + // TODO Felix handles improper XML differently, not sure this is spec'ed behavior. + // disable @Test public void testNamespaceHandling() throws Exception { Bundle tb8 = installBundle("tb8"); tb8.start(); @@ -1628,7 +1639,7 @@ public class DSTest { // 1.0.0 assertEquals("Configuration data should not be available for notsetNS100", 0, getBaseConfigData(COMP_NOTSET_100)); // component notsetNS100 - property set by Configuration Admin; XML NS 1.0.0 - Configuration config = cm.getConfiguration(COMP_NOTSET_100); + Configuration config = cm.getConfiguration(COMP_NOTSET_100, null); config.update(props); Thread.sleep(timeout * 2); assertEquals("Configuration data should be available for notsetNS100 and equal to 1", 1, @@ -1638,7 +1649,7 @@ public class DSTest { // 1.1.0 assertEquals("Configuration data should not be available for notsetNS110", 0, getBaseConfigData(COMP_NOTSET_110)); // component notsetNS110 - property set by Configuration Admin; XML NS 1.1.0 - config = cm.getConfiguration(COMP_NOTSET_110); + config = cm.getConfiguration(COMP_NOTSET_110, null); config.update(props); Thread.sleep(timeout * 2); assertEquals("Configuration data should be available for notsetNS110 and equal to 1", 1, @@ -1649,7 +1660,7 @@ public class DSTest { assertEquals("Component optionalNS100 should not be activated", -1, getBaseConfigData(COMP_OPTIONAL_100)); // component optionalNS100 - property set by Configuration Admin; XML NS // 1.0.0 - INVALID COMPONENT - config = cm.getConfiguration(COMP_OPTIONAL_100); + config = cm.getConfiguration(COMP_OPTIONAL_100, null); config.update(props); Thread.sleep(timeout * 2); assertEquals("Component optionalNS100 should not be activated", -1, getBaseConfigData(COMP_OPTIONAL_100)); @@ -1660,7 +1671,7 @@ public class DSTest { getBaseConfigData(COMP_OPTIONAL_110)); // component optionalNS110 - property set by Configuration Admin; XML NS // 1.1.0 - config = cm.getConfiguration(COMP_OPTIONAL_110); + config = cm.getConfiguration(COMP_OPTIONAL_110, null); config.update(props); Thread.sleep(timeout * 2); assertEquals("Configuration data should be available for optionalNS110 and equal to 1", 1, @@ -1671,7 +1682,7 @@ public class DSTest { assertEquals("Component requireNS100 should not be activated", -1, getBaseConfigData(COMP_REQUIRE_100)); // component requireNS100 - property set by Configuration Admin; XML NS // 1.0.0 - INVALID COMPONENT - config = cm.getConfiguration(COMP_REQUIRE_100); + config = cm.getConfiguration(COMP_REQUIRE_100, null); config.update(props); Thread.sleep(timeout * 2); assertEquals("Component requireNS100 should not be activated", -1, getBaseConfigData(COMP_REQUIRE_100)); @@ -1682,7 +1693,7 @@ public class DSTest { getBaseConfigData(COMP_REQUIRE_110)); // component requireNS110 - property set by Configuration Admin; XML NS // 1.1.0 - config = cm.getConfiguration(COMP_REQUIRE_110); + config = cm.getConfiguration(COMP_REQUIRE_110, null); config.update(props); Thread.sleep(timeout * 2); assertEquals("Configuration data should be available for requireNS110 and equal to 1", 1, @@ -1693,7 +1704,7 @@ public class DSTest { assertEquals("Component ignoreNS100 should not be activated", -1, getBaseConfigData(COMP_IGNORE_100)); // component ignoreNS100 - property set by Configuration Admin; XML NS 1.0.0 // - INVALID COMPONENT - config = cm.getConfiguration(COMP_IGNORE_100); + config = cm.getConfiguration(COMP_IGNORE_100, null); config.update(props); Thread.sleep(timeout * 2); assertEquals("Component ignoreNS100 should not be activated", -1, getBaseConfigData(COMP_IGNORE_100)); @@ -1703,7 +1714,7 @@ public class DSTest { assertEquals("Configuration data should not be available for ignoreNS110, but it should be satisfied", 0, getBaseConfigData(COMP_IGNORE_110)); // component ignoreNS110 - property set by Configuration Admin; XML NS 1.1.0 - config = cm.getConfiguration(COMP_IGNORE_110); + config = cm.getConfiguration(COMP_IGNORE_110, null); config.update(props); Thread.sleep(timeout * 2); assertEquals("Configuration data should not be available for ignoreNS110, but it should be satisfied", 0, @@ -1730,7 +1741,7 @@ public class DSTest { // 1.0.0 assertEquals("Configuration data should not be available for notsetNS100", 0, getBaseConfigData(COMP_NOTSET_100)); // component notsetNS100 - property set by Configuration Admin; XML NS 1.0.0 - Configuration config = cm.createFactoryConfiguration(COMP_NOTSET_100); + Configuration config = cm.createFactoryConfiguration(COMP_NOTSET_100, null); config.update(props); Thread.sleep(timeout * 2); assertEquals("Configuration data should be available for notsetNS100 and equal to 1", 1, @@ -1740,7 +1751,7 @@ public class DSTest { // 1.1.0 assertEquals("Configuration data should not be available for notsetNS110", 0, getBaseConfigData(COMP_NOTSET_110)); // component notsetNS110 - property set by Configuration Admin; XML NS 1.1.0 - config = cm.createFactoryConfiguration(COMP_NOTSET_110); + config = cm.createFactoryConfiguration(COMP_NOTSET_110, null); config.update(props); Thread.sleep(timeout * 2); assertEquals("Configuration data should be available for notsetNS110 and equal to 1", 1, @@ -1751,7 +1762,7 @@ public class DSTest { assertEquals("Component optionalNS100 should not be activated", -1, getBaseConfigData(COMP_OPTIONAL_100)); // component optionalNS100 - property set by Configuration Admin; XML NS // 1.0.0 - INVALID COMPONENT - config = cm.createFactoryConfiguration(COMP_OPTIONAL_100); + config = cm.createFactoryConfiguration(COMP_OPTIONAL_100, null); config.update(props); Thread.sleep(timeout * 2); assertEquals("Component optionalNS100 should not be activated", -1, getBaseConfigData(COMP_OPTIONAL_100)); @@ -1762,7 +1773,7 @@ public class DSTest { getBaseConfigData(COMP_OPTIONAL_110)); // component optionalNS110 - property set by Configuration Admin; XML NS // 1.1.0 - config = cm.createFactoryConfiguration(COMP_OPTIONAL_110); + config = cm.createFactoryConfiguration(COMP_OPTIONAL_110, null); config.update(props); Thread.sleep(timeout * 2); assertEquals("Configuration data should be available for optionalNS110 and equal to 1", 1, @@ -1773,7 +1784,7 @@ public class DSTest { assertEquals("Component requireNS100 should not be activated", -1, getBaseConfigData(COMP_REQUIRE_100)); // component requireNS100 - property set by Configuration Admin; XML NS // 1.0.0 - INVALID COMPONENT - config = cm.createFactoryConfiguration(COMP_REQUIRE_100); + config = cm.createFactoryConfiguration(COMP_REQUIRE_100, null); config.update(props); Thread.sleep(timeout * 2); assertEquals("Component requireNS100 should not be activated", -1, getBaseConfigData(COMP_REQUIRE_100)); @@ -1784,7 +1795,7 @@ public class DSTest { getBaseConfigData(COMP_REQUIRE_110)); // component requireNS110 - property set by Configuration Admin; XML NS // 1.1.0 - config = cm.createFactoryConfiguration(COMP_REQUIRE_110); + config = cm.createFactoryConfiguration(COMP_REQUIRE_110, null); config.update(props); Thread.sleep(timeout * 2); assertEquals("Configuration data should be available for requireNS110 and equal to 1", 1, @@ -1795,7 +1806,7 @@ public class DSTest { assertEquals("Component ignoreNS100 should not be activated", -1, getBaseConfigData(COMP_IGNORE_100)); // component ignoreNS100 - property set by Configuration Admin; XML NS 1.0.0 // - INVALID COMPONENT - config = cm.createFactoryConfiguration(COMP_IGNORE_100); + config = cm.createFactoryConfiguration(COMP_IGNORE_100, null); config.update(props); Thread.sleep(timeout * 2); assertEquals("Component ignoreNS100 should not be activated", -1, getBaseConfigData(COMP_IGNORE_100)); @@ -1805,7 +1816,7 @@ public class DSTest { assertEquals("Configuration data should not be available for ignoreNS110, but it should be satisfied", 0, getBaseConfigData(COMP_IGNORE_110)); // component ignoreNS110 - property set by Configuration Admin; XML NS 1.1.0 - config = cm.createFactoryConfiguration(COMP_IGNORE_110); + config = cm.createFactoryConfiguration(COMP_IGNORE_110, null); config.update(props); Thread.sleep(timeout * 2); assertEquals("Configuration data should not be available for ignoreNS110, but it should be satisfied", 0, @@ -1938,7 +1949,7 @@ public class DSTest { ConfigurationAdmin cm = (ConfigurationAdmin) trackerCM.getService(); if (cm == null) return; - Configuration config = cm.getConfiguration(CC_BC_MAP_INT_NS110); + Configuration config = cm.getConfiguration(CC_BC_MAP_INT_NS110, null); Dictionary properties = config.getProperties(); if (properties == null) { properties = new Hashtable(); @@ -1954,7 +1965,7 @@ public class DSTest { bs = getBaseService(CC_BC_MAP_INT_NS110); assertNotNull(bs); - config = cm.getConfiguration(CC_BC_MAP_INT_NS110); + config = cm.getConfiguration(CC_BC_MAP_INT_NS110, null); config.delete(); Thread.sleep(timeout * 2); assertEquals("Deactivation reason shall be DEACTIVATION_REASON_CONFIGURATION_DELETED", 4, @@ -2150,7 +2161,7 @@ public class DSTest { try { for (int i = firstComp; i <= lastComp; i++) { - Configuration config = cm.getConfiguration(compPrefix + i); + Configuration config = cm.getConfiguration(compPrefix + i, null); Dictionary properties = config.getProperties(); if (properties == null) { properties = new Hashtable(); @@ -2250,12 +2261,12 @@ public class DSTest { Hashtable props = new Hashtable(10); props.put("config.dummy.data", Integer.valueOf(1)); - cm.getConfiguration(MOD_NOTSET_NS100).update(props); - cm.getConfiguration(MOD_NOARGS_NS100).update(props); - cm.getConfiguration(MOD_CC_NS100).update(props); - cm.getConfiguration(MOD_BC_NS100).update(props); - cm.getConfiguration(MOD_MAP_NS100).update(props); - cm.getConfiguration(MOD_CC_BC_MAP_NS100).update(props); + cm.getConfiguration(MOD_NOTSET_NS100, null).update(props); + cm.getConfiguration(MOD_NOARGS_NS100, null).update(props); + cm.getConfiguration(MOD_CC_NS100, null).update(props); + cm.getConfiguration(MOD_BC_NS100, null).update(props); + cm.getConfiguration(MOD_MAP_NS100, null).update(props); + cm.getConfiguration(MOD_CC_BC_MAP_NS100, null).update(props); Thread.sleep(timeout * 2); @@ -2268,14 +2279,14 @@ public class DSTest { PropertiesProvider bs = getBaseService(MOD_NOTSET_NS100); assertNotNull(bs); - cm.getConfiguration(MOD_NOTSET_NS100).update(props); + cm.getConfiguration(MOD_NOTSET_NS100, null).update(props); Thread.sleep(timeout * 2); assertEquals("Modified method of " + MOD_NOTSET_NS100 + " should not be called", 0, (1 << 0) & getBaseConfigData(bs)); assertEquals("Deactivate method of " + MOD_NOTSET_NS100 + " should be called", 1 << 7, (1 << 7) & getBaseConfigData(bs)); bs = getBaseService(MOD_NOTSET_NS100); - cm.getConfiguration(MOD_NOTSET_NS100).update(unsatisfyingProps); + cm.getConfiguration(MOD_NOTSET_NS100, null).update(unsatisfyingProps); Thread.sleep(timeout * 2); assertEquals("Modified method of " + MOD_NOTSET_NS100 + " should not be called", 0, (1 << 0) & getBaseConfigData(bs)); @@ -2308,12 +2319,12 @@ public class DSTest { Hashtable props = new Hashtable(10); props.put("config.dummy.data", Integer.valueOf(1)); - cm.getConfiguration(MOD_NOTSET_NS110).update(props); - cm.getConfiguration(MOD_NOARGS_NS110).update(props); - cm.getConfiguration(MOD_CC_NS110).update(props); - cm.getConfiguration(MOD_BC_NS110).update(props); - cm.getConfiguration(MOD_MAP_NS110).update(props); - cm.getConfiguration(MOD_CC_BC_MAP_NS110).update(props); + cm.getConfiguration(MOD_NOTSET_NS110, null).update(props); + cm.getConfiguration(MOD_NOARGS_NS110, null).update(props); + cm.getConfiguration(MOD_CC_NS110, null).update(props); + cm.getConfiguration(MOD_BC_NS110, null).update(props); + cm.getConfiguration(MOD_MAP_NS110, null).update(props); + cm.getConfiguration(MOD_CC_BC_MAP_NS110, null).update(props); Thread.sleep(timeout * 2); @@ -2325,14 +2336,14 @@ public class DSTest { unsatisfyingProps.put("ref.target", "(component.name=org.eclipse.equinox.ds.tests.tb21.unexisting.provider)"); PropertiesProvider bs = getBaseService(MOD_NOTSET_NS110); - cm.getConfiguration(MOD_NOTSET_NS110).update(props); + cm.getConfiguration(MOD_NOTSET_NS110, null).update(props); Thread.sleep(timeout * 2); assertEquals("Modified method of " + MOD_NOTSET_NS110 + " should not be called", 0, (1 << 0) & getBaseConfigData(bs)); assertEquals("Deactivate method of " + MOD_NOTSET_NS110 + " should be called", 1 << 7, (1 << 7) & getBaseConfigData(bs)); bs = getBaseService(MOD_NOTSET_NS110); - cm.getConfiguration(MOD_NOTSET_NS110).update(unsatisfyingProps); + cm.getConfiguration(MOD_NOTSET_NS110, null).update(unsatisfyingProps); Thread.sleep(timeout * 2); assertEquals("Modified method of " + MOD_NOTSET_NS110 + " should not be called", 0, (1 << 0) & getBaseConfigData(bs)); @@ -2344,13 +2355,13 @@ public class DSTest { & getBaseConfigData(bs)); bs = getBaseService(MOD_NOARGS_NS110); - cm.getConfiguration(MOD_NOARGS_NS110).update(props); + cm.getConfiguration(MOD_NOARGS_NS110, null).update(props); Thread.sleep(timeout * 2); assertEquals("Modified method of " + MOD_NOARGS_NS110 + " should be called", 1 << 1, (1 << 1) & getBaseConfigData(bs)); assertEquals("Deactivate method of " + MOD_NOARGS_NS110 + " should not be called", 0, (1 << 7) & getBaseConfigData(bs)); - cm.getConfiguration(MOD_NOARGS_NS110).update(unsatisfyingProps); + cm.getConfiguration(MOD_NOARGS_NS110, null).update(unsatisfyingProps); Thread.sleep(timeout * 2); assertEquals("Deactivate method of " + MOD_NOARGS_NS110 + " should be called", 1 << 7, (1 << 7) & getBaseConfigData(bs)); @@ -2360,11 +2371,11 @@ public class DSTest { & getBaseConfigData(bs)); bs = getBaseService(MOD_CC_NS110); - cm.getConfiguration(MOD_CC_NS110).update(props); + cm.getConfiguration(MOD_CC_NS110, null).update(props); Thread.sleep(timeout * 2); assertEquals("Modified method of " + MOD_CC_NS110 + " should be called", 1 << 2, (1 << 2) & getBaseConfigData(bs)); assertEquals("Deactivate method of " + MOD_CC_NS110 + " should not be called", 0, (1 << 7) & getBaseConfigData(bs)); - cm.getConfiguration(MOD_CC_NS110).update(unsatisfyingProps); + cm.getConfiguration(MOD_CC_NS110, null).update(unsatisfyingProps); Thread.sleep(timeout * 2); assertEquals("Deactivate method of " + MOD_CC_NS110 + " should be called", 1 << 7, (1 << 7) & getBaseConfigData(bs)); // Re-activating @@ -2372,11 +2383,11 @@ public class DSTest { assertEquals("Activate method of " + MOD_CC_NS110 + " should be called", 1 << 6, (1 << 6) & getBaseConfigData(bs)); bs = getBaseService(MOD_BC_NS110); - cm.getConfiguration(MOD_BC_NS110).update(props); + cm.getConfiguration(MOD_BC_NS110, null).update(props); Thread.sleep(timeout * 2); assertEquals("Modified method of " + MOD_BC_NS110 + " should be called", 1 << 3, (1 << 3) & getBaseConfigData(bs)); assertEquals("Deactivate method of " + MOD_BC_NS110 + " should not be called", 0, (1 << 7) & getBaseConfigData(bs)); - cm.getConfiguration(MOD_BC_NS110).update(unsatisfyingProps); + cm.getConfiguration(MOD_BC_NS110, null).update(unsatisfyingProps); Thread.sleep(timeout * 2); assertEquals("Deactivate method of " + MOD_BC_NS110 + " should be called", 1 << 7, (1 << 7) & getBaseConfigData(bs)); // Re-activating @@ -2384,11 +2395,11 @@ public class DSTest { assertEquals("Activate method of " + MOD_BC_NS110 + " should be called", 1 << 6, (1 << 6) & getBaseConfigData(bs)); bs = getBaseService(MOD_MAP_NS110); - cm.getConfiguration(MOD_MAP_NS110).update(props); + cm.getConfiguration(MOD_MAP_NS110, null).update(props); Thread.sleep(timeout * 2); assertEquals("Modified method of " + MOD_MAP_NS110 + " should be called", 1 << 4, (1 << 4) & getBaseConfigData(bs)); assertEquals("Deactivate method of " + MOD_MAP_NS110 + " should not be called", 0, (1 << 7) & getBaseConfigData(bs)); - cm.getConfiguration(MOD_MAP_NS110).update(unsatisfyingProps); + cm.getConfiguration(MOD_MAP_NS110, null).update(unsatisfyingProps); Thread.sleep(timeout * 2); assertEquals("Deactivate method of " + MOD_MAP_NS110 + " should be called", 1 << 7, (1 << 7) & getBaseConfigData(bs)); @@ -2397,13 +2408,13 @@ public class DSTest { assertEquals("Activate method of " + MOD_MAP_NS110 + " should be called", 1 << 6, (1 << 6) & getBaseConfigData(bs)); bs = getBaseService(MOD_CC_BC_MAP_NS110); - cm.getConfiguration(MOD_CC_BC_MAP_NS110).update(props); + cm.getConfiguration(MOD_CC_BC_MAP_NS110, null).update(props); Thread.sleep(timeout * 2); assertEquals("Modified method of " + MOD_CC_BC_MAP_NS110 + " should be called", 1 << 5, (1 << 5) & getBaseConfigData(bs)); assertEquals("Deactivate method of " + MOD_CC_BC_MAP_NS110 + " should not be called", 0, (1 << 7) & getBaseConfigData(bs)); - cm.getConfiguration(MOD_CC_BC_MAP_NS110).update(unsatisfyingProps); + cm.getConfiguration(MOD_CC_BC_MAP_NS110, null).update(unsatisfyingProps); Thread.sleep(timeout * 2); assertEquals("Deactivate method of " + MOD_CC_BC_MAP_NS110 + " should be called", 1 << 7, (1 << 7) & getBaseConfigData(bs)); @@ -2426,10 +2437,10 @@ public class DSTest { Hashtable props = new Hashtable(10); props.put("config.dummy.data", Integer.valueOf(1)); - cm.getConfiguration(MOD_CC_NS110).update(props); - cm.getConfiguration(MOD_NOT_EXIST_NS110).update(props); - cm.getConfiguration(MOD_THROW_EX_NS110).update(props); - cm.getConfiguration(MOD_BC_NS110).update(props); + cm.getConfiguration(MOD_CC_NS110, null).update(props); + cm.getConfiguration(MOD_NOT_EXIST_NS110, null).update(props); + cm.getConfiguration(MOD_THROW_EX_NS110, null).update(props); + cm.getConfiguration(MOD_BC_NS110, null).update(props); Thread.sleep(timeout * 2); tb21a.start(); @@ -2438,7 +2449,7 @@ public class DSTest { // Verifying correctness of updated component properties PropertiesProvider bs = getBaseService(MOD_CC_NS110); props.put("config.dummy.data", Integer.valueOf(2)); - cm.getConfiguration(MOD_CC_NS110).update(props); + cm.getConfiguration(MOD_CC_NS110, null).update(props); Thread.sleep(timeout * 2); Object val = ((ComponentContextProvider) bs).getComponentContext().getProperties().get("config.dummy.data"); assertEquals("Modified method of " + MOD_CC_NS110 + " should be called", 1 << 2, (1 << 2) & getBaseConfigData(bs)); @@ -2447,7 +2458,7 @@ public class DSTest { // Specified modified method doesn't exist, deactivate() should be called // instead of modified bs = getBaseService(MOD_NOT_EXIST_NS110); - cm.getConfiguration(MOD_NOT_EXIST_NS110).update(props); + cm.getConfiguration(MOD_NOT_EXIST_NS110, null).update(props); Thread.sleep(timeout * 2); assertEquals("Deactivate method of " + MOD_NOT_EXIST_NS110 + " should be called", 1 << 7, (1 << 7) & getBaseConfigData(bs)); @@ -2459,14 +2470,14 @@ public class DSTest { // Specified modified method throws exception. Normal workflow should // continue, deactivate() should not be called bs = getBaseService(MOD_THROW_EX_NS110); - cm.getConfiguration(MOD_THROW_EX_NS110).update(props); + cm.getConfiguration(MOD_THROW_EX_NS110, null).update(props); Thread.sleep(timeout * 2); assertEquals("Deactivate method of " + MOD_THROW_EX_NS110 + " should not be called", 0, (1 << 7) & getBaseConfigData(bs)); // Deleting component configuration bs = getBaseService(MOD_BC_NS110); - cm.getConfiguration(MOD_BC_NS110).delete(); + cm.getConfiguration(MOD_BC_NS110, null).delete(); Thread.sleep(timeout * 2); assertEquals("Modified method of " + MOD_BC_NS110 + " should not be called", 0, (1 << 5) & getBaseConfigData(bs)); assertEquals("Deactivate method of " + MOD_BC_NS110 + " should be called", 1 << 7, (1 << 7) & getBaseConfigData(bs)); @@ -2506,7 +2517,7 @@ public class DSTest { waitBundleStart(); PropertiesProvider bs = getBaseService(MANDATORY_REF_COMP); - assertEquals("Component " + MANDATORY_REF_COMP + " should not be activated", null, bs); + assertNotNull("Component " + MANDATORY_REF_COMP + " should not be activated", bs); bs = getBaseService(OPTIONAL_REF_COMP); assertEquals("Component " + OPTIONAL_REF_COMP + " should be activated", 1 << 2, (1 << 2) & getBaseConfigData(bs)); @@ -2523,11 +2534,11 @@ public class DSTest { Hashtable props = new Hashtable(11); props.put("config.base.data", Integer.valueOf(1)); //create the configurations for the test DS components - Configuration config = cm.getConfiguration(COMP_OPTIONAL); + Configuration config = cm.getConfiguration(COMP_OPTIONAL, null); config.update(props); - config = cm.getConfiguration(COMP_REQUIRE); + config = cm.getConfiguration(COMP_REQUIRE, null); config.update(props); - config = cm.getConfiguration(COMP_IGNORE); + config = cm.getConfiguration(COMP_IGNORE, null); config.update(props); //wait for CM to process the configuration updates Thread.sleep(timeout * 2); @@ -2860,7 +2871,7 @@ public class DSTest { final String PROP = "test.property"; // set component configuration - config = cm.getConfiguration(CONFIG_PID); + config = cm.getConfiguration(CONFIG_PID, null); Dictionary configProperties = config.getProperties(); if (configProperties == null) { configProperties = new Hashtable(); diff --git a/bundles/org.eclipse.equinox.ds/.classpath b/bundles/org.eclipse.equinox.ds/.classpath index be1ef39ba..ad32c83a7 100644 --- a/bundles/org.eclipse.equinox.ds/.classpath +++ b/bundles/org.eclipse.equinox.ds/.classpath @@ -1,7 +1,7 @@ - - + + diff --git a/bundles/org.eclipse.equinox.ds/.options b/bundles/org.eclipse.equinox.ds/.options deleted file mode 100644 index 288afbfcf..000000000 --- a/bundles/org.eclipse.equinox.ds/.options +++ /dev/null @@ -1,16 +0,0 @@ -# Debugging options for the org.eclipse.equinox.ds plugin - -# Turns on/off debugging of SCR -org.eclipse.equinox.ds/debug=false -# Specifies that logged entries should be printed to the framework runtime console -org.eclipse.equinox.ds/print_on_console=false -# Enables generating and printing logs about the time performance of the operations executed by the SCR -org.eclipse.equinox.ds/performance=false -# Makes instance of each component nevertheless components are "immediate" or not -org.eclipse.equinox.ds/instantiate_all=false - -#Advanced options -# Enables caching of the parsed XML documents of the component descriptions -#org.eclipse.equinox.ds/cache_descriptions=false -# Specifies the maximum time in milliseconds, which is allowed to a user component's activate or bind method to take. If the method invocation has not finished, a new dispatcher thread will be launched to process the pending work of SCR -#org.eclipse.equinox.ds/block_timeout=30000 diff --git a/bundles/org.eclipse.equinox.ds/.settings/.api_filters b/bundles/org.eclipse.equinox.ds/.settings/.api_filters new file mode 100644 index 000000000..1c3121fc9 --- /dev/null +++ b/bundles/org.eclipse.equinox.ds/.settings/.api_filters @@ -0,0 +1,35 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/bundles/org.eclipse.equinox.ds/.settings/org.eclipse.jdt.core.prefs b/bundles/org.eclipse.equinox.ds/.settings/org.eclipse.jdt.core.prefs index d304116cd..c6fec0e94 100644 --- a/bundles/org.eclipse.equinox.ds/.settings/org.eclipse.jdt.core.prefs +++ b/bundles/org.eclipse.equinox.ds/.settings/org.eclipse.jdt.core.prefs @@ -1,4 +1,3 @@ -#Thu Aug 16 11:00:59 EDT 2007 eclipse.preferences.version=1 org.eclipse.jdt.core.builder.cleanOutputFolder=clean org.eclipse.jdt.core.builder.duplicateResourceTask=warning @@ -7,24 +6,24 @@ org.eclipse.jdt.core.builder.resourceCopyExclusionFilter=*.launch org.eclipse.jdt.core.circularClasspath=error org.eclipse.jdt.core.classpath.exclusionPatterns=enabled org.eclipse.jdt.core.classpath.multipleOutputLocations=enabled -org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=disabled -org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.2 +org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled +org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.6 org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve -org.eclipse.jdt.core.compiler.compliance=1.4 +org.eclipse.jdt.core.compiler.compliance=1.6 org.eclipse.jdt.core.compiler.debug.lineNumber=generate org.eclipse.jdt.core.compiler.debug.localVariable=generate org.eclipse.jdt.core.compiler.debug.sourceFile=generate org.eclipse.jdt.core.compiler.doc.comment.support=enabled org.eclipse.jdt.core.compiler.maxProblemPerUnit=1000 org.eclipse.jdt.core.compiler.problem.annotationSuperInterface=warning -org.eclipse.jdt.core.compiler.problem.assertIdentifier=warning +org.eclipse.jdt.core.compiler.problem.assertIdentifier=error org.eclipse.jdt.core.compiler.problem.autoboxing=ignore org.eclipse.jdt.core.compiler.problem.deprecation=warning org.eclipse.jdt.core.compiler.problem.deprecationInDeprecatedCode=disabled org.eclipse.jdt.core.compiler.problem.deprecationWhenOverridingDeprecatedMethod=enabled org.eclipse.jdt.core.compiler.problem.discouragedReference=error org.eclipse.jdt.core.compiler.problem.emptyStatement=warning -org.eclipse.jdt.core.compiler.problem.enumIdentifier=warning +org.eclipse.jdt.core.compiler.problem.enumIdentifier=error org.eclipse.jdt.core.compiler.problem.fieldHiding=warning org.eclipse.jdt.core.compiler.problem.finalParameterBound=ignore org.eclipse.jdt.core.compiler.problem.finallyBlockNotCompletingNormally=warning @@ -72,7 +71,7 @@ org.eclipse.jdt.core.compiler.problem.unusedParameterWhenImplementingAbstract=en org.eclipse.jdt.core.compiler.problem.unusedParameterWhenOverridingConcrete=enabled org.eclipse.jdt.core.compiler.problem.unusedPrivateMember=error org.eclipse.jdt.core.compiler.problem.varargsArgumentNeedCast=warning -org.eclipse.jdt.core.compiler.source=1.3 +org.eclipse.jdt.core.compiler.source=1.6 org.eclipse.jdt.core.formatter.align_type_members_on_columns=false org.eclipse.jdt.core.formatter.alignment_for_arguments_in_allocation_expression=16 org.eclipse.jdt.core.formatter.alignment_for_arguments_in_enum_constant=16 @@ -144,7 +143,12 @@ org.eclipse.jdt.core.formatter.indent_statements_compare_to_body=true org.eclipse.jdt.core.formatter.indent_switchstatements_compare_to_cases=true org.eclipse.jdt.core.formatter.indent_switchstatements_compare_to_switch=true org.eclipse.jdt.core.formatter.indentation.size=4 -org.eclipse.jdt.core.formatter.insert_new_line_after_annotation=insert +org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_field=insert +org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_local_variable=insert +org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_method=insert +org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_package=insert +org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_parameter=insert +org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_type=insert org.eclipse.jdt.core.formatter.insert_new_line_after_opening_brace_in_array_initializer=do not insert org.eclipse.jdt.core.formatter.insert_new_line_at_end_of_file_if_missing=do not insert org.eclipse.jdt.core.formatter.insert_new_line_before_catch_in_try_statement=do not insert diff --git a/bundles/org.eclipse.equinox.ds/META-INF/MANIFEST.MF b/bundles/org.eclipse.equinox.ds/META-INF/MANIFEST.MF index 9d7b397b9..7ddb10403 100644 --- a/bundles/org.eclipse.equinox.ds/META-INF/MANIFEST.MF +++ b/bundles/org.eclipse.equinox.ds/META-INF/MANIFEST.MF @@ -2,45 +2,17 @@ Manifest-Version: 1.0 Bundle-ManifestVersion: 2 Bundle-Name: %bundleName Bundle-SymbolicName: org.eclipse.equinox.ds;singleton:=true -Bundle-Version: 1.4.500.qualifier +Bundle-Version: 1.5.0.qualifier Bundle-Vendor: %bundleVendor Bundle-Activator: org.eclipse.equinox.internal.ds.Activator Bundle-Description: This bundle provides support for OSGi Declarative Services Import-Package: - org.eclipse.equinox.internal.util.event;version="1.0", - org.eclipse.equinox.internal.util.hash;version="1.0", - org.eclipse.equinox.internal.util.pool;version="1.0", - org.eclipse.equinox.internal.util.ref;version="1.0", - org.eclipse.equinox.internal.util.threadpool;version="1.0", - org.eclipse.equinox.internal.util.timer;version="1.0", - org.eclipse.osgi.framework.console;version="1.0.0";resolution:=optional, - org.eclipse.osgi.framework.log;version="1.0.0", - org.eclipse.osgi.service.debug;version="1.0", - org.eclipse.osgi.service.environment;version="1.2.0", - org.eclipse.osgi.util, - org.osgi.framework;version="1.3", - org.osgi.service.cm;version="1.2", - org.osgi.service.component;version="[1.1,1.4)", - org.osgi.service.log;version="1.3.0", - org.osgi.util.tracker;version="1.3", - org.apache.felix.scr; version="[1.6,1.7)" -Provide-Capability: osgi.extender; - osgi.extender="osgi.component"; - version:Version="1.2"; - uses:="org.osgi.service.component" -Export-Package: - org.eclipse.equinox.internal.ds;x-internal:=true, - org.eclipse.equinox.internal.ds.impl;x-internal:=true, - org.eclipse.equinox.internal.ds.model;x-internal:=true, - org.eclipse.equinox.internal.ds.storage.file;x-internal:=true, - org.eclipse.equinox.internal.util.io;x-internal:=true, - org.eclipse.equinox.internal.util.xml;x-internal:=true, - org.eclipse.equinox.internal.util.xml.impl;x-internal:=true, - org.eclipse.equinox.internal.util.string;x-internal:=true, - org.apache.felix.scr;version="1.6" -Bundle-RequiredExecutionEnvironment: OSGi/Minimum-1.2, - CDC-1.1/Foundation-1.1, - J2SE-1.4 -Lazy-ManifestFilter: (Service-Component=*) + org.eclipse.osgi.service.environment;version="1.3.0", + org.osgi.framework;version="1.8.0", + org.osgi.framework.namespace;version="1.1.0", + org.osgi.framework.startlevel;version="1.0.0", + org.osgi.framework.wiring;version="1.2.0" +Require-Bundle: org.apache.felix.scr;bundle-version="[2.0.0,3.0.0)";visibility:=reexport +Bundle-RequiredExecutionEnvironment: JavaSE-1.6 Bundle-Localization: plugin diff --git a/bundles/org.eclipse.equinox.ds/build.properties b/bundles/org.eclipse.equinox.ds/build.properties index 706e5fc97..68112e79c 100644 --- a/bundles/org.eclipse.equinox.ds/build.properties +++ b/bundles/org.eclipse.equinox.ds/build.properties @@ -14,7 +14,6 @@ output.. = bin/ bin.includes = META-INF/,\ .,\ about.html,\ - .options,\ plugin.properties,\ about_files/ src.includes = about.html,\ diff --git a/bundles/org.eclipse.equinox.ds/pom.xml b/bundles/org.eclipse.equinox.ds/pom.xml index 78dd32f0a..acd9b96a2 100644 --- a/bundles/org.eclipse.equinox.ds/pom.xml +++ b/bundles/org.eclipse.equinox.ds/pom.xml @@ -19,6 +19,6 @@ org.eclipse.equinox org.eclipse.equinox.ds - 1.4.500-SNAPSHOT + 1.5.0-SNAPSHOT eclipse-plugin diff --git a/bundles/org.eclipse.equinox.ds/src/org/apache/felix/scr/Component.java b/bundles/org.eclipse.equinox.ds/src/org/apache/felix/scr/Component.java deleted file mode 100644 index ea5406409..000000000 --- a/bundles/org.eclipse.equinox.ds/src/org/apache/felix/scr/Component.java +++ /dev/null @@ -1,332 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ -package org.apache.felix.scr; - -import java.util.Dictionary; -import org.osgi.framework.Bundle; -import org.osgi.service.component.ComponentInstance; - -/** - * The Component interface represents a single component managed - * by the Service Component Runtime. Management agents may access the Component - * instances through the {@link ScrService}. - */ -public interface Component { - - /** - * The Component has just been created and is still disabled or it has - * been disabled by calling the {@link #disable()} method (value is 1). - */ - static final int STATE_DISABLED = 1; - - /** - * The Component is being enabled (value is 512). After the component has - * been enabled it enters the {@link #STATE_UNSATISFIED} state. - * @since 1.2 - */ - static final int STATE_ENABLING = 512; - - /** - * The Component has been enabled and is now going to be activated (value - * is 2). - * @deprecated as of version 1.2 the enabled state is collapsed into the - * {@link #STATE_UNSATISFIED} state. This status code is never returned - * from the {@link #getState()} method. - */ - static final int STATE_ENABLED = 2; - - /** - * The Component activation failed because any dependency is not satisfied - * (value is 4). - */ - static final int STATE_UNSATISFIED = 4; - - /** - * The Component is currently being activated either because it has been - * enabled or because any dependency which was previously unsatisfied has - * become satisfied (value is 8). - */ - static final int STATE_ACTIVATING = 8; - - /** - * The Component has successfully been activated and is fully functional - * (value is 16). This is the state of immediate components after - * successful activation. Delayed and Service Factory Components enter - * this state when the service instance has actually be instantiated because - * the service has been acquired. - */ - static final int STATE_ACTIVE = 16; - - /** - * The Component has successfully been activated but is a Delayed or Service - * Factory Component pending instantiation on first use (value is 32). - */ - static final int STATE_REGISTERED = 32; - - /** - * The Component is a Component Factory ready to create Component instances - * with the ComponentFactory.newInstance(Dictionary) method - * or (if enabled with the ds.factory.enabled configuration) to - * manage Component instances from configuration data received from the - * Configuration Admin Service (value is 64). - */ - static final int STATE_FACTORY = 64; - - /** - * The Component is being deactivated either because it is being disabled - * or because a dependency is not satisfied any more (value is 128). After - * deactivation the Component enters the {@link #STATE_UNSATISFIED} state. - */ - static final int STATE_DEACTIVATING = 128; - - /** - * The Component is being disabled (value is 1024). After the component has - * been disabled it enters the {@link #STATE_DISABLED} state. - * @since 1.2 - */ - static final int STATE_DISABLING = 1024; - - /** - * The Component is being disposed off (value is 2048). After the component - * has been disposed off it enters the {@link #STATE_DESTROYED} state. - * @since 1.2 - */ - static final int STATE_DISPOSING = 2048; - - /** - * The Component has been destroyed and cannot be used any more (value is - * 256). This state is only used when the bundle declaring the component - * is being stopped and all components have to be removed. - * @deprecated as of version 1.2 this constant has been renamed to - * {@link #STATE_DISPOSED}. - */ - static final int STATE_DESTROYED = 256; - - /** - * The Component has been disposed off and cannot be used any more (value is - * 256). This state is used when the bundle declaring the component - * is being stopped and all components have to be removed. This status is - * also the final status of a component after the - * ComponentInstance.dispose() method has been called. - * @since 1.2 - */ - static final int STATE_DISPOSED = 256; - - /** - * Returns the component ID of this component. This ID is managed by the - * SCR. If the component is not currently enabled the ID might not be - * assigned to the component (yet) and this method will return -1 in this - * case. - */ - long getId(); - - /** - * Returns the name of the component, which is also used as the service PID. - * This method provides access to the name attribute of the - * component element. - */ - String getName(); - - /** - * Returns the current state of the Component, which is one of the - * STATE_* constants defined in this interface. - */ - int getState(); - - /** - * Returns the Bundle declaring this component. - */ - Bundle getBundle(); - - /** - * Returns the component factory name or null if this component - * is not defined as a component factory. This method provides access to - * the factory attribute of the component - * element. - */ - String getFactory(); - - /** - * Returns true if this component is a service factory. This - * method returns the value of the serviceFactory attribute of - * the service element. If the component has no service - * element, this method returns false. - */ - boolean isServiceFactory(); - - /** - * Returns the class name of the Component implementation. This method - * provides access to the class attribute of the - * implementation element. - */ - String getClassName(); - - /** - * Returns whether the Component is declared to be enabled initially. This - * method provides access to the enabled attribute of the - * component element. - */ - boolean isDefaultEnabled(); - - /** - * Returns whether the Component is an Immediate or a Delayed Component. - * This method provides access to the immediate attribute of - * the component element. - */ - boolean isImmediate(); - - /** - * Returns an array of service names provided by this Component or - * null if the Component is not registered as a service. This - * method provides access to the interface attributes of the - * provide elements. - */ - String[] getServices(); - - /** - * Returns the properties of the Component. The Dictionary returned is a - * private copy of the actual properties and contains the same entries as - * are used to register the Component as a service and are returned by - * the ComponentContext.getProperties() method. - */ - Dictionary getProperties(); - - /** - * Returns an array of {@link Reference} instances representing the service - * references (or dependencies) of this Component. If the Component has no - * references, null is returned. - */ - Reference[] getReferences(); - - /** - * Returns the org.osgi.service.component.ComponentInstance - * representing this component or null if this component - * is not been activated yet. - * - * @since 1.2 - */ - ComponentInstance getComponentInstance(); - - /** - * Returns the name of the method to be called when the component is being - * activated. - *

- * This method never returns null, that is, if this method is - * not declared in the component descriptor this method returns the - * default value activate. - * - * @since 1.2 - */ - String getActivate(); - - /** - * Returns true if the name of the method to be called on - * component activation (see {@link #getActivate()} is declared in the - * component descriptor or not. - *

- * For a component declared in a Declarative Services 1.0 descriptor, this - * method always returns false. - * - * @since 1.2 - */ - boolean isActivateDeclared(); - - /** - * Returns the name of the method to be called when the component is being - * deactivated. - *

- * This method never returns null, that is, if this method is - * not declared in the component descriptor this method returns the - * default value deactivate. - * - * @since 1.2 - */ - String getDeactivate(); - - /** - * Returns true if the name of the method to be called on - * component deactivation (see {@link #getDeactivate()} is declared in the - * component descriptor or not. - *

- * For a component declared in a Declarative Services 1.0 descriptor, this - * method always returns false. - * - * @since 1.2 - */ - boolean isDeactivateDeclared(); - - /** - * Returns the name of the method to be called when the component - * configuration has been updated or null if such a method is - * not declared in the component descriptor. - *

- * For a component declared in a Declarative Services 1.0 descriptor, this - * method always returns null. - * - * @since 1.2 - */ - String getModified(); - - /** - * Returns the configuration policy declared in the component descriptor. - * If the component descriptor is a Declarative Services 1.0 descriptor or - * not configuration policy has been declared, the default value - * optional is returned. - *

- * The returned string is one of the three policies defined in the - * Declarative Services specification 1.1: - *

- *
optional
- *
Configuration from the Configuration Admin service is supplied to - * the component if available. Otherwise the component is activated without - * Configuration Admin configuration. This is the default value reflecting - * the behavior of Declarative Services 1.0
- *
require
- *
Configuration is required. The component remains unsatisfied until - * configuration is available from the Configuration Admin service.
- *
ignore
- *
Configuration is ignored. No Configuration Admin service - * configuration is supplied to the component.
- *
- * - * @since 1.2 - */ - String getConfigurationPolicy(); - - /** - * Enables this Component if it is disabled. If the Component is not - * currently {@link #STATE_DISABLED disabled} this method has no effect. If - * the Component is {@link #STATE_DESTROYED destroyed}, this method throws - * an IllegalStateException. - * - * @throws IllegalStateException If the Component is destroyed. - */ - void enable(); - - /** - * Disables this Component if it is enabled. If the Component is already - * {@link #STATE_DISABLED disabled} this method has no effect. If the - * Component is {@link #STATE_DESTROYED destroyed}, this method throws an - * IllegalStateException. - * - * @throws IllegalStateException If the Component is destroyed. - */ - void disable(); - -} diff --git a/bundles/org.eclipse.equinox.ds/src/org/apache/felix/scr/Reference.java b/bundles/org.eclipse.equinox.ds/src/org/apache/felix/scr/Reference.java deleted file mode 100644 index 786d4f006..000000000 --- a/bundles/org.eclipse.equinox.ds/src/org/apache/felix/scr/Reference.java +++ /dev/null @@ -1,119 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ -package org.apache.felix.scr; - -import org.osgi.framework.ServiceReference; - -/** - * The Reference interface represents a single reference (or - * dependency) to a service used by a Component. - */ -public interface Reference { - - /** - * Returns the name of this Reference. This method provides access to the - * name attribute of the reference element. - */ - String getName(); - - /** - * Returns the name of the service used by this Reference. This method - * provides access to the interface attribute of the - * reference element. - */ - String getServiceName(); - - /** - * Returns an array of references to the services bound to this Reference - * or null if no services are currently bound. - */ - ServiceReference[] getServiceReferences(); - - /** - * Returns whether this reference is satisfied. A {@link #isOptional() optional} - * component is always satisfied. Otherwise true is only - * returned if at least one service is bound. - */ - boolean isSatisfied(); - - /** - * Returns whether this reference is optional. This method provides access - * to the lower bound of the cardinality attribute of the - * reference element. In other words, this method returns - * true if the cardinality is 0..1 or 0..n. - */ - boolean isOptional(); - - /** - * Returns whether this reference is multiple. This method provides access - * to the upper bound of the cardinality attribute of the - * reference element. In other words, this method returns - * true if the cardinality is 0..n or 1..n. - */ - boolean isMultiple(); - - /** - * Returns true if the reference is defined with static policy. - * This method provides access to the policy element of the - * reference element. true is returned if the - * policy is defined as static. - */ - boolean isStatic(); - - /** - * Returns the value of the target property of this reference. Initially - * (without overwriting configuration) this method provides access to the - * target attribute of the reference element. If - * configuration overwrites the target property, this method returns the - * value of the Component property whose name is derived from the - * {@link #getName() reference name} plus the suffix .target. If - * no target property exists this method returns null. - */ - String getTarget(); - - /** - * Returns the name of the method called if a service is being bound to - * the Component or null if no such method is configured. This - * method provides access to the bind attribute of the - * reference element. - */ - String getBindMethodName(); - - /** - * Returns the name of the method called if a service is being unbound from - * the Component or null if no such method is configured. This - * method provides access to the unbind attribute of the - * reference element. - */ - String getUnbindMethodName(); - - /** - * Returns the name of the method called if a bound service updates its - * service registration properties or null if no such method - * is configured. This method provides access to the updated - * attribute of the reference element. - *

- * For a component declared in a Declarative Services 1.0 and 1.1 - * descriptor, this method always returns null. - * - * @since 1.4 - */ - String getUpdatedMethodName(); - -} diff --git a/bundles/org.eclipse.equinox.ds/src/org/apache/felix/scr/ScrService.java b/bundles/org.eclipse.equinox.ds/src/org/apache/felix/scr/ScrService.java deleted file mode 100644 index 385b2d170..000000000 --- a/bundles/org.eclipse.equinox.ds/src/org/apache/felix/scr/ScrService.java +++ /dev/null @@ -1,83 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ -package org.apache.felix.scr; - -import org.osgi.framework.Bundle; - -/** - * The ScrService represents the Declarative Services main - * controller also known as the Service Component Runtime or SCR for short. - * It provides access to the components managed the SCR. - */ -public interface ScrService { - - /** - * Returns an array of all components managed by this SCR instance. The - * components are returned in ascending order of their component.id. If - * there are no components currently managed by the SCR, null - * is returned. - * - * @return The components or null if there are none. - */ - Component[] getComponents(); - - /** - * Returns the component whose component.id matches the given - * componentId or null if no component with the - * given id is currently managed. - * - * @param componentId The ID of the component to return - * - * @return The indicated component or null if no such - * component exists. - */ - Component getComponent(long componentId); - - /** - * Returns the components whose component.name matches the - * given componentName or null if no component - * with the given name is currently managed. - *

- * If the component name refers to a component factory component or a - * component configured with multiple factory configurations this method - * returns multiple component instances. - * - * @param componentName The name of the component to return - * - * @return The indicated components or null if no such - * component exists. - * @since 1.5 (Apache Felix Declarative Services 1.4.2) - */ - Component[] getComponents(String componentName); - - /** - * Returns an array of all components managed by this SCR instance on - * behalf of the given bundle. The components are returned in ascending - * order of their component.id. If there are no components managed by the - * SCR for the given bundle, null is returned. - * - * @param bundle The Bundle whose components are to be - * returned. - * - * @return The bundle's components or null if the bundle - * has none. - */ - Component[] getComponents(Bundle bundle); - -} diff --git a/bundles/org.eclipse.equinox.ds/src/org/apache/felix/scr/package.html b/bundles/org.eclipse.equinox.ds/src/org/apache/felix/scr/package.html deleted file mode 100644 index 4efb8d91b..000000000 --- a/bundles/org.eclipse.equinox.ds/src/org/apache/felix/scr/package.html +++ /dev/null @@ -1,15 +0,0 @@ - - - - - Package-level Javadoc - - -Provides access to the components managed by the Service Component Runtime (Declarative Services). -

-Package Specification

-

-This package specifies API for accessing to the components managed by the Service Component Runtime (Declarative Services). -

- - diff --git a/bundles/org.eclipse.equinox.ds/src/org/eclipse/equinox/internal/ds/Activator.java b/bundles/org.eclipse.equinox.ds/src/org/eclipse/equinox/internal/ds/Activator.java index 28d6e8ed2..d163ebd11 100644 --- a/bundles/org.eclipse.equinox.ds/src/org/eclipse/equinox/internal/ds/Activator.java +++ b/bundles/org.eclipse.equinox.ds/src/org/eclipse/equinox/internal/ds/Activator.java @@ -1,438 +1,55 @@ /******************************************************************************* - * Copyright (c) 1997, 2013 by ProSyst Software GmbH - * http://www.prosyst.com + * Copyright (c) 2016 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: - * ProSyst Software GmbH - initial API and implementation + * IBM Corporation - initial API and implementation *******************************************************************************/ package org.eclipse.equinox.internal.ds; -import java.io.IOException; -import java.util.Dictionary; -import java.util.Hashtable; -import org.apache.felix.scr.ScrService; -import org.eclipse.equinox.internal.util.ref.Log; -import org.eclipse.osgi.framework.log.FrameworkLog; -import org.eclipse.osgi.framework.log.FrameworkLogEntry; -import org.eclipse.osgi.service.debug.DebugOptions; +import java.util.List; import org.eclipse.osgi.service.environment.EnvironmentInfo; import org.osgi.framework.*; -import org.osgi.service.cm.*; -import org.osgi.service.component.ComponentConstants; -import org.osgi.service.log.LogService; -import org.osgi.util.tracker.ServiceTracker; - -/** - * This is the main starting class for the Service Component Runtime. - * The SCR is not fully initialized until it detects at least one bundle providing DS components. - * Thus it has considerably small startup time and does improve a little the runtime performance - * since it does not listen for service events. - * - * @author Valentin Valchev - * @author Stoyan Boshev - * @author Pavlin Dobrev - */ - -public class Activator implements BundleActivator, SynchronousBundleListener, ServiceListener { - - public static BundleContext bc = null; - public static ConfigurationAdmin configAdmin = null; - public static boolean security = false; - - private ServiceRegistration configListenerReg; - private SCRManager scrManager = null; - public ScrServiceImpl scrService = null; - private ServiceRegistration scrServiceReg; - private ServiceRegistration scrCommandProviderReg; - private static FrameworkLog fwLog; - private boolean inited = false; +import org.osgi.framework.namespace.BundleNamespace; +import org.osgi.framework.startlevel.BundleStartLevel; +import org.osgi.framework.wiring.BundleWire; +import org.osgi.framework.wiring.BundleWiring; - public static Log log; - public static boolean DEBUG; - public static boolean PERF; - public static boolean DBSTORE; - public static boolean INSTANTIATE_ALL; - public static boolean startup; +public class Activator implements BundleActivator { - static long time[] = null; - - public static void timeLog(String message) { - time[1] = time[0]; - log.debug(message + String.valueOf((time[0] = System.currentTimeMillis()) - time[1]), null); - } - - private void initSCR() { - synchronized (this) { - if (inited) - return; - inited = true; - } - - boolean lazyIniting = false; - if (startup && time == null) { - long tmp = System.currentTimeMillis(); - time = new long[] {tmp, 0, tmp}; - lazyIniting = true; - if (startup) - timeLog("[BEGIN - lazy SCR init]"); //$NON-NLS-1$ - } - - WorkThread.IDLE_TIMEOUT = getInteger("equinox.ds.idle_timeout", 1000); //$NON-NLS-1$ - WorkThread.BLOCK_TIMEOUT = getInteger("equinox.ds.block_timeout", 30000); //$NON-NLS-1$ - - try { - bc.addServiceListener(this, "(objectClass=" + ConfigurationAdmin.class.getName() + ')'); //$NON-NLS-1$ - } catch (InvalidSyntaxException e) { - //should never happen - } - //get config admin service if available - ServiceReference caRef = bc.getServiceReference(ConfigurationAdmin.class.getName()); - if (caRef != null) { - configAdmin = (ConfigurationAdmin) bc.getService(caRef); - } - if (startup) - timeLog("ConfigurationAdmin service getting took "); //$NON-NLS-1$ - - scrManager = new SCRManager(); - if (startup) - timeLog("SCRManager instantiation took "); //$NON-NLS-1$ - - // add the configuration listener - we to receive CM events to restart - // components - configListenerReg = bc.registerService(ConfigurationListener.class.getName(), scrManager, null); - if (startup) - timeLog("ConfigurationListener service registered for "); //$NON-NLS-1$ - bc.addServiceListener(scrManager); - - scrManager.startIt(); - if (Activator.startup) - Activator.timeLog("startIt() method took "); //$NON-NLS-1$ - - installCommandProvider(); - - if (startup && lazyIniting) { - log.debug("[END - lazy SCR init] Activator.initSCR() method executed for " + String.valueOf(time[0] - time[2]), null); //$NON-NLS-1$ - time = null; - } - } - - /* - * (non-Javadoc) - * - * @see org.osgi.framework.BundleActivator#start(org.osgi.framework.BundleContext) - */ - public void start(BundleContext bundleContext) throws Exception { - Activator.bc = bundleContext; - startup = getBoolean("equinox.measurements.bundles", false); //$NON-NLS-1$ - if (startup) { - long tmp = System.currentTimeMillis(); - time = new long[] {tmp, 0, tmp}; - } - // initialize the logging routines - log = new Log(bundleContext, false); - ServiceTracker debugTracker = new ServiceTracker(bundleContext, DebugOptions.class.getName(), null); - debugTracker.open(); - DebugOptions debugOptions = (DebugOptions) debugTracker.getService(); - DEBUG = getBooleanDebugOption(debugOptions, "org.eclipse.equinox.ds/debug", false) || getBoolean("equinox.ds.debug", false); //$NON-NLS-1$ //$NON-NLS-2$ - PERF = getBooleanDebugOption(debugOptions, "org.eclipse.equinox.ds/performance", false) || getBoolean("equinox.ds.perf", false); //$NON-NLS-1$ //$NON-NLS-2$ - INSTANTIATE_ALL = getBooleanDebugOption(debugOptions, "org.eclipse.equinox.ds/instantiate_all", false) || getBoolean("equinox.ds.instantiate_all", false); //$NON-NLS-1$ //$NON-NLS-2$ - - DBSTORE = getBooleanDebugOption(debugOptions, "org.eclipse.equinox.ds/cache_descriptions", true) || getBoolean("equinox.ds.dbstore", true); //$NON-NLS-1$ //$NON-NLS-2$ - boolean print = getBooleanDebugOption(debugOptions, "org.eclipse.equinox.ds/print_on_console", false) || getBoolean("equinox.ds.print", false); //$NON-NLS-1$ //$NON-NLS-2$ - log.setDebug(DEBUG); - log.setPrintOnConsole(print); - //DebugOptions no longer needed - debugTracker.close(); - ServiceReference fwRef = bc.getServiceReference(FrameworkLog.class.getName()); - if (fwRef != null) { - fwLog = (FrameworkLog) bc.getService(fwRef); - } - - if (startup) - timeLog("[BEGIN - start method] Creating Log instance and initializing log system took "); //$NON-NLS-1$ - - security = Log.security(); - boolean hasHeaders = false; - Bundle[] allBundles = bundleContext.getBundles(); - for (int i = 0; i < allBundles.length; i++) { - Dictionary allHeaders = allBundles[i].getHeaders(""); //$NON-NLS-1$ - if (allHeaders.get(ComponentConstants.SERVICE_COMPONENT) != null) { - hasHeaders = true; - break; - } - } - - if (hasHeaders) { - initSCR(); - } else { - // there are no bundles holding components - SCR will not be - // initialized yet - bundleContext.addBundleListener(this); - } - ServiceReference envInfoRef = bc.getServiceReference(EnvironmentInfo.class.getName()); + public void start(BundleContext context) throws Exception { + ServiceReference envInfoRef = context.getServiceReference(EnvironmentInfo.class); EnvironmentInfo envInfo = null; if (envInfoRef != null) { - envInfo = (EnvironmentInfo) bc.getService(envInfoRef); + envInfo = context.getService(envInfoRef); } if (envInfo != null) { envInfo.setProperty("equinox.use.ds", "true"); //$NON-NLS-1$//$NON-NLS-2$ - bc.ungetService(envInfoRef); + context.ungetService(envInfoRef); } else { System.setProperty("equinox.use.ds", "true"); //$NON-NLS-1$ //$NON-NLS-2$ } - scrService = new ScrServiceImpl(); - scrServiceReg = bc.registerService(ScrService.class.getName(), scrService, null); - - if (startup) { - log.debug("[END - start method] Activator.start() method executed for " + String.valueOf(time[0] - time[2]), null); //$NON-NLS-1$ - time = null; - } - } - - /* - * (non-Javadoc) - * - * @see org.osgi.framework.BundleActivator#stop(org.osgi.framework.BundleContext) - */ - public void stop(BundleContext bundleContext) throws Exception { - if (scrManager != null) { - scrManager.stopIt(); - bundleContext.removeServiceListener(scrManager); + BundleWiring wiring = context.getBundle().adapt(BundleWiring.class); + List required = wiring.getRequiredWires(BundleNamespace.BUNDLE_NAMESPACE); + if (required.isEmpty()) { + throw new IllegalStateException("No org.apache.felix.scr bundle found!"); //$NON-NLS-1$ } - // dispose the CM Listener - if (configListenerReg != null) { - configListenerReg.unregister(); - } - if (scrService != null) { - scrService.dispose(); - scrServiceReg.unregister(); - } - - if (scrCommandProviderReg != null) - scrCommandProviderReg.unregister(); - - if (scrManager != null) { - bundleContext.removeBundleListener(scrManager); - } else { - bundleContext.removeBundleListener(this); - } - ServiceReference envInfoRef = bc.getServiceReference(EnvironmentInfo.class.getName()); - EnvironmentInfo envInfo = null; - if (envInfoRef != null) { - envInfo = (EnvironmentInfo) bc.getService(envInfoRef); - } - if (envInfo != null) { - envInfo.setProperty("equinox.use.ds", "false"); //$NON-NLS-1$//$NON-NLS-2$ - bc.ungetService(envInfoRef); - } else { - System.setProperty("equinox.use.ds", "false"); //$NON-NLS-1$ //$NON-NLS-2$ - } - - log.close(); - log = null; - } - - public static Filter createFilter(String filter) throws InvalidSyntaxException { - return bc.createFilter(filter); - } - - public void bundleChanged(BundleEvent event) { - if (event.getType() == BundleEvent.STARTED || event.getType() == BundleEvent.LAZY_ACTIVATION) { - Dictionary allHeaders = event.getBundle().getHeaders(""); //$NON-NLS-1$ - if ((allHeaders.get(ComponentConstants.SERVICE_COMPONENT)) != null) { - // The bundle is holding components - activate scr - bc.removeBundleListener(this); - initSCR(); - } - } - } - - public static Configuration getConfiguration(String pid) throws IOException { - if (configAdmin != null) { - return configAdmin.getConfiguration(pid); - } - return null; - } - - public static Configuration[] listConfigurations(String filter) throws IOException, InvalidSyntaxException { - if (configAdmin != null) { - return configAdmin.listConfigurations(filter); - } - return null; - } - - public static boolean getBoolean(String property, boolean defaultValue) { - String prop = (bc != null) ? bc.getProperty(property) : System.getProperty(property); - if (prop != null) { - return prop.equalsIgnoreCase("true"); //$NON-NLS-1$ - } - return defaultValue; - } - - public static boolean getBoolean(String property) { - return getBoolean(property, false); - } - - public static int getInteger(String property, int defaultValue) { - String prop = (bc != null) ? bc.getProperty(property) : System.getProperty(property); - if (prop != null) { - try { - return Integer.decode(prop).intValue(); - } catch (NumberFormatException e) { - //do nothing - } - } - return defaultValue; - } - - public boolean getBooleanDebugOption(DebugOptions optionsService, String option, boolean defaultValue) { - if (optionsService != null) { - String value = optionsService.getOption(option); - if (value != null) - return value.equalsIgnoreCase("true"); //$NON-NLS-1$ - } - return defaultValue; - } - - private void installCommandProvider() { - try { - SCRCommandProvider scrCommandProvider = new SCRCommandProvider(scrManager); - Hashtable reg_props = new Hashtable(1, 1); - reg_props.put(org.osgi.framework.Constants.SERVICE_RANKING, new Integer(Integer.MAX_VALUE)); - scrCommandProviderReg = bc.registerService(org.eclipse.osgi.framework.console.CommandProvider.class.getName(), scrCommandProvider, reg_props); - } catch (NoClassDefFoundError e) { - //the org.eclipse.osgi.framework.console package is optional - if (Activator.DEBUG) { - log.debug("Cannot register SCR CommandProvider!", e); //$NON-NLS-1$ - } - } - } - - public static void log(BundleContext bundleContext, int level, String message, Throwable t) { - LogService logService = null; - ServiceReference logRef = null; - if (bundleContext != null) { - try { - logRef = bundleContext.getServiceReference(LogService.class.getName()); - if (logRef != null) { - logService = (LogService) bundleContext.getService(logRef); - } - } catch (Exception e) { - if (Activator.DEBUG) { - log.debug("Cannot get LogService for bundle " + bundleContext.getBundle().getSymbolicName(), e); //$NON-NLS-1$ - } - } - } - if (logService != null) { - logService.log(level, message, t); - bundleContext.ungetService(logRef); - if (log.getPrintOnConsole()) { - String prefix = ""; //$NON-NLS-1$ - switch (level) { - case LogService.LOG_ERROR : - prefix = "ERROR "; //$NON-NLS-1$ - break; - case LogService.LOG_WARNING : - prefix = "WARNING "; //$NON-NLS-1$ - break; - case LogService.LOG_INFO : - prefix = "INFO "; //$NON-NLS-1$ - break; - } - dumpOnConsole(prefix, bundleContext, message, t, level == LogService.LOG_ERROR); - } - } else { - logRef = bc.getServiceReference(LogService.class.getName()); - if (logRef == null) { - //log service is not available - if (!log.getPrintOnConsole() && !log.autoPrintOnConsole && fwLog == null) { - //The log will not print the message on the console and the FrameworkLog service is not available - //Will print errors on the console as last resort - if (level == LogService.LOG_ERROR) { - dumpOnConsole("ERROR ", bundleContext, message, t, true); //$NON-NLS-1$ - } - } - } - - //using the SCR log - switch (level) { - case LogService.LOG_ERROR : - log.error(message, t); - break; - case LogService.LOG_WARNING : - log.warning(message, t); - break; - case LogService.LOG_INFO : - log.info(message); - break; - default : - log.debug(message, t); - break; - } - } - if (fwLog != null) { - logToFWLog(bundleContext != null ? bundleContext.getBundle().getSymbolicName() : bc.getBundle().getSymbolicName(), level, message, t); + Bundle scr = required.get(0).getProvider().getBundle(); + if (!"org.apache.felix.scr".equals(scr.getSymbolicName())) { //$NON-NLS-1$ + throw new IllegalStateException("Required wrong bundle: " + scr); //$NON-NLS-1$ } + BundleStartLevel equinoxSDstartLevel = context.getBundle().adapt(BundleStartLevel.class); + BundleStartLevel scrStartLevel = scr.adapt(BundleStartLevel.class); + scrStartLevel.setStartLevel(equinoxSDstartLevel.getStartLevel()); + scr.start(); } - private static void dumpOnConsole(String prefix, BundleContext bundleContext, String msg, Throwable t, boolean printInErr) { - String id = (bundleContext == null) ? "SCR " : bundleContext.getBundle().getBundleId() + " "; //$NON-NLS-1$//$NON-NLS-2$ - String message = prefix + id + msg; - if (printInErr) { - System.err.println(message); - } else { - System.out.println(message); - } - if (t != null) { - t.printStackTrace(); - } + public void stop(BundleContext context) throws Exception { + // do nothing; just keep scr persistently started } - private static void logToFWLog(String bsn, int level, String message, Throwable t) { - int severity = FrameworkLogEntry.INFO; - switch (level) { - case LogService.LOG_ERROR : - severity = FrameworkLogEntry.ERROR; - break; - case LogService.LOG_WARNING : - severity = FrameworkLogEntry.WARNING; - break; - case LogService.LOG_INFO : - severity = FrameworkLogEntry.INFO; - break; - case LogService.LOG_DEBUG : - severity = FrameworkLogEntry.INFO; - break; - } - fwLog.log(new FrameworkLogEntry(bsn, severity, 0, message, 0, t, null)); - } - - public void serviceChanged(ServiceEvent event) { - switch (event.getType()) { - case ServiceEvent.REGISTERED : - Object caService = bc.getService(event.getServiceReference()); - configAdmin = (ConfigurationAdmin) caService; - if (caService != null) { - // Config Admin registered - if (scrManager != null) { - scrManager.configAdminRegistered((ConfigurationAdmin) caService, event.getServiceReference()); - } - } - break; - case ServiceEvent.UNREGISTERING : - //get replacement config admin service if available - ServiceReference caRef = bc.getServiceReference(ConfigurationAdmin.class.getName()); - if (caRef != null) { - configAdmin = (ConfigurationAdmin) bc.getService(caRef); - } else { - configAdmin = null; - } - break; - } - } } diff --git a/bundles/org.eclipse.equinox.ds/src/org/eclipse/equinox/internal/ds/CircularityException.java b/bundles/org.eclipse.equinox.ds/src/org/eclipse/equinox/internal/ds/CircularityException.java deleted file mode 100644 index 094a2ed33..000000000 --- a/bundles/org.eclipse.equinox.ds/src/org/eclipse/equinox/internal/ds/CircularityException.java +++ /dev/null @@ -1,35 +0,0 @@ -/******************************************************************************* - * Copyright (c) 1997, 2008 by ProSyst Software GmbH - * http://www.prosyst.com - * 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: - * ProSyst Software GmbH - initial API and implementation - *******************************************************************************/ -package org.eclipse.equinox.internal.ds; - -import org.eclipse.equinox.internal.ds.model.ServiceComponentProp; - -/** - * Used to find circular dependencies - * - * @author Pavlin Dobrev - * @version 1.0 - */ - -public class CircularityException extends Exception { - private static final long serialVersionUID = 1L; - private ServiceComponentProp causingComponent; - - public CircularityException(ServiceComponentProp scp) { - this.causingComponent = scp; - } - - public ServiceComponentProp getCausingComponent() { - return causingComponent; - } - -} diff --git a/bundles/org.eclipse.equinox.ds/src/org/eclipse/equinox/internal/ds/ComponentStorage.java b/bundles/org.eclipse.equinox.ds/src/org/eclipse/equinox/internal/ds/ComponentStorage.java deleted file mode 100644 index 09ce29720..000000000 --- a/bundles/org.eclipse.equinox.ds/src/org/eclipse/equinox/internal/ds/ComponentStorage.java +++ /dev/null @@ -1,126 +0,0 @@ -/******************************************************************************* - * Copyright (c) 1997-2013 by ProSyst Software GmbH and others. - * http://www.prosyst.com - * 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: - * ProSyst Software GmbH - initial API and implementation - *******************************************************************************/ -package org.eclipse.equinox.internal.ds; - -import java.io.IOException; -import java.io.InputStream; -import java.net.URL; -import java.util.*; -import org.eclipse.equinox.internal.ds.model.DeclarationParser; -import org.eclipse.osgi.util.ManifestElement; -import org.eclipse.osgi.util.NLS; -import org.osgi.framework.Bundle; -import org.osgi.service.component.ComponentConstants; -import org.osgi.service.log.LogService; - -/** - * @author Stoyan Boshev - * @author Pavlin Dobrev - */ - -public abstract class ComponentStorage { - - private final DeclarationParser parser = new DeclarationParser(); - - /** - * This method will load the component definitions from a bundle. The - * returned value should contain vector with 'ServiceComponent' elements. - * - * @param bundle bundle, containing DS components - * @param dsHeader the DS header value which is in the bundle's manifest - * @return null if there are no component definitions. - */ - public abstract Vector loadComponentDefinitions(Bundle bundle, String dsHeader); - - /** - * This method is called when a bundle has been uninstalled and therefore its cached components must be removed - * @param bundleID the id of the uninstalled bundle - */ - public abstract void deleteComponentDefinitions(long bundleID); - - /** - * Called when the DS bundle is about to stop. This method must store any unsaved data - */ - public abstract void stop(); - - protected Vector parseXMLDeclaration(Bundle bundle, String dsHeader) throws Exception { - Vector components = new Vector(); - if (dsHeader == null) - return components; - ManifestElement[] elements = ManifestElement.parseHeader(ComponentConstants.SERVICE_COMPONENT, dsHeader); - Collection/**/urlCollection = computeComponentDefinitionUrls(bundle, elements); - // the parser is not thread safe!!! - synchronized (parser) { - // illegal components are ignored, but framework event is posted for - // them; however, it will continue and try to load any legal - // definitions - URL url; - for (Iterator/**/urls = urlCollection.iterator(); urls.hasNext();) { - url = (URL) urls.next(); - if (Activator.DEBUG) { - Activator.log.debug("ComponentStorage.parseXMLDeclaration(): loading " + url.toString(), null); //$NON-NLS-1$ - } - InputStream is = null; - try { - is = url.openStream(); - if (is == null) { - Activator.log(bundle.getBundleContext(), LogService.LOG_ERROR, NLS.bind(Messages.CANT_OPEN_STREAM_TO_COMPONENT_XML, url), null); - } else { - int compSize = components.size(); - parser.parse(is, bundle, components, url.toString()); - if (compSize == components.size()) { - Activator.log(bundle.getBundleContext(), LogService.LOG_WARNING, NLS.bind(Messages.NO_COMPONENTS_FOUND, url), null); - } - } - } catch (IOException ie) { - Activator.log(bundle.getBundleContext(), LogService.LOG_ERROR, NLS.bind(Messages.ERROR_OPENING_COMP_XML, url), ie); - } catch (Throwable t) { - Activator.log(bundle.getBundleContext(), LogService.LOG_ERROR, NLS.bind(Messages.ILLEGAL_DEFINITION_FILE, url), t); - } finally { - if (is != null) { - is.close(); - } - } - } // end while - - components = parser.components; - // make sure the clean-up the parser cache, for the next bundle to - // work properly!!! - parser.components = null; - } - return components; - } - - protected Collection/**/computeComponentDefinitionUrls(Bundle bundle, ManifestElement[] elements) { - Collection/**/result = new ArrayList/**/(5); - // process all definition file - for (int i = 0; i < elements.length; i++) { - String[] definitionFiles = elements[i].getValueComponents(); - for (int j = 0; j < definitionFiles.length; j++) { - String definitionFile = definitionFiles[j]; - int ind = definitionFile.lastIndexOf('/'); - String path = ind != -1 ? definitionFile.substring(0, ind) : "/"; //$NON-NLS-1$ - - Enumeration/**/urls = bundle.findEntries(path, ind != -1 ? definitionFile.substring(ind + 1) : definitionFile, false); - if (urls == null || !urls.hasMoreElements()) { - Activator.log(bundle.getBundleContext(), LogService.LOG_ERROR, NLS.bind(Messages.COMPONENT_XML_NOT_FOUND, bundle.getSymbolicName(), definitionFile), null); - continue; - } - - while (urls.hasMoreElements()) - result.add(urls.nextElement()); - } - } - return result; - } - -} diff --git a/bundles/org.eclipse.equinox.ds/src/org/eclipse/equinox/internal/ds/FactoryReg.java b/bundles/org.eclipse.equinox.ds/src/org/eclipse/equinox/internal/ds/FactoryReg.java deleted file mode 100644 index 96912b247..000000000 --- a/bundles/org.eclipse.equinox.ds/src/org/eclipse/equinox/internal/ds/FactoryReg.java +++ /dev/null @@ -1,67 +0,0 @@ -/******************************************************************************* - * Copyright (c) 1997-2009 by ProSyst Software GmbH - * http://www.prosyst.com - * 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: - * ProSyst Software GmbH - initial API and implementation - *******************************************************************************/ -package org.eclipse.equinox.internal.ds; - -import org.eclipse.equinox.internal.ds.model.ServiceComponentProp; -import org.eclipse.osgi.util.NLS; -import org.osgi.framework.*; -import org.osgi.service.component.*; -import org.osgi.service.log.LogService; - -/** - * @author Pavlin Dobrev - * @version 1.0 - */ - -final class FactoryReg implements ServiceFactory { - - /* the instance created */ - private final ServiceComponentProp component; - - FactoryReg(ServiceComponentProp component) { - this.component = component; - } - - // ServiceFactory.getService method. - public Object getService(Bundle bundle, ServiceRegistration registration) { - - try { - if (Activator.DEBUG) { - Activator.log.debug("FactoryReg.getService(): created new service for component " + component.name, null); //$NON-NLS-1$ - } - ComponentInstance ci = InstanceProcess.staticRef.buildComponent(bundle, component, null, false); - // ci can be null if the component is already disposed while being built - if (ci != null) { - return ci.getInstance(); - } - } catch (Throwable t) { - if (!(t instanceof ComponentException)) { - Activator.log(component.bc, LogService.LOG_ERROR, NLS.bind(Messages.CANT_GET_SERVICE, component.name), t); - } else { - throw (ComponentException) t; - } - } - return null; - } - - // ServiceFactory.ungetService method. - public void ungetService(Bundle bundle, ServiceRegistration registration, Object service) { - if (Activator.DEBUG) { - Activator.log.debug("FactoryReg.ungetService(): registration = " + registration.toString(), null); //$NON-NLS-1$ - } - component.disposeObj(service, ComponentConstants.DEACTIVATION_REASON_UNSPECIFIED); - } - - public String toString() { - return component.name + " FactoryRegistration"; //$NON-NLS-1$ - } -} diff --git a/bundles/org.eclipse.equinox.ds/src/org/eclipse/equinox/internal/ds/InstanceProcess.java b/bundles/org.eclipse.equinox.ds/src/org/eclipse/equinox/internal/ds/InstanceProcess.java deleted file mode 100644 index b822cc8ba..000000000 --- a/bundles/org.eclipse.equinox.ds/src/org/eclipse/equinox/internal/ds/InstanceProcess.java +++ /dev/null @@ -1,838 +0,0 @@ -/******************************************************************************* - * Copyright (c) 1997, 2010 by ProSyst Software GmbH - * http://www.prosyst.com - * 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: - * ProSyst Software GmbH - initial API and implementation - *******************************************************************************/ -package org.eclipse.equinox.internal.ds; - -import java.lang.reflect.InvocationTargetException; -import java.util.*; -import org.apache.felix.scr.Component; -import org.eclipse.equinox.internal.ds.impl.ComponentFactoryImpl; -import org.eclipse.equinox.internal.ds.impl.ComponentInstanceImpl; -import org.eclipse.equinox.internal.ds.model.*; -import org.eclipse.osgi.util.NLS; -import org.osgi.framework.*; -import org.osgi.service.cm.Configuration; -import org.osgi.service.component.*; -import org.osgi.service.log.LogService; - -/** - * This class is responsible for creating, tracking and disposing of service - * instances and registrations. - * - * @author Valentin Valchev - * @author Stoyan Boshev - * @author Pavlin Dobrev - */ - -public class InstanceProcess { - - public static Resolver resolver; - public static InstanceProcess staticRef; - - /** map SCP:ServiceRegistration */ - protected Hashtable factoryRegistrations; - - /** - * Used with stackCount to handle circular dependencies in the - * {@link InstanceProcess#buildComponent(Bundle, ServiceComponentProp, Object)} - * method. - */ - private Vector delayedBindList; - - //key - the SPC being built; value - the thread that builds the SCP - static Hashtable buildingThreads = new Hashtable(7); - //key - the building thread; value - Counter - holds the count of entries in buildComponent method - static Hashtable stackCounts = new Hashtable(7); - //specifies the maximum time that a thread must wait for the building thread to complete the building of the SCP - static int waitTime = Activator.getInteger("equinox.scr.waitTimeOnBlock", 10000); //$NON-NLS-1$ - - //a flag used for synchronization of build/dispose operations - boolean busyBuilding = false; - //the working thread that performs the current build/dispose operation - Thread workingThread; - //an object used for synchronization when changing the status of busyBuilding flag - Object lock = new Object(); - //used to count the number of times a lock is held when required recursively - int lockCounter = 0; - - /** - * Handle Instance processing building and disposing. - * - * @param resolver - * the resolver instance - */ - InstanceProcess(Resolver resolver) { - InstanceProcess.resolver = resolver; - factoryRegistrations = new Hashtable(19); - delayedBindList = new Vector(10); - staticRef = this; - } - - /** - * dispose cleanup the SCR is shutting down - */ - void dispose() { - factoryRegistrations = null; - } - - // gets the synch lock to perform some build/release work - void getLock() { - synchronized (lock) { - Thread currentThread = Thread.currentThread(); - if (!busyBuilding) { - busyBuilding = true; - lockCounter++; - workingThread = currentThread; - } else if (workingThread == currentThread) { - //increase the lock counter - the lock is required recursively - lockCounter++; - } else if (workingThread != currentThread) { - long start = System.currentTimeMillis(); - long timeToWait = waitTime; - boolean lockSucceeded = false; - do { - try { - lock.wait(timeToWait); - } catch (InterruptedException e) { - // do nothing - } - if (!busyBuilding) { - busyBuilding = true; - lockCounter++; - workingThread = currentThread; - lockSucceeded = true; - break; - } - timeToWait = waitTime + start - System.currentTimeMillis(); - } while (timeToWait > 0); - //check if the timeout has passed or the lock is actually successfully held - if (!lockSucceeded) { - // The lock is not yet released! - // Allow the operation but log a warning - Activator.log(null, LogService.LOG_WARNING, NLS.bind(Messages.TIMEOUT_GETTING_LOCK, Integer.toString(InstanceProcess.waitTime)), new Exception("Debug stacktrace")); //$NON-NLS-1$ - } - } - } - } - - // free the synch lock - void freeLock() { - synchronized (lock) { - if (busyBuilding) { - if (workingThread == Thread.currentThread()) { - //only the thread holding the lock can release it - lockCounter--; - } - // release the lock in case the lock counter has decreased to 0 - if (lockCounter == 0) { - busyBuilding = false; - workingThread = null; - lock.notify(); - } - } - } - } - - /** - * Builds the Service Component descriptions (registration of needed - * services, building of component instances if necessary (includes - * activating and binding) - * - * @param list - - * a Vector of all components to build. - */ - public void buildComponents(Vector list, boolean security) { - ServiceComponentProp scp = null; - ServiceComponent sc; - String factoryPid = null; - - // loop through SCP list of enabled - if (list != null) { - getLock(); - Vector listToBuild = new Vector(); - for (int i = 0; i < list.size(); i++) { - scp = (ServiceComponentProp) list.elementAt(i); - if (scp.getState() != Component.STATE_UNSATISFIED) { - //no need to build the component: - // 1) it is disposed or about to be disposed - // 2) it is already built or being built - continue; - } - scp.setState(Component.STATE_ACTIVATING); - listToBuild.addElement(scp); - } - freeLock(); - for (int i = 0; i < listToBuild.size(); i++) { - scp = (ServiceComponentProp) listToBuild.elementAt(i); - getLock(); - if (scp.getState() != Component.STATE_ACTIVATING) { - //no need to build the component: - // 1) it is disposed or about to be disposed - // 2) it is already built or being built - freeLock(); - continue; - } - long start = 0l; - boolean successfullyBuilt = true; - try { - if (Activator.PERF) { - start = System.currentTimeMillis(); - Activator.log.info("[DS perf] Start building component " + scp); //$NON-NLS-1$ - } - sc = scp.serviceComponent; - if (sc.immediate || (sc.factory == null && Activator.INSTANTIATE_ALL)) { - if (Activator.DEBUG) { - Activator.log.debug("InstanceProcess.buildComponents(): building immediate component " + scp.name, null); //$NON-NLS-1$ - } - if (scp.instances.isEmpty()) { - try { - buildComponent(null, scp, null, security); - } catch (Throwable e) { - resolver.reorderSCP(scp); - successfullyBuilt = false; - if (!(e instanceof ComponentException)) { - Activator.log(null, LogService.LOG_ERROR, NLS.bind(Messages.CANNOT_BUILD_COMPONENT, scp), e); - } - } - } - if (successfullyBuilt) { - if (sc.serviceInterfaces != null) { - // this component registers service - //the service will be registered only if the component was successfully built - - // this will create either plain service component registration - // or a service factory registration - registerService(scp, sc.serviceFactory, null); - } - scp.setState(Component.STATE_ACTIVE); - } - } else { - - // ComponentFactory - if (sc.factory != null) { - // check if it is NOT a component config created by a - // component factory - if (scp.isComponentFactory()) { - if (Activator.DEBUG) { - Activator.log.debug("InstanceProcess.buildComponents(): building component factory " + scp.name, null); //$NON-NLS-1$ - } - - // check if MSF - try { - Configuration config = Activator.getConfiguration(sc.getConfigurationPID()); - if (config != null) { - factoryPid = config.getFactoryPid(); - } - } catch (Exception e) { - Activator.log(null, LogService.LOG_ERROR, NLS.bind(Messages.CANNOT_GET_CONFIGURATION, sc.getConfigurationPID()), e); - } - - // if MSF throw exception - can't be - // ComponentFactory add MSF - if (factoryPid != null) { - Vector toDisable = new Vector(1); - toDisable.addElement(sc); - InstanceProcess.resolver.disableComponents(toDisable, ComponentConstants.DEACTIVATION_REASON_UNSPECIFIED); - successfullyBuilt = false; - throw new org.osgi.service.component.ComponentException(Messages.INCOMPATIBLE_COMBINATION); - } - scp.setState(Component.STATE_FACTORY); - registerComponentFactory(scp); - // when registering a ComponentFactory we must not - // register the component configuration as service - continue; - } - } - - // check whether there is a service to register - if (sc.provides != null) { - // this will create either plain service component - // registration or a service factory registration - scp.setState(Component.STATE_REGISTERED); - registerService(scp, sc.serviceFactory, null); - } - } - } catch (Throwable t) { - Activator.log(null, LogService.LOG_ERROR, NLS.bind(Messages.EXCEPTION_BUILDING_COMPONENT, scp.serviceComponent), t); - } finally { - if (!successfullyBuilt) { - scp.setState(Component.STATE_UNSATISFIED); - } - freeLock(); - if (Activator.PERF) { - start = System.currentTimeMillis() - start; - Activator.log.info("[DS perf] The component " + scp + " is built for " + Long.toString(start) + "ms"); //$NON-NLS-1$ //$NON-NLS-2$//$NON-NLS-3$ - } - } - } // end for - } // end if (list != null) - } - - /** - * - * Dispose of Component Instances, includes unregistering services and - * removing instances. - * - * @param scpList - - * list of ComponentDescriptions plus Property objects to be - * disposed - */ - void disposeInstances(Vector scpList, int deactivateReason) { - // loop through SC+P list to be disposed - if (scpList != null) { - for (int i = 0; i < scpList.size(); i++) { - ServiceComponentProp scp = (ServiceComponentProp) scpList.elementAt(i); - getLock(); - if (scp.isUnsatisfied()) { - //it is already deactivated - freeLock(); - continue; - } - long start = 0l; - try { - scp.setState(Component.STATE_DEACTIVATING); - if (Activator.PERF) { - start = System.currentTimeMillis(); - Activator.log.info("[DS perf] Start disposing component " + scp); //$NON-NLS-1$ - } - disposeInstances(scp, deactivateReason); - } catch (Throwable t) { - Activator.log(null, LogService.LOG_ERROR, NLS.bind(Messages.ERROR_DISPOSING_INSTANCES, scp), t); - } finally { - resolver.componentDisposed(scp); - freeLock(); - if (Activator.PERF) { - start = System.currentTimeMillis() - start; - Activator.log.info("[DS perf] The component " + scp + " is disposed for " + Long.toString(start) + "ms"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ - } - } - } - } - } - - /** - * @param scp - */ - private void disposeInstances(ServiceComponentProp scp, int deactivateReason) { - if (scp.isComponentFactory()) { - if (Activator.DEBUG) { - Activator.log.debug("InstanceProcess.disposeInstances(): disposing component factory " + scp.name, null); //$NON-NLS-1$ - } - ServiceRegistration reg = (ServiceRegistration) factoryRegistrations.remove(scp); - try { - if (reg != null) - reg.unregister(); - } catch (IllegalStateException e) { - // Service is already unregistered do nothing - Activator.log(null, LogService.LOG_WARNING, NLS.bind(Messages.FACTORY_REGISTRATION_ALREADY_DISPOSED, scp.name), null); - } - } - ServiceComponent sc = scp.serviceComponent; - // if no Services provided - dispose of instance immediately - if (sc.provides == null) { - if (Activator.DEBUG) { - Activator.log.debug("InstanceProcess.disposeInstances(): disposing non-provider component " + scp.name, null); //$NON-NLS-1$ - } - scp.dispose(deactivateReason); - } else { - // The component registers services - if (Activator.DEBUG) { - Activator.log.debug("InstanceProcess.disposeInstances(): unregistering component " + scp.name, null); //$NON-NLS-1$ - } - - // unregister services if any - if (scp.registration != null) { - try { - ServiceRegistration reg = scp.registration; - scp.setRegistration(null); - reg.unregister(); - } catch (IllegalStateException e) { - // Service is already unregistered do nothing - Activator.log(null, LogService.LOG_WARNING, NLS.bind(Messages.REGISTRATION_ALREADY_DISPOSED, scp.name), null); - } - } else { - if (Activator.DEBUG) { - Activator.log.debug("InstanceProcess.disposeInstances(): cannot find registrations for " + scp.name, null); //$NON-NLS-1$ - } - } - scp.dispose(deactivateReason); - } - } - - /** - * Register the Component Factory - * - * @param scp - */ - private void registerComponentFactory(ServiceComponentProp scp) { - if (factoryRegistrations.get(scp) != null) { - //the service factory is already registered - return; - } - ComponentFactory factory = new ComponentFactoryImpl(scp); - ServiceComponent sc = scp.serviceComponent; - BundleContext bc = scp.bc; - // if the factory attribute is set on the component element then - // register a - // component factory service - // for the Service Component on behalf of the Service Component. - Hashtable properties = new Hashtable(2); - properties.put(ComponentConstants.COMPONENT_NAME, sc.name); - properties.put(ComponentConstants.COMPONENT_FACTORY, sc.factory); - ServiceRegistration reg = bc.registerService(ComponentFactory.class.getName(), factory, properties); - factoryRegistrations.put(scp, reg); - } - - /** - * Called by Resolver when there is a need of dynamic binding of references - * - * @param refList the references to be bound - * @return a Vector containing the Reference objects that are still not bound due to ClassCircularityError. - * The returned value may be null if all of the passed references are successfully bound - */ - final Vector dynamicBind(Vector refList) { - if (refList == null || refList.isEmpty()) { - return null; - } - Vector unboundRefs = null; - for (int i = 0; i < refList.size(); i++) { - Reference ref = (Reference) refList.elementAt(i); - ServiceComponentProp scp = ref.scp; - - Vector instances = scp.instances; - if (instances != null) { - for (int j = 0; j < instances.size(); j++) { - ComponentInstance compInstance = (ComponentInstance) instances.elementAt(j); - if (compInstance != null) { - try { - scp.bindReference(ref, compInstance); - } catch (ClassCircularityError cce) { - if (unboundRefs == null) { - unboundRefs = new Vector(1); - } - unboundRefs.add(ref); - Activator.log(scp.bc, LogService.LOG_ERROR, NLS.bind(Messages.ERROR_BINDING_REFERENCE, ref.reference), cce); - } catch (Throwable t) { - Activator.log(scp.bc, LogService.LOG_ERROR, NLS.bind(Messages.ERROR_BINDING_REFERENCE, ref.reference), t); - } - } - } - } else { - // the component is not used and therefore it is not yet - // instantiated! - if (Activator.DEBUG) { - Activator.log.debug("InstanceProcess.dynamicBind(): null instances for component " + scp.name, null); //$NON-NLS-1$ - } - } - } - return unboundRefs; - } - - /** - * Called by dispatcher ( Resolver) when work available on queue - * - * @param serviceTable - * Map of ReferenceDescription:subtable Subtable Maps scp:service - * object - */ - final void dynamicUnBind(Hashtable serviceTable) { - try { - if (serviceTable == null || serviceTable.isEmpty()) { - return; - } - // for each element in the table - Enumeration e = serviceTable.keys(); - while (e.hasMoreElements()) { - Reference ref = (Reference) e.nextElement(); - Hashtable serviceSubTable = (Hashtable) serviceTable.get(ref); - Enumeration sub = serviceSubTable.keys(); - while (sub.hasMoreElements()) { - ServiceComponentProp scp = (ServiceComponentProp) sub.nextElement(); - ServiceReference serviceReference = (ServiceReference) serviceSubTable.get(scp); - // get the list of instances created - Vector instances = scp.instances; - for (int i = 0; i < instances.size(); i++) { - ComponentInstance compInstance = (ComponentInstance) instances.elementAt(i); - if (compInstance != null) { - try { - scp.unbindDynamicReference(ref, compInstance, serviceReference); - } catch (Throwable t) { - Activator.log(null, LogService.LOG_ERROR, NLS.bind(Messages.ERROR_UNBINDING_REFERENCE, ref.reference, compInstance.getInstance()), t); - } - } - } - } - } - } catch (Throwable e) { - //should not happen - Activator.log(null, LogService.LOG_ERROR, Messages.UNEXPECTED_ERROR, e); - } - } - - /** - * Called by dispatcher ( Resolver) when service properties have been modified for some reference - * - * @param serviceReferenceTable Map of ::> - */ - final void referencePropertiesUpdated(Hashtable serviceReferenceTable) { - // for each element in the table - Enumeration e = serviceReferenceTable.keys(); - while (e.hasMoreElements()) { - Reference ref = (Reference) e.nextElement(); - Hashtable serviceSubTable = (Hashtable) serviceReferenceTable.get(ref); - Enumeration sub = serviceSubTable.keys(); - while (sub.hasMoreElements()) { - ServiceComponentProp scp = (ServiceComponentProp) sub.nextElement(); - ServiceReference serviceReference = (ServiceReference) serviceSubTable.get(scp); - // get the list of instances created - Vector instances = scp.instances; - for (int i = 0; i < instances.size(); i++) { - ComponentInstance compInstance = (ComponentInstance) instances.elementAt(i); - if (compInstance != null) { - try { - scp.updatedReference(ref, compInstance, serviceReference); - } catch (Throwable t) { - Activator.log(null, LogService.LOG_ERROR, NLS.bind(Messages.ERROR_UPDATING_REFERENCE, ref.reference, compInstance.getInstance()), t); - } - } - } - } - } - } - - /** - * registerService - * - * @param scp - * ComponentDescription plus Properties - * @param factory - * boolean - * @param ci - * the component instance created by ComponentFactoryImpl! - */ - private void registerService(ServiceComponentProp scp, boolean factory, ComponentInstanceImpl ci) { - // register the service using a ServiceFactory - ServiceRegistration reg = null; - Object service; - if (scp.registration != null) { - //the service has already been registered - return; - } - if (factory) { - // register as service factory - service = new FactoryReg(scp); - } else { - service = new ServiceReg(scp, ci); - } - - reg = scp.bc.registerService(scp.serviceComponent.provides, service, scp.getPublicServiceProperties()); - - if (Activator.DEBUG) { - Activator.log.debug("InstanceProcess.registerService(): " + scp.name + " registered as " + ((factory) ? "*factory*" : "*service*"), null); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ - } - if (scp.isUnsatisfied()) { - //must unregister the service because it was not able to unregister when the component was disposed - try { - reg.unregister(); - if (Activator.DEBUG) { - Activator.log.debug("InstanceProcess.registerService(): The service of component " + scp.name + " was unregistered because the component is already disposed!", null); //$NON-NLS-1$ //$NON-NLS-2$ - } - } catch (IllegalStateException e) { - // Service is already unregistered do nothing - } - } else { - scp.setRegistration(reg); - } - } - - public ComponentInstanceImpl buildComponent(Bundle usingBundle, ServiceComponentProp scp, Object instance, boolean security) throws ComponentException { - if (Activator.DEBUG) { - Activator.log.debug("InstanceProcess.buildComponent(): building component " + scp.name, null); //$NON-NLS-1$ - } - getLock(); - Counter counter; - Thread curThread = Thread.currentThread(); - synchronized (scp) { - Thread theSCPThread = (Thread) buildingThreads.get(scp); - if (theSCPThread != null && curThread != theSCPThread) { //manage cyclic calls - if (scp.isKindOfFactory()) { - // The scp is a kind of factory - multiple instances are allowed. - // The building of the scp is allowed - } else { - long start = System.currentTimeMillis(); - long timeToWait = waitTime; - do { - try { - scp.wait(timeToWait); - } catch (InterruptedException ie) { - //do nothing - } - if (buildingThreads.get(scp) == null) { - //the lock is released - break; - } - timeToWait = waitTime + start - System.currentTimeMillis(); - } while (timeToWait > 0); - - //check if the timeout has passed or the scp is actually built - if (buildingThreads.get(scp) != null) { - freeLock(); - // The SCP is not yet built - // We have two options here: - // 1 - Return the instance (if already created) nevertheless it is not finished its binding and activation phase - // 2 - throw an exception because something may have gone wrong - if (!scp.instances.isEmpty()) { - Activator.log(null, LogService.LOG_WARNING, Messages.RETURNING_NOT_FULLY_ACTIVATED_INSTANCE, new Exception("Debug callstack")); //$NON-NLS-1$ - return (ComponentInstanceImpl) scp.instances.firstElement(); - } - - throw new RuntimeException(NLS.bind(Messages.INSTANCE_CREATION_TOOK_LONGER, scp, Integer.toString(waitTime))); - } - } - } - buildingThreads.put(scp, curThread); - - // keep track of how many times we have re-entered this method - counter = (Counter) stackCounts.get(curThread); - if (counter == null) { - counter = new Counter(); - stackCounts.put(curThread, counter); - } - counter.count++; - } - - long start = 0l; - try { - if (Activator.PERF) { - start = System.currentTimeMillis(); - Activator.log.info("[DS perf] Start building instance of component " + scp); //$NON-NLS-1$ - } - ComponentInstanceImpl componentInstance = null; - try { - componentInstance = scp.build(usingBundle, instance, security); - } catch (ClassCircularityError e) { - processSCPInClassCircularityError(scp); - throw new ComponentException(NLS.bind(Messages.ERROR_BUILDING_COMPONENT_INSTANCE, scp.serviceComponent), e); - } catch (ComponentException e) { - Activator.log(null, LogService.LOG_ERROR, e.getMessage(), e.getCause()); - Throwable t = e.getCause(); - if (t instanceof InvocationTargetException) { - Throwable cause = t.getCause(); - if (cause instanceof ClassCircularityError) { - processSCPInClassCircularityError(scp); - } - } - - throw e; - } catch (Throwable t) { - Activator.log(null, LogService.LOG_ERROR, NLS.bind(Messages.ERROR_BUILDING_COMPONENT_INSTANCE, scp.serviceComponent), t); - throw new ComponentException(NLS.bind(Messages.ERROR_BUILDING_COMPONENT_INSTANCE, scp.serviceComponent), t); - } finally { - // keep track of how many times we have re-entered this method - counter.count--; - if (Activator.PERF) { - start = System.currentTimeMillis() - start; - Activator.log.info("[DS perf] The instance of component " + scp + " is built for " + Long.toString(start) + "ms"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ - } - } - - // if this is the last time in this method and we have "delayed" - // bind actions to do (there was a circularity during bind) - if (counter.count == 0 && !delayedBindList.isEmpty()) { - // put delayed dynamic binds on the queue. - // (this is used to handle circularity) - resolver.mgr.enqueueWork(resolver, Resolver.DYNAMICBIND, delayedBindList.clone(), security); - delayedBindList.removeAllElements(); - } - - return componentInstance; - } finally { - synchronized (scp) { - if (counter.count == 0) { - stackCounts.remove(curThread); - } - buildingThreads.remove(scp); - scp.notify(); - } - freeLock(); - } - } - - private void processSCPInClassCircularityError(ServiceComponentProp currentScp) { - Vector component = new Vector(1); - component.add(currentScp.serviceComponent); - resolver.mgr.enqueueWork(resolver.mgr, resolver.mgr.ENABLE_COMPONENTS, component, false); - } - - public void modifyComponent(ServiceComponentProp scp, Dictionary newProps) throws ComponentException { - if (Activator.DEBUG) { - Activator.log.debug("Modifying component " + scp.name, null); //$NON-NLS-1$ - } - getLock(); - long start = 0l; - try { - if (!scp.isBuilt()) { - return; - } - if (Activator.PERF) { - start = System.currentTimeMillis(); - Activator.log.info("[DS perf] Modifying component " + scp.name); //$NON-NLS-1$ - } - try { - scp.modify(newProps); - } catch (ComponentException e) { - Activator.log(null, LogService.LOG_ERROR, e.getMessage(), e.getCause()); - throw e; - } catch (Throwable t) { - Activator.log(null, LogService.LOG_ERROR, NLS.bind(Messages.ERROR_MODIFYING_COMPONENT, scp.serviceComponent), t); - throw new ComponentException(NLS.bind(Messages.ERROR_MODIFYING_COMPONENT, scp.serviceComponent), t); - } finally { - // keep track of how many times we have re-entered this method - if (Activator.PERF) { - start = System.currentTimeMillis() - start; - Activator.log.info("[DS perf] Component " + scp + " modified for " + Long.toString(start) + "ms"); //$NON-NLS-1$//$NON-NLS-2$ //$NON-NLS-3$ - } - } - } finally { - freeLock(); - } - } - - /** - * Acquire a service object from a {@link ServiceReference}. - * - * This method checks if "getting" the service could cause a cycle. If so, - * it breaks the cycle and returns null. - * - * @param reference - * @param serviceReference - * - * @return the service object or null if it would cause a circularity - */ - public Object getService(Reference reference, ServiceReference serviceReference) { - // check if getting this service would cause a circularity - if (checkCanCauseCycle(reference, serviceReference)) { - if (Activator.DEBUG) { - Activator.log.debug("InstanceProcess.getService(): cannot get service because of circularity! Reference is: " + reference.reference.name + " ; The service reference is " + serviceReference, null); //$NON-NLS-1$//$NON-NLS-2$ - } - return null; - } - - // getting this service will not cause a circularity - Object serviceObject = reference.scp.bc.getService(serviceReference); - if (serviceObject == null) { - if (Activator.DEBUG) { - Activator.log.debug("[SCR] Returned service object by the bundle context is null. The reference is " + reference.reference.name + "; The ServiceReference is " + serviceReference, null); //$NON-NLS-1$ //$NON-NLS-2$ - } - } - return serviceObject; - } - - /** - * Check the "cycle list" put in the scp by the resolver to see if getting - * this reference would cause a circularity. - * - * A circularity is only possible if the "producer" of the service is also a - * service component. - * - * If getting the service could cause a circularity and the reference's - * policy is "dynamic", add an entry to the "delayed bind list" which is - * processed when the component is built - * - * @param reference - * @param serviceReference - * @return if getting the service could cause a circularity - */ - private boolean checkCanCauseCycle(Reference reference, ServiceReference serviceReference) { - - ServiceComponentProp consumerSCP = reference.scp; - // if we are not building a component, no cycles possible - if (buildingThreads.isEmpty()) { - return false; - } - - String producerComponentName = (String) serviceReference.getProperty(ComponentConstants.COMPONENT_NAME); - - // if producer is not a service component, no cycles possible - if (producerComponentName == null) { - return false; - } - - // check if producer is the "delayed activate" list - if (consumerSCP.getDelayActivateSCPNames() == null || !consumerSCP.getDelayActivateSCPNames().contains(producerComponentName)) { - return false; - } - - // find producer scp - ServiceComponentProp producerSCP = null; - synchronized (resolver.getSyncLock()) { - for (int i = 0; i < resolver.scpEnabled.size(); i++) { - ServiceComponentProp scp = (ServiceComponentProp) resolver.scpEnabled.elementAt(i); - if (producerComponentName.equals(scp.serviceComponent.name)) { - // found the producer scp - producerSCP = scp; - break; - } - } - } - - if (producerSCP != null) { - if (producerSCP.getState() == Component.STATE_ACTIVE) { - if (producerSCP.serviceComponent.serviceFactory) { - // producer is a service factory - there is a new instance for every - // bundle, so see if one of the instances is used by this bundle - if (!producerSCP.instances.isEmpty()) { - Bundle bundle = consumerSCP.bc.getBundle(); - for (int i = 0; i < producerSCP.instances.size(); i++) { - ComponentInstanceImpl producerComponentInstance = (ComponentInstanceImpl) producerSCP.instances.elementAt(i); - if (producerComponentInstance.getComponentContext().getUsingBundle().equals(bundle)) { - // a producer already exists, so no cycle possible - return false; - } - } - } - } else { - // producer is not a service factory - there will only ever be one - // instance - if it exists then no cycle possible - if (!producerSCP.instances.isEmpty()) { - return false; - } - } - } - } - - // producer scp is not active - do not activate it because that could - // cause circularity - - // if reference has bind method and policy=dynamic, activate later and bind - if (reference.reference.bind != null && reference.policy == ComponentReference.POLICY_DYNAMIC) { - // delay bind by putting on the queue later - if (Activator.DEBUG) { - Activator.log.debug("[SCR] Adding reference for delayed binding. Reference is " + reference.reference.name, null); //$NON-NLS-1$ - } - delayedBindList.addElement(reference); - } - - // can't get service now because of circularity - we will bind later - // (dynamically) if the reference had a bind method and was dynamic - return true; - } - - /** - * Counts re-entry in to the - * {@link InstanceProcess#buildComponent(Bundle, ServiceComponentProp, Object)} method. - * This is used to handle circular dependencies. - */ - static class Counter { - int count = 0; - } - -} diff --git a/bundles/org.eclipse.equinox.ds/src/org/eclipse/equinox/internal/ds/Messages.java b/bundles/org.eclipse.equinox.ds/src/org/eclipse/equinox/internal/ds/Messages.java deleted file mode 100644 index 2e7d6d503..000000000 --- a/bundles/org.eclipse.equinox.ds/src/org/eclipse/equinox/internal/ds/Messages.java +++ /dev/null @@ -1,183 +0,0 @@ -/******************************************************************************* - * Copyright (c) 1997, 2010 by ProSyst Software GmbH - * http://www.prosyst.com - * 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: - * ProSyst Software GmbH - initial API and implementation - *******************************************************************************/ -package org.eclipse.equinox.internal.ds; - -import org.eclipse.osgi.util.NLS; - -public class Messages extends NLS { - private static final String BUNDLE_NAME = "org.eclipse.equinox.internal.ds.SCRmessages"; //$NON-NLS-1$ - public static String ALL_COMPONENTS; - public static String ALL_REFERENCES_RESOLVED; - public static String BIND_METHOD_NOT_FOUND_OR_NOT_ACCESSIBLE; - public static String UPDATED_METHOD_NOT_FOUND_OR_NOT_ACCESSIBLE; - public static String UPDATED_METHOD_NOT_CALLED; - public static String BUNDLE_NOT_FOUND; - public static String CANNOT_BUILD_COMPONENT; - public static String CANNOT_CREATE_INSTANCE; - public static String CANNOT_FIND_COMPONENT_BUNDLE; - public static String CANNOT_GET_CONFIGURATION; - public static String CANNOT_GET_REFERENCES; - public static String CANNOT_MODIFY_INSTANCE__MODIFY_METHOD_NOT_FOUND; - public static String CANT_ACTIVATE_INSTANCE; - public static String CANT_GET_SERVICE; - public static String CANT_GET_SERVICE_OBJECT; - public static String CANT_LIST_CONFIGURATIONS; - public static String CANT_OPEN_STREAM_TO_COMPONENT_XML; - public static String CANT_RESOLVE_COMPONENT_INSTANCE; - public static String CIRCULARITY_EXCEPTION_FOUND; - public static String COMPONENT_DISPOSED; - public static String COMPONENT_CONFIGURATIONS; - public static String COMPONENT_DETAILS; - public static String COMPONENT_HAS_ILLEGAL_REFERENCE; - public static String COMPONENT_ID_DEFINIED_BY_LIST_COMMAND; - public static String COMPONENT_LACKS_APPROPRIATE_PERMISSIONS; - public static String COMPONENT_NAME; - public static String COMPONENT_NAME_IS_NULL; - public static String COMPONENT_NOT_FOUND; - public static String COMPONENT_NOT_RESOLVED; - public static String COMPONENT_REQURES_CONFIGURATION_ACTIVATION; - public static String COMPONENT_RESOLVED; - public static String COMPONENT_WAS_NOT_BUILT; - public static String COMPONENT_XML_NOT_FOUND; - public static String COMPONENTS_IN_BUNDLE; - public static String CONFIG_ADMIN_SERVICE_NOT_AVAILABLE; - public static String CONFIG_PROPERTIES; - public static String COULD_NOT_CREATE_INSTANCE; - public static String COULD_NOT_CREATE_NEW_INSTANCE; - public static String DISABLE_ALL_COMPONENTS; - public static String DISABLE_COMPONENT; - public static String DISABLING_ALL_BUNDLE_COMPONENTS; - public static String DISABLING_ALL_COMPONENTS; - public static String DUPLICATED_REFERENCE_NAMES; - public static String DUPLICATED_SERVICE_TAGS; - public static String DYNAMIC_INFO; - public static String ENABLE_ALL_COMPONENTS; - public static String ENABLE_COMPONENT; - public static String ENABLING_ALL_BUNDLE_COMPONENTS; - public static String ENABLING_ALL_COMPONENTS; - public static String ERROR_BINDING_REFERENCE; - public static String ERROR_UPDATING_REFERENCE; - public static String ERROR_BUILDING_COMPONENT_INSTANCE; - public static String ERROR_CREATING_SCP; - public static String ERROR_DEACTIVATING_INSTANCE; - public static String ERROR_DISPATCHING_WORK; - public static String ERROR_DISPOSING_INSTANCES; - public static String ERROR_LISTING_CONFIGURATIONS; - public static String ERROR_LOADING_COMPONENTS; - public static String ERROR_LOADING_DATA_FILE; - public static String ERROR_LOADING_PROPERTIES_FILE; - public static String ERROR_OPENING_COMP_XML; - public static String ERROR_PARSING_MANIFEST_HEADER; - public static String ERROR_PROCESSING_CONFIGURATION; - public static String ERROR_PROCESSING_END_TAG; - public static String ERROR_PROCESSING_PROPERTY; - public static String ERROR_PROCESSING_START_TAG; - public static String ERROR_UNBINDING_REFERENCE; - public static String ERROR_UNBINDING_REFERENCE2; - public static String EXCEPTION_ACTIVATING_INSTANCE; - public static String EXCEPTION_BUILDING_COMPONENT; - public static String EXCEPTION_CREATING_COMPONENT_INSTANCE; - public static String EXCEPTION_GETTING_METHOD; - public static String EXCEPTION_LOCATING_SERVICE; - public static String EXCEPTION_LOCATING_SERVICES; - public static String EXCEPTION_MODIFYING_COMPONENT; - public static String EXCEPTION_UNBINDING_REFERENCE; - public static String EXPECTED_PARAMETER_COMPONENT_ID; - public static String FACTORY_CONF_NOT_APPLICABLE_FOR_COMPONENT_FACTORY; - public static String FACTORY_REGISTRATION_ALREADY_DISPOSED; - public static String FOUND_COMPONENTS_WITH_DUPLICATED_NAMES; - public static String FOUND_COMPONENTS_WITH_DUPLICATED_NAMES2; - public static String ILLEGAL_DEFINITION_FILE; - public static String ILLEGAL_ELEMENT_IN_SERVICE_TAG; - public static String ILLEGAL_TAG_FOUND; - public static String INCOMPATIBLE_COMBINATION; - public static String INCORRECT_ACTIVATION_POLICY; - public static String INCORRECT_VALUE_TYPE; - public static String INSTANCE_ALREADY_CREATED; - public static String INSTANCE_CREATION_TOOK_LONGER; - public static String INSTANCE_NOT_BOUND; - public static String INVALID_CARDINALITY_ATTR; - public static String INVALID_COMPONENT_FACTORY_AND_SERVICE_FACTORY; - public static String INVALID_COMPONENT_ID; - public static String INVALID_COMPONENT_IMMEDIATE_AND_FACTORY; - public static String INVALID_COMPONENT_IMMEDIATE_AND_SERVICE_FACTORY; - public static String INVALID_COMPONENT_NO_SERVICES_NO_IMMEDIATE; - public static String INVALID_COMPONENT_TAG__MULTIPLE_IMPL_ATTRIBS; - public static String INVALID_COMPONENT_TAG__NO_CLASS_ATTR; - public static String INVALID_OBJECT; - public static String INVALID_POLICY_ATTR; - public static String INVALID_POLICY_OPTION_ATTR; - public static String INVALID_PROPERTIES_TAG__INVALID_ENTRY_VALUE; - public static String INVALID_PROPERTIES_TAG__NO_ENTRY_ATTR; - public static String INVALID_PROPERTY_TAG__NO_BODY_CONTENT; - public static String INVALID_PROPERTY_TAG__NO_NAME_ATTR; - public static String INVALID_PROPERTY_TYPE; - public static String INVALID_PROVIDE_TAG__NO_INTERFACE_ATTR; - public static String INVALID_REFERENCE_TAG__BIND_ATTR_EMPTY; - public static String INVALID_REFERENCE_TAG__BIND_EQUALS_UNBIND; - public static String INVALID_REFERENCE_TAG__UNBIND_ATTR_EMPTY; - public static String INVALID_REFERENCE_TAG__UPDATED_ATTR_EMPTY; - public static String INVALID_SERVICE_REFERENCE; - public static String INVALID_SERVICE_TAG__NO_PROVIDE_TAG; - public static String INVALID_TAG_ACCORDING_TO_NAMESPACE1_0; - public static String INVALID_TAG_ACCORDING_TO_NAMESPACE1_2; - public static String INVALID_TARGET_FILTER; - public static String LIST_ALL_BUNDLE_COMPONENTS; - public static String LIST_ALL_COMPONENTS; - public static String LOCATED_IN_BUNDLE; - public static String METHOD_UNACCESSABLE; - public static String MISSING_CHARACTER; - public static String NO_BUILT_COMPONENT_CONFIGURATIONS; - public static String NO_COMPONENTS_FOUND; - public static String NO_IMPLEMENTATION_ATTRIBUTE; - public static String NO_INTERFACE_ATTR_IN_REFERENCE_TAG; - public static String NO_NAME_ATTRIBUTE; - public static String NOT_RESOLVED_REFERENCES; - public static String PRINT_COMPONENT_INFO; - public static String PROCESSING_BUNDLE_FAILED; - public static String REGISTERED_AS_COMPONENT_AND_MANAGED_SERVICE_FACORY; - public static String REGISTRATION_ALREADY_DISPOSED; - public static String RETURNING_NOT_FULLY_ACTIVATED_INSTANCE; - public static String SCR; - public static String SENT_DISABLING_REQUEST; - public static String SENT_ENABLING_REQUEST; - public static String SERVICE_REFERENCE_ALREADY_BOUND; - public static String SERVICE_USAGE_COUNT; - public static String SPECIFIED_ACTIVATE_METHOD_NOT_FOUND; - public static String SPECIFIED_DEACTIVATE_METHOD_NOT_FOUND; - public static String STATE; - public static String STATIC_OPTIONAL_REFERENCE_TO_BE_REMOVED; - public static String TIMEOUT_GETTING_LOCK; - public static String TIMEOUT_PROCESSING; - public static String TIMEOUT_REACHED_ENABLING_COMPONENTS; - public static String UNEXPECTED_ERROR; - public static String UNEXPECTED_EXCEPTION; - public static String UNSUPPORTED_TYPE; - public static String WRONG_PARAMETER; - public static String WRONG_PARAMETER2; - public static String ERROR_DELETING_COMPONENT_DEFINITIONS; - public static String ERROR_WRITING_OBJECT; - public static String ERROR_READING_OBJECT; - public static String DBMANAGER_SERVICE_TRACKER_OPENED; - public static String ERROR_LOADING_COMPONENT_DEFINITIONS; - public static String ERROR_MODIFYING_COMPONENT; - public static String ERROR_SAVING_COMPONENT_DEFINITIONS; - public static String FILE_DOESNT_EXIST_OR_DIRECTORY; - static { - // initialize resource bundle - NLS.initializeMessages(BUNDLE_NAME, Messages.class); - } - - private Messages() { - // - } -} diff --git a/bundles/org.eclipse.equinox.ds/src/org/eclipse/equinox/internal/ds/Reference.java b/bundles/org.eclipse.equinox.ds/src/org/eclipse/equinox/internal/ds/Reference.java deleted file mode 100644 index 0e6148354..000000000 --- a/bundles/org.eclipse.equinox.ds/src/org/eclipse/equinox/internal/ds/Reference.java +++ /dev/null @@ -1,493 +0,0 @@ -/******************************************************************************* - * Copyright (c) 1997-2010 by ProSyst Software GmbH - * http://www.prosyst.com - * 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: - * ProSyst Software GmbH - initial API and implementation - * Joerg-Christian Boehme - bug.id = 246757 - * Andrew Teirney - bug.id = 278732 - *******************************************************************************/ -package org.eclipse.equinox.internal.ds; - -import java.util.*; -import org.eclipse.equinox.internal.ds.model.*; -import org.eclipse.osgi.util.NLS; -import org.osgi.framework.*; -import org.osgi.service.component.ComponentConstants; -import org.osgi.service.log.LogService; - -/** - * The reference class is used only in the resolver. It is actually like - * "instance of a references". It is used to track available, eligible - * references. The reference objects relates to ServiceComponentProp as many to - * one. - * - * @author Valentin Valchev - * @author Stoyan Boshev - * @author Pavlin Dobrev - */ -public final class Reference implements org.apache.felix.scr.Reference { - - public ComponentReference reference; - ServiceComponentProp scp; - - // -- begin cache - String interfaceName; - String target; - int policy; - int cardinalityHigh; - int cardinalityLow; - - //holds the matching service references in case the component has no bind method - //in case the cardinality is 1..1, the vector will hold only one matching ServiceReference - Vector boundServiceReferences = new Vector(1); - - // -- end cache - - /** - * Reference object - * - * @param reference - * the component reference - * @param properties - * the *actual* properties that the component has. These are the - * SCP properties, e.g the default one in the XML file + the one - * that are configured in the CM. - */ - Reference(ComponentReference reference, ServiceComponentProp scp, Dictionary properties) { - this.reference = reference; - this.scp = scp; - this.interfaceName = reference.interfaceName; - this.target = reference.target; - - // RFC 80 section 5.3.1.3: - // If [target] is not specified and there is no .target - // component - // property, then the selection filter used to select the desired - // service is - // �(objectClass=�++�)�. - if (properties != null) { - target = (String) properties.get(reference.name + ComponentConstants.REFERENCE_TARGET_SUFFIX); - } - if (target == null) { - target = "(objectClass=" + interfaceName + ")"; //$NON-NLS-1$ //$NON-NLS-2$ - } - - // If it is not specified, then a policy of �static� is used. - policy = reference.policy; - - // Cardinality indicates the number of services, matching this - // reference, - // which will bind to this Service Component. Possible values are: - // 0..1, 0..n, 1..1 (i.e. exactly one), 1..n (i.e. at least one). - // This attribute is optional. If it is not specified, then a - // cardinality - // of �1..1� is used. - switch (reference.cardinality) { - case ComponentReference.CARDINALITY_0_1 : - cardinalityLow = 0; - cardinalityHigh = 1; - break; - case ComponentReference.CARDINALITY_0_N : - cardinalityLow = 0; - cardinalityHigh = Integer.MAX_VALUE; - break; - case ComponentReference.CARDINALITY_1_1 : - cardinalityLow = 1; - cardinalityHigh = 1; - break; - case ComponentReference.CARDINALITY_1_N : - cardinalityLow = 1; - cardinalityHigh = Integer.MAX_VALUE; - } - - } - - public String getTarget() { - return target; - } - - public void setTarget(String newTarget) { - target = newTarget; - } - - // used in Resolver.resolveEligible() - final boolean hasProviders(Hashtable serviceReferenceTable) { - // check whether the component's bundle has service GET permission - if (System.getSecurityManager() != null && !scp.bc.getBundle().hasPermission(new ServicePermission(interfaceName, ServicePermission.GET))) { - return false; - } - // Get all service references for this target filter - try { - ServiceReference[] serviceReferences = null; - serviceReferences = scp.bc.getServiceReferences(interfaceName, target); - // Only return true if there is a service published that this Reference - // represents and we know about it (if we care about it) - if (serviceReferences != null) { - if (serviceReferenceTable == null) - return true; - for (int i = 0; i < serviceReferences.length; i++) { - if (serviceReferenceTable.containsKey(serviceReferences[i])) { - return true; - } - } - } - } catch (InvalidSyntaxException e) { - Activator.log(reference.component.bc, LogService.LOG_WARNING, "Reference.hasProviders(): " + NLS.bind(Messages.INVALID_TARGET_FILTER, target), e); //$NON-NLS-1$ - } - return false; - } - - // if the cardinality is "0..1" or "0..n" then this refernce is not required - final boolean isRequiredFor(ServiceComponent cd) { - // // we want to re-resolve if the component is static and already - // eligible - // if (policy == ComponentReference.POLICY_STATIC && cd.eligible) { - // return true; - // } - return cardinalityLow == 1; - } - - public boolean isRequired() { - return cardinalityLow == 1; - } - - public boolean isUnary() { - return cardinalityHigh == 1; - } - - // used in Resolver.selectDynamicBind() - final boolean bindNewReference(ServiceReference referenceToBind, boolean dynamicBind) { - if (dynamicBind) { - if (policy == ComponentReference.POLICY_STATIC) { - return false; - } - } else { - if (policy == ComponentReference.POLICY_DYNAMIC) { - return false; - } - if (this.reference.policy_option == ComponentReference.POLICY_OPTION_RELUCTANT) { - return false; - } - } - - String[] serviceNames = (String[]) referenceToBind.getProperty(Constants.OBJECTCLASS); - boolean hasName = false; - for (int i = 0; i < serviceNames.length; i++) { - if (serviceNames[i].equals(interfaceName)) { - hasName = true; - break; - } - } - if (!hasName) { - return false; - } - - if (this.reference.bind != null) { - if (this.reference.serviceReferences.size() >= cardinalityHigh) { - if (this.reference.policy_option == ComponentReference.POLICY_OPTION_RELUCTANT) { - return false; - } else if (this.reference.policy_option == ComponentReference.POLICY_OPTION_GREEDY) { - //check if the single bound service needs replacement with higher ranked service - Object currentBoundServiceReference = this.reference.serviceReferences.keys().nextElement(); - int res = referenceToBind.compareTo(currentBoundServiceReference); - if (res <= 0) { - // bound service shall not be replaced - return false; - } - } - } - } else if (!dynamicBind) { - //custom case: static reference with no bind method - check its bound service references list - if (boundServiceReferences.size() >= cardinalityHigh) { - if (this.reference.policy_option == ComponentReference.POLICY_OPTION_GREEDY) { - //check if the single bound service needs replacement with higher ranked service - Object currentBoundServiceReference = boundServiceReferences.elementAt(0); - int res = referenceToBind.compareTo(currentBoundServiceReference); - if (res <= 0) { - // bound service shall not be replaced - return false; - } - } - } - } - - // check target filter - try { - Filter filter = FrameworkUtil.createFilter(target); - if (!filter.match(referenceToBind)) { - return false; - } - } catch (InvalidSyntaxException e) { - return false; - } - return true; - } - - /** - * Called to determine if the specified new target filter will still satisfy the current state of the reference - * @param newTargetFilter the new target filter to be checked - * @return true if the reference will still be satisfied after the filter replacement - */ - public boolean doSatisfy(String newTargetFilter) { - ServiceReference[] refs = null; - try { - refs = scp.bc.getServiceReferences(reference.interfaceName, newTargetFilter); - } catch (InvalidSyntaxException e) { - Activator.log(scp.bc, LogService.LOG_WARNING, "[SCR] " + NLS.bind(Messages.INVALID_TARGET_FILTER, newTargetFilter), e); //$NON-NLS-1$ - return false; - } - - if (refs == null) { - if (cardinalityLow > 0) { - //the reference is mandatory, but there are no matching services with the new target filter - return false; - } - if (policy == ComponentReference.POLICY_STATIC) { - if (this.reference.bind != null) { - if (this.reference.serviceReferences.size() > 0) { - //have bound services which are not matching the new filter - return false; - } - } else { - //custom case: static reference with no bind method - check its bound service references list - if (boundServiceReferences.size() > 0) { - //have bound services which are not matching the new filter - return false; - } - } - } - //the reference is not mandatory and the dynamic bound services can be unbound - return true; - } - if (policy == ComponentReference.POLICY_STATIC) { - if (this.reference.bind != null) { - Enumeration keys = this.reference.serviceReferences.keys(); - while (keys.hasMoreElements()) { - Object serviceRef = keys.nextElement(); - boolean found = false; - for (int i = 0; i < refs.length; i++) { - if (refs[i] == serviceRef) { - found = true; - break; - } - } - if (!found) { - //the bound service reference is not already in the satisfied references set. - //since this is a static reference a restart of the component is required - return false; - } - } - if (cardinalityHigh > 1 && this.reference.serviceReferences.size() < refs.length) { - //there are more services to bind. this requires restart of the component since the reference is static - return false; - } - } else { - //custom case: static reference with no bind method - for (int i = 0; i < boundServiceReferences.size(); i++) { - Object serviceRef = boundServiceReferences.elementAt(i); - boolean found = false; - for (int j = 0; j < refs.length; j++) { - if (refs[j] == serviceRef) { - found = true; - break; - } - } - if (!found) { - //the bound service reference is not already in the satisfied references set. - //since this is a static reference a restart of the component is required - return false; - } - } - if (cardinalityHigh > 1 && boundServiceReferences.size() < refs.length) { - //there are more services to bind. this requires restart of the component since the reference is static - return false; - } - - } - } - return true; - } - - // used in Resolver.selectDynamicUnBind(); - final boolean dynamicUnbindReference(ServiceReference changedReference) { - // nothing dynamic to do if static - if (policy == ComponentReference.POLICY_STATIC) { - return false; - } - // now check if the Service Reference is found in the list of saved - // ServiceReferences - if (!this.reference.serviceReferences.containsKey(changedReference)) { - return false; - } - return true; - } - - final boolean staticUnbindReference(ServiceReference changedReference) { - // does not apply if its policy is dynamic - if (policy == ComponentReference.POLICY_DYNAMIC) { - return false; - } - // now check if the Service Reference is found in the list of saved - // ServiceReferences; this list is saved in case the component has a bind method - if (this.reference.serviceReferences.containsKey(changedReference)) { - return true; - } - if (boundServiceReferences.size() > 0) { - return (cardinalityHigh == 1) ? boundServiceReferences.elementAt(0) == changedReference : boundServiceReferences.contains(changedReference); - } - return false; - } - - /** - * Checks if the passed service reference is satisfying this reference according to the target filter - * @param serviceReference the service reference to check - * @return true, if the service reference do satisfy this reference, otherwise returns false - */ - public boolean isInSatisfiedList(ServiceReference serviceReference) { - Filter filter; - try { - filter = FrameworkUtil.createFilter(target); - } catch (InvalidSyntaxException e) { - Activator.log(reference.component.bc, LogService.LOG_WARNING, "Reference.isInSatisfiedList(): " + NLS.bind(Messages.INVALID_TARGET_FILTER, target), e); //$NON-NLS-1$ - return false; - } - return filter.match(serviceReference); - } - - public void setBoundServiceReferences(ServiceReference[] references) { - if (policy == ComponentReference.POLICY_DYNAMIC) { - //not relevant to dynamic references - return; - } - - boundServiceReferences.removeAllElements(); - if (cardinalityHigh == 1) { - boundServiceReferences.addElement(references[0]); - } else { - for (int i = 0; i < references.length; i++) { - boundServiceReferences.addElement(references[i]); - } - } - } - - /** - * Selects the providers that provide service required by this reference - * @param scps the list of SCPs to be searched for providers - * @return an array of SCPs that provide service required by this reference - */ - public ServiceComponentProp[] selectProviders(Vector scps) { - Filter filter; - try { - filter = FrameworkUtil.createFilter(target); - } catch (InvalidSyntaxException e) { - Activator.log(reference.component.bc, LogService.LOG_WARNING, "Reference.selectProviders(): " + NLS.bind(Messages.INVALID_TARGET_FILTER, target), e); //$NON-NLS-1$ - return null; - } - Vector result = new Vector(2); - for (int i = 0; i < scps.size(); i++) { - ServiceComponentProp providerSCP = (ServiceComponentProp) scps.elementAt(i); - if (providerSCP.serviceComponent.serviceInterfaces != null && providerSCP.serviceComponent.serviceInterfaces.contains(interfaceName)) { - if (filter.match(providerSCP.getProperties())) { - result.addElement(providerSCP); - } - } - } - ServiceComponentProp[] res = new ServiceComponentProp[result.size()]; - result.copyInto(res); - return res; - } - - public boolean isBound() { - if (this.reference.bind != null) { - return (this.reference.serviceReferences.size() >= cardinalityLow); - } - return true; - } - - public Vector getBoundServiceReferences() { - return boundServiceReferences; - } - - public String getBindMethodName() { - return reference.bind; - } - - public String getName() { - return reference.name; - } - - public String getServiceName() { - return reference.interfaceName; - } - - public ServiceReference[] getServiceReferences() { - Vector result = null; - if (this.reference.bind != null) { - if (!reference.serviceReferences.isEmpty()) { - result = new Vector(2); - Enumeration keys = reference.serviceReferences.keys(); - while (keys.hasMoreElements()) { - result.add(keys.nextElement()); - } - } - } else { - //no bind method - if (!boundServiceReferences.isEmpty()) { - result = (Vector) boundServiceReferences.clone(); - } - } - if (result != null && !result.isEmpty()) { - ServiceReference[] finalResult = new ServiceReference[result.size()]; - result.copyInto(finalResult); - return finalResult; - } - return null; - } - - public String getUnbindMethodName() { - return reference.unbind; - } - - public boolean isMultiple() { - return cardinalityHigh > 1; - } - - public boolean isOptional() { - return cardinalityLow == 0; - } - - public boolean isSatisfied() { - if (cardinalityLow == 0) { - return true; - } - try { - ServiceReference[] serviceReferences = reference.component.bc.getServiceReferences(interfaceName, target); - if (serviceReferences != null) { - return true; - } - } catch (InvalidSyntaxException e) { - // do nothing - } - return false; - } - - public boolean isStatic() { - return policy == ComponentReference.POLICY_STATIC; - } - - /* (non-Javadoc) - * @see org.apache.felix.scr.Reference#getUpdatedMethodName() - */ - public String getUpdatedMethodName() { - if (reference.component.isNamespaceAtLeast12()) { - return reference.updated; - } - return null; - } - -} diff --git a/bundles/org.eclipse.equinox.ds/src/org/eclipse/equinox/internal/ds/Resolver.java b/bundles/org.eclipse.equinox.ds/src/org/eclipse/equinox/internal/ds/Resolver.java deleted file mode 100644 index 03b582ae4..000000000 --- a/bundles/org.eclipse.equinox.ds/src/org/eclipse/equinox/internal/ds/Resolver.java +++ /dev/null @@ -1,1245 +0,0 @@ -/******************************************************************************* - * Copyright (c) 1997, 2010 by ProSyst Software GmbH - * http://www.prosyst.com - * 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: - * ProSyst Software GmbH - initial API and implementation - * Andrew Teirney - bug.id = 278732 - * Simon Kaegi - bug.id = 296750 - *******************************************************************************/ -package org.eclipse.equinox.internal.ds; - -import java.util.*; -import org.apache.felix.scr.Component; -import org.eclipse.equinox.internal.ds.model.*; -import org.eclipse.osgi.util.NLS; -import org.osgi.framework.*; -import org.osgi.service.cm.Configuration; -import org.osgi.service.cm.ConfigurationAdmin; -import org.osgi.service.component.ComponentConstants; -import org.osgi.service.component.ComponentException; -import org.osgi.service.log.LogService; - -/** - * Resolver.java - * - * @author Valentin Valchev - * @author Stoyan Boshev - * @author Pavlin Dobrev - */ -public final class Resolver implements WorkPerformer { - - // these strings are used only for debugging purpose - static final String[] WORK_TITLES = {"BUILD ", "DYNAMICBIND ", "DISPOSE "}; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ - - /** - * Service Component instances need to be built. - */ - public static final int BUILD = 1; - - /** - * Service Component instances need to be rebound - */ - public static final int DYNAMICBIND = 2; - - /** - * Service Component instances need to be disposed - */ - public static final int DISPOSE = 3; - - /* Holds the enabled SCPs*/ - protected Vector scpEnabled; - - private InstanceProcess instanceProcess; - - private Object syncLock = new Object(); - - private Hashtable serviceReferenceTable = new Hashtable(); - - public SCRManager mgr; - - // TODO: Add a hashtable connecting servicereference to a list of References - // which they are bound to - // This way the search of references to unbind becomes faster when there are - // plenty of components. - // Keep in mind that build process is asynchronous. - - static { - /** preload some DS bundle classes to avoid classloader deadlocks */ - Reference.class.getName(); - SCRUtil.class.getName(); - } - - /** - * Resolver constructor - * - */ - Resolver(SCRManager mgr) { - scpEnabled = new Vector(); - // satisfiedSCPs = new Vector(); - instanceProcess = new InstanceProcess(this); - this.mgr = mgr; - } - - void synchronizeServiceReferences() { - synchronized (syncLock) { - try { - ServiceReference[] references = Activator.bc.getAllServiceReferences(null, null); - serviceReferenceTable.clear(); - if (references != null) { - for (int i = 0; i < references.length; i++) { - serviceReferenceTable.put(references[i], Boolean.TRUE); - } - } - } catch (InvalidSyntaxException e) { - Activator.log(Activator.bc, LogService.LOG_WARNING, "Resolver(): " + NLS.bind(Messages.INVALID_TARGET_FILTER, ""), e); //$NON-NLS-1$ //$NON-NLS-2$ - } - } - } - - public Object getSyncLock() { - return syncLock; - } - - // This method should be called when the event processing thread is blocked - // in a user code - void queueBlocked() { - syncLock = new Object(); - instanceProcess = new InstanceProcess(this); - } - - // -- begin *enable* component routines - /** - * enableComponents - called by the dispatchWorker - * - * @param serviceComponents - - * a list of all component descriptions for a single bundle to be - * enabled Receive ArrayList of enabled CD's from ComponentCache - * For each CD add to list of enabled create list of CD:CD+P - * create list of CD+P:ref ( where ref is a Reference Object) - * resolve CD+P - */ - void enableComponents(Vector serviceComponents) { - long start = 0l; - if (Activator.DEBUG) { - Activator.log.debug("Resolver.enableComponents(): " + (serviceComponents != null ? serviceComponents.toString() : "null"), null); //$NON-NLS-1$ //$NON-NLS-2$ - } - if (Activator.PERF) { - start = System.currentTimeMillis(); - } - - synchronized (syncLock) { - Configuration[] configs = null; - - if (serviceComponents != null) { - for (int i = 0; i < serviceComponents.size(); i++) { - ServiceComponent current = (ServiceComponent) serviceComponents.elementAt(i); - - // don't enable components which are not marked enabled - // this is done here, not in the activator just because it - // saves a little memory - if (!current.enabled) { - if (Activator.DEBUG) { - Activator.log.debug("Resolver.enableComponents(): ignoring not enabled component " + current.name, null); //$NON-NLS-1$ - } - continue; - } - if (current.componentProps != null && current.componentProps.size() > 0) { - //component is already enabled and processed. Skipping it. - continue; - } - - current.setState(Component.STATE_UNSATISFIED); - - if (current.getConfigurationPolicy() == ServiceComponent.CONF_POLICY_IGNORE) { - //skip looking for configurations - map(current, (Dictionary) null); - continue; - } - - // check for a Configuration properties for this component - try { - String filter = "(|(" + Constants.SERVICE_PID + '=' + current.getConfigurationPID() + ")(" + ConfigurationAdmin.SERVICE_FACTORYPID + '=' + current.getConfigurationPID() + "))"; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ - configs = Activator.listConfigurations(filter); - } catch (Exception e) { - Activator.log(null, LogService.LOG_ERROR, NLS.bind(Messages.CANT_LIST_CONFIGURATIONS, current.name), e); - } - // if no Configuration - if (configs == null || configs.length == 0) { - if (current.getConfigurationPolicy() != ServiceComponent.CONF_POLICY_REQUIRE) { - // create ServiceComponent + Prop - map(current, (Dictionary) null); - } else { - String customReason = Activator.configAdmin != null ? "" : Messages.CONFIG_ADMIN_SERVICE_NOT_AVAILABLE; //$NON-NLS-1$ - if (Activator.DEBUG) { - Activator.log.debug(NLS.bind(Messages.COMPONENT_REQURES_CONFIGURATION_ACTIVATION, current.name) + customReason, null); - } - } - } else { - // if ManagedServiceFactory - Configuration config = configs[0]; - if (config.getFactoryPid() != null && config.getFactoryPid().equals(current.getConfigurationPID())) { - // if ComponentFactory is specified - if (current.factory != null) { - Activator.log(current.bc, LogService.LOG_ERROR, NLS.bind(Messages.REGISTERED_AS_COMPONENT_AND_MANAGED_SERVICE_FACORY, current.name), null); - continue; // skip current component - } - if (Activator.DEBUG) { - Activator.log.debug("[SCR - Resolver] Resolver.enableComponents(): " + current.name + " as *managed service factory*", null); //$NON-NLS-1$ //$NON-NLS-2$ - } - try { - configs = Activator.listConfigurations("(service.factoryPid=" + config.getFactoryPid() + ")"); //$NON-NLS-1$ //$NON-NLS-2$ - } catch (Exception e) { - Activator.log(null, LogService.LOG_ERROR, NLS.bind(Messages.CANT_LIST_CONFIGURATIONS, current.name), e); - } - // for each MSF set of properties(P), map(CD, new - // CD+P(CD,P)) - if (configs != null) { - for (int index = 0; index < configs.length; index++) { - map(current, configs[index]); - } - } - } else { - if (Activator.DEBUG) { - Activator.log.debug("[SCR - Resolver] Resolver.enableComponents(): " + current.name + " as *service*", null); //$NON-NLS-1$ //$NON-NLS-2$ - } // if Service, not ManagedServiceFactory - map(current, config); - } - } // end has configuration - } // end process all components! - } - } - - buildNewlySatisfied(true); - - if (Activator.PERF) { - start = System.currentTimeMillis() - start; - Activator.log.info("[DS perf] " + (serviceComponents != null ? Integer.toString(serviceComponents.size()) : "") + " Components enabled for " + Long.toString(start) + "ms"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ - } - } - - protected ServiceComponentProp map(ServiceComponent component, Configuration config) { - Dictionary configProps = null; - if (config != null) { - try { - configProps = config.getProperties(); - } catch (IllegalStateException ise) { - // the configuration may have beed deleted already - } - } - ServiceComponentProp scp = map(component, configProps); - if (config != null) { - // set the service PID & Factory Pid - String pid = config.getPid(); - String fpid = config.getFactoryPid(); - if (pid != null) - scp.properties.put(Constants.SERVICE_PID, pid); - if (fpid != null) - scp.properties.put(ConfigurationAdmin.SERVICE_FACTORYPID, fpid); - } - return scp; - } - - /** - * Create the SCP and add to the maps - * - * @param component the component for which SCP will be created - * @param configProperties CM configuration properties - */ - public ServiceComponentProp map(ServiceComponent component, Dictionary configProperties) { - ServiceComponentProp scp = null; - try { - if (Activator.DEBUG) { - Activator.log.debug("Resolver.map(): Creating SCP for component " + component.name, null); //$NON-NLS-1$ - } - scp = new ServiceComponentProp(component, configProperties, mgr); - - // Get all the required service reference descriptions for this - Vector referenceDescriptions = component.references; - - // for each Reference Description, create a reference object - if (referenceDescriptions != null && !referenceDescriptions.isEmpty()) { - Vector references = new Vector(referenceDescriptions.size()); - - for (int i = 0; i < referenceDescriptions.size(); i++) { - // create new Reference Object and add to CD+P:ref map - ComponentReference cRef = (ComponentReference) referenceDescriptions.elementAt(i); - - Reference ref = new Reference(cRef, scp, scp.getProperties()); - references.addElement(ref); - } - scp.references = references; - } - component.addServiceComponentProp(scp); - scpEnabled.addElement(scp); - - } catch (Throwable t) { - Activator.log(component.bc, LogService.LOG_ERROR, NLS.bind(Messages.ERROR_CREATING_SCP, component), t); - } - return scp; - } - - /** - * Get the Eligible Components - * - * loop through CD+P list of enabled get references check if eligible if - * true add to eligible list send to Instance Process - * - */ - void getEligible(ServiceEvent event) { - - if (Activator.DEBUG) { - Activator.log.debug("Resolver.getEligible(): processing service event " + event.toString(), null); //$NON-NLS-1$ - String eventType = ""; //$NON-NLS-1$ - if (event.getType() == ServiceEvent.UNREGISTERING) { - eventType = "UNREGISTERING"; //$NON-NLS-1$ - } else if (event.getType() == ServiceEvent.REGISTERED) { - eventType = "REGISTERED"; //$NON-NLS-1$ - } else if (event.getType() == ServiceEvent.MODIFIED) { - eventType = "MODIFIED"; //$NON-NLS-1$ - } - Activator.log.debug("Service event type: " + eventType, null); //$NON-NLS-1$ - } - - Object target = null; - Vector resolvedComponents = null; - switch (event.getType()) { - case ServiceEvent.REGISTERED : - - synchronized (syncLock) { - serviceReferenceTable.put(event.getServiceReference(), Boolean.TRUE); - if (scpEnabled.isEmpty()) - return; // check for any enabled configurations - - //check for any static references with policy option "greedy" that need to be bound with this service reference - target = selectStaticBind(scpEnabled, event.getServiceReference()); - } - - if (target != null) { - //dispose instances of components with static reference that needs to be bound with the service reference - instanceProcess.disposeInstances((Vector) target, ComponentConstants.DEACTIVATION_REASON_REFERENCE); - } - - synchronized (syncLock) { - resolvedComponents = getComponentsToBuild(); - target = selectDynamicBind(scpEnabled, event.getServiceReference()); - } - - //do synchronous bind - if (target != null) { - Vector unboundRefs = instanceProcess.dynamicBind((Vector) target); - if (unboundRefs != null) { - // put delayed dynamic binds on the queue - // (this is used to handle class circularity errors) - mgr.enqueueWork(this, Resolver.DYNAMICBIND, unboundRefs, false); - } - } - - if (!resolvedComponents.isEmpty()) { - instanceProcess.buildComponents(resolvedComponents, false); - } - - break; - case ServiceEvent.UNREGISTERING : - Vector componentsToDispose; - synchronized (syncLock) { - //check for components with static reference to this service - componentsToDispose = selectStaticUnBind(scpEnabled, event.getServiceReference(), false); - } - //dispose instances from staticUnbind - if (componentsToDispose != null) { - instanceProcess.disposeInstances(componentsToDispose, ComponentConstants.DEACTIVATION_REASON_REFERENCE); - } - - Vector newlyUnsatisfiedSCPs; - synchronized (syncLock) { - serviceReferenceTable.remove(event.getServiceReference()); - if (scpEnabled.isEmpty()) - return; // check for any enabled configurations - - newlyUnsatisfiedSCPs = selectNewlyUnsatisfied(event.getServiceReference()); - } - if (!newlyUnsatisfiedSCPs.isEmpty()) { - // synchronously dispose newly unsatisfied components - instanceProcess.disposeInstances(newlyUnsatisfiedSCPs, ComponentConstants.DEACTIVATION_REASON_REFERENCE); - } - - synchronized (syncLock) { - // Pass in the set of currently resolved components, check each one - - // do we need to unbind - target = selectDynamicUnBind(scpEnabled, event.getServiceReference(), false); - - if (componentsToDispose != null || !newlyUnsatisfiedSCPs.isEmpty()) { - // some components with static references were disposed. Try to build them again - // get list of newly satisfied SCPs and build them - resolvedComponents = getComponentsToBuild(); - } - } - - instanceProcess.dynamicUnBind((Hashtable) target); // do synchronous unbind - - if (resolvedComponents != null && !resolvedComponents.isEmpty()) { - instanceProcess.buildComponents(resolvedComponents, false); - } - - return; - - case ServiceEvent.MODIFIED : - synchronized (syncLock) { - if (scpEnabled.isEmpty()) - return; // check for any enabled configurations - - // check for newly unsatisfied components and synchronously - // dispose them - newlyUnsatisfiedSCPs = selectNewlyUnsatisfied(event.getServiceReference()); - } - - if (!newlyUnsatisfiedSCPs.isEmpty()) { - instanceProcess.disposeInstances(newlyUnsatisfiedSCPs, ComponentConstants.DEACTIVATION_REASON_REFERENCE); - } - - synchronized (syncLock) { - //check for components with static reference to this service - componentsToDispose = selectStaticUnBind(scpEnabled, event.getServiceReference(), true); - } - - if (componentsToDispose != null) { - instanceProcess.disposeInstances(componentsToDispose, ComponentConstants.DEACTIVATION_REASON_REFERENCE); - } - - synchronized (syncLock) { - //check for any static references with policy option "greedy" that need to be bound with this service reference - componentsToDispose = selectStaticBind(scpEnabled, event.getServiceReference()); - } - - if (componentsToDispose != null) { - //dispose instances of components with static reference that needs to be bound with the modified service reference - instanceProcess.disposeInstances(componentsToDispose, ComponentConstants.DEACTIVATION_REASON_REFERENCE); - } - - Hashtable referencesToUpdate = null; - synchronized (syncLock) { - // dynamic unbind - // check each satisfied scp - do we need to unbind - target = selectDynamicUnBind(scpEnabled, event.getServiceReference(), true); - - //check references that need to be updated - referencesToUpdate = selectReferencesToUpdate(scpEnabled, event.getServiceReference()); - } - - if (target != null) { - instanceProcess.dynamicUnBind((Hashtable) target); - } - if (referencesToUpdate != null) { - instanceProcess.referencePropertiesUpdated(referencesToUpdate); - } - - synchronized (syncLock) { - // dynamic bind - target = selectDynamicBind(scpEnabled, event.getServiceReference()); - - // get list of newly satisfied SCPs and build them - resolvedComponents = getComponentsToBuild(); - } - - if (target != null) { - Vector unboundRefs = instanceProcess.dynamicBind((Vector) target); - if (unboundRefs != null) { - // put delayed dynamic binds on the queue - // (this is used to handle class circularity errors) - mgr.enqueueWork(this, Resolver.DYNAMICBIND, unboundRefs, false); - } - } - if (!resolvedComponents.isEmpty()) { - instanceProcess.buildComponents(resolvedComponents, false); - } - } - } - - public void buildNewlySatisfied(boolean checkForDependencyCycles) { - Vector resolvedComponents; - synchronized (syncLock) { - if (checkForDependencyCycles) { - findDependencyCycles(); - } - resolvedComponents = getComponentsToBuild(); - } - - if (!resolvedComponents.isEmpty()) { - instanceProcess.buildComponents(resolvedComponents, false); - } - } - - private Vector getComponentsToBuild() { - Vector resolvedComponents = resolveEligible(); - // select the satisfied components only - ServiceComponentProp scp; - for (int i = resolvedComponents.size() - 1; i >= 0; i--) { - scp = (ServiceComponentProp) resolvedComponents.elementAt(i); - if (scp.getState() != Component.STATE_UNSATISFIED) { - resolvedComponents.removeElementAt(i); - } - } - return resolvedComponents; - } - - /** - * Notifies the resolver that a component has been disposed. - * It should accordingly update its data structures if needed - * - **/ - public void componentDisposed(ServiceComponentProp scp) { - // - } - - private Vector resolveEligible() { - try { - Vector enabledSCPs = (Vector) scpEnabled.clone(); - for (int k = enabledSCPs.size() - 1; k >= 0; k--) { - ServiceComponentProp scp = (ServiceComponentProp) enabledSCPs.elementAt(k); - try { - Vector refs = scp.references; - for (int i = 0; refs != null && i < refs.size(); i++) { - // Loop though all the references (dependencies)for a given - // scp. If a dependency is not met, remove it's associated scp and - // re-run the algorithm - Reference reference = (Reference) refs.elementAt(i); - if (reference != null) { - boolean resolved = !reference.isRequiredFor(scp.serviceComponent) || reference.hasProviders(this.serviceReferenceTable); - - if (!resolved) { - if (Activator.DEBUG) { - Activator.log.debug("Resolver.resolveEligible(): reference '" + reference.reference.name + "' of component '" + scp.name + "' is not resolved", null); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ - } - enabledSCPs.removeElementAt(k); - break; - } - } - } - } catch (IllegalStateException ise) { - //the bundle of the scp is probably already uninstalled - scpEnabled.removeElement(scp); - enabledSCPs.removeElementAt(k); - continue; - } - // check if the bundle providing the service has permission to - // register the provided interface(s) - if (scp.serviceComponent.provides != null && System.getSecurityManager() != null) { - String[] provides = scp.serviceComponent.provides; - boolean hasPermission = true; - int i = 0; - for (; i < provides.length; i++) { - // make sure bundle has permission to register the service - try { - if (!scp.bc.getBundle().hasPermission(new ServicePermission(provides[i], ServicePermission.REGISTER))) { - hasPermission = false; - break; - } - } catch (IllegalStateException ise) { - // the bundle of the service component is uninstalled - // System.out.println("IllegalStateException occured - // while processing component "+scp); - // ise.printStackTrace(); - hasPermission = false; - break; - } catch (Throwable t) { - // System.out.println("Exception occured processing - // component "+scp); - // t.printStackTrace(); - hasPermission = false; - break; - } - } - if (!hasPermission) { - Activator.log(null, LogService.LOG_WARNING, NLS.bind(Messages.COMPONENT_LACKS_APPROPRIATE_PERMISSIONS, scp.name, provides[i]), null); - removeEnabledSCP(scp); - enabledSCPs.removeElementAt(k); - continue; - } - } - if (!scp.isBuilt() && !(scp.getState() == Component.STATE_DEACTIVATING)) { - scp.setState(Component.STATE_UNSATISFIED); - } - } - - if (Activator.DEBUG) { - Activator.log.debug("Resolver.resolveEligible(): resolved components = " + enabledSCPs.toString(), null); //$NON-NLS-1$ - } - return enabledSCPs; - } catch (Throwable e) { - Activator.log(null, LogService.LOG_ERROR, Messages.UNEXPECTED_EXCEPTION, e); - return new Vector(); - } - } - - private Vector selectNewlyUnsatisfied(ServiceReference serviceRef) { - try { - Vector result = (Vector) scpEnabled.clone(); - for (int k = result.size() - 1; k >= 0; k--) { - try { - ServiceComponentProp scp = (ServiceComponentProp) result.elementAt(k); - Vector refs = scp.references; - boolean toDispose = false; - for (int i = 0; refs != null && i < refs.size(); i++) { - // Loop though all the references (dependencies)for a given - // scp. If a dependency is not met, remove it's associated - // scp and re-run the algorithm - Reference reference = (Reference) refs.elementAt(i); - if (reference != null) { - if (serviceRef != null && reference.reference.bind != null && scp.getState() == Component.STATE_ACTIVE && !(reference.dynamicUnbindReference(serviceRef) || reference.staticUnbindReference(serviceRef))) { - //make quick test - the service reference is not bound to the current component reference - continue; - } - if (serviceRef != null && !isPossibleMatch(reference, serviceRef)) { - // the service reference is not a possible match. Skipping further checks - continue; - } - boolean resolved = !reference.isRequiredFor(scp.serviceComponent) || reference.hasProviders(this.serviceReferenceTable); - - if (!resolved && scp.isBuilt()) { - if (Activator.DEBUG) { - Activator.log.debug("Resolver.selectNewlyUnsatisfied(): reference '" + reference.reference.name + "' of component '" + scp.name + "' is not resolved", null); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ - } - toDispose = true; - break; - } - } - } - if (!toDispose) { - result.removeElementAt(k); - } - } catch (IllegalStateException ise) { - //the bundle of the scp is probably already uninstalled - scpEnabled.removeElement(result.elementAt(k)); - result.removeElementAt(k); - continue; - } - } - return result; - } catch (Throwable e) { - Activator.log(null, LogService.LOG_ERROR, Messages.UNEXPECTED_EXCEPTION, e); - return new Vector(1); - } - } - - private boolean isPossibleMatch(Reference reference, ServiceReference serviceRef) { - String[] serviceNames = (String[]) serviceRef.getProperty(Constants.OBJECTCLASS); - boolean hasName = false; - for (int i = 0; i < serviceNames.length; i++) { - if (serviceNames[i].equals(reference.interfaceName)) { - hasName = true; - break; - } - } - if (!hasName) { - return false; - } - // check target filter - try { - Filter filter = FrameworkUtil.createFilter(reference.target); - if (!filter.match(serviceRef)) { - return false; - } - } catch (InvalidSyntaxException e) { - return false; - } - return true; - } - - // -- begin *disable* component routines - /** - * Disable list of ComponentDescriptions - * - * get all CD+P's from CD:CD+P Map get instances from CD+P:list of instance - * (1:n) map - * - * Strip out of Map all CD+P's Continue to pull string check each Ref - * dependency and continue to pull out CD+P's if they become not eligible - * Then call Resolver to re-resolve - * - * @param componentDescriptions - */ - void disableComponents(Vector componentDescriptions, int deactivateReason) { - long start = 0l; - if (Activator.PERF) { - start = System.currentTimeMillis(); - } - - ServiceComponentProp scp; - ServiceComponent component; - - Vector removeList = null; - - // Received list of CDs to disable - if (componentDescriptions != null) { - for (int i = 0; i < componentDescriptions.size(); i++) { - // get the first CD - component = (ServiceComponent) componentDescriptions.elementAt(i); - component.enabled = false; - component.setState(Component.STATE_DISABLED); - if (Activator.DEBUG) { - Activator.log.debug("Resolver.disableComponents() " + component.name, null); //$NON-NLS-1$ - } - - // then get the list of SCPs for this CD - Vector scpList = component.componentProps; - if (scpList != null) { - for (int iter = 0; iter < scpList.size(); iter++) { - scp = (ServiceComponentProp) scpList.elementAt(iter); - if (removeList == null) { - removeList = new Vector(); - } - removeList.addElement(scp); - } - } - if (removeList != null) { - disposeComponentConfigs(removeList, deactivateReason); - removeList.removeAllElements(); - } - if (component.componentProps != null) { - for (int j = 0; j < component.componentProps.size(); j++) { - scp = (ServiceComponentProp) component.componentProps.elementAt(j); - scp.setState(Component.STATE_DISPOSED); - } - component.componentProps.removeAllElements(); - } - } - } - - if (Activator.PERF) { - start = System.currentTimeMillis() - start; - Activator.log.info("[DS perf] " + Integer.toString(componentDescriptions.size()) + " Components disabled for " + Long.toString(start) + "ms"); //$NON-NLS-1$//$NON-NLS-2$ //$NON-NLS-3$ - } - } - - public void disposeComponentConfigs(Vector scps, int deactivateReason) { - // unregister, deactivate, and unbind - synchronized (syncLock) { - removeAll(scpEnabled, scps); - } - instanceProcess.disposeInstances(scps, deactivateReason); - } - - // -- end *service listener* - - public void performWork(int workAction, Object workObject) { - try { - if (Activator.DEBUG) { - String work = WORK_TITLES[workAction - 1]; - Activator.log.debug("Resolver.performWork(): " + work + workObject, null); //$NON-NLS-1$ - } - switch (workAction) { - case BUILD : - if (workObject != null) { - instanceProcess.buildComponents((Vector) workObject, false); - } - break; - case DYNAMICBIND : - if (workObject != null) { - Vector toBind = (Vector) workObject; - synchronized (syncLock) { - // remove unsatisfied configs - for (int i = toBind.size() - 1; i >= 0; i--) { - Reference ref = (Reference) toBind.elementAt(i); - if (ref.scp.isUnsatisfied()) { - //System.out.println("--BIND: removing "+ref.scp); - toBind.removeElementAt(i); - } - } - if (toBind.isEmpty()) - return; - } - instanceProcess.dynamicBind(toBind); - - } - break; - case DISPOSE : - if (workObject != null) { - instanceProcess.disposeInstances((Vector) workObject, ComponentConstants.DEACTIVATION_REASON_UNSPECIFIED); - } - break; - } - } catch (Throwable e) { - Activator.log(null, LogService.LOG_ERROR, Messages.UNEXPECTED_EXCEPTION, e); - } - } - - private Vector selectDynamicBind(Vector scps, ServiceReference serviceReference) { - try { - Vector toBind = null; - for (int i = 0, size = scps.size(); i < size; i++) { - ServiceComponentProp scp = (ServiceComponentProp) scps.elementAt(i); - if (scp.isUnsatisfied()) { - //do not check disposed components - continue; - } - // if it is not already eligible it will bind with the static - // scps - Vector references = scp.references; - // it is absolutely legal component if it doesn't contains - // references! - if (references != null) { - for (int j = 0; j < references.size(); j++) { - Reference reference = (Reference) references.elementAt(j); - if (reference.bindNewReference(serviceReference, true)) { - if (toBind == null) { - toBind = new Vector(2); - } - toBind.addElement(reference); - } - } - } - } - if (toBind != null && Activator.DEBUG) { - Activator.log.debug("Resolver.selectDynamicBind(): selected = " + toBind.toString(), null); //$NON-NLS-1$ - } - return toBind; - } catch (Throwable t) { - Activator.log(null, LogService.LOG_ERROR, Messages.UNEXPECTED_EXCEPTION, t); - return null; - } - } - - //Returns the components with static reference that needs to be bound with the service reference. - //This can happen if the static reference has policy option "greedy" - private Vector selectStaticBind(Vector scps, ServiceReference serviceReference) { - try { - Vector toBind = null; - for (int i = 0, size = scps.size(); i < size; i++) { - ServiceComponentProp scp = (ServiceComponentProp) scps.elementAt(i); - if (scp.isUnsatisfied()) { - //do not check disposed components - continue; - } - Vector references = scp.references; - if (references != null) { - for (int j = 0; j < references.size(); j++) { - Reference reference = (Reference) references.elementAt(j); - if (reference.bindNewReference(serviceReference, false)) { - if (toBind == null) { - toBind = new Vector(2); - } - toBind.addElement(reference); - } - } - } - } - Vector result = null; - Reference ref = null; - if (toBind != null) { - result = new Vector(); - for (int i = 0; i < toBind.size(); i++) { - ref = (Reference) toBind.elementAt(i); - if (!result.contains(ref.scp)) { - result.addElement(ref.scp); - } - } - } - - if (result != null && Activator.DEBUG) { - Activator.log.debug("Resolver.selectStaticBind(): selected = " + result.toString(), null); //$NON-NLS-1$ - } - return result; - } catch (Throwable t) { - Activator.log(null, LogService.LOG_ERROR, Messages.UNEXPECTED_EXCEPTION, t); - return null; - } - } - - private Vector selectStaticUnBind(Vector scpsToCheck, ServiceReference serviceReference, boolean checkSatisfied) { - try { - Vector toUnbind = null; - for (int i = 0, size = scpsToCheck.size(); i < size; i++) { - ServiceComponentProp scp = (ServiceComponentProp) scpsToCheck.elementAt(i); - if (scp.isUnsatisfied()) { - //the scp is already deactivated - continue; - } - // if it is not already eligible it will bind with the static scps - Vector references = scp.references; - // it is absolutely legal component if it doesn't contains references! - if (references != null) { - for (int j = 0; j < references.size(); j++) { - Reference reference = (Reference) references.elementAt(j); - if (reference.staticUnbindReference(serviceReference)) { - if (checkSatisfied && reference.isInSatisfiedList(serviceReference)) { - //the service reference do still satisfy the reference and shall not be unbound - continue; - } - if (toUnbind == null) { - toUnbind = new Vector(2); - } - toUnbind.addElement(scp); - } - } - } - } - if (toUnbind != null) - if (Activator.DEBUG) { - Activator.log.debug("Resolver.selectStaticUnBind(): selected = " + toUnbind.toString(), null); //$NON-NLS-1$ - } - return toUnbind; - } catch (Throwable t) { - Activator.log(null, LogService.LOG_ERROR, Messages.UNEXPECTED_EXCEPTION, t); - return null; - } - } - - /** - * selectDynamicUnBind Determine which resolved component description with - * properties need to unbind from this unregistering service Return map of - * reference description and component description with properties, for - * each. - * - * @param scps - * @param serviceReference - * @return this is fairly complex to explain ;( - */ - private Hashtable selectDynamicUnBind(Vector scps, ServiceReference serviceReference, boolean checkSatisfied) { - try { - if (Activator.DEBUG) { - Activator.log.debug("Resolver.selectDynamicUnBind(): entered", null); //$NON-NLS-1$ - } - Hashtable unbindTable = null; // ReferenceDescription:subTable - for (int i = 0; i < scps.size(); i++) { - Hashtable unbindSubTable = null; // scp:sr - ServiceComponentProp scp = (ServiceComponentProp) scps.elementAt(i); - - if (scp.isUnsatisfied()) { - //do not check deactivated components - continue; - } - Vector references = scp.references; - // some components may not contain references and it is - // absolutely valid - if (references != null) { - for (int j = 0; j < references.size(); j++) { - Reference reference = (Reference) references.elementAt(j); - // Does the scp require this service, use the Reference - // object to check - if (reference.dynamicUnbindReference(serviceReference)) { - if (checkSatisfied && reference.isInSatisfiedList(serviceReference)) { - //the service reference do still satisfy the reference and shall not be unbound - continue; - } - if (Activator.DEBUG) { - Activator.log.debug("Resolver.selectDynamicUnBind(): unbinding " + scp.toString(), null); //$NON-NLS-1$ - } - if (unbindSubTable == null) { - unbindSubTable = new Hashtable(11); - } - unbindSubTable.put(scp, serviceReference); - if (unbindTable == null) { - unbindTable = new Hashtable(11); - } - unbindTable.put(reference, unbindSubTable); - } else { - if (Activator.DEBUG) { - Activator.log.debug("Resolver.selectDynamicUnBind(): not unbinding " + scp + " service ref=" + serviceReference, null); //$NON-NLS-1$ //$NON-NLS-2$ - } - } - } - } - } - if (unbindTable != null && Activator.DEBUG) { - Activator.log.debug("Resolver.selectDynamicUnBind(): unbindTable is " + unbindTable.toString(), null); //$NON-NLS-1$ - } - return unbindTable; - } catch (Throwable t) { - Activator.log(null, LogService.LOG_ERROR, Messages.UNEXPECTED_EXCEPTION, t); - return null; - } - } - - /** - * Determine which component references needs to be updated by their specified updated method due to the current service references properties change - * - * @param scps - * @param serviceReference - * @return Map of ::> - * - */ - private Hashtable selectReferencesToUpdate(Vector scps, ServiceReference serviceReference) { - try { - if (Activator.DEBUG) { - Activator.log.debug("Resolver.selectReferencesToUpdate(): entered", null); //$NON-NLS-1$ - } - Hashtable referencesTable = null; - for (int i = 0; i < scps.size(); i++) { - Hashtable updateSubTable = null; - ServiceComponentProp scp = (ServiceComponentProp) scps.elementAt(i); - - if (scp.isUnsatisfied() || !scp.serviceComponent.isNamespaceAtLeast12()) { - //do not check deactivated components or components which are not DS 1.2 compliant - continue; - } - Vector references = scp.references; - if (references != null) { - for (int j = 0; j < references.size(); j++) { - Reference reference = (Reference) references.elementAt(j); - if (reference.reference.updated == null) { - //the reference does not have updated method specified - continue; - } - if (reference.isStatic() ? reference.staticUnbindReference(serviceReference) : reference.dynamicUnbindReference(serviceReference)) { - if (Activator.DEBUG) { - Activator.log.debug("Resolver.selectReferencesToUpdate(): selected for update reference " + reference.reference.name + " of component " + scp.toString(), null); //$NON-NLS-1$ //$NON-NLS-2$ - } - if (updateSubTable == null) { - updateSubTable = new Hashtable(11); - } - updateSubTable.put(scp, serviceReference); - if (referencesTable == null) { - referencesTable = new Hashtable(11); - } - referencesTable.put(reference, updateSubTable); - } - } - } - } - if (referencesTable != null && Activator.DEBUG) { - Activator.log.debug("Resolver.selectReferencesToUpdate(): referencesTable is " + referencesTable.toString(), null); //$NON-NLS-1$ - } - return referencesTable; - } catch (Throwable t) { - Activator.log(null, LogService.LOG_ERROR, Messages.UNEXPECTED_EXCEPTION, t); - return null; - } - } - - // used by the ComponentFactoryImpl to build new Component configurations - public ServiceComponentProp mapNewFactoryComponent(ServiceComponent component, Dictionary configProperties) { - synchronized (syncLock) { - // create a new scp (adds to resolver enabledSCPs list) - ServiceComponentProp newSCP = map(component, configProperties); - newSCP.setComponentFactory(false); // avoid registration of new - // ComponentFactory - - // we added a SCP, so check for circularity and mark cycles - findDependencyCycles(); - - // get list of newly satisfied SCPs and check whether the new SCP is - // satisfied - Vector eligibleSCPs = resolveEligible(); - if (!eligibleSCPs.contains(newSCP)) { - removeEnabledSCP(newSCP); - throw new ComponentException(NLS.bind(Messages.CANT_RESOLVE_COMPONENT_INSTANCE, newSCP, configProperties)); - } - return newSCP; - } - } - - /** - * Check through the enabled list for cycles. Cycles can only exist if every - * service is provided by a Service Component (not legacy OSGi). If the - * cycle has no optional dependencies, log an error and disable a Component - * Configuration in the cycle. If cycle can be "broken" by an optional - * dependency, make a note (stored in the - * {@link ServiceComponentProp#delayActivateSCPNames} Vector). - * - * @throws CircularityException - * if cycle exists with no optional dependencies - */ - private void findDependencyCycles() { - Vector emptyVector = new Vector(); - try { - // find the SCPs that resolve using other SCPs and record their - // dependencies - Hashtable dependencies = new Hashtable(); - - for (int i = scpEnabled.size() - 1; i >= 0; i--) { - ServiceComponentProp enabledSCP = (ServiceComponentProp) scpEnabled.elementAt(i); - if (enabledSCP.references != null) { - Vector dependencyVector = new Vector(1); - for (int j = 0; j < enabledSCP.references.size(); j++) { - Reference reference = (Reference) enabledSCP.references.elementAt(j); - - // see if it resolves to one of the other enabled SCPs - ServiceComponentProp[] providerSCPs = reference.selectProviders(scpEnabled); - if (providerSCPs != null) { - for (int k = 0; k < providerSCPs.length; k++) { - dependencyVector.addElement(new ReferenceSCPWrapper(reference, providerSCPs[k])); - } - } - } // end for - - if (!dependencyVector.isEmpty()) { - // SCP resolves using some other SCPs, could be a cycle - dependencies.put(enabledSCP, dependencyVector); - } else { - dependencies.put(enabledSCP, emptyVector); - } - } - } // end for - - // traverse dependency tree and look for cycles - Hashtable visited = new Hashtable(11); - Enumeration keys = dependencies.keys(); - - while (keys.hasMoreElements()) { - ServiceComponentProp scp = (ServiceComponentProp) keys.nextElement(); - if (!visited.containsKey(scp)) { - Vector currentStack = new Vector(2); - checkDependencies(scp, visited, dependencies, currentStack); - } - } - } catch (CircularityException e) { - Activator.log(e.getCausingComponent().serviceComponent.bc, LogService.LOG_ERROR, NLS.bind(Messages.CIRCULARITY_EXCEPTION_FOUND, e.getCausingComponent().serviceComponent), e); - // disable offending SCP - removeEnabledSCP(e.getCausingComponent()); - // try again - findDependencyCycles(); - } - } - - /** - * Recursively do a depth-first traversal of a dependency tree, looking for - * cycles. - *

- * If a cycle is found, calls - * {@link Resolver#processDependencyCycle(ReferenceSCPWrapper, Vector)}. - *

- * - * @param scp - * current node in dependency tree - * @param visited - * holdes the visited nodes - * @param dependencies - * Dependency tree - a Hashtable of ({@link ServiceComponentProp}):(Vector - * of {@link ReferenceSCPWrapper}s) - * @param currentStack - * Vector of {@link ReferenceSCPWrapper}s - the history of our - * traversal so far (the path back to the root of the tree) - * @throws CircularityException - * if an cycle with no optional dependencies is found. - */ - private void checkDependencies(ServiceComponentProp scp, Hashtable visited, Hashtable dependencies, Vector currentStack) throws CircularityException { - - // the component has already been visited and it's dependencies checked - // for cycles - if (visited.containsKey(scp)) { - return; - } - - Vector refSCPs = (Vector) dependencies.get(scp); - if (refSCPs != null) { - for (int i = 0; i < refSCPs.size(); i++) { - ReferenceSCPWrapper refSCP = (ReferenceSCPWrapper) refSCPs.elementAt(i); - if (currentStack.contains(refSCP)) { - // may throw circularity exception - processDependencyCycle(refSCP, currentStack); - continue; - } - currentStack.addElement(refSCP); - - checkDependencies(refSCP.producer, visited, dependencies, currentStack); - - currentStack.removeElement(refSCP); - } - } - visited.put(scp, ""); //$NON-NLS-1$ - } - - /** - * A cycle was detected. SCP is referenced by the last element in - * currentStack. Throws CircularityException if the cycle does not contain - * an optional dependency, else choses a point at which to "break" the cycle - * (the break point must be immediately after an optional dependency) and - * adds a "cycle note". - * - * @see ServiceComponentProp#delayActivateSCPNames - */ - private void processDependencyCycle(ReferenceSCPWrapper refSCP, Vector currentStack) throws CircularityException { - // find an optional dependency - ReferenceSCPWrapper optionalRefSCP = null; - for (int i = currentStack.indexOf(refSCP); i < currentStack.size(); i++) { - ReferenceSCPWrapper cycleRefSCP = (ReferenceSCPWrapper) currentStack.elementAt(i); - if (!cycleRefSCP.ref.isRequired()) { - optionalRefSCP = cycleRefSCP; - break; - } - } - if (optionalRefSCP == null) { - throw new CircularityException(refSCP.ref.scp); - } - // check whether the optional reference is static - this is not allowed - // because of the way components with static refereces are built - if (optionalRefSCP.ref.policy == ComponentReference.POLICY_STATIC) { - Activator.log(optionalRefSCP.ref.scp.bc, LogService.LOG_ERROR, NLS.bind(Messages.STATIC_OPTIONAL_REFERENCE_TO_BE_REMOVED, optionalRefSCP.ref.reference), null); - - optionalRefSCP.ref.scp.references.removeElement(optionalRefSCP.ref); - } - - // the dependent component will be processed with delay whenever - // necessary - optionalRefSCP.ref.scp.setDelayActivateSCPName(optionalRefSCP.producer.serviceComponent.name); - } - - // used to remove all elements of vector which occur in another vector - private void removeAll(Vector src, Vector elementsToRemove) { - for (int i = src.size() - 1; i >= 0; i--) { - if (elementsToRemove.contains(src.elementAt(i))) { - src.removeElementAt(i); - } - } - } - - private void removeEnabledSCP(ServiceComponentProp scp) { - scpEnabled.removeElement(scp); - scp.serviceComponent.componentProps.remove(scp); - scp.setState(Component.STATE_DISPOSED); - } - - /** - * Reorder the specified SCP and place it at the end of the enabledSCPs list - * @param scp the SCP to reorder - */ - protected void reorderSCP(ServiceComponentProp scp) { - synchronized (syncLock) { - if (scpEnabled.removeElement(scp)) { - scpEnabled.addElement(scp); - } - } - } - - public void removeFromSatisfiedList(ServiceComponentProp scp) { - Vector tmp = new Vector(); - tmp.addElement(scp); - mgr.enqueueWork(this, Resolver.DISPOSE, tmp, false); - } - - /** - * Used to traverse the dependency tree in order to find cycles. - * - */ - private static class ReferenceSCPWrapper { - public Reference ref; - public ServiceComponentProp producer; - - protected ReferenceSCPWrapper(Reference ref, ServiceComponentProp producer) { - this.ref = ref; - this.producer = producer; - } - - public String toString() { - return "Reference : " + ref + " ::: SCP : " + producer; //$NON-NLS-1$ //$NON-NLS-2$ - } - } - - public Component getComponent(long componentId) { - synchronized (scpEnabled) { - for (int i = 0; i < scpEnabled.size(); i++) { - ServiceComponentProp scp = (ServiceComponentProp) scpEnabled.elementAt(i); - if (scp.getId() == componentId) { - return scp; - } - } - } - return null; - } - -} diff --git a/bundles/org.eclipse.equinox.ds/src/org/eclipse/equinox/internal/ds/SCRCommandProvider.java b/bundles/org.eclipse.equinox.ds/src/org/eclipse/equinox/internal/ds/SCRCommandProvider.java deleted file mode 100644 index 5598a4aaa..000000000 --- a/bundles/org.eclipse.equinox.ds/src/org/eclipse/equinox/internal/ds/SCRCommandProvider.java +++ /dev/null @@ -1,810 +0,0 @@ -/******************************************************************************* - * Copyright (c) 1997-2011 by ProSyst Software GmbH - * http://www.prosyst.com - * 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: - * ProSyst Software GmbH - initial API and implementation - * Simon Archer - bug.id = 288783 - * Lazar Kirchev - bug.id = 320377 - *******************************************************************************/ -package org.eclipse.equinox.internal.ds; - -import java.io.IOException; -import java.io.InputStream; -import java.net.URL; -import java.util.*; -import org.eclipse.equinox.internal.ds.impl.ComponentInstanceImpl; -import org.eclipse.equinox.internal.ds.model.*; -import org.eclipse.osgi.framework.console.CommandInterpreter; -import org.eclipse.osgi.framework.console.CommandProvider; -import org.eclipse.osgi.util.NLS; -import org.osgi.framework.*; -import org.osgi.service.component.ComponentConstants; - -/** - * SCRCommandProvider class provides some useful commands for managing the Service Component Runtime - * - * @author Stoyan Boshev - * @version 1.0 - */ -public class SCRCommandProvider implements CommandProvider { - - private Resolver resolver; - private SCRManager scrManager; - - private int curID = 1; - private Hashtable componentRefsIDs = null; - - protected SCRCommandProvider(SCRManager scrManager) { - this.scrManager = scrManager; - this.resolver = InstanceProcess.resolver; - } - - public String getHelp() { - return getHelp(null); - } - - /* - * This method either returns the help message for a particular command, - * or returns the help messages for all commands (if commandName is null) - */ - private String getHelp(String commandName) { - boolean all = commandName == null; - StringBuffer res = new StringBuffer(1000); - if (all) { - res.append("---").append(Messages.SCR).append("---\r\n"); //$NON-NLS-1$ //$NON-NLS-2$ - } - if (all || "list".equals(commandName) || "ls".equals(commandName)) { //$NON-NLS-1$ //$NON-NLS-2$ - res.append("\tlist/ls [-c] [bundle id] - ").append(Messages.LIST_ALL_COMPONENTS); //$NON-NLS-1$ - res.append("\r\n\t\t\t").append(Messages.LIST_ALL_BUNDLE_COMPONENTS); //$NON-NLS-1$ - } - if (all || "component".equals(commandName) || "comp".equals(commandName)) { //$NON-NLS-1$ //$NON-NLS-2$ - res.append("\r\n\tcomponent/comp - ").append(Messages.PRINT_COMPONENT_INFO); //$NON-NLS-1$ - res.append("\r\n\t\t\t - ").append(Messages.COMPONENT_ID_DEFINIED_BY_LIST_COMMAND); //$NON-NLS-1$ - } - if (all || "enable".equals(commandName) || "en".equals(commandName)) { //$NON-NLS-1$ //$NON-NLS-2$ - res.append("\r\n\tenable/en - ").append(Messages.ENABLE_COMPONENT); //$NON-NLS-1$ - res.append("\r\n\t\t\t - ").append(Messages.COMPONENT_ID_DEFINIED_BY_LIST_COMMAND); //$NON-NLS-1$ - } - if (all || "disable".equals(commandName) || "dis".equals(commandName)) { //$NON-NLS-1$ //$NON-NLS-2$ - res.append("\n\tdisable/dis - ").append(Messages.DISABLE_COMPONENT); //$NON-NLS-1$ - res.append("\n\t\t\t - ").append(Messages.COMPONENT_ID_DEFINIED_BY_LIST_COMMAND); //$NON-NLS-1$ - } - if (all || "enableAll".equals(commandName) || "enAll".equals(commandName)) { //$NON-NLS-1$ //$NON-NLS-2$ - res.append("\r\n\tenableAll/enAll [bundle id] - ").append(Messages.ENABLE_ALL_COMPONENTS); //$NON-NLS-1$ - } - if (all || "disableAll".equals(commandName) || "disAll".equals(commandName)) { //$NON-NLS-1$ //$NON-NLS-2$ - res.append("\n\tdisableAll/disAll [bundle id] - ").append(Messages.DISABLE_ALL_COMPONENTS).append("\n"); //$NON-NLS-1$ //$NON-NLS-2$ - } - return res.toString(); - } - - /** - * Handle the list command - * - * @param intp A CommandInterpreter object containing the command and it's arguments. - */ - public void _list(CommandInterpreter intp) throws Exception { - boolean completeInfo = false; - Bundle b = null; - String[] params = getParams(intp); - if (params.length > 0) { - if (params[0].equals("-c")) { //$NON-NLS-1$ - completeInfo = true; - if (params.length > 1) { - b = getBundle(intp, params[1]); - if (b == null) { - return; - } - } - } else { - b = getBundle(intp, params[0]); - if (b == null) { - return; - } - } - } - listComponents(intp, b, completeInfo); - } - - /** - * Shortcut to list command - * - * @param intp A CommandInterpreter object containing the command and it's arguments. - */ - public void _ls(CommandInterpreter intp) throws Exception { - _list(intp); - } - - /** - * Handle the component command - * - * @param intp A CommandInterpreter object containing the command and it's arguments. - */ - public void _component(CommandInterpreter intp) throws Exception { - String[] params = getParams(intp); - if (params.length > 0) { - int compIndex = -1; - try { - compIndex = Integer.parseInt(params[0]); - } catch (NumberFormatException nfe) { - intp.println(NLS.bind(Messages.WRONG_PARAMETER, params[0])); - return; - } - printComponentDetails(intp, compIndex); - return; - } - intp.println(Messages.EXPECTED_PARAMETER_COMPONENT_ID); - } - - /** - * Shortcut to component command - * - * @param intp A CommandInterpreter object containing the command and it's arguments. - */ - public void _comp(CommandInterpreter intp) throws Exception { - _component(intp); - } - - /** - * Handle the enable command - * - * @param intp A CommandInterpreter object containing the command and it's arguments. - */ - public void _enable(CommandInterpreter intp) throws Exception { - String[] params = getParams(intp); - if (params.length > 0) { - int compIndex = -1; - try { - compIndex = Integer.parseInt(params[0]); - } catch (NumberFormatException nfe) { - intp.println(NLS.bind(Messages.WRONG_PARAMETER, params[0])); - return; - } - enableComponent(intp, compIndex); - return; - } - intp.println(Messages.EXPECTED_PARAMETER_COMPONENT_ID); - } - - /** - * Shortcut to enable command - * - * @param intp A CommandInterpreter object containing the command and it's arguments. - */ - public void _en(CommandInterpreter intp) throws Exception { - _enable(intp); - } - - /** - * Handle the disable command - * - * @param intp A CommandInterpreter object containing the command and it's arguments. - */ - public void _disable(CommandInterpreter intp) throws Exception { - String[] params = getParams(intp); - if (params.length > 0) { - int compIndex = -1; - try { - compIndex = Integer.parseInt(params[0]); - } catch (NumberFormatException nfe) { - intp.println(NLS.bind(Messages.WRONG_PARAMETER, params[0])); - return; - } - disableComponent(intp, compIndex); - return; - } - intp.println(Messages.EXPECTED_PARAMETER_COMPONENT_ID); - } - - /** - * Shortcut to disable command - * - * @param intp A CommandInterpreter object containing the command and it's arguments. - */ - public void _dis(CommandInterpreter intp) throws Exception { - _disable(intp); - } - - /** - * Handle the enableAll command - * - * @param intp A CommandInterpreter object containing the command and it's arguments. - */ - public void _enableAll(CommandInterpreter intp) throws Exception { - String[] params = getParams(intp); - Bundle b = null; - if (params.length > 0) { - b = getBundle(intp, params[0]); - if (b == null) { - return; - } - } - enableAll(intp, b); - } - - /** - * Shortcut to enableAll command - * - * @param intp A CommandInterpreter object containing the command and it's arguments. - */ - public void _enAll(CommandInterpreter intp) throws Exception { - _enableAll(intp); - } - - /** - * Handle the disableAll command - * - * @param intp A CommandInterpreter object containing the command and it's arguments. - */ - public void _disableAll(CommandInterpreter intp) throws Exception { - String[] params = getParams(intp); - Bundle b = null; - if (params.length > 0) { - b = getBundle(intp, params[0]); - if (b == null) { - return; - } - } - disableAll(intp, b); - } - - /** - * Shortcut to disableAll command - * - * @param intp A CommandInterpreter object containing the command and it's arguments. - */ - public void _disAll(CommandInterpreter intp) throws Exception { - _disableAll(intp); - } - - /** - * Handles the help command - * - * @param intp - * @return description for a particular command or false if there is no command with the specified name - */ - public Object _help(CommandInterpreter intp) { - String commandName = intp.nextArgument(); - if (commandName == null) { - return Boolean.FALSE; - } - String help = getHelp(commandName); - - if (help.length() > 0) { - return help; - } - return Boolean.FALSE; - } - - private String[] getParams(CommandInterpreter intp) { - Vector arguments = new Vector(); - String arg = intp.nextArgument(); - while (arg != null) { - if (arg != null) { - arguments.addElement(arg); - } - arg = intp.nextArgument(); - } - String[] res = new String[arguments.size()]; - arguments.copyInto(res); - return res; - } - - private Bundle getBundle(CommandInterpreter intp, String bidString) { - long bid = -1; - try { - bid = Long.parseLong(bidString); - } catch (NumberFormatException nfe) { - intp.println(NLS.bind(Messages.WRONG_PARAMETER2, bidString)); - return null; - } - Bundle b = Activator.bc.getBundle(bid); - if (b == null) { - intp.println(NLS.bind(Messages.BUNDLE_NOT_FOUND, bidString)); - } - return b; - } - - private ComponentRef findComponentWithID(int compID) { - if (componentRefsIDs != null) { - Enumeration keys = componentRefsIDs.keys(); - while (keys.hasMoreElements()) { - ComponentRef key = (ComponentRef) keys.nextElement(); - if (key.id == compID) { - return key; - } - } - } - return null; - } - - private void printComponentDetails(CommandInterpreter intp, int componentIndex) { - ComponentRef cRef = findComponentWithID(componentIndex); - if (cRef == null) { - intp.println(Messages.INVALID_COMPONENT_ID); - return; - } - - Bundle b = Activator.bc.getBundle(cRef.bid); - if (b != null) { - Vector components = (Vector) scrManager.bundleToServiceComponents.get(b); - if (components != null) { - for (int i = 0; i < components.size(); i++) { - ServiceComponent sc = (ServiceComponent) components.elementAt(i); - if (sc.name.equals(cRef.name)) { - printComponentDetails(intp, sc); - break; - } - } - } - } else { - intp.println(Messages.CANNOT_FIND_COMPONENT_BUNDLE); - } - } - - private void printComponentDetails(CommandInterpreter intp, ServiceComponent sc) { - intp.println("\t" + sc.toString()); //$NON-NLS-1$ - intp.println(Messages.DYNAMIC_INFO); - Vector unresulvedReferences = getUnresolvedReferences(sc); - boolean resolved = true; - if (unresulvedReferences != null) { - for (int i = 0; i < unresulvedReferences.size(); i++) { - if (isMandatory((ComponentReference) unresulvedReferences.elementAt(i))) { - resolved = false; - break; - } - } - } - if (resolved) { - intp.println(Messages.COMPONENT_RESOLVED); - } else { - intp.println(Messages.COMPONENT_NOT_RESOLVED); - } - - if (unresulvedReferences != null) { - intp.println(Messages.NOT_RESOLVED_REFERENCES); - for (int i = 0; i < unresulvedReferences.size(); i++) { - intp.println(" " + unresulvedReferences.elementAt(i)); //$NON-NLS-1$ - } - } else { - intp.println(Messages.ALL_REFERENCES_RESOLVED); - } - intp.println(Messages.COMPONENT_CONFIGURATIONS); - Vector enabledSCPs = (Vector) resolver.scpEnabled.clone(); - for (int i = 0; i < enabledSCPs.size(); i++) { - ServiceComponentProp scp = (ServiceComponentProp) enabledSCPs.elementAt(i); - if (scp.serviceComponent == sc) { - printSCP(intp, scp); - } - } - if (sc.getConfigurationPolicy() == ServiceComponent.CONF_POLICY_REQUIRE) { - if (resolved && (sc.componentProps == null || sc.componentProps.size() == 0)) { - intp.println(Messages.NO_BUILT_COMPONENT_CONFIGURATIONS); - } - } - intp.println(); - } - - private void printSCP(CommandInterpreter intp, ServiceComponentProp scp) { - Hashtable props = scp.properties; - intp.println(Messages.CONFIG_PROPERTIES); - Enumeration keys = props.keys(); - while (keys.hasMoreElements()) { - Object key = keys.nextElement(); - Object value = props.get(key); - intp.print(" " + key + " = "); //$NON-NLS-1$ //$NON-NLS-2$ - intp.print(SCRUtil.getStringRepresentation(value)); - intp.println(); - } - intp.println(" Instances:"); //$NON-NLS-1$ - if (scp.instances.size() > 0) { - ComponentInstanceImpl instance = null; - for (int i = 0; i < scp.instances.size(); i++) { - instance = (ComponentInstanceImpl) scp.instances.elementAt(i); - intp.println(" " + instance); //$NON-NLS-1$ - if (instance.bindedServices.size() > 0) { - intp.println(" Bound References:"); //$NON-NLS-1$ - Enumeration refs = instance.bindedServices.keys(); - ServiceReference sr = null; - while (refs.hasMoreElements()) { - sr = (ServiceReference) refs.nextElement(); - Object interfaces = sr.getProperty(Constants.OBJECTCLASS); - intp.println(" " + SCRUtil.getStringRepresentation(interfaces)); //$NON-NLS-1$ - intp.println(" -> " + instance.bindedServices.get(sr)); //$NON-NLS-1$ - } - } - } - } else { - // there are no instances either because the references are not satisfied or because some runtime issues appear; for example the bind method was not found in the class - String issues = scp.serviceComponent.getComponentIssues(); - if (issues != null) { - intp.println(" No instances were created because: " + issues); //$NON-NLS-1$ - } - } - } - - private Vector getUnresolvedReferences(ServiceComponent sc) { - Vector unresolved = new Vector(); - if (sc.references != null) { - for (int i = 0; i < sc.references.size(); i++) { - ComponentReference ref = (ComponentReference) sc.references.elementAt(i); - if (!hasProviders(ref)) { - unresolved.addElement(ref); - } - } - } - - return unresolved.isEmpty() ? null : unresolved; - } - - private boolean hasProviders(ComponentReference ref) { - ////check whether the component's bundle has service GET permission - if (System.getSecurityManager() != null && !ref.component.bc.getBundle().hasPermission(new ServicePermission(ref.interfaceName, ServicePermission.GET))) { - return false; - } - //// Get all service references for this target filter - try { - ServiceReference[] serviceReferences = null; - serviceReferences = ref.component.bc.getServiceReferences(ref.interfaceName, ref.target); - if (serviceReferences != null) { - return true; - } - } catch (InvalidSyntaxException e) { - //do nothing - } - return false; - } - - private boolean isMandatory(ComponentReference ref) { - return ref.cardinality == ComponentReference.CARDINALITY_1_1 || ref.cardinality == ComponentReference.CARDINALITY_1_N; - } - - private void enableAll(CommandInterpreter intp, Bundle b) { - Vector componentsToEnable = new Vector(); - if (b != null) { - intp.println(NLS.bind(Messages.ENABLING_ALL_BUNDLE_COMPONENTS, getBundleRepresentationName(b))); - } else { - intp.println(Messages.ENABLING_ALL_COMPONENTS); - } - if (b != null) { - if (scrManager.bundleToServiceComponents != null) { - Vector components = (Vector) scrManager.bundleToServiceComponents.get(b); - if (components != null) { - for (int i = 0; i < components.size(); i++) { - ServiceComponent sc = (ServiceComponent) components.elementAt(i); - if (!sc.enabled) { - componentsToEnable.addElement(sc); - sc.enabled = true; - } - } - if (!componentsToEnable.isEmpty()) { - resolver.enableComponents(componentsToEnable); - } - } - } - } else { - if (scrManager.bundleToServiceComponents != null) { - Bundle[] allBundles = Activator.bc.getBundles(); - for (int j = 0; j < allBundles.length; j++) { - Vector components = (Vector) scrManager.bundleToServiceComponents.get(allBundles[j]); - if (components != null) { - for (int i = 0; i < components.size(); i++) { - ServiceComponent sc = (ServiceComponent) components.elementAt(i); - if (!sc.enabled) { - componentsToEnable.addElement(sc); - sc.enabled = true; - } - } - } - } - if (!componentsToEnable.isEmpty()) { - resolver.enableComponents(componentsToEnable); - } - } - } - } - - private void disableAll(CommandInterpreter intp, Bundle b) { - Vector componentsToDisable = new Vector(); - if (b != null) { - intp.println(NLS.bind(Messages.DISABLING_ALL_BUNDLE_COMPONENTS, getBundleRepresentationName(b))); - } else { - intp.println(Messages.DISABLING_ALL_COMPONENTS); - } - if (b != null) { - if (scrManager.bundleToServiceComponents != null) { - Vector components = (Vector) scrManager.bundleToServiceComponents.get(b); - if (components != null) { - for (int i = 0; i < components.size(); i++) { - ServiceComponent sc = (ServiceComponent) components.elementAt(i); - if (sc.enabled) { - componentsToDisable.addElement(sc); - sc.enabled = false; - } - } - if (!componentsToDisable.isEmpty()) { - resolver.disableComponents(componentsToDisable, ComponentConstants.DEACTIVATION_REASON_DISABLED); - } - } - } - } else { - if (scrManager.bundleToServiceComponents != null) { - Bundle[] allBundles = Activator.bc.getBundles(); - for (int j = 0; j < allBundles.length; j++) { - Vector components = (Vector) scrManager.bundleToServiceComponents.get(allBundles[j]); - if (components != null) { - for (int i = 0; i < components.size(); i++) { - ServiceComponent sc = (ServiceComponent) components.elementAt(i); - if (sc.enabled) { - componentsToDisable.addElement(sc); - sc.enabled = false; - } - } - } - } - if (!componentsToDisable.isEmpty()) { - resolver.disableComponents(componentsToDisable, ComponentConstants.DEACTIVATION_REASON_DISABLED); - } - } - } - } - - private void enableComponent(CommandInterpreter intp, int componentIndex) { - ComponentRef cRef = findComponentWithID(componentIndex); - if (cRef == null) { - intp.println(Messages.INVALID_COMPONENT_ID); - return; - } - scrManager.enableComponent(cRef.name, Activator.bc.getBundle(cRef.bid)); - intp.println(NLS.bind(Messages.SENT_ENABLING_REQUEST, cRef.name)); - } - - private void disableComponent(CommandInterpreter intp, int componentIndex) { - ComponentRef cRef = findComponentWithID(componentIndex); - if (cRef == null) { - intp.println(Messages.INVALID_COMPONENT_ID); - return; - } - scrManager.disableComponent(cRef.name, Activator.bc.getBundle(cRef.bid)); - intp.println(NLS.bind(Messages.SENT_DISABLING_REQUEST, cRef.name)); - } - - /* commands */ - - private void listComponents(CommandInterpreter intp, Bundle b, boolean completeInfo) { - if (componentRefsIDs == null) - componentRefsIDs = new Hashtable(101); - - if (b != null) { - intp.println(NLS.bind(Messages.COMPONENTS_IN_BUNDLE, getBundleRepresentationName(b))); - if (componentRefsIDs.isEmpty()) { - initComponentRefs(); - } - } else { - intp.println(Messages.ALL_COMPONENTS); - } - - if (b == null || scrManager.bundleToServiceComponents != null && scrManager.bundleToServiceComponents.get(b) != null) { - intp.print("ID"); //$NON-NLS-1$ - if (completeInfo) { - intp.println(Messages.COMPONENT_DETAILS); - } else { - intp.print(Messages.STATE); - intp.print(Messages.COMPONENT_NAME); - intp.println(Messages.LOCATED_IN_BUNDLE); - } - } - - if (b != null) { - if (scrManager.bundleToServiceComponents != null) { - - Vector components = (Vector) scrManager.bundleToServiceComponents.get(b); - if (components != null) { - for (int i = 0; i < components.size(); i++) { - ServiceComponent sc = (ServiceComponent) components.elementAt(i); - ComponentRef aRef = new ComponentRef(b.getBundleId(), sc.name); - ComponentRef ref = (ComponentRef) componentRefsIDs.get(aRef); - if (ref == null) { - ref = aRef; - ref.id = generateID(); - componentRefsIDs.put(ref, ref); - } - if (completeInfo) { - intp.print(ref.id + ""); //$NON-NLS-1$ - printComponentDetails(intp, sc); - } else { - ////print short info - intp.print("" + ref.id); //$NON-NLS-1$ - intp.print("\t" + SCRUtil.getStateStringRepresentation(sc.getState())); //$NON-NLS-1$ - intp.print("\t\t" + sc.name); //$NON-NLS-1$ - intp.println("\t\t\t" + getBundleRepresentationName(b) + "(bid=" + b.getBundleId() + ")"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ - } - } - } - - // check the bundle for issues during components resolving - // first check for service component header in this bundle - String dsHeader = null; - Dictionary allHeaders = b.getHeaders(""); //$NON-NLS-1$ - - if (!((dsHeader = (String) allHeaders.get(ComponentConstants.SERVICE_COMPONENT)) != null)) { - // no component descriptions in this bundle - intp.println("No ServiceComponent header was found in bundle " + b.toString()); //$NON-NLS-1$ - return; - } - - // second check if the ds xml is correct - Vector issues = parseXMLDeclaration(b, dsHeader); - if (issues.size() > 0) { - intp.println(); - intp.println("Issues encountered when parsing components xml declarations"); //$NON-NLS-1$ - for (int i = 0; i < issues.size(); i++) { - intp.println("\t" + issues.get(i)); //$NON-NLS-1$ - intp.println(); - } - } - - } - - } else { - if (scrManager.bundleToServiceComponents != null) { - Bundle[] allBundles = Activator.bc.getBundles(); - for (int j = 0; j < allBundles.length; j++) { - Vector components = (Vector) scrManager.bundleToServiceComponents.get(allBundles[j]); - if (components != null) { - for (int i = 0; i < components.size(); i++) { - ServiceComponent sc = (ServiceComponent) components.elementAt(i); - ComponentRef aRef = new ComponentRef(allBundles[j].getBundleId(), sc.name); - ComponentRef ref = (ComponentRef) componentRefsIDs.get(aRef); - if (ref == null) { - ref = aRef; - ref.id = generateID(); - componentRefsIDs.put(ref, ref); - } - - if (completeInfo) { - intp.print(ref.id + ""); //$NON-NLS-1$ - printComponentDetails(intp, sc); - } else { - ////print short info - intp.print("" + ref.id); //$NON-NLS-1$ - intp.print("\t" + SCRUtil.getStateStringRepresentation(sc.getState())); //$NON-NLS-1$ - intp.print("\t\t" + sc.name); //$NON-NLS-1$ - intp.println("\t\t\t" + getBundleRepresentationName(allBundles[j]) + "(bid=" + allBundles[j].getBundleId() + ")"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ - } - } - } - } - } - } - } - - private void initComponentRefs() { - if (scrManager.bundleToServiceComponents != null) { - Bundle[] allBundles = Activator.bc.getBundles(); - for (int j = 0; j < allBundles.length; j++) { - Vector components = (Vector) scrManager.bundleToServiceComponents.get(allBundles[j]); - if (components != null) { - for (int i = 0; i < components.size(); i++) { - ServiceComponent sc = (ServiceComponent) components.elementAt(i); - ComponentRef aRef = new ComponentRef(allBundles[j].getBundleId(), sc.name); - ComponentRef ref = (ComponentRef) componentRefsIDs.get(aRef); - if (ref == null) { - ref = aRef; - ref.id = generateID(); - componentRefsIDs.put(ref, ref); - } - } - } - } - } - } - - private String getBundleRepresentationName(Bundle b) { - String res = b.getSymbolicName(); - if (res == null) { - res = "with ID " + b.getBundleId(); //$NON-NLS-1$ - } - return res; - } - - private synchronized int generateID() { - return curID++; - } - - protected Vector parseXMLDeclaration(Bundle bundle, String dsHeader) { - Vector componentsIssues = new Vector(); - Vector components = new Vector(); - try { - if (dsHeader != null) { - StringTokenizer tok = new StringTokenizer(dsHeader, ","); //$NON-NLS-1$ - DeclarationParser parser = new DeclarationParser(true); - // process all definition file - while (tok.hasMoreElements()) { - String definitionFile = tok.nextToken().trim(); - int ind = definitionFile.lastIndexOf('/'); - String path = ind != -1 ? definitionFile.substring(0, ind) : "/"; //$NON-NLS-1$ - InputStream is = null; - - Enumeration urls = bundle.findEntries(path, ind != -1 ? definitionFile.substring(ind + 1) : definitionFile, false); - if (urls == null || !urls.hasMoreElements()) { - componentsIssues.add(NLS.bind(Messages.COMPONENT_XML_NOT_FOUND, bundle.getSymbolicName(), definitionFile)); - continue; - } - - // illegal components are ignored, but framework event is posted for - // them; however, it will continue and try to load any legal - // definitions - URL url; - while (urls.hasMoreElements()) { - url = (URL) urls.nextElement(); - if (Activator.DEBUG) { - Activator.log.debug("ComponentStorage.parseXMLDeclaration(): loading " + url.toString(), null); //$NON-NLS-1$ - } - try { - is = url.openStream(); - if (is == null) { - componentsIssues.add(NLS.bind(Messages.CANT_OPEN_STREAM_TO_COMPONENT_XML, url)); - } else { - try { - parser.parse(is, bundle, components, url.toString()); - } catch (Exception e) { - componentsIssues.add(e.getMessage()); - } - } - } catch (IOException ie) { - componentsIssues.add(NLS.bind(Messages.ERROR_OPENING_COMP_XML, url) + "\n\t" + ie); //$NON-NLS-1$ - } catch (Throwable t) { - componentsIssues.add(NLS.bind(Messages.ILLEGAL_DEFINITION_FILE, url) + "\n\t" + t); //$NON-NLS-1$ - } finally { - if (is != null) { - is.close(); - } - } - } - } // end while - - components = parser.components; - // make sure the clean-up the parser cache, for the next bundle to - // work properly!!! - parser.components = null; - } - } catch (Exception e) { - componentsIssues.add("Exception [" + e + "] while parsing DS xml definition."); //$NON-NLS-1$ //$NON-NLS-2$ - } - return componentsIssues; - } - - private static class ComponentRef { - ////the ID of the bundle holding this service component - long bid; - ////the name of the service component - String name; - ////the temporary id given to this reference. It will be used by certain console commands - int id = -1; - - public ComponentRef(long bid, String name) { - this.bid = bid; - this.name = name; - } - - public boolean equals(Object o) { - if (o instanceof ComponentRef) { - ComponentRef obj = (ComponentRef) o; - return (obj.bid == bid && name.equals(obj.name)); - } - return false; - } - - public int hashCode() { - return name.hashCode(); - } - - } - -} diff --git a/bundles/org.eclipse.equinox.ds/src/org/eclipse/equinox/internal/ds/SCRManager.java b/bundles/org.eclipse.equinox.ds/src/org/eclipse/equinox/internal/ds/SCRManager.java deleted file mode 100644 index 1536f536a..000000000 --- a/bundles/org.eclipse.equinox.ds/src/org/eclipse/equinox/internal/ds/SCRManager.java +++ /dev/null @@ -1,977 +0,0 @@ -/******************************************************************************* - * Copyright (c) 1997-2010 by ProSyst Software GmbH - * http://www.prosyst.com - * 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: - * ProSyst Software GmbH - initial API and implementation - * Andrew Teirney - bug.id = 278732 - *******************************************************************************/ -package org.eclipse.equinox.internal.ds; - -import java.io.IOException; -import java.security.AccessController; -import java.security.PrivilegedAction; -import java.util.*; -import org.apache.felix.scr.Component; -import org.eclipse.equinox.internal.ds.model.*; -import org.eclipse.equinox.internal.util.event.Queue; -import org.eclipse.equinox.internal.util.threadpool.ThreadPoolManager; -import org.eclipse.osgi.util.NLS; -import org.osgi.framework.*; -import org.osgi.service.cm.*; -import org.osgi.service.component.ComponentConstants; -import org.osgi.service.component.ComponentException; -import org.osgi.service.log.LogService; -import org.osgi.util.tracker.ServiceTracker; - -/** - * Acts as a "Bundle Manager" - a listener for bundle events. Whenever a bundle - * is stopped or started it will invoke the resolver to respectively enable or - * disable the contained components. Notice, the SynchronousBundleListener - * bundle listeners are called prior bundle event is completed. - * - * It is also a listener for update and delete configuration events, sent by - * Configuration Admin, thus handling the changes in configurations which are meant - * to configure the properties of DS components - * - * @author Maria Ivanova - * @author Stoyan Boshev - * @author Pavlin Dobrev - */ - -public class SCRManager implements ServiceListener, SynchronousBundleListener, ConfigurationListener, WorkPerformer, PrivilegedAction { - - /** work action type */ - public final int ENABLE_COMPONENTS = 1; - public final int DISABLE_COMPONENTS = 2; - - protected Hashtable bundleToServiceComponents; - protected Hashtable processingBundles = new Hashtable(5); - protected Queue queue; - private Resolver resolver; - - private WorkThread workThread; - protected boolean running = false; - protected boolean stopped = false; - private ServiceTracker threadPoolManagerTracker; - private boolean hasRegisteredServiceListener = false; - private ComponentStorage storage; - - /** - * Constructs the SCRManager. - */ - public SCRManager() { - hasRegisteredServiceListener = true; - queue = new Queue(10); - if (Activator.startup) - Activator.timeLog("Queue instantiated for "); //$NON-NLS-1$ - - threadPoolManagerTracker = new ServiceTracker(Activator.bc, ThreadPoolManager.class.getName(), null); - threadPoolManagerTracker.open(); - if (Activator.startup) - Activator.timeLog("Threadpool service tracker opened for "); //$NON-NLS-1$ - - resolver = new Resolver(this); - if (Activator.startup) - Activator.timeLog("Resolver instantiated for "); //$NON-NLS-1$ - - resolver.synchronizeServiceReferences(); - if (Activator.startup) - Activator.timeLog("resolver.synchronizeServiceReferences() method took "); //$NON-NLS-1$ - - String storageClass = Activator.bc.getProperty("scr.storage.class"); //$NON-NLS-1$ - if (storageClass == null) { - storageClass = "org.eclipse.equinox.internal.ds.storage.file.FileStorage"; //$NON-NLS-1$ - } - try { - storage = (ComponentStorage) Class.forName(storageClass).getConstructor(new Class[] {BundleContext.class}).newInstance(new Object[] {Activator.bc}); - } catch (Exception e) { - Activator.log(null, LogService.LOG_ERROR, NLS.bind(Messages.COULD_NOT_CREATE_INSTANCE, storageClass), e); - } - if (Activator.startup) - Activator.timeLog("Creating storage took "); //$NON-NLS-1$ - - Activator.bc.addBundleListener(this); - } - - public void startIt() { - // loop through the currently installed bundles - Bundle[] bundles = Activator.bc.getBundles(); - if (bundles != null) { - for (int i = 0; i < bundles.length; i++) { - Bundle current = bundles[i]; - // try to process the active ones. - if (current.getState() == Bundle.ACTIVE) { - startedBundle(current); - } else if (current.getState() == Bundle.STARTING) { - String lazy = (String) current.getHeaders("").get(Constants.BUNDLE_ACTIVATIONPOLICY); //$NON-NLS-1$ - if (lazy != null && lazy.indexOf(Constants.ACTIVATION_LAZY) >= 0) { - startedBundle(current); - } - } - } - } - } - - /** - * Add an event to the queue. The event will be forwarded to target service - * as soon as possible. - * - * @param upEv - * event, holding info for update/deletion of a configuration. - */ - public void addEvent(Object upEv, boolean securityCall) { - try { - synchronized (queue) { - queue.put(upEv); - if (!running) { - if (queue.size() > 0) { - running = true; - workThread = new WorkThread(this); - if (securityCall) { - AccessController.doPrivileged(this); - return; - } - ThreadPoolManager threadPool = (ThreadPoolManager) threadPoolManagerTracker.getService(); - if (threadPool != null) { - threadPool.execute(workThread, Thread.MAX_PRIORITY, "Component Resolve Thread"); //$NON-NLS-1$ - } else { - new Thread(workThread, "Component Resolve Thread").start(); //$NON-NLS-1$ - } - } - } else if (workThread.waiting > 0) { - queue.notifyAll(); - } - } - } catch (Throwable e) { - Activator.log(null, LogService.LOG_ERROR, Messages.UNEXPECTED_EXCEPTION, e); - } - } - - public Object run() { - ThreadPoolManager threadPool = (ThreadPoolManager) threadPoolManagerTracker.getService(); - if (threadPool != null) { - threadPool.execute(workThread, Thread.MAX_PRIORITY, "Component Resolve Thread"); //$NON-NLS-1$ - } else { - new Thread(workThread, "Component Resolve Thread").start(); //$NON-NLS-1$ - } - return null; - } - - public void queueBlocked() { - resolver.queueBlocked(); - synchronized (queue) { - running = false; - addEvent(null, Activator.security); // will result in starting new - // WorkThread to process the queued work - } - } - - /** - * This methods takes the input parameters and creates a Queued object and - * queues it. The thread is notified. - * - * @param d - * Dispatcher for this item - * @param a - * Action for this item - * @param o - * Object for this item - * @param securityCall specifies whether to use security privileged call - */ - public void enqueueWork(WorkPerformer d, int a, Object o, boolean securityCall) { - addEvent(new QueuedJob(d, a, o), securityCall); - } - - /** - * Stops this thread, making it getting out of method run. - */ - public void stopIt() { - stopped = true; - disposeBundles(); - if (queue != null) { - queue.clear(); - } - if (running) { - synchronized (queue) { - queue.notify(); - } - int counter = 0; - - while (running && counter < 20) { - // wait maximum 2 seconds to complete current task in the queue - try { - Thread.sleep(100); - } catch (InterruptedException ie) { - //nothing to do - } - counter++; - } - } - stopped = true; - threadPoolManagerTracker.close(); - storage.stop(); - } - - public void serviceChanged(ServiceEvent sEv) { - - resolver.getEligible(sEv); - } - - public final void bundleChanged(BundleEvent event) { - long start = 0l; - if (Activator.PERF) { - start = System.currentTimeMillis(); - Activator.log.info("[DS perf] Started processing bundle event " + event); //$NON-NLS-1$ - } - int type = event.getType(); - if (type == BundleEvent.STOPPING) { - stoppingBundle(event.getBundle()); - } else if (type == BundleEvent.STARTED) { - startedBundle(event.getBundle()); - } else if (type == BundleEvent.LAZY_ACTIVATION) { - startedBundle(event.getBundle()); - } else if (type == BundleEvent.UNINSTALLED && Activator.DBSTORE) { - storage.deleteComponentDefinitions(event.getBundle().getBundleId()); - } - if (Activator.PERF) { - start = System.currentTimeMillis() - start; - Activator.log.info("[DS perf] Processed bundle event '" + event + "' for " + start + "ms"); //$NON-NLS-1$//$NON-NLS-2$ //$NON-NLS-3$ - } - } - - // -- begin 'CM listener' - /** - * Listen for configuration changes - * - * Service Components can receive properties from the Configuration Admin - * service. If a Service Component is activated and it�s properties are - * updated in the Configuration Admin service, the SCR must deactivate the - * component and activate the component again using the new properties. - * - * @param event - * ConfigurationEvent - */ - public void configurationEvent(ConfigurationEvent event) { - if (bundleToServiceComponents != null && !bundleToServiceComponents.isEmpty()) { - addEvent(event, true); - } - } - - protected void processConfigurationEvent(ConfigurationEvent event) { - if (bundleToServiceComponents == null || bundleToServiceComponents.isEmpty()) { - // no components found till now - return; - } - long start = 0l; - try { - if (Activator.DEBUG) { - Activator.log.debug(" Resolver.configurationEvent(): pid = " + event.getPid() + ", fpid = " + event.getFactoryPid(), null); //$NON-NLS-1$ //$NON-NLS-2$ - } - if (Activator.PERF) { - start = System.currentTimeMillis(); - Activator.log.info("[DS perf] Started processing configuration event " + event); //$NON-NLS-1$ - } - - String pid = event.getPid(); - String fpid = event.getFactoryPid(); - for (Enumeration keys = bundleToServiceComponents.keys(); keys.hasMoreElements();) { - Vector bundleComps = (Vector) bundleToServiceComponents.get(keys.nextElement()); - // bundleComps may be null since bundleToServiceComponents - // may have been modified by another thread - if (bundleComps != null) { - for (int i = 0; i < bundleComps.size(); i++) { - ServiceComponent sc = (ServiceComponent) bundleComps.elementAt(i); - if (sc.getConfigurationPolicy() == ServiceComponent.CONF_POLICY_IGNORE) { - //skip processing of this component - it is not interested in configuration changes - continue; - } - String name = sc.getConfigurationPID(); - if (name.equals(pid) || name.equals(fpid)) { - if (name.equals(fpid) && sc.factory != null) { - Activator.log(sc.bc, LogService.LOG_ERROR, NLS.bind(Messages.FACTORY_CONF_NOT_APPLICABLE_FOR_COMPONENT_FACTORY, sc.name), null); - return; - } - if (sc.enabled) { - if (Activator.DEBUG) { - Activator.log.debug("SCRManager.processConfigurationEvent(): found component - " + pid, null); //$NON-NLS-1$ - } - processConfigurationEvent(event, sc); - } - return; - } - } - } - } - } catch (Throwable e) { - Activator.log(null, LogService.LOG_ERROR, NLS.bind(Messages.ERROR_PROCESSING_CONFIGURATION, event.getReference().getBundle()), e); - } finally { - if (Activator.PERF) { - start = System.currentTimeMillis() - start; - Activator.log.info("[DS perf] Processed configuration event '" + event + "' for " + start + "ms"); //$NON-NLS-1$ //$NON-NLS-2$//$NON-NLS-3$ - } - } - } - - private void processConfigurationEvent(ConfigurationEvent event, ServiceComponent sc) { - Configuration[] config = null; - - String pid = event.getPid(); - String fpid = event.getFactoryPid(); - - switch (event.getType()) { - case ConfigurationEvent.CM_UPDATED : - - String filter = (fpid != null ? "(&" : "") + "(" + Constants.SERVICE_PID + "=" + pid + ")" + (fpid != null ? ("(" + ConfigurationAdmin.SERVICE_FACTORYPID + "=" + fpid + "))") : ""); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ //$NON-NLS-5$ //$NON-NLS-6$ //$NON-NLS-7$ //$NON-NLS-8$ //$NON-NLS-9$ - try { - config = Activator.listConfigurations(filter); - } catch (IOException e) { - Activator.log(null, LogService.LOG_ERROR, Messages.ERROR_LISTING_CONFIGURATIONS, e); - } catch (InvalidSyntaxException e) { - Activator.log(null, LogService.LOG_ERROR, Messages.ERROR_LISTING_CONFIGURATIONS, e); - } - - if (config == null) { - // The configuration may have been deleted by the now - // If it does not exist we must do nothing - return; - } - - // if NOT a factory - if (fpid == null) { - // there is only one SCP for this SC - boolean requiresRestart = true; - if (sc.isNamespaceAtLeast11() && sc.modifyMethodName != "") { //$NON-NLS-1$ - ServiceComponentProp scp = sc.getServiceComponentProp(); - if (scp != null && scp.isBuilt()) { - //process only built components - requiresRestart = processConfigurationChange(scp, config[0]); - } - } - if (requiresRestart) { - // there is only one SCP for this SC, so we can disable the SC - Vector components = new Vector(); - components.addElement(sc); - resolver.disableComponents(components, ComponentConstants.DEACTIVATION_REASON_CONFIGURATION_MODIFIED); - - // now re-enable the SC - the resolver will pick up the new config - sc.enabled = true; - resolver.enableComponents(components); - } - - // If a MSF - // create a new SCP or update an existing one - } else { - - // get scp with this PID - ServiceComponentProp scp = sc.getComponentPropByPID(pid); - - // if only the no-props scp exists, replace it - if (scp == null && sc.componentProps != null) { - synchronized (sc.componentProps) { - if (sc.componentProps.size() == 1 && (((ServiceComponentProp) sc.componentProps.elementAt(0)).getProperties().get(Constants.SERVICE_PID) == null)) { - scp = (ServiceComponentProp) sc.componentProps.elementAt(0); - } - } - } - boolean requiresRestart = true; - if (sc.isNamespaceAtLeast11() && sc.modifyMethodName != "" && scp != null) { //$NON-NLS-1$ - if (scp.isBuilt()) { - //process only built components - requiresRestart = processConfigurationChange(scp, config[0]); - } - } - if (requiresRestart) { - // if old scp exists, dispose it - if (scp != null) { - // config already exists - dispose of it - sc.componentProps.removeElement(scp); - Vector components = new Vector(); - components.addElement(scp); - resolver.disposeComponentConfigs(components, ComponentConstants.DEACTIVATION_REASON_CONFIGURATION_MODIFIED); - scp.setState(Component.STATE_DISPOSED); - } - - // create a new scp (adds to resolver enabledSCPs list) - resolver.map(sc, config[0]); - - // kick the resolver to figure out if SCP is satisfied, etc - resolver.enableComponents(null); - } - } - - break; - case ConfigurationEvent.CM_DELETED : - - // if not a factory - if (fpid == null) { - - // there is only one SCP for this SC, so we can disable the SC - Vector components = new Vector(); - components.addElement(sc); - resolver.disableComponents(components, ComponentConstants.DEACTIVATION_REASON_CONFIGURATION_DELETED); - - // now re-enable the SC - the resolver will create SCP with - // no configAdmin properties - sc.enabled = true; - resolver.enableComponents(components); - } else { - // config is a factory - - // get SCP created for this config (with this PID) - ServiceComponentProp scp = sc.getComponentPropByPID(pid); - - // if this was the last SCP created for this factory - if (sc.componentProps.size() == 1) { - // there is only one SCP for this SC, so we can disable the - // SC - Vector components = new Vector(); - components.addElement(sc); - resolver.disableComponents(components, ComponentConstants.DEACTIVATION_REASON_CONFIGURATION_DELETED); - // now re-enable the SC - the resolver will create SCP - // with no configAdmin properties - sc.enabled = true; - sc.setState(Component.STATE_UNSATISFIED); - resolver.enableComponents(components); - } else { - // in case it has ever been constructed - if (scp != null) { - // we can just dispose this SCP - sc.componentProps.removeElement(scp); - Vector components = new Vector(); - components.addElement(scp); - resolver.disposeComponentConfigs(components, ComponentConstants.DEACTIVATION_REASON_CONFIGURATION_DELETED); - scp.setState(Component.STATE_DISPOSED); - } - } - } - break; - } - } - - /** - * Process the modification of the specified component. - * If it cannot be modified, the method will return true indicating the component has to be restarted. - * @param scp the component to modify - * @param config the configuration that brings the new properties - * @return true, if the component needs restart (to be deactivated and then eventually activated again) - */ - private boolean processConfigurationChange(ServiceComponentProp scp, Configuration config) { - boolean result = false; - Hashtable currentProps = scp.properties; - Dictionary newProps = config.getProperties(); - Enumeration keys = currentProps.keys(); - Vector checkedFilters = new Vector(); - while (keys.hasMoreElements() && !result) { - String key = (String) keys.nextElement(); - if (key.endsWith(".target")) { //$NON-NLS-1$ - checkedFilters.addElement(key); - String newFilter = (String) newProps.get(key); - Reference reference = null; - String refName = key.substring(0, key.length() - ".target".length()); //$NON-NLS-1$ - Vector references = scp.references; - for (int i = 0; i < references.size(); i++) { - reference = (Reference) references.elementAt(i); - if (reference.reference.name.equals(refName)) { - break; - } - reference = null; - } - //check if there is a reference corresponding to the target property - if (reference != null) { - if (newFilter != null) { - if (!newFilter.equals(currentProps.get(key))) { - //the filter differs the old one - result = result || !reference.doSatisfy(newFilter); - } - } else { - //the target filter is removed. Using the default filter to check - if (reference.policy == ComponentReference.POLICY_STATIC) { - result = result || !reference.doSatisfy("(objectClass=" + reference.reference.interfaceName + ")"); //$NON-NLS-1$ //$NON-NLS-2$ - } - } - } - } - } - - //now check the new properties if they have new target properties defined - keys = newProps.keys(); - while (keys.hasMoreElements() && !result) { - String key = (String) keys.nextElement(); - if (key.endsWith(".target") && !checkedFilters.contains(key)) { //$NON-NLS-1$ - Reference reference = null; - String refName = key.substring(0, key.length() - ".target".length()); //$NON-NLS-1$ - Vector references = scp.references; - for (int i = 0; i < references.size(); i++) { - reference = (Reference) references.elementAt(i); - if (reference.reference.name.equals(refName)) { - break; - } - reference = null; - } - //check if there is a reference corresponding to the target property - if (reference != null) { - result = result || !reference.doSatisfy((String) newProps.get(key)); - } - } - } - - if (!result) { - //do process component modification via the InstanceProcess - try { - InstanceProcess.staticRef.modifyComponent(scp, newProps); - } catch (ComponentException ce) { - //could happen if the modify method is not found - result = true; - } - } - return result; - } - - private void disposeBundles() { - // dispose ALL bundles - if (bundleToServiceComponents != null) { - for (Enumeration e = bundleToServiceComponents.keys(); e.hasMoreElements();) { - Bundle bundle = (Bundle) e.nextElement(); - stoppingBundle(bundle); - } - bundleToServiceComponents.clear(); - bundleToServiceComponents = null; - } - } - - void stoppingBundle(Bundle bundle) { - if (bundleToServiceComponents != null) { - Vector components = (Vector) bundleToServiceComponents.remove(bundle); - // disable the components which the bundle provides - if (components != null) { - if (Activator.DEBUG) { - String bundleName = bundle.getSymbolicName(); - bundleName = (bundleName == null || "".equals(bundleName)) ? bundle.getLocation() : bundleName; //$NON-NLS-1$ - Activator.log.debug("SCRManager.stoppingBundle : " + bundleName, null); //$NON-NLS-1$ - } - resolver.disableComponents(components, ComponentConstants.DEACTIVATION_REASON_BUNDLE_STOPPED); - - //set disposed state to all components since some of them might be still referenced by the ScrService - for (int i = 0; i < components.size(); i++) { - ServiceComponent sc = (ServiceComponent) components.elementAt(i); - sc.setState(Component.STATE_DISPOSED); - } - if (bundleToServiceComponents.size() == 0) { - hasRegisteredServiceListener = false; - Activator.bc.removeServiceListener(this); - } - } - } - } - - void startedBundle(Bundle bundle) { - synchronized (processingBundles) { - if (processingBundles.get(bundle) != null) { - //the bundle is already being processed - return; - } - processingBundles.put(bundle, ""); //$NON-NLS-1$ - } - try { - startedBundle2(bundle); - } finally { - processingBundles.remove(bundle); - } - } - - void startedBundle2(Bundle bundle) { - long start = 0l; - if (Activator.PERF) { - start = System.currentTimeMillis(); - } - if (bundleToServiceComponents != null && bundleToServiceComponents.get(bundle) != null) { - // the bundle is already processed - skipping it - return; - } - - String dsHeader = null; - Dictionary allHeaders = bundle.getHeaders(""); //$NON-NLS-1$ - - if (!((dsHeader = (String) allHeaders.get(ComponentConstants.SERVICE_COMPONENT)) != null)) { - // no component descriptions in this bundle - return; - } - - Vector components = storage.loadComponentDefinitions(bundle, dsHeader); - if (components != null && !components.isEmpty()) { - if (!hasRegisteredServiceListener) { - hasRegisteredServiceListener = true; - Activator.bc.addServiceListener(this); - resolver.synchronizeServiceReferences(); - } - if (Activator.PERF) { - start = System.currentTimeMillis() - start; - Activator.log.info("[DS perf] The components of bundle " + bundle + " are parsed for " + start + "ms"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ - } - if (bundleToServiceComponents == null) { - synchronized (this) { - if (bundleToServiceComponents == null) { - bundleToServiceComponents = new Hashtable(11); - } - } - } - - //check whether component's names are unique - ServiceComponent comp; - ServiceComponent comp2; - L1: for (int i = 0; i < components.size(); i++) { - comp = (ServiceComponent) components.elementAt(i); - //check if unique in its bundle - for (int j = i + 1; j < components.size(); j++) { - comp2 = (ServiceComponent) components.elementAt(j); - if (comp.name.equals(comp2.name)) { - Activator.log(comp.bc, LogService.LOG_ERROR, NLS.bind(Messages.FOUND_COMPONENTS_WITH_DUPLICATED_NAMES, comp), null); - //removing one of the components - components.remove(i); - i--; - continue L1; - } - } - //check if the component is globally unique - Enumeration keys = bundleToServiceComponents.keys(); - while (keys.hasMoreElements()) { - Vector components2 = (Vector) bundleToServiceComponents.get(keys.nextElement()); - for (int j = 0; j < components2.size(); j++) { - comp2 = (ServiceComponent) components2.elementAt(j); - if (comp.name.equals(comp2.name)) { - Activator.log(comp.bc, LogService.LOG_WARNING, NLS.bind(Messages.FOUND_COMPONENTS_WITH_DUPLICATED_NAMES2, comp, comp2), null); - } - } - } - - if (comp.autoenable) { - comp.enabled = true; - } - } - // store the components in the cache - bundleToServiceComponents.put(bundle, components.clone()); - if (workThread != null && workThread.processingThread == Thread.currentThread()) { - //we are in the queue thread already. Processing synchronously the job - resolver.enableComponents(components); - } else { - // this will also resolve the component dependencies! - enqueueWork(this, ENABLE_COMPONENTS, components, false); - synchronized (components) { - long startTime = System.currentTimeMillis(); - try { - while (!components.isEmpty() && (System.currentTimeMillis() - startTime < WorkThread.BLOCK_TIMEOUT)) { - components.wait(1000); - } - if (System.currentTimeMillis() - startTime >= WorkThread.BLOCK_TIMEOUT) { - Activator.log(null, LogService.LOG_WARNING, NLS.bind(Messages.TIMEOUT_REACHED_ENABLING_COMPONENTS, getBundleName(bundle), Integer.toString(WorkThread.BLOCK_TIMEOUT)), null); - } - } catch (InterruptedException e) { - //do nothing - } - } - } - } - } - - private String getBundleName(Bundle b) { - if (b.getSymbolicName() != null) { - return b.getSymbolicName(); - } - return b.getLocation(); - } - - public void enableComponent(String name, Bundle bundle) { - changeComponent(name, bundle, true); - } - - private void changeComponent(String name, Bundle bundle, boolean enable) { - if (bundleToServiceComponents == null) { - // already disposed! - return; - } - try { - Vector componentsToProcess = null; - - if (Activator.DEBUG) { - String message = (enable ? "SCRManager.enableComponent(): " : "SCRManager.disableComponent(): ").concat(name != null ? name : "*all*") + " from bundle " + getBundleName(bundle); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ - Activator.log.debug(message, null); - } - Vector bundleComponents = (Vector) bundleToServiceComponents.get(bundle); - if (bundleComponents != null) { - if (name != null) { - boolean found = false; - for (int i = 0; i < bundleComponents.size(); i++) { - ServiceComponent component = (ServiceComponent) bundleComponents.elementAt(i); - if (component.name.equals(name)) { - found = true; - if (component.enabled != enable) { - component.enabled = enable; - component.setState(enable ? Component.STATE_ENABLING : Component.STATE_DISABLING); - componentsToProcess = new Vector(2); - componentsToProcess.addElement(component); - break; - } - } - } - if (!found) { - throw new IllegalArgumentException(NLS.bind(Messages.COMPONENT_NOT_FOUND, name, bundle)); - } - } else { - if (enable) { - // processing null parameter should be done only when - // enabling components - ServiceComponent sc; - componentsToProcess = new Vector(); - for (int i = 0; i < bundleComponents.size(); i++) { - sc = ((ServiceComponent) bundleComponents.elementAt(i)); - if (!sc.enabled) { - componentsToProcess.addElement(sc); - sc.enabled = enable; - sc.setState(Component.STATE_ENABLING); - } - } - } - } - - } - // publish to resolver the list of SCs to enable - if (componentsToProcess != null && !componentsToProcess.isEmpty()) { - if (enable) { - enqueueWork(this, ENABLE_COMPONENTS, componentsToProcess, Activator.security); - } else { - enqueueWork(this, DISABLE_COMPONENTS, componentsToProcess, Activator.security); - } - } - } catch (IllegalArgumentException iae) { - throw iae; - } catch (Throwable e) { - Activator.log(null, LogService.LOG_ERROR, Messages.UNEXPECTED_EXCEPTION, e); - } - } - - /** - * QueuedJob represents the items placed on the asynch dispatch queue. - */ - static class QueuedJob { - final WorkPerformer performer; - /** the required type of action to do */ - final int actionType; - /** work input data to be performed */ - final Object workToDo; - - /** - * Constructor for work queue item - * - * @param d - * Dispatcher for this item - * @param a - * Action for this item - * @param o - * Object for this item - */ - QueuedJob(WorkPerformer d, int a, Object o) { - performer = d; - actionType = a; - workToDo = o; - } - - void dispatch() { - try { - /* Call the WorkPerformer to process the work. */ - performer.performWork(actionType, workToDo); - } catch (Throwable t) { - Activator.log(null, LogService.LOG_ERROR, Messages.ERROR_DISPATCHING_WORK, t); - } - } - - public String toString() { - return "[QueuedJob] WorkPerformer: " + performer + "; actionType " + actionType; //$NON-NLS-1$ //$NON-NLS-2$ - } - } - - // -- begin enable/disable components - /** - * disableComponent - The specified component name must be in the same - * bundle as this component. Called by SC componentContext method - * - * @param name - * The name of a component to disable - * @param bundle - * The bundle which contains the Service Component to be disabled - */ - public void disableComponent(String name, Bundle bundle) { - changeComponent(name, bundle, false); - } - - /* - * (non-Javadoc) - * - * @see org.eclipse.equinox.internal.ds.util.WorkPerformer#performWork(int, - * java.lang.Object) - */ - public void performWork(int workAction, Object workObject) { - if (workAction == ENABLE_COMPONENTS) { - resolver.enableComponents((Vector) workObject); - //notify that the component enabling has finished - synchronized (workObject) { - ((Vector) workObject).clear(); - workObject.notify(); - } - } else if (workAction == DISABLE_COMPONENTS) { - resolver.disableComponents((Vector) workObject, ComponentConstants.DEACTIVATION_REASON_DISABLED); - } - } - - protected void configAdminRegistered(ConfigurationAdmin configAdmin, ServiceReference caReference) { - if (bundleToServiceComponents == null || bundleToServiceComponents.isEmpty()) { - // no components found till now - return; - } - Vector toProcess = new Vector(1); - Configuration[] configs = null; - try { - configs = configAdmin.listConfigurations(null); - } catch (Exception e) { - Activator.log(null, LogService.LOG_ERROR, Messages.ERROR_LISTING_CONFIGURATIONS, e); - } - if (configs == null || configs.length == 0) { - //no configurations found - return; - } - //process all components to find such that need to be evaluated when ConfigAdmin is available - for (Enumeration keys = bundleToServiceComponents.keys(); keys.hasMoreElements();) { - Vector bundleComps = (Vector) bundleToServiceComponents.get(keys.nextElement()); - // bundleComps may be null since bundleToServiceComponents - // may have been modified by another thread - if (bundleComps != null) { - for (int i = 0; i < bundleComps.size(); i++) { - ServiceComponent sc = (ServiceComponent) bundleComps.elementAt(i); - if (sc.getConfigurationPolicy() == ServiceComponent.CONF_POLICY_IGNORE) { - //skip processing of this component - it is not interested in configuration changes - continue; - } - if (sc.enabled) { - String componentPID = sc.getConfigurationPID(); - for (int j = 0; j < configs.length; j++) { - if (configs[j].getPid().equals(componentPID) || componentPID.equals(configs[j].getFactoryPid())) { - if (componentPID.equals(configs[j].getFactoryPid()) && sc.factory != null) { - Activator.log(sc.bc, LogService.LOG_ERROR, NLS.bind(Messages.FACTORY_CONF_NOT_APPLICABLE_FOR_COMPONENT_FACTORY, sc.name), null); - break; - } - //found a configuration for this component - if (sc.componentProps == null || sc.componentProps.size() == 0) { - if (sc.getConfigurationPolicy() == ServiceComponent.CONF_POLICY_REQUIRE) { - //the component is not yet mapped because it is requiring configuration. Try to process it - toProcess.addElement(sc); - } - } else { - //process the component configurations and eventually modify or restart them - ConfigurationEvent ce = new ConfigurationEvent(caReference, ConfigurationEvent.CM_UPDATED, configs[j].getFactoryPid(), configs[j].getPid()); - configurationEvent(ce); - } - break; - } - } - } - } - } - } - if (toProcess.size() > 0) { - enqueueWork(this, ENABLE_COMPONENTS, toProcess, false); - } - } - - public Component[] getComponents() { - if (bundleToServiceComponents == null || bundleToServiceComponents.isEmpty()) { - // no components found till now - return null; - } - Vector result = new Vector(); - Enumeration en = bundleToServiceComponents.keys(); - while (en.hasMoreElements()) { - Bundle b = (Bundle) en.nextElement(); - Vector serviceComponents = (Vector) bundleToServiceComponents.get(b); - for (int i = 0; i < serviceComponents.size(); i++) { - ServiceComponent sc = (ServiceComponent) serviceComponents.elementAt(i); - if (sc.componentProps != null && !sc.componentProps.isEmpty()) { - //add the created runtime components props - result.addAll(sc.componentProps); - } else { - //add the declared component itself - result.add(sc); - } - } - } - if (!result.isEmpty()) { - Component[] res = new Component[result.size()]; - result.copyInto(res); - return res; - } - return null; - } - - public Component[] getComponents(Bundle bundle) { - if (bundleToServiceComponents == null || bundleToServiceComponents.isEmpty()) { - // no components found till now - return null; - } - Vector serviceComponents = (Vector) bundleToServiceComponents.get(bundle); - if (serviceComponents != null) { - Vector result = new Vector(); - for (int i = 0; i < serviceComponents.size(); i++) { - ServiceComponent sc = (ServiceComponent) serviceComponents.elementAt(i); - if (sc.componentProps != null && !sc.componentProps.isEmpty()) { - //add the created runtime components props - result.addAll(sc.componentProps); - } else { - //add the declared component itself - result.add(sc); - } - } - if (!result.isEmpty()) { - Component[] res = new Component[result.size()]; - result.copyInto(res); - return res; - } - } - return null; - } - - public Component[] getComponents(String componentName) { - if (bundleToServiceComponents == null || bundleToServiceComponents.isEmpty()) { - // no components found till now - return null; - } - Vector result = new Vector(); - Enumeration en = bundleToServiceComponents.keys(); - while (en.hasMoreElements()) { - Bundle b = (Bundle) en.nextElement(); - Vector serviceComponents = (Vector) bundleToServiceComponents.get(b); - for (int i = 0; i < serviceComponents.size(); i++) { - ServiceComponent sc = (ServiceComponent) serviceComponents.elementAt(i); - if (sc.getName().equals(componentName)) { - if (sc.componentProps != null && !sc.componentProps.isEmpty()) { - // add the created runtime components props - result.addAll(sc.componentProps); - } else { - // add the declared component itself - result.add(sc); - } - break; - } - } - } - if (!result.isEmpty()) { - Component[] res = new Component[result.size()]; - result.copyInto(res); - return res; - } - return null; - } - -} diff --git a/bundles/org.eclipse.equinox.ds/src/org/eclipse/equinox/internal/ds/SCRUtil.java b/bundles/org.eclipse.equinox.ds/src/org/eclipse/equinox/internal/ds/SCRUtil.java deleted file mode 100644 index 05dad5a60..000000000 --- a/bundles/org.eclipse.equinox.ds/src/org/eclipse/equinox/internal/ds/SCRUtil.java +++ /dev/null @@ -1,279 +0,0 @@ -/******************************************************************************* - * Copyright (c) 1997, 2010 by ProSyst Software GmbH - * http://www.prosyst.com - * 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: - * ProSyst Software GmbH - initial API and implementation - *******************************************************************************/ -package org.eclipse.equinox.internal.ds; - -import java.lang.reflect.Method; -import java.lang.reflect.Modifier; -import java.util.Dictionary; -import java.util.Enumeration; -import org.apache.felix.scr.Component; -import org.eclipse.equinox.internal.util.pool.ObjectCreator; -import org.eclipse.equinox.internal.util.pool.ObjectPool; - -/** - * Holds useful methods used by SCR. - * - * @author Valentin Valchev - * @author Stoyan Boshev - * @author Pavlin Dobrev - */ - -public final class SCRUtil implements ObjectCreator { - - private static ObjectPool objectArrayPool; - - static { - SCRUtil u = new SCRUtil(); - // FIXME: use some kind of logging for the object pool to determine - // the optimal solution! - objectArrayPool = new ObjectPool(u, 10, 2); - } - - private SCRUtil() { - // - } - - public static Object[] getObjectArray() { - return (Object[]) objectArrayPool.getObject(); - } - - public static void release(Object[] objectArray) { - for (int j = 0; j < objectArray.length; j++) { - objectArray[j] = null; - } - objectArrayPool.releaseObject(objectArray); - } - - public Object getInstance() throws Exception { - return new Object[1]; - } - - public static void copyTo(Dictionary dst, Dictionary src) { - if (src == null || dst == null) { - return; - } - Object key; - for (Enumeration e = src.keys(); e.hasMoreElements();) { - key = e.nextElement(); - dst.put(key, src.get(key)); - } - } - - /** - * Checks whether the method can be accessed according to the DS v1.1 specification rules (112.8.4 Locating Component Methods) - * @param implClass the component implementation class - * @param currentClass the class where the method is located. This class is in the component implementation class hierarchy - * @param methodToCheck the method to be checked - * @param isComponent11 specifies whether the component is according to schema 1.1 or higher. Its value is true in case the component version is v1.1 or higher - * @return true, if the method can be executed - */ - public static boolean checkMethodAccess(Class implClass, Class currentClass, Method methodToCheck, boolean isComponent11) { - int modifiers = methodToCheck.getModifiers(); - boolean result = true; - if (isComponent11) { - if (currentClass == implClass) { - //the method is located in the component impl class - //allow all types of modifiers - } else { - //the method is located in a super class of the component impl class - if (Modifier.isPrivate(modifiers)) { - // private method - no access - result = false; - } else if (!Modifier.isPublic(modifiers) && !Modifier.isProtected(modifiers)) { - // not protected neither public neither private - this is private package case - if (currentClass.getPackage() != implClass.getPackage()) { - //do not accept the method if its class package differs the package of the component impl class - result = false; - } - } - } - } else { - result = Modifier.isPublic(modifiers) || Modifier.isProtected(modifiers); - } - return result; - } - - private static Method setAccessibleMethod = null; - private static Object[] args = null; - private static boolean failed = false; - - /** - * This method is added only for JVM compatibility. Actually setAccessible() - * is available since jdk1.2. The older java runtimes don't have this - * method. - * - * However, you can call this method. It is guaranteed that it will do the - * right job. - * - * @param method - * the method to set accessible. - */ - public static final void setAccessible(Method method) { - try { - if (setAccessibleMethod == null && !failed) { - setAccessibleMethod = Class.forName("java.lang.reflect.AccessibleObject").getMethod("setAccessible", new Class[] {boolean.class}); //$NON-NLS-1$ //$NON-NLS-2$ - args = new Object[] {Boolean.TRUE}; - } - if (setAccessibleMethod != null) - setAccessibleMethod.invoke(method, args); - } catch (Exception e) { - failed = true; - } - } - - /** - * Gets the string representation of an Object. This method is - * helpful if the passed parameter is a type of array. If the objects is not - * recognized as array, the method will simply return the toString() value - * - * @param value - * an object which should be represented as string - * @return the string representation of the - */ - public static String getStringRepresentation(Object value) { - if (value == null) - return "null"; //$NON-NLS-1$ - //this would speedup many cases - if (value instanceof String) - return (String) value; - - StringBuffer res = new StringBuffer(200); - - if (value instanceof String[]) { - res.append("String["); //$NON-NLS-1$ - String[] arr = (String[]) value; - for (int i = 0; i < arr.length; i++) { - res.append(arr[i]); - if (i != arr.length - 1) { - res.append(","); //$NON-NLS-1$ - } - } - res.append("]"); //$NON-NLS-1$ - } else if (value instanceof int[]) { - res.append("int["); //$NON-NLS-1$ - int[] arr = (int[]) value; - for (int i = 0; i < arr.length; i++) { - res.append(arr[i] + ""); //$NON-NLS-1$ - if (i != arr.length - 1) { - res.append(","); //$NON-NLS-1$ - } - } - res.append("]"); //$NON-NLS-1$ - } else if (value instanceof long[]) { - res.append("long["); //$NON-NLS-1$ - long[] arr = (long[]) value; - for (int i = 0; i < arr.length; i++) { - res.append(arr[i] + ""); //$NON-NLS-1$ - if (i != arr.length - 1) { - res.append(","); //$NON-NLS-1$ - } - } - res.append("]"); //$NON-NLS-1$ - } else if (value instanceof char[]) { - res.append("char["); //$NON-NLS-1$ - char[] arr = (char[]) value; - for (int i = 0; i < arr.length; i++) { - res.append(arr[i] + ""); //$NON-NLS-1$ - if (i != arr.length - 1) { - res.append(","); //$NON-NLS-1$ - } - } - res.append("]"); //$NON-NLS-1$ - } else if (value instanceof boolean[]) { - res.append("boolean["); //$NON-NLS-1$ - boolean[] arr = (boolean[]) value; - for (int i = 0; i < arr.length; i++) { - res.append(arr[i] + ""); //$NON-NLS-1$ - if (i != arr.length - 1) { - res.append(","); //$NON-NLS-1$ - } - } - res.append("]"); //$NON-NLS-1$ - } else if (value instanceof double[]) { - res.append("double["); //$NON-NLS-1$ - double[] arr = (double[]) value; - for (int i = 0; i < arr.length; i++) { - res.append(arr[i] + ""); //$NON-NLS-1$ - if (i != arr.length - 1) { - res.append(","); //$NON-NLS-1$ - } - } - res.append("]"); //$NON-NLS-1$ - } else if (value instanceof float[]) { - res.append("float["); //$NON-NLS-1$ - float[] arr = (float[]) value; - for (int i = 0; i < arr.length; i++) { - res.append(arr[i] + ""); //$NON-NLS-1$ - if (i != arr.length - 1) { - res.append(","); //$NON-NLS-1$ - } - } - res.append("]"); //$NON-NLS-1$ - } else if (value instanceof Object[]) { - res.append("Object["); //$NON-NLS-1$ - Object[] arr = (Object[]) value; - for (int i = 0; i < arr.length; i++) { - res.append(getStringRepresentation(arr[i])); - if (i != arr.length - 1) { - res.append(","); //$NON-NLS-1$ - } - } - res.append("]"); //$NON-NLS-1$ - } else { - return value.toString(); - } - return res.toString(); - } - - /** - * Gets the string presentation of a state defined by the interface org.apache.felix.scr.Component - * @param state the specified state - * @return the string representation of the specified state - */ - public static String getStateStringRepresentation(int state) { - String result = "Unknown"; //$NON-NLS-1$ - switch (state) { - case Component.STATE_ACTIVATING : - result = "Activating"; //$NON-NLS-1$ - break; - case Component.STATE_ACTIVE : - result = "Active"; //$NON-NLS-1$ - break; - case Component.STATE_DEACTIVATING : - result = "Deactivating"; //$NON-NLS-1$ - break; - case Component.STATE_DISABLED : - result = "Disabled"; //$NON-NLS-1$ - break; - case Component.STATE_DISPOSED : - result = "Disposed"; //$NON-NLS-1$ - break; - case Component.STATE_DISPOSING : - result = "Disposing"; //$NON-NLS-1$ - break; - case Component.STATE_ENABLING : - result = "Enabling"; //$NON-NLS-1$ - break; - case Component.STATE_FACTORY : - result = "Factory"; //$NON-NLS-1$ - break; - case Component.STATE_REGISTERED : - result = "Registered"; //$NON-NLS-1$ - break; - case Component.STATE_UNSATISFIED : - result = "Unsatisfied"; //$NON-NLS-1$ - break; - - } - return result; - } -} diff --git a/bundles/org.eclipse.equinox.ds/src/org/eclipse/equinox/internal/ds/SCRmessages.properties b/bundles/org.eclipse.equinox.ds/src/org/eclipse/equinox/internal/ds/SCRmessages.properties deleted file mode 100644 index 19d2a4898..000000000 --- a/bundles/org.eclipse.equinox.ds/src/org/eclipse/equinox/internal/ds/SCRmessages.properties +++ /dev/null @@ -1,168 +0,0 @@ -############################################################################### -# Copyright (c) 1997, 2010 by ProSyst Software GmbH -# http://www.prosyst.com -# 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: -# ProSyst Software GmbH - initial API and implementation -############################################################################### -ALL_COMPONENTS=All Components: -ALL_REFERENCES_RESOLVED=\ \ All component references are satisfied -BIND_METHOD_NOT_FOUND_OR_NOT_ACCESSIBLE=[SCR] ComponentReference.bind(): bind method ''{0}'' is not found or it is not accessible! -UPDATED_METHOD_NOT_FOUND_OR_NOT_ACCESSIBLE=[SCR] Updated method ''{0}'' is not found or it is not accessible! -UPDATED_METHOD_NOT_CALLED=[SCR] Updated method of reference {0} of component {1} cannot be called because its parameter service object cannot be retrieved! -BUNDLE_NOT_FOUND=Bundle with ID {0} was not found! -CANNOT_BUILD_COMPONENT=[SCR] Cannot build component {0} -CANNOT_CREATE_INSTANCE=ServiceReg.getService(): Could not create instance of {0} -CANNOT_FIND_COMPONENT_BUNDLE=Could not find the bundle of the specified component\! It is possibly uninstalled. -CANNOT_GET_CONFIGURATION=[SCR] Cannot get configuration for component {0} -CANNOT_GET_REFERENCES=[SCR] Cannot get references for {0} -CANNOT_MODIFY_INSTANCE__MODIFY_METHOD_NOT_FOUND=[SCR] Cannot modify instance {0} of component {1}\! The specified modify method was not found\! -CANT_ACTIVATE_INSTANCE=[SCR] Cannot activate instance {0} of component {1} -CANT_GET_SERVICE=FactoryReg.getService(): Cannot create instance of {0} -CANT_GET_SERVICE_OBJECT=[SCR] Could not get the service object relevant to the reference. One possible reason is a circularity problem. Another possible reason is that BundleContext.getService() returns null. -CANT_LIST_CONFIGURATIONS=[SCR] Cannot list configurations for component {0} -CANT_OPEN_STREAM_TO_COMPONENT_XML=[SCR] Could not open stream to component definition file {0} -CANT_RESOLVE_COMPONENT_INSTANCE=Cannot resolve instance of {0} with properties {1} -CIRCULARITY_EXCEPTION_FOUND=[SCR] Circularity Exception found for component: {0} -COMPONENT_DISPOSED=The component is disposed -COMPONENT_CONFIGURATIONS=\ \ Component configurations : -COMPONENT_DETAILS=\tComponent details -COMPONENT_HAS_ILLEGAL_REFERENCE=The component ''{0}'' defined at line {1} contains illegal reference {2} -COMPONENT_ID_DEFINIED_BY_LIST_COMMAND=The ID of the component as displayed by the list command -COMPONENT_LACKS_APPROPRIATE_PERMISSIONS=[SCR] Cannot satisfy component ''{0}'' because its bundle does not have permissions to register service with interface {1} -COMPONENT_NAME=\t\t\tComponent Name -COMPONENT_NAME_IS_NULL=Component name must not be null -COMPONENT_NOT_FOUND=component {0} not found in bundle {1} -COMPONENT_NOT_RESOLVED=\ \ *The component is NOT satisfied -COMPONENT_REQURES_CONFIGURATION_ACTIVATION=The ''{0}'' component''s configuration could not be satisfied because it is required to be initialized by a ConfigurationAdmin service Configuration object, but one was not found. -COMPONENT_RESOLVED=\ \ The component is satisfied -COMPONENT_WAS_NOT_BUILT=The component was not built because some of its references could not be bound. The component is {0} -COMPONENT_XML_NOT_FOUND=[SCR] Component definition XMLs not found in bundle {0}. The component header value is {1} -COMPONENTS_IN_BUNDLE=Components in bundle {0}: -CONFIG_ADMIN_SERVICE_NOT_AVAILABLE=The ConfigurationAdmin service is not available. -CONFIG_PROPERTIES=\ \ \ \ Configuration properties: -COULD_NOT_CREATE_INSTANCE=[SCR - SCRManager] could not create instance for {0} -COULD_NOT_CREATE_NEW_INSTANCE=Failed to create new instance -DISABLE_ALL_COMPONENTS=Disables all components; use [bundle id] to disable all components of the specified bundle -DISABLE_COMPONENT=Disables the specified component; -DISABLING_ALL_BUNDLE_COMPONENTS=Disabling all components in bundle {0} -DISABLING_ALL_COMPONENTS=Disabling all components -DUPLICATED_REFERENCE_NAMES=The component ''{0}'' defined at line {1} contains references with duplicate names -DUPLICATED_SERVICE_TAGS=The ''service'' tag is duplicated at line {0} -DYNAMIC_INFO=Dynamic information : -ENABLE_ALL_COMPONENTS=Enables all components; use [bundle id] to enable all components of the specified bundle -ENABLE_COMPONENT=Enables the specified component; -ENABLING_ALL_BUNDLE_COMPONENTS=Enabling all components in bundle {0} -ENABLING_ALL_COMPONENTS=Enabling all components -ERROR_BINDING_REFERENCE=[SCR] Error while trying to bind reference {0} -ERROR_BUILDING_COMPONENT_INSTANCE=Error while building configuration of component {0} -ERROR_CREATING_SCP=[SCR] Unexpected exception while creating configuration for component {0} -ERROR_DEACTIVATING_INSTANCE=[SCR] Error while attempting to deactivate instance of component {0} -ERROR_DISPATCHING_WORK=[SCR] Error dispatching work -ERROR_DISPOSING_INSTANCES=Exception while disposing instances of component {0} -ERROR_LISTING_CONFIGURATIONS=Error while listing CM Configurations -ERROR_LOADING_COMPONENTS=[SCR] Error while loading components from DB -ERROR_LOADING_DATA_FILE=[SCR] Error while loading components from data file {0} -ERROR_LOADING_PROPERTIES_FILE=[SCR - DeclarationParser.doProperties()] Error while loading properties file -ERROR_OPENING_COMP_XML=[SCR] Error occurred while opening component definition file {0} -ERROR_PARSING_MANIFEST_HEADER=Error attempting parse manifest element header -ERROR_PROCESSING_CONFIGURATION=[SCR] Error while processing configuration event for bundle {0} -ERROR_PROCESSING_END_TAG=[SCR] Error occurred while processing end tag of XML ''{0}'' in bundle {1}! -ERROR_PROCESSING_PROPERTY=[SCR - DeclarationParser.doProperty()] Error while processing property ''{0}'' in XML {1}! -ERROR_PROCESSING_START_TAG=[SCR] Error occurred while processing start tag of XML ''{0}'' in bundle {1}! -ERROR_UNBINDING_REFERENCE=[SCR] Error while dynamically unbinding reference ''{0}'' of component instance {1} -ERROR_UPDATING_REFERENCE=[SCR] Error while updating reference ''{0}'' of component instance {1} -ERROR_UNBINDING_REFERENCE2=Exception while unbinding reference {0} -EXCEPTION_ACTIVATING_INSTANCE=[SCR] Exception while activating instance {0} of component {1} -EXCEPTION_BUILDING_COMPONENT=[SCR] Exception occurred while building component configuration of component {0} -EXCEPTION_CREATING_COMPONENT_INSTANCE=Exception occurred while creating new instance of component {0} -EXCEPTION_GETTING_METHOD=[SCR] Exception occurred while getting method ''{0}'' of class {1} -EXCEPTION_LOCATING_SERVICE=Exception occurred while locating service for interface {0} -EXCEPTION_LOCATING_SERVICES=Exception occurred while locating services for interface {0} -EXCEPTION_MODIFYING_COMPONENT=[SCR] Exception while modifying instance {0} of component {1} -EXCEPTION_UNBINDING_REFERENCE=[SCR] Exception occurred while unbinding reference {0} -EXPECTED_PARAMETER_COMPONENT_ID=This command expects a component ID as parameter\! -FACTORY_CONF_NOT_APPLICABLE_FOR_COMPONENT_FACTORY=[SCR - SCRManager] ComponentFactory {0} cannot be managed using factory configuration! -FACTORY_REGISTRATION_ALREADY_DISPOSED=InstanceProcess.disposeInstances(): registration for component factory {0} is already disposed! -FOUND_COMPONENTS_WITH_DUPLICATED_NAMES=[SCR] Found components with duplicated names inside their bundle\! This component will not be processed: {0} -FOUND_COMPONENTS_WITH_DUPLICATED_NAMES2=[SCR] Found components with duplicated names\! Details: \nComponent1 : {0}\nComponent2: {1} -ILLEGAL_DEFINITION_FILE=[SCR] Illegal definition file: {0} -ILLEGAL_ELEMENT_IN_SERVICE_TAG=Found illegal element ''{0}'' for tag ''service'' at line {1} -ILLEGAL_TAG_FOUND=Found illegal tag named ''{0}'' in component XML, at line {1} -INCOMPATIBLE_COMBINATION=ManagedServiceFactory and ComponentFactory are incompatible -INCORRECT_ACTIVATION_POLICY=The component ''{0}'' has incorrect value for attribute ''configuration-policy'', line {1} -INCORRECT_VALUE_TYPE=Value {0} does not fit its type! -INSTANCE_ALREADY_CREATED=Instance of ''{0}''is already created! -INSTANCE_CREATION_TOOK_LONGER=The instance creation of component {0} took longer than {1}ms. There might be a synchronization problem in this callstack or just the instance creation took too long! -INSTANCE_NOT_BOUND=[SCR] ComponentReference.unbind(): component instance not bound\! It is: {0} -INVALID_CARDINALITY_ATTR=The ''cardinality'' attribute has invalid value ''{0}'' at line {1} -INVALID_COMPONENT_FACTORY_AND_SERVICE_FACTORY=The component ''{0}'' is invalid. The component cannot be both factory component and service factory -INVALID_COMPONENT_ID=Invalid component ID\! -INVALID_COMPONENT_IMMEDIATE_AND_FACTORY=The component ''{0}'' is invalid. The component cannot be both immediate and a factory component -INVALID_COMPONENT_IMMEDIATE_AND_SERVICE_FACTORY=The component ''{0}'' is invalid. The component cannot be both immediate and a service factory -INVALID_COMPONENT_NO_SERVICES_NO_IMMEDIATE=The component ''{0}'' is invalid. The component must be immediate since it does not provide any services -INVALID_COMPONENT_TAG__MULTIPLE_IMPL_ATTRIBS=The ''component'' tag must have exactly one ''implementation'' attribute at line {0} -INVALID_COMPONENT_TAG__NO_CLASS_ATTR=The ''implementation'' element must have ''class'' attribute set at line {0} -INVALID_OBJECT=The Object ''{0}'' is not created by the component named {1} -INVALID_POLICY_ATTR=The ''policy'' attribute has invalid value ''{0}'' at line {1} -INVALID_POLICY_OPTION_ATTR=The ''policy-option'' attribute has invalid value ''{0}'' at line {1} -INVALID_PROPERTIES_TAG__INVALID_ENTRY_VALUE=The specified ''entry'' for the ''properties'' tag at line {0} doesn''t contain valid reference to a property file: {1} -INVALID_PROPERTIES_TAG__NO_ENTRY_ATTR=The ''properties'' tag must include ''entry'' attribute, at line {0} -INVALID_PROPERTY_TAG__NO_BODY_CONTENT=The 'property' tag must have body content if 'value' attribute is not specified\! -INVALID_PROPERTY_TAG__NO_NAME_ATTR=The ''property'' tag must have ''name'' attribute set at line {0} -INVALID_PROPERTY_TYPE=Illegal property type ''{0}'' at line {1} -INVALID_PROVIDE_TAG__NO_INTERFACE_ATTR=The ''provide'' tag must have ''interface'' attribute set at line {0} -INVALID_REFERENCE_TAG__BIND_ATTR_EMPTY=The ''reference'' tag at line {0} is invalid: ''bind'' attribute is empty! -INVALID_REFERENCE_TAG__BIND_EQUALS_UNBIND=The ''reference'' tag at line {0} is invalid: ''bind'' and ''unbind'' values are equal! -INVALID_REFERENCE_TAG__UNBIND_ATTR_EMPTY=The ''reference'' tag at line {0} is invalid: ''unbind'' attribute is empty! -INVALID_REFERENCE_TAG__UPDATED_ATTR_EMPTY=The ''reference'' tag at line {0} is invalid: ''updated'' attribute is empty! -INVALID_SERVICE_REFERENCE=[SCR] ComponentReference.unbind(): invalid service reference {0} -INVALID_SERVICE_TAG__NO_PROVIDE_TAG=The ''service'' tag must have one ''provide'' tag set at line {0} -INVALID_TAG_ACCORDING_TO_NAMESPACE1_0=The component is according to namespace v1.0.0 and must not have ''{0}'' tag set, at line {1} -INVALID_TAG_ACCORDING_TO_NAMESPACE1_2=The component must have namespace v1.2.0 in order to accept attribute ''{0}'' set, at line {1} -INVALID_TARGET_FILTER=invalid target filter {0} -LIST_ALL_BUNDLE_COMPONENTS=use [bundle id] to list the components of the specified bundle -LIST_ALL_COMPONENTS=Lists all components; add -c to display the complete info for each component; -LOCATED_IN_BUNDLE=\t\t\tLocated in bundle -METHOD_UNACCESSABLE=[SCR] Method ''{0}'' is not public or protected and cannot be executed! The method is located in the class: {1} -MISSING_CHARACTER=Missing character -NO_BUILT_COMPONENT_CONFIGURATIONS=\ \ *The component has NO built configurations\! The reason might be that it requires initialization by configuration provided by Configuration Admin but none was found -NO_COMPONENTS_FOUND=[SCR] No components were found while processing component definition file {0} -NO_IMPLEMENTATION_ATTRIBUTE=The component ''{0}'' misses ''implementation'' attribute, line {1} -NO_INTERFACE_ATTR_IN_REFERENCE_TAG=The ''reference'' tag must have ''interface'' attribute, at line {0} -NO_NAME_ATTRIBUTE=The component definition misses ''name'' attribute, line {0} -NOT_RESOLVED_REFERENCES=\ \ The following references are not satisfied: -PRINT_COMPONENT_INFO=Prints all available information about the specified component; -PROCESSING_BUNDLE_FAILED=[SCR] Unexpected exception while processing bundle with id {0} : {1} -REGISTERED_AS_COMPONENT_AND_MANAGED_SERVICE_FACORY=[SCR - Resolver] Cannot specify both ComponentFactory and ManagedServiceFactory\nThe name of the ComponentFactory component is {0} -REGISTRATION_ALREADY_DISPOSED=InstanceProcess.disposeInstances(): registration for component {0} is already disposed! -RETURNING_NOT_FULLY_ACTIVATED_INSTANCE=Returning SCP instance which is not fully activated\! -SCR=Service Component Runtime -SENT_DISABLING_REQUEST=Sent request for disabling component {0} -SENT_ENABLING_REQUEST=Sent request for enabling component {0} -SERVICE_REFERENCE_ALREADY_BOUND=[SCR] ComponentReference.bind(): service reference {0} is already bound to instance {1} -SERVICE_USAGE_COUNT=service ''{0}'' is used {1} time(s) -SPECIFIED_ACTIVATE_METHOD_NOT_FOUND=[SCR] Cannot activate instance {0} of component {1}! The specified activate method was not found! -SPECIFIED_DEACTIVATE_METHOD_NOT_FOUND=[SCR] Cannot correctly deactivate instance {0} of component {1}! The specified deactivate method was not found! -STATE=\tState -STATIC_OPTIONAL_REFERENCE_TO_BE_REMOVED=[SCR] Static optional reference detected in a component cycle and it will be removed. The reference is {0} -TIMEOUT_GETTING_LOCK=Getting a lock required more than {0} ms. There might be a synchronization problem in this callstack or just the build/dispose process of some components took too long! -TIMEOUT_PROCESSING=[SCR - WorkThread] Timeout occurred\! Thread was blocked on processing {0} -TIMEOUT_REACHED_ENABLING_COMPONENTS=[SCR] Enabling components of bundle {0} did not complete in {1} ms -UNEXPECTED_ERROR=[SCR] Unexpected error\! -UNEXPECTED_EXCEPTION=[SCR] Unexpected exception occurred\! -UNSUPPORTED_TYPE=Unsupported type: {0} -WRONG_PARAMETER=Wrong parameter {0}! It is not a number! -WRONG_PARAMETER2=Wrong parameter {0} -ERROR_DELETING_COMPONENT_DEFINITIONS=Error deleting component's definitions! -ERROR_WRITING_OBJECT=Error writing object! -ERROR_READING_OBJECT=Error reading object! -DBMANAGER_SERVICE_TRACKER_OPENED=DBManager service tracker opened for -ERROR_LOADING_COMPONENT_DEFINITIONS=Error while loading component's definitions! -ERROR_MODIFYING_COMPONENT=Error modifying component {0} -ERROR_SAVING_COMPONENT_DEFINITIONS=Error while saving component's definitions! -FILE_DOESNT_EXIST_OR_DIRECTORY=File doesn't exist or is a directory! diff --git a/bundles/org.eclipse.equinox.ds/src/org/eclipse/equinox/internal/ds/ScrServiceImpl.java b/bundles/org.eclipse.equinox.ds/src/org/eclipse/equinox/internal/ds/ScrServiceImpl.java deleted file mode 100644 index 96325681e..000000000 --- a/bundles/org.eclipse.equinox.ds/src/org/eclipse/equinox/internal/ds/ScrServiceImpl.java +++ /dev/null @@ -1,54 +0,0 @@ -/******************************************************************************* - * Copyright (c) 1997-2010 by ProSyst Software GmbH - * http://www.prosyst.com - * 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: - * ProSyst Software GmbH - initial API and implementation - *******************************************************************************/ -package org.eclipse.equinox.internal.ds; - -import org.apache.felix.scr.Component; -import org.apache.felix.scr.ScrService; -import org.osgi.framework.Bundle; - -public class ScrServiceImpl implements ScrService { - - boolean disposed = false; - - public Component getComponent(long componentId) { - if (!disposed && InstanceProcess.resolver != null) { - return InstanceProcess.resolver.getComponent(componentId); - } - return null; - } - - public Component[] getComponents() { - if (!disposed && InstanceProcess.resolver != null) { - return InstanceProcess.resolver.mgr.getComponents(); - } - return null; - } - - public Component[] getComponents(Bundle bundle) { - if (!disposed && InstanceProcess.resolver != null) { - return InstanceProcess.resolver.mgr.getComponents(bundle); - } - return null; - } - - public void dispose() { - disposed = true; - } - - public Component[] getComponents(String componentName) { - if (!disposed && InstanceProcess.resolver != null) { - return InstanceProcess.resolver.mgr.getComponents(componentName); - } - return null; - } - -} diff --git a/bundles/org.eclipse.equinox.ds/src/org/eclipse/equinox/internal/ds/ServiceReg.java b/bundles/org.eclipse.equinox.ds/src/org/eclipse/equinox/internal/ds/ServiceReg.java deleted file mode 100644 index 053ade255..000000000 --- a/bundles/org.eclipse.equinox.ds/src/org/eclipse/equinox/internal/ds/ServiceReg.java +++ /dev/null @@ -1,120 +0,0 @@ -/******************************************************************************* - * Copyright (c) 1997, 2010 by ProSyst Software GmbH - * http://www.prosyst.com - * 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: - * ProSyst Software GmbH - initial API and implementation - *******************************************************************************/ -package org.eclipse.equinox.internal.ds; - -import org.eclipse.equinox.internal.ds.impl.ComponentInstanceImpl; -import org.eclipse.equinox.internal.ds.model.ServiceComponentProp; -import org.eclipse.osgi.util.NLS; -import org.osgi.framework.*; -import org.osgi.service.component.ComponentConstants; -import org.osgi.service.component.ComponentException; -import org.osgi.service.log.LogService; - -/** - * @author Stoyan Boshev - * @author Pavlin Dobrev - * @version 1.2 - */ - -final class ServiceReg implements ServiceFactory { - - static boolean dontDisposeInstances = true; - - // tracking the instance usage and re-instantiation - private int useCount = 0; - private ComponentInstanceImpl instance; - - // model - private ServiceComponentProp scp; - - static { - String tmp = Activator.bc.getProperty("equinox.scr.dontDisposeInstances"); //$NON-NLS-1$ - dontDisposeInstances = (tmp != null) ? !tmp.equalsIgnoreCase("false") : true; //$NON-NLS-1$ - } - - ServiceReg(ServiceComponentProp scp, ComponentInstanceImpl instance) { - this.scp = scp; - this.instance = instance; - } - - // ServiceFactory.getService method. - public Object getService(Bundle bundle, ServiceRegistration registration) { - try { - if (instance == null) { - instance = InstanceProcess.staticRef.buildComponent(bundle, scp, null, false); - //instance could be null if the component is already disposed - if (instance == null) { - return null; - } - } - synchronized (this) { - useCount++; - } - if (Activator.DEBUG) { - Activator.log.debug("ServiceReg.getService(): service '" + scp.name + "' is used " + Integer.toString(useCount) + " time(s), object = " + instance.getInstance(), null); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ - } - return instance.getInstance(); - } catch (Exception e) { - if (!(e instanceof ComponentException)) { - Activator.log(null, LogService.LOG_ERROR, NLS.bind(Messages.CANNOT_CREATE_INSTANCE, scp.name), e); - return null; - } - throw (ComponentException) e; - } - } - - // ServiceFactory.ungetService method. - public void ungetService(Bundle bundle, ServiceRegistration registration, Object service) { - boolean shallDispose = false; - synchronized (this) { - useCount--; - if (useCount == 0) { - shallDispose = true; - } - } - if (shallDispose) { - if (!dontDisposeInstances && !scp.serviceComponent.immediate) { - //dispose instance only if disposing is allowed and the component is not immediate one. - - //Immediate components are custom case - according to me, their instances should not be disposed - // because they are probably needed during the whole component's life - if (Activator.DEBUG) { - Activator.log.debug("ServiceReg.ungetService(): service '" + scp.name + "' no longer used, disposing object = " + service, null); //$NON-NLS-1$ //$NON-NLS-2$ - } - // dispose only the instance - don't dispose the component - // itself! - scp.disposeObj(service, ComponentConstants.DEACTIVATION_REASON_UNSPECIFIED); - // delete the instance so it can be garbage collected! - instance = null; - } else { - if (Activator.DEBUG) { - Activator.log.debug("ServiceReg.ungetService(): service '" + scp.name + "' is used " + Integer.toString(useCount) + " time(s)", null); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ - } - } - } else { - if (useCount < 0) { - Activator.log(null, LogService.LOG_WARNING, "ServiceReg.ungetService(): " + NLS.bind(Messages.SERVICE_USAGE_COUNT, scp.name, Integer.toString(useCount)), new Exception("Debug callstack")); //$NON-NLS-1$ //$NON-NLS-2$ - } else if (Activator.DEBUG) { - Activator.log.debug("ServiceReg.ungetService(): service '" + scp.name + "' is used " + Integer.toString(useCount) + " time(s)", null); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ - } - } - } - - /* - * (non-Javadoc) - * - * @see java.lang.Object#toString() - */ - public String toString() { - return scp.name + " Service Registration"; //$NON-NLS-1$ - } -} diff --git a/bundles/org.eclipse.equinox.ds/src/org/eclipse/equinox/internal/ds/WorkPerformer.java b/bundles/org.eclipse.equinox.ds/src/org/eclipse/equinox/internal/ds/WorkPerformer.java deleted file mode 100644 index 0a1791b47..000000000 --- a/bundles/org.eclipse.equinox.ds/src/org/eclipse/equinox/internal/ds/WorkPerformer.java +++ /dev/null @@ -1,37 +0,0 @@ -/******************************************************************************* - * Copyright (c) 1997, 2008 by ProSyst Software GmbH - * http://www.prosyst.com - * 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: - * ProSyst Software GmbH - initial API and implementation - *******************************************************************************/ -package org.eclipse.equinox.internal.ds; - -/** - * The WorkPerformer interface contains a method that is called by a queue to - * perform certain work. - * - * @author Pavlin Dobrev - * @version 1.0 - */ - -public interface WorkPerformer { - - /** - * This method can then complete processing work on the work queue thread. - * - *

- * The job queue will ignore any Throwable thrown by this method in order to - * continue proper dispatching the next work items. - * - * @param actionId - * Action ID of the work type which has to be done. - * @param dataToProcess - * The data which has to be processed - */ - public void performWork(int actionId, Object dataToProcess); -} diff --git a/bundles/org.eclipse.equinox.ds/src/org/eclipse/equinox/internal/ds/WorkThread.java b/bundles/org.eclipse.equinox.ds/src/org/eclipse/equinox/internal/ds/WorkThread.java deleted file mode 100644 index ea50ef3e0..000000000 --- a/bundles/org.eclipse.equinox.ds/src/org/eclipse/equinox/internal/ds/WorkThread.java +++ /dev/null @@ -1,111 +0,0 @@ -/******************************************************************************* - * Copyright (c) 1997, 2010 by ProSyst Software GmbH - * http://www.prosyst.com - * 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: - * ProSyst Software GmbH - initial API and implementation - *******************************************************************************/ -package org.eclipse.equinox.internal.ds; - -import org.eclipse.equinox.internal.util.event.Queue; -import org.eclipse.equinox.internal.util.ref.TimerRef; -import org.eclipse.equinox.internal.util.timer.TimerListener; -import org.eclipse.osgi.util.NLS; -import org.osgi.service.cm.ConfigurationEvent; -import org.osgi.service.log.LogService; - -/** - * @author Stoyan Boshev - * @author Pavlin Dobrev - */ - -public class WorkThread implements Runnable, TimerListener { - - public static int IDLE_TIMEOUT = 1000; - public static int BLOCK_TIMEOUT = 30000; - private SCRManager mgr; - private Object objectToProcess; - boolean running = true; - Thread processingThread; - - int waiting = 0; - - public WorkThread(SCRManager mgr) { - this.mgr = mgr; - } - - /** - * While the event queue has elements - they are processed, i.e. - * ManagedService(Factories) are informed for the event. - */ - public void run() { - processingThread = Thread.currentThread(); - do { - try { - Queue queue = mgr.queue; - synchronized (queue) { - if (mgr.stopped) { - mgr.running = false; - break; - } - if (Activator.DEBUG) { - Activator.log.debug("WorkThread.run()", null); //$NON-NLS-1$ - } - if (queue.size() == 0) { // wait for more events - try { - waiting++; - queue.wait(IDLE_TIMEOUT); - } catch (Exception ignore) { - //ignore - } - waiting--; - if (mgr.stopped || queue.size() == 0) { - mgr.running = false; - break; - } - } - objectToProcess = queue.get(); - - if (objectToProcess != null) { - if (Activator.DEBUG) { - Activator.log.debug("WorkThread.run(): object to process " + objectToProcess.toString(), null); //$NON-NLS-1$ - } - } else { - continue; - } - } - if (TimerRef.timer != null) { - TimerRef.notifyAfter(this, BLOCK_TIMEOUT, 1); - } else { - if (Activator.DEBUG) { - Activator.log.debug("[SCR] WorkThread.run(): Timer service is not available! Skipping timeout check", null); //$NON-NLS-1$ - } - } - if (objectToProcess instanceof SCRManager.QueuedJob) { - ((SCRManager.QueuedJob) objectToProcess).dispatch(); - } else if (objectToProcess instanceof ConfigurationEvent) { - mgr.processConfigurationEvent((ConfigurationEvent) objectToProcess); - } - } catch (Throwable t) { - // just for any case. Must not happen in order to keep thread alive - Activator.log(null, LogService.LOG_ERROR, Messages.UNEXPECTED_EXCEPTION, t); - } finally { - TimerRef.removeListener(this, 1); - } - } while (running); - objectToProcess = null; - processingThread = null; - } - - public void timer(int event) { - Activator.log(null, LogService.LOG_WARNING, NLS.bind(Messages.TIMEOUT_PROCESSING, objectToProcess), null); - running = false; - objectToProcess = null; - mgr.queueBlocked(); - } - -} diff --git a/bundles/org.eclipse.equinox.ds/src/org/eclipse/equinox/internal/ds/impl/ComponentContextImpl.java b/bundles/org.eclipse.equinox.ds/src/org/eclipse/equinox/internal/ds/impl/ComponentContextImpl.java deleted file mode 100644 index 586204202..000000000 --- a/bundles/org.eclipse.equinox.ds/src/org/eclipse/equinox/internal/ds/impl/ComponentContextImpl.java +++ /dev/null @@ -1,328 +0,0 @@ -/******************************************************************************* - * Copyright (c) 1997-2011 by ProSyst Software GmbH - * http://www.prosyst.com - * 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: - * ProSyst Software GmbH - initial API and implementation - * Joerg-Christian Boehme - bug.id = 246757 - *******************************************************************************/ -package org.eclipse.equinox.internal.ds.impl; - -import java.util.Dictionary; -import java.util.Vector; -import org.eclipse.equinox.internal.ds.*; -import org.eclipse.equinox.internal.ds.model.*; -import org.eclipse.osgi.util.NLS; -import org.osgi.framework.*; -import org.osgi.service.component.*; - -/** - * ComponentContextImpl.java - * - * @author Valentin Valchev, Nina Ruseva - * @author Stoyan Boshev - * @author Pavlin Dobrev - */ - -public class ComponentContextImpl implements ComponentContext { - - /* ComponentInstance instance */ - private ComponentInstanceImpl componentInstance; - /* ComponentDescription */ - private ServiceComponentProp scp; - - private Bundle usingBundle; - - private SCRManager mgr; - - public ComponentContextImpl(ServiceComponentProp scp, Bundle usingBundle, ComponentInstanceImpl ci, SCRManager mgr) { - this.scp = scp; - this.componentInstance = ci; - this.usingBundle = usingBundle; - this.mgr = mgr; - } - - /* - * (non-Javadoc) - * - * @see org.osgi.service.component.ComponentContext#getProperties() - */ - public Dictionary getProperties() { - return scp.getProperties(); - } - - /* - * (non-Javadoc) Returns the service object for the specified service - * reference name. - * - * @param name The name of a service reference as specified in a reference - * element in this component's description. @return A service object for the - * referenced service or null if the reference cardinality is - * 0..1 or 0..n and no matching service is - * available. @throws ComponentException If the Service Component Runtime - * catches an exception while activating the target service. - * - * @see org.osgi.service.component.ComponentContext#locateService(java.lang.String) - */ - public Object locateService(String name) { - if (scp.references == null) { - return null; - } - if (Activator.DEBUG) { - Activator.log.debug("ComponentContextImpl.locateService(): " + name, null); //$NON-NLS-1$ - } - Vector references = scp.references; - for (int i = 0; i < references.size(); i++) { - Reference reference = (Reference) references.elementAt(i); - ComponentReference ref = reference.reference; - - // find the Reference Description with the specified name - if (ref.name.equals(name)) { - ServiceReference serviceReference = null; - synchronized (ref.serviceReferences) { - if (ref.serviceReferences.size() == 1) { - //in case of there is only one bound service (or the reference is unary) - serviceReference = (ServiceReference) ref.serviceReferences.keys().nextElement(); - } - } - try { - if (serviceReference == null) { - Vector boundServiceReferences = reference.getBoundServiceReferences(); - if (reference.isUnary() && boundServiceReferences.size() > 0) { - //get the bound service reference for the unary reference - serviceReference = (ServiceReference) boundServiceReferences.elementAt(0); - } - if (serviceReference == null) { - // try to find service in the FW - ServiceReference[] serviceReferences = scp.bc.getServiceReferences(ref.interfaceName, reference.getTarget()); - if (serviceReferences != null && serviceReferences.length > 0) { - // the services references are sorted by - // service.reference and service.id - // so get the first one in the list - serviceReference = serviceReferences[0]; - } - } - } - if (serviceReference != null) { - return getBoundService(reference, serviceReference); - } - } catch (Throwable t) { - if (t instanceof ComponentException) { - throw (ComponentException) t; - } - throw new ComponentException(NLS.bind(Messages.EXCEPTION_LOCATING_SERVICE, name), t); - } - if (Activator.DEBUG) { - Activator.log.debug("ComponentContextImpl.locateService(): error, service not found - " + ref.interfaceName + "; the comp. context belongs to " + scp.name, null); //$NON-NLS-1$ //$NON-NLS-2$ - } - } - } - return null; - } - - /* - * Returns the service objects for the specified service reference name. - * - * @param name The name of a service reference as specified in a reference - * element in this component's description. @return An array of service - * objects for the referenced service or null if the - * reference cardinality is 0..1 or 0..n and - * no matching service is available. - * - * @throws ComponentException If the Service Component Runtime catches an - * exception while activating a target service. - * - * @see org.osgi.service.component.ComponentContext#locateServices(java.lang.String) - */ - public Object[] locateServices(String name) { - if (scp.references == null) { - return null; - } - - if (Activator.DEBUG) { - Activator.log.debug("ComponentContextImpl.locateServices(): " + name, null); //$NON-NLS-1$ - } - Vector references = scp.references; - for (int i = 0; i < references.size(); i++) { - Reference reference = (Reference) references.elementAt(i); - ComponentReference ref = reference.reference; - - if (ref.name.equals(name)) { - ServiceReference[] serviceReferences = null; - try { - if (reference.isUnary()) { - ServiceReference serviceReference = null; - synchronized (ref.serviceReferences) { - if (ref.serviceReferences.size() > 0) { - //in case the reference is unary - serviceReference = (ServiceReference) ref.serviceReferences.keys().nextElement(); - } - } - if (serviceReference == null) { - Vector boundServiceReferences = reference.getBoundServiceReferences(); - if (boundServiceReferences.size() > 0) { - //get the bound service reference for the unary reference - serviceReference = (ServiceReference) boundServiceReferences.elementAt(0); - } - } - if (serviceReference != null) { - Object result = getBoundService(reference, serviceReference); - if (result != null) { - return new Object[] {result}; - } - } - } - serviceReferences = scp.bc.getServiceReferences(ref.interfaceName, reference.getTarget()); - if (serviceReferences != null) { - Vector theServices = new Vector(5); - Object service; - for (int j = 0; j < serviceReferences.length; j++) { - service = getBoundService(reference, serviceReferences[j]); - if (service != null) { - theServices.addElement(service); - } - } - if (!theServices.isEmpty()) { - return theServices.toArray(); - } - } - } catch (Throwable t) { - if (t instanceof ComponentException) { - throw (ComponentException) t; - } - throw new ComponentException(NLS.bind(Messages.EXCEPTION_LOCATING_SERVICES, name), t); - } - } - } - return null; - } - - /* - * (non-Javadoc) - * - * @see org.osgi.service.component.ComponentContext#locateService(String - * name, ServiceReference reference) - */ - public Object locateService(String name, ServiceReference serviceReference) { - if (scp.references == null) { - return null; - } - if (Activator.DEBUG) { - Activator.log.debug("ComponentContextImpl.locateService(): " + name + " by service reference : " + serviceReference, null); //$NON-NLS-1$ //$NON-NLS-2$ - } - Vector references = scp.references; - try { - for (int i = 0; i < references.size(); i++) { - Reference reference = (Reference) references.elementAt(i); - ComponentReference ref = reference.reference; - - if (ref.name.equals(name)) { - if (serviceReference == null || !ref.serviceReferences.containsKey(serviceReference)) { - // the serviceReference is not bound to the specified - // reference - if (Activator.DEBUG) { - String referenceToString = (serviceReference == null) ? null : serviceReference.toString(); - Activator.log.debug("ComponentContextImpl.locateService(): the specified service reference is not bound to the specified reference" + referenceToString, null); //$NON-NLS-1$ - } - return null; - } - return getBoundService(reference, serviceReference); - } - } - } catch (Throwable t) { - if (t instanceof ComponentException) { - throw (ComponentException) t; - } - throw new ComponentException(NLS.bind(Messages.EXCEPTION_LOCATING_SERVICE, name), t); - } - return null; - } - - private Object getBoundService(Reference reference, ServiceReference theServiceReference) { - Object result = componentInstance.bindedServices.get(theServiceReference); - if (result != null) { - // will skip the circularity checking in InstanceProcess.getService - return result; - } - result = InstanceProcess.staticRef.getService(reference, theServiceReference); - // the service object could be null because of circularity - if (result != null) { - componentInstance.bindedServices.put(theServiceReference, result); - return result; - } - return null; - } - - /* - * (non-Javadoc) - * - * @see org.osgi.service.component.ComponentContext#getBundleContext() - */ - public BundleContext getBundleContext() { - return scp.bc; - } - - /* - * (non-Javadoc) - * - * @see org.osgi.service.component.ComponentContext#getUsingBundle() - */ - public Bundle getUsingBundle() { - // this is only for service factories! - ServiceComponent componentDescription = scp.serviceComponent; - if ((componentDescription.provides == null) || (!componentDescription.serviceFactory)) { - return null; - } - return usingBundle; - } - - /* - * (non-Javadoc) - * - * @see org.osgi.service.component.ComponentContext#getComponentInstance() - */ - public ComponentInstance getComponentInstance() { - return componentInstance; - } - - /* - * (non-Javadoc) - * - * @see org.osgi.service.component.ComponentContext#enableComponent(java.lang.String) - */ - public void enableComponent(String name) { - mgr.enableComponent(name, scp.bc.getBundle()); - } - - /* - * (non-Javadoc) - * - * @see org.osgi.service.component.ComponentContext#disableComponent(java.lang.String) - */ - public void disableComponent(String name) { - if (name == null) { - throw new IllegalArgumentException(Messages.COMPONENT_NAME_IS_NULL); - } - mgr.disableComponent(name, scp.bc.getBundle()); - } - - /* - * (non-Javadoc) - * - * @see org.osgi.service.component.ComponentContext#getServiceReference() - */ - public ServiceReference getServiceReference() { - if (scp.serviceComponent.provides != null) { - ServiceRegistration reg = scp.registration; - if (reg != null) { - return reg.getReference(); - } - } - return null; - } - -} diff --git a/bundles/org.eclipse.equinox.ds/src/org/eclipse/equinox/internal/ds/impl/ComponentFactoryImpl.java b/bundles/org.eclipse.equinox.ds/src/org/eclipse/equinox/internal/ds/impl/ComponentFactoryImpl.java deleted file mode 100644 index 9a3d8e2b3..000000000 --- a/bundles/org.eclipse.equinox.ds/src/org/eclipse/equinox/internal/ds/impl/ComponentFactoryImpl.java +++ /dev/null @@ -1,117 +0,0 @@ -/******************************************************************************* - * Copyright (c) 1997-2011 by ProSyst Software GmbH - * http://www.prosyst.com - * 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: - * ProSyst Software GmbH - initial API and implementation - *******************************************************************************/ -package org.eclipse.equinox.internal.ds.impl; - -import java.util.*; -import org.apache.felix.scr.Component; -import org.eclipse.equinox.internal.ds.*; -import org.eclipse.equinox.internal.ds.model.ServiceComponentProp; -import org.osgi.service.component.*; -import org.osgi.service.log.LogService; - -/** - * ComponentFactoryImpl.java - * - * @author Valentin Valchev - * @author Stoyan Boshev - * @author Pavlin Dobrev - */ - -public class ComponentFactoryImpl implements ComponentFactory { - - private ServiceComponentProp sci; - - /** - * ComponentFactoryImpl - * - * @param component - * the ComponentDescription Object with Properties - */ - public ComponentFactoryImpl(ServiceComponentProp component) { - this.sci = component; - } - - /** - * Create a new instance of the component. Additional properties may be - * provided for the component instance. - * - * @param additionalProps - * Additional properties for the component instance. - * @return A ComponentInstance object encapsulating the component instance. - * The returned component instance has been activated. - */ - public ComponentInstance newInstance(Dictionary additionalProps) { - ComponentInstanceImpl instance = null; - ServiceComponentProp newSCP = null; - try { - if (Activator.DEBUG) { - Activator.log.debug("ComponentFactoryImpl.newInstance(): " + sci.name, null); //$NON-NLS-1$ - } - - // merge properties - Hashtable props = new Hashtable((Map) sci.getProperties()); - SCRUtil.copyTo(props, additionalProps); - - // create a new SCP (adds to resolver scpEnabled list) - newSCP = InstanceProcess.resolver.mapNewFactoryComponent(sci.serviceComponent, props); - - // register the component and make instance if immediate - Vector toBuild = new Vector(1); - toBuild.addElement(newSCP); - InstanceProcess.staticRef.buildComponents(toBuild, Activator.security); - if (!newSCP.instances.isEmpty()) { - // an instance was built because the component is either - // immediate - // or someone has got it as service (if provides one) - instance = (ComponentInstanceImpl) newSCP.instances.firstElement(); - } - if (instance == null && !newSCP.isImmediate()) { - // finally build an instance if not done yet - instance = InstanceProcess.staticRef.buildComponent(null, newSCP, null, Activator.security); - } - if (instance == null) { - //the instance could not be build because the component cannot be activated - //throw exception to notify the user - throw new ComponentException(Messages.COULD_NOT_CREATE_NEW_INSTANCE); - } - } catch (Throwable e) { - //remove the component configuration - if (newSCP != null) { - disposeSCP(newSCP); - } - if (e instanceof ComponentException) { - throw (ComponentException) e; - } - Activator.log(null, LogService.LOG_ERROR, "ComponentFactoryImpl.newInstance(): failed for " + sci.name + " with properties " + additionalProps, e); //$NON-NLS-1$ //$NON-NLS-2$ - throw new ComponentException(Messages.COULD_NOT_CREATE_NEW_INSTANCE, e); - } - return instance; - } - - private void disposeSCP(ServiceComponentProp scp) { - scp.serviceComponent.componentProps.removeElement(scp); - Vector toDispose = new Vector(1); - toDispose.addElement(scp); - InstanceProcess.resolver.disposeComponentConfigs(toDispose, ComponentConstants.DEACTIVATION_REASON_UNSPECIFIED); - scp.setState(Component.STATE_DISPOSED); - } - - /* - * (non-Javadoc) - * - * @see java.lang.Object#toString() - */ - public String toString() { - return "ComponentFactory for " + sci.name; //$NON-NLS-1$ - } - -} diff --git a/bundles/org.eclipse.equinox.ds/src/org/eclipse/equinox/internal/ds/impl/ComponentInstanceImpl.java b/bundles/org.eclipse.equinox.ds/src/org/eclipse/equinox/internal/ds/impl/ComponentInstanceImpl.java deleted file mode 100644 index fbd3b02ac..000000000 --- a/bundles/org.eclipse.equinox.ds/src/org/eclipse/equinox/internal/ds/impl/ComponentInstanceImpl.java +++ /dev/null @@ -1,107 +0,0 @@ -/******************************************************************************* - * Copyright (c) 1997, 2010 by ProSyst Software GmbH - * http://www.prosyst.com - * 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: - * ProSyst Software GmbH - initial API and implementation - *******************************************************************************/ -package org.eclipse.equinox.internal.ds.impl; - -import java.util.*; -import org.apache.felix.scr.Component; -import org.eclipse.equinox.internal.ds.Activator; -import org.eclipse.equinox.internal.ds.InstanceProcess; -import org.eclipse.equinox.internal.ds.model.ServiceComponentProp; -import org.osgi.framework.ServiceReference; -import org.osgi.service.component.*; - -/** - * ComponentInstanceImpl.java - * - * @author Valentin Valchev - * @author Stoyan Boshev - * @author Pavlin Dobrev - */ - -public class ComponentInstanceImpl implements ComponentInstance { - - private Object instance; - private ServiceComponentProp scp; - private ComponentContext componentContext; - - // ServiceReference to service objects which are binded to this instance - public Hashtable bindedServices = new Hashtable(11); - - public ComponentInstanceImpl(Object instance, ServiceComponentProp scp) { - this.instance = instance; - this.scp = scp; - } - - /* - * (non-Javadoc) - * - * @see org.osgi.service.component.ComponentInstance#dispose() - */ - public void dispose() { - if (scp == null) { - // already disposed! - return; - } - if (Activator.DEBUG) { - Activator.log.debug("ComponentInstanceImpl.dispose(): disposing instance of component " + scp.name, null); //$NON-NLS-1$ - } - if (!scp.isComponentFactory() && scp.serviceComponent.factory != null) { - // this is a component factory instance, so dispose SCP - scp.serviceComponent.componentProps.removeElement(scp); - Vector toDispose = new Vector(1); - toDispose.addElement(scp); - InstanceProcess.resolver.disposeComponentConfigs(toDispose, ComponentConstants.DEACTIVATION_REASON_DISPOSED); - if (scp != null) { - scp.setState(Component.STATE_DISPOSED); - } - } else { - scp.dispose(this, ComponentConstants.DEACTIVATION_REASON_DISPOSED); - } - - // free service references if some are left ungotten - freeServiceReferences(); - scp = null; - componentContext = null; - instance = null; - } - - // check whether some cached service references are not yet removed and - // ungotten - public void freeServiceReferences() { - if (!bindedServices.isEmpty()) { - Enumeration keys = bindedServices.keys(); - while (keys.hasMoreElements()) { - ServiceReference reference = (ServiceReference) keys.nextElement(); - bindedServices.remove(reference); - scp.bc.ungetService(reference); - } - } - } - - /* - * (non-Javadoc) - * - * @see org.osgi.service.component.ComponentInstance#getInstance() - */ - public Object getInstance() { - return instance; - } - - public ComponentContext getComponentContext() { - return componentContext; - } - - public void setComponentContext(ComponentContext componentContext) { - this.componentContext = componentContext; - } - -} diff --git a/bundles/org.eclipse.equinox.ds/src/org/eclipse/equinox/internal/ds/impl/ReadOnlyDictionary.java b/bundles/org.eclipse.equinox.ds/src/org/eclipse/equinox/internal/ds/impl/ReadOnlyDictionary.java deleted file mode 100644 index 624bbbe46..000000000 --- a/bundles/org.eclipse.equinox.ds/src/org/eclipse/equinox/internal/ds/impl/ReadOnlyDictionary.java +++ /dev/null @@ -1,139 +0,0 @@ -/******************************************************************************* - * Copyright (c) 1997-2011 by ProSyst Software GmbH - * http://www.prosyst.com - * 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: - * ProSyst Software GmbH - initial API and implementation - *******************************************************************************/ -package org.eclipse.equinox.internal.ds.impl; - -import java.util.*; - -/** - * This is an utility class to provide a read-only dictionary. - * - * @author Stoyan Boshev - */ -public class ReadOnlyDictionary extends Dictionary implements Map { - - Map delegate; - - /** - * Creates a new ReadOnlyDictionary with initial set of properties - * - * @param initialProps the initialProperties for this dictionary - */ - public ReadOnlyDictionary(Map initialProps) { - this.delegate = initialProps != null ? initialProps : Collections.EMPTY_MAP; - } - - public void updateDelegate(Map newDelegate) { - this.delegate = newDelegate != null ? newDelegate : Collections.EMPTY_MAP; - } - - /* (non-Javadoc) - * @see java.util.Dictionary#put(K, V) - */ - public Object put(Object key, Object value) { - // do not modify - this is read only - throw new UnsupportedOperationException(); - } - - /* (non-Javadoc) - * @see java.util.Dictionary#remove(java.lang.Object) - */ - public Object remove(Object key) { - // do not modify - this is read only - throw new UnsupportedOperationException(); - } - - /* (non-Javadoc) - * @see java.util.Dictionary#size() - */ - public int size() { - return delegate.size(); - } - - /* (non-Javadoc) - * @see java.util.Dictionary#isEmpty() - */ - public boolean isEmpty() { - return delegate.isEmpty(); - } - - /* (non-Javadoc) - * @see java.util.Dictionary#keys() - */ - public Enumeration keys() { - return Collections.enumeration(delegate.keySet()); - } - - /* (non-Javadoc) - * @see java.util.Dictionary#elements() - */ - public Enumeration elements() { - return Collections.enumeration(delegate.values()); - } - - /* (non-Javadoc) - * @see java.util.Dictionary#get(java.lang.Object) - */ - public Object get(Object key) { - return delegate.get(key); - } - - /* (non-Javadoc) - * @see java.util.Map#containsKey(java.lang.Object) - */ - public boolean containsKey(Object key) { - return delegate.containsKey(key); - } - - /* (non-Javadoc) - * @see java.util.Map#containsValue(java.lang.Object) - */ - public boolean containsValue(Object value) { - return delegate.containsValue(value); - } - - /* (non-Javadoc) - * @see java.util.Map#clear() - */ - public void clear() { - // do not modify - this is read only - throw new UnsupportedOperationException(); - } - - /* (non-Javadoc) - * @see java.util.Map#putAll(java.util.Map) - */ - public void putAll(Map arg0) { - // do not modify - this is read only - throw new UnsupportedOperationException(); - } - - /* (non-Javadoc) - * @see java.util.Map#values() - */ - public Collection values() { - return Collections.unmodifiableCollection(delegate.values()); - } - - /* (non-Javadoc) - * @see java.util.Map#keySet() - */ - public Set keySet() { - return Collections.unmodifiableSet(delegate.keySet()); - } - - /* (non-Javadoc) - * @see java.util.Map#entrySet() - */ - public Set entrySet() { - return Collections.unmodifiableSet(delegate.entrySet()); - } -} diff --git a/bundles/org.eclipse.equinox.ds/src/org/eclipse/equinox/internal/ds/model/ComponentReference.java b/bundles/org.eclipse.equinox.ds/src/org/eclipse/equinox/internal/ds/model/ComponentReference.java deleted file mode 100644 index 7e0395783..000000000 --- a/bundles/org.eclipse.equinox.ds/src/org/eclipse/equinox/internal/ds/model/ComponentReference.java +++ /dev/null @@ -1,800 +0,0 @@ -/******************************************************************************* - * Copyright (c) 1997-2010 by ProSyst Software GmbH - * http://www.prosyst.com - * 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: - * ProSyst Software GmbH - initial API and implementation - * Jeremy Volkman - bug.id = 182560 - * Simon Archer - bug.id = 223454 - * Lazar Kirchev - bug.id = 320377 - *******************************************************************************/ -package org.eclipse.equinox.internal.ds.model; - -import java.io.*; -import java.lang.reflect.*; -import java.util.*; -import org.eclipse.equinox.internal.ds.*; -import org.eclipse.equinox.internal.ds.impl.ComponentInstanceImpl; -import org.eclipse.equinox.internal.util.io.Externalizable; -import org.eclipse.osgi.util.NLS; -import org.osgi.framework.InvalidSyntaxException; -import org.osgi.framework.ServiceReference; -import org.osgi.service.component.ComponentInstance; -import org.osgi.service.log.LogService; - -/** - * @author Stoyan Boshev - * @author Pavlin Dobrev - */ -public class ComponentReference implements Externalizable, org.apache.felix.scr.Reference { - - public static final int CARDINALITY_0_1 = 0; - public static final int CARDINALITY_0_N = 1; - public static final int CARDINALITY_1_1 = 2; - public static final int CARDINALITY_1_N = 3; - public static final int POLICY_STATIC = 0; - public static final int POLICY_DYNAMIC = 1; - - public static final int POLICY_OPTION_RELUCTANT = 0; // default - public static final int POLICY_OPTION_GREEDY = 1; - - // --- begin: XML def - public String name; - public String interfaceName; // required - public int cardinality = CARDINALITY_1_1; - public int policy = POLICY_STATIC; - public String target; - public String bind; - public String unbind; - //defined by DS specification v1.2 - schema v1.2.0 - public String updated; - public int policy_option = POLICY_OPTION_RELUCTANT; - // --- end: XML def - public ServiceComponent component; - - // --- begin: cache - private boolean bindCached; - private boolean unbindCached; - private boolean updatedCached; - Method bindMethod; - Method unbindMethod; - Method updatedMethod; - // --- end: cache - - // --- begin: model - - // Contains mapping of ServiceReference to ComponentInstance or Vector of ComponentInstances. - // The service reference is bound to the ComponentInstance or to each of the ComponentInstances in the Vector - public Hashtable serviceReferences = new Hashtable(3); - - // avoids recursive calling of unbind method for one and the same instance - private Hashtable serviceReferencesToUnbind = new Hashtable(3); - - static final Class[] SERVICE_REFERENCE = new Class[] {ServiceReference.class}; - - // --- end: model; - - ComponentReference(ServiceComponent component) { - this.component = component; - if (this.component.references == null) { - this.component.references = new Vector(2); - } - this.component.references.addElement(this); - } - - Method getMethod(ComponentInstanceImpl componentInstance, Reference reference, String methodName, ServiceReference serviceReference) { - - Class consumerClass = componentInstance.getInstance().getClass(); - Object serviceObject = null; - Class serviceObjectClass = null; - Class interfaceClass = null; - Class[] param_interfaceClass = null; - Method method = null; - while (consumerClass != null) { - - // search this class' methods - // look for various forms of bind methods - - // 1) check for bind(ServiceReference) method - try { - method = consumerClass.getDeclaredMethod(methodName, SERVICE_REFERENCE); - } catch (NoSuchMethodException e) { - // - } catch (NoClassDefFoundError err) { - // this may happen on skelmir VM or in case of class loading problems - logWarning(NLS.bind(Messages.EXCEPTION_GETTING_METHOD, methodName, consumerClass.getName()), err, reference); - } - - if (method != null && SCRUtil.checkMethodAccess(componentInstance.getInstance().getClass(), consumerClass, method, component.isNamespaceAtLeast11())) - break; - - // we need a serviceObject to keep looking, create one if necessary - if (serviceObject == null) { - serviceObject = componentInstance.bindedServices.get(serviceReference); - if (serviceObject == null) { - serviceObject = InstanceProcess.staticRef.getService(reference, serviceReference); - } - if (serviceObject == null) { - // we could not create a serviceObject because of circularity or the BundleContext.getService(ServiceReference) returned null - logWarning(Messages.CANT_GET_SERVICE_OBJECT, null, reference); - return null; - } - componentInstance.bindedServices.put(serviceReference, serviceObject); - serviceObjectClass = serviceObject.getClass(); - - // figure out the interface class - this is guaranteed to succeed or else - // the framework would not have let us have the service object - Class searchForInterfaceClass = serviceObjectClass; - while (searchForInterfaceClass != null) { - // first look through interfaces - Class[] interfaceClasses = searchForInterfaceClass.getInterfaces(); - for (int i = 0; i < interfaceClasses.length; i++) { - if (interfaceClasses[i].getName().equals(interfaceName)) { - interfaceClass = interfaceClasses[i]; - break; - } - } - if (interfaceClass != null) { - break; - } - - // also check the class itself - if (searchForInterfaceClass.getName().equals(interfaceName)) { - interfaceClass = searchForInterfaceClass; - break; - } - - // advance up the superclasses - searchForInterfaceClass = searchForInterfaceClass.getSuperclass(); - } - - param_interfaceClass = new Class[] {interfaceClass}; - - } // end if(serviceObject == null) - - // 2) check for bind(Service interface) method - try { - method = consumerClass.getDeclaredMethod(methodName, param_interfaceClass); - } catch (NoSuchMethodException e) { - // - } catch (NoClassDefFoundError err) { - // this may happen on skelmir VM or in case of class loading problems - logWarning(NLS.bind(Messages.EXCEPTION_GETTING_METHOD, methodName, consumerClass.getName()), err, reference); - } - if (method != null && SCRUtil.checkMethodAccess(componentInstance.getInstance().getClass(), consumerClass, method, component.isNamespaceAtLeast11())) - break; - - // 3) check for bind(class.isAssignableFrom(serviceObjectClass)) - // method - Method[] methods = consumerClass.getDeclaredMethods(); - for (int i = 0; i < methods.length; i++) { - Class[] params = methods[i].getParameterTypes(); - if (params.length == 1 && methods[i].getName().equals(methodName) && params[0].isAssignableFrom(serviceObjectClass)) { - - method = methods[i]; - break; - } - } - if (method != null && SCRUtil.checkMethodAccess(componentInstance.getInstance().getClass(), consumerClass, method, component.isNamespaceAtLeast11())) - break; - - //implement search for bind/unbind methods according to schema v1.1.0 - if (component.isNamespaceAtLeast11()) { - for (int i = 0; i < methods.length; i++) { - Class[] params = methods[i].getParameterTypes(); - if (params.length == 2 && methods[i].getName().equals(methodName) && params[0] == interfaceClass && params[1] == Map.class) { - method = methods[i]; - break; - } - } - if (method != null && SCRUtil.checkMethodAccess(componentInstance.getInstance().getClass(), consumerClass, method, true)) - break; - - for (int i = 0; i < methods.length; i++) { - Class[] params = methods[i].getParameterTypes(); - if (params.length == 2 && methods[i].getName().equals(methodName) && params[0].isAssignableFrom(serviceObjectClass) && params[1] == Map.class) { - method = methods[i]; - break; - } - } - } - if (method != null) - break; - - // we couldn't find the method - try the superclass - consumerClass = consumerClass.getSuperclass(); - } - - if (method == null) { - logMethodNotFoundError(componentInstance, reference, methodName); - return null; - } - - if (!SCRUtil.checkMethodAccess(componentInstance.getInstance().getClass(), consumerClass, method, component.isNamespaceAtLeast11())) { - // if method is not visible, log error message - logMethodNotVisible(componentInstance, reference, methodName, method.getParameterTypes()); - return null; - } - - int modifier = method.getModifiers(); - if (!Modifier.isPublic(modifier)) { - SCRUtil.setAccessible(method); - } - - return method; - } - - private void logMethodNotVisible(ComponentInstanceImpl componentInstance, Reference reference, String methodName, Class[] param_interfaceClasses) { - StringBuffer buffer = createBuffer(); - buffer.append("[SCR] Method "); //$NON-NLS-1$ - buffer.append(methodName); - buffer.append('('); - for (int i = 0; i < param_interfaceClasses.length; i++) { - buffer.append(param_interfaceClasses[i].getName()); - if (i < param_interfaceClasses.length - 1) { - buffer.append(','); - } - } - buffer.append(')'); - buffer.append(" is not accessible!"); //$NON-NLS-1$ - component.componentIssues.add("Method [" + methodName + "] is not accessible in " + componentInstance.getInstance().getClass()); - appendDetails(buffer, reference); - String message = buffer.toString(); - Activator.log(reference.reference.component.bc, LogService.LOG_ERROR, message, null); - } - - private void logMethodNotFoundError(ComponentInstanceImpl componentInstance, Reference reference, String methodName) { - StringBuffer buffer = createBuffer(); - buffer.append("[SCR] Method was not found: "); //$NON-NLS-1$ - buffer.append(methodName); - buffer.append('('); - buffer.append("..."); //$NON-NLS-1$ - buffer.append(')'); - component.componentIssues.add("Method [" + methodName + "] was not found in " + componentInstance.getInstance().getClass()); - appendDetails(buffer, reference); - String message = buffer.toString(); - Activator.log(reference.reference.component.bc, LogService.LOG_ERROR, message, null); - } - - private void appendDetails(StringBuffer buffer, Reference reference) { - try { - String indent = "\n\t"; //$NON-NLS-1$ - buffer.append(indent); - buffer.append("Details:"); //$NON-NLS-1$ - buffer.append(indent); - buffer.append("Problematic reference = " + reference.reference); //$NON-NLS-1$ - buffer.append(indent); - buffer.append("of service component = "); //$NON-NLS-1$ - buffer.append(reference.reference.component.name); - buffer.append(indent); - buffer.append("component implementation class = "); //$NON-NLS-1$ - buffer.append(reference.reference.component.implementation); - buffer.append(indent); - buffer.append("located in bundle with symbolic name = "); //$NON-NLS-1$ - buffer.append(component.bc.getBundle().getSymbolicName()); - buffer.append(indent); - buffer.append("bundle location = "); //$NON-NLS-1$ - buffer.append(component.bc.getBundle().getLocation()); - } catch (Throwable t) { - //prevent possible exceptions in case the component's bundle becomes uninstalled - } - } - - private void logWarning(String message, Throwable t, Reference reference) { - StringBuffer buffer = createBuffer(); - buffer.append(message); - appendDetails(buffer, reference); - Activator.log(reference.reference.component.bc, LogService.LOG_WARNING, buffer.toString(), t); - } - - private void logError(String message, Throwable t, Reference reference) { - StringBuffer buffer = createBuffer(); - buffer.append(message); - String cause = t.toString(); - if (t instanceof InvocationTargetException) { - cause = "The called method throws: " + t.getCause().toString(); - } - component.componentIssues.add(message + " Root Cause [" + cause + "]"); - appendDetails(buffer, reference); - Activator.log(reference.reference.component.bc, LogService.LOG_ERROR, buffer.toString(), t); - } - - private StringBuffer createBuffer() { - return new StringBuffer(400); - } - - final boolean bind(Reference reference, ComponentInstance instance, ServiceReference serviceReference) throws Exception { - if (bind != null) { - boolean bound = false; - // DON'T rebind the same object again - synchronized (serviceReferences) { - Vector instances = (Vector) serviceReferences.get(serviceReference); - if (instances == null) { - instances = new Vector(1); - instances.addElement(instance); - serviceReferences.put(serviceReference, instances); - } else if (instances.contains(instance)) { - if (reference.isUnary()) { - logWarning(NLS.bind(Messages.SERVICE_REFERENCE_ALREADY_BOUND, serviceReference, instance), null, reference); - } - return false; - } else { - instances.addElement(instance); - } - } - // retrieve the method from cache - if (!bindCached) { - bindMethod = getMethod((ComponentInstanceImpl) instance, reference, bind, serviceReference); - // bindMethod can be null in case of circularity - if (bindMethod != null) { - bindCached = true; - } - } - // invoke the method - if (bindMethod != null) { - Object methodParam = null; - Class[] paramTypes = bindMethod.getParameterTypes(); - if (paramTypes.length == 1 && paramTypes[0].equals(ServiceReference.class)) { - methodParam = serviceReference; - } else { - // bindedServices is filled by the getMethod function - methodParam = ((ComponentInstanceImpl) instance).bindedServices.get(serviceReference); - if (methodParam == null) { - methodParam = InstanceProcess.staticRef.getService(reference, serviceReference); - if (methodParam != null) { - ((ComponentInstanceImpl) instance).bindedServices.put(serviceReference, methodParam); - } - } - if (methodParam == null) { - // cannot get serviceObject because of circularity - - //remove the component instance marked as bound - removeServiceReference(serviceReference, instance); - return false; - } - } - - Object[] params = null; - if (paramTypes.length == 1) { - params = SCRUtil.getObjectArray(); - params[0] = methodParam; - } else { - //this is the case where we have 2 parameters: a service object and a Map, holding the service properties - HashMap map = new HashMap(); - String[] keys = serviceReference.getPropertyKeys(); - for (int i = 0; i < keys.length; i++) { - map.put(keys[i], serviceReference.getProperty(keys[i])); - } - params = new Object[] {methodParam, map}; - } - - try { - bindMethod.invoke(instance.getInstance(), params); - bound = true; - } catch (Throwable t) { - logError(NLS.bind(Messages.ERROR_BINDING_REFERENCE, this), t, reference); - //remove the component instance marked as bound - removeServiceReference(serviceReference, instance); - } finally { - if (params.length == 1) { - SCRUtil.release(params); - } - } - } else { - //remove the component instance marked as bound - removeServiceReference(serviceReference, instance); - // could be also circularity break - logWarning(NLS.bind(Messages.BIND_METHOD_NOT_FOUND_OR_NOT_ACCESSIBLE, bind), null, reference); - } - return bound; - } - return false; - } - - private void removeServiceReference(ServiceReference serviceReference, ComponentInstance instance) { - Vector instances = (Vector) serviceReferences.get(serviceReference); - instances.removeElement(instance); - if (instances.isEmpty()) { - serviceReferences.remove(serviceReference); - } - } - - public final void unbind(Reference reference, ComponentInstance instance, ServiceReference serviceReference) { - // don't unbind an object that wasn't bound - boolean referenceExists = true; - synchronized (serviceReferences) { - Vector instances = (Vector) serviceReferences.get(serviceReference); - if (instances == null) { - referenceExists = false; - } else { - if (!instances.contains(instance)) { - logWarning(NLS.bind(Messages.INSTANCE_NOT_BOUND, instance), null, reference); - return; - } - } - if (referenceExists) { - Vector instancesToUnbind = (Vector) serviceReferencesToUnbind.get(serviceReference); - if (instancesToUnbind != null && instancesToUnbind.contains(instance)) { - //the service reference is already in process of unbinding - return; - } - if (instancesToUnbind == null) { - instancesToUnbind = new Vector(1); - serviceReferencesToUnbind.put(serviceReference, instancesToUnbind); - } - instancesToUnbind.addElement(instance); - } - } - if (!referenceExists) { - logWarning(NLS.bind(Messages.INVALID_SERVICE_REFERENCE, serviceReference), null, reference); - return; - } - try { - if (unbind != null) { - // retrieve the unbind method from cache - if (!unbindCached) { - unbindCached = true; - unbindMethod = getMethod((ComponentInstanceImpl) instance, reference, unbind, serviceReference); - } - // invoke the method - if (unbindMethod != null) { - Object methodParam = null; - Class[] paramTypes = unbindMethod.getParameterTypes(); - if (paramTypes.length == 1 && paramTypes[0].equals(ServiceReference.class)) { - methodParam = serviceReference; - } else { - // bindedServices is filled by the getMethod function - methodParam = ((ComponentInstanceImpl) instance).bindedServices.get(serviceReference); - if (methodParam == null) { - methodParam = InstanceProcess.staticRef.getService(reference, serviceReference); - } - if (methodParam == null) { - // probably cannot get serviceObject because of - // circularity - return; - } - } - - Object[] params = null; - if (paramTypes.length == 1) { - params = SCRUtil.getObjectArray(); - params[0] = methodParam; - } else { - //this is the case where we have 2 parameters: a service object and a Map, holding the service properties - HashMap map = new HashMap(); - String[] keys = serviceReference.getPropertyKeys(); - for (int i = 0; i < keys.length; i++) { - map.put(keys[i], serviceReference.getProperty(keys[i])); - } - params = new Object[] {methodParam, map}; - } - try { - unbindMethod.invoke(instance.getInstance(), params); - } catch (Throwable t) { - logError(NLS.bind(Messages.EXCEPTION_UNBINDING_REFERENCE, this), t, reference); - } finally { - if (params.length == 1) { - SCRUtil.release(params); - } - } - } - } - } finally { - synchronized (serviceReferences) { - Vector instances = (Vector) serviceReferences.get(serviceReference); - instances.removeElement(instance); - if (instances.isEmpty()) { - serviceReferences.remove(serviceReference); - } - - instances = (Vector) serviceReferencesToUnbind.get(serviceReference); - instances.removeElement(instance); - if (instances.isEmpty()) { - serviceReferencesToUnbind.remove(serviceReference); - } - } - } - if (((ComponentInstanceImpl) instance).bindedServices.remove(serviceReference) != null) { - component.bc.ungetService(serviceReference); - } - } - - final void updated(Reference reference, ComponentInstance instance, ServiceReference serviceReference) { - if (updated != null) { - synchronized (serviceReferences) { - Vector instances = (Vector) serviceReferences.get(serviceReference); - if (instances == null || !instances.contains(instance)) { - //this instance is not bound to the passed service reference - return; - } - } - // retrieve the method from cache - if (!updatedCached) { - updatedMethod = getMethod((ComponentInstanceImpl) instance, reference, updated, serviceReference); - // updatedMethod can be null in case of circularity - if (updatedMethod != null) { - updatedCached = true; - } - } - // invoke the method - if (updatedMethod != null) { - Object methodParam = null; - Class[] paramTypes = updatedMethod.getParameterTypes(); - if (paramTypes.length == 1 && paramTypes[0].equals(ServiceReference.class)) { - methodParam = serviceReference; - } else { - // bindedServices is filled by the getMethod function - methodParam = ((ComponentInstanceImpl) instance).bindedServices.get(serviceReference); - if (methodParam == null) { - methodParam = InstanceProcess.staticRef.getService(reference, serviceReference); - if (methodParam != null) { - ((ComponentInstanceImpl) instance).bindedServices.put(serviceReference, methodParam); - } - } - if (methodParam == null) { - // cannot get serviceObject because of circularity - Activator.log(null, LogService.LOG_WARNING, NLS.bind(Messages.UPDATED_METHOD_NOT_CALLED, name, component.name), null); - return; - } - } - - Object[] params = null; - if (paramTypes.length == 1) { - params = SCRUtil.getObjectArray(); - params[0] = methodParam; - } else { - //this is the case where we have 2 parameters: a service object and a Map, holding the service properties - HashMap map = new HashMap(); - String[] keys = serviceReference.getPropertyKeys(); - for (int i = 0; i < keys.length; i++) { - map.put(keys[i], serviceReference.getProperty(keys[i])); - } - params = new Object[] {methodParam, map}; - } - - try { - updatedMethod.invoke(instance.getInstance(), params); - } catch (Throwable t) { - logError(NLS.bind(Messages.ERROR_UPDATING_REFERENCE, this, instance.getInstance()), t, reference); - } finally { - if (params.length == 1) { - SCRUtil.release(params); - } - } - } else { - // could be also circularity break - logWarning(NLS.bind(Messages.UPDATED_METHOD_NOT_FOUND_OR_NOT_ACCESSIBLE, updated), null, reference); - } - } - } - - public final void dispose() { - bindCached = unbindCached = updatedCached = false; - bindMethod = unbindMethod = updatedMethod = null; - serviceReferences = null; - } - - public final String toString() { - StringBuffer buffer = new StringBuffer(); - buffer.append("Reference["); //$NON-NLS-1$ - buffer.append("name = ").append(name); //$NON-NLS-1$ - buffer.append(", interface = ").append(interfaceName); //$NON-NLS-1$ - buffer.append(", policy = "); //$NON-NLS-1$ - switch (policy) { - case POLICY_DYNAMIC : - buffer.append("dynamic"); //$NON-NLS-1$ - break; - case POLICY_STATIC : - buffer.append("static"); //$NON-NLS-1$ - } - if (component.isNamespaceAtLeast12()) { - buffer.append(", policy-option = "); //$NON-NLS-1$ - switch (policy_option) { - case POLICY_OPTION_RELUCTANT : - buffer.append("reluctant"); //$NON-NLS-1$ - break; - case POLICY_OPTION_GREEDY : - buffer.append("greedy"); //$NON-NLS-1$ - } - } - - buffer.append(", cardinality = "); //$NON-NLS-1$ - switch (cardinality) { - case CARDINALITY_0_1 : - buffer.append("0..1"); //$NON-NLS-1$ - break; - case CARDINALITY_0_N : - buffer.append("0..n"); //$NON-NLS-1$ - break; - case CARDINALITY_1_1 : - buffer.append("1..1"); //$NON-NLS-1$ - break; - case CARDINALITY_1_N : - buffer.append("1..n"); //$NON-NLS-1$ - } - buffer.append(", target = ").append(target); //$NON-NLS-1$ - buffer.append(", bind = ").append(bind); //$NON-NLS-1$ - buffer.append(", unbind = ").append(unbind); //$NON-NLS-1$ - if (component.isNamespaceAtLeast12()) { - buffer.append(", updated = ").append(updated); //$NON-NLS-1$ - } - buffer.append("]"); //$NON-NLS-1$ - return buffer.toString(); - } - - /* - * (non-Javadoc) - * - * @see org.eclipse.equinox.internal.util.io.Externalizable#writeObject(java.io.OutputStream) - */ - public synchronized void writeObject(OutputStream o) throws Exception { - try { - DataOutputStream out; - if (o instanceof DataOutputStream) { - out = (DataOutputStream) o; - } else { - out = new DataOutputStream(o); - } - boolean flag; - out.writeUTF(name); - out.writeUTF(interfaceName); - out.writeInt(cardinality); - out.writeInt(policy); - - flag = target != null; - out.writeBoolean(flag); - if (flag) - out.writeUTF(target); - - flag = bind != null; - out.writeBoolean(flag); - if (flag) - out.writeUTF(bind); - - flag = unbind != null; - out.writeBoolean(flag); - if (flag) - out.writeUTF(unbind); - - // DS 1.2 support - out.writeBoolean(component.isNamespaceAtLeast12()); - if (component.isNamespaceAtLeast12()) { - flag = updated != null; - out.writeBoolean(flag); - if (flag) - out.writeUTF(updated); - - out.writeInt(policy_option); - } - } catch (Exception e) { - Activator.log(null, LogService.LOG_ERROR, Messages.ERROR_WRITING_OBJECT, e); - throw e; - } - } - - /* - * (non-Javadoc) - * - * @see org.eclipse.equinox.internal.util.io.Externalizable#readObject(java.io.InputStream) - */ - public synchronized void readObject(InputStream s) throws Exception { - try { - DataInputStream in; - if (s instanceof DataInputStream) { - in = (DataInputStream) s; - } else { - in = new DataInputStream(s); - } - boolean flag; - name = in.readUTF(); - interfaceName = in.readUTF(); - cardinality = in.readInt(); - policy = in.readInt(); - flag = in.readBoolean(); - if (flag) - target = in.readUTF(); - - flag = in.readBoolean(); - if (flag) - bind = in.readUTF(); - - flag = in.readBoolean(); - if (flag) - unbind = in.readUTF(); - - // DS 1.2 support - flag = in.readBoolean(); - if (flag) { - //This is a DS 1.2 component - flag = in.readBoolean(); - if (flag) - updated = in.readUTF(); - policy_option = in.readInt(); - } - } catch (Exception e) { - Activator.log(null, LogService.LOG_ERROR, Messages.ERROR_READING_OBJECT, e); - throw e; - } - } - - public String getBindMethodName() { - return bind; - } - - public String getName() { - return name; - } - - public String getServiceName() { - return interfaceName; - } - - public ServiceReference[] getServiceReferences() { - Vector result = null; - if (bind != null) { - if (!serviceReferences.isEmpty()) { - result = new Vector(2); - Enumeration keys = serviceReferences.keys(); - while (keys.hasMoreElements()) { - result.add(keys.nextElement()); - } - } - } - if (result != null && !result.isEmpty()) { - ServiceReference[] finalResult = new ServiceReference[result.size()]; - result.copyInto(finalResult); - return finalResult; - } - return null; - } - - public String getTarget() { - return target; - } - - public String getUnbindMethodName() { - return unbind; - } - - public boolean isMultiple() { - return cardinality == ComponentReference.CARDINALITY_0_N || cardinality == ComponentReference.CARDINALITY_1_N; - } - - public boolean isOptional() { - return cardinality == ComponentReference.CARDINALITY_0_1 || cardinality == ComponentReference.CARDINALITY_0_N; - } - - public boolean isSatisfied() { - if (isOptional()) { - return true; - } - try { - ServiceReference[] _serviceReferences = component.bc.getServiceReferences(interfaceName, target); - if (_serviceReferences != null) { - return true; - } - } catch (InvalidSyntaxException e) { - // do nothing - } - return false; - } - - public boolean isStatic() { - return policy == ComponentReference.POLICY_STATIC; - } - - /* (non-Javadoc) - * @see org.apache.felix.scr.Reference#getUpdatedMethodName() - */ - public String getUpdatedMethodName() { - if (component.isNamespaceAtLeast12()) { - return updated; - } - return null; - } - -} diff --git a/bundles/org.eclipse.equinox.ds/src/org/eclipse/equinox/internal/ds/model/DeclarationParser.java b/bundles/org.eclipse.equinox.ds/src/org/eclipse/equinox/internal/ds/model/DeclarationParser.java deleted file mode 100644 index 8f4f2952d..000000000 --- a/bundles/org.eclipse.equinox.ds/src/org/eclipse/equinox/internal/ds/model/DeclarationParser.java +++ /dev/null @@ -1,885 +0,0 @@ -/******************************************************************************* - * Copyright (c) 1997, 2010 by ProSyst Software GmbH - * http://www.prosyst.com - * 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: - * ProSyst Software GmbH - initial API and implementation - * Lazar Kirchev - bug.id = 320377 - *******************************************************************************/ -package org.eclipse.equinox.internal.ds.model; - -import java.io.IOException; -import java.io.InputStream; -import java.net.URL; -import java.util.*; -import org.eclipse.equinox.internal.ds.Activator; -import org.eclipse.equinox.internal.ds.Messages; -import org.eclipse.equinox.internal.util.xml.*; -import org.eclipse.osgi.util.NLS; -import org.osgi.framework.*; -import org.osgi.service.log.LogService; - -/** - * Processes the parsing of the component description XMLs - * - * @author Valentin Valchev - * @author Stoyan Boshev - * @author Pavlin Dobrev - * @author Teodor Bakardzhiev - */ -public class DeclarationParser implements ExTagListener { - - private static final String XMLNS_1_0 = "http://www.osgi.org/xmlns/scr/v1.0.0"; //$NON-NLS-1$ - private static final String XMLNS_1_1 = "http://www.osgi.org/xmlns/scr/v1.1.0"; //$NON-NLS-1$ - private static final String XMLNS_1_2 = "http://www.osgi.org/xmlns/scr/v1.2.0"; //$NON-NLS-1$ - private static final String ATTR_XMLNS = "xmlns"; //$NON-NLS-1$ - - private static final String COMPONENT_TAG_NAME = "component"; //$NON-NLS-1$ - - //component attributes - private static final String ATTR_AUTOENABLE = "enabled"; //$NON-NLS-1$ - private static final String ATTR_NAME = "name"; //$NON-NLS-1$ - private static final String ATTR_FACTORY = "factory"; //$NON-NLS-1$ - private static final String ATTR_IMMEDIATE = "immediate"; //$NON-NLS-1$ - //component attributes according to schema v1.1 - private static final String ATTR_CONF_POLICY = "configuration-policy"; //$NON-NLS-1$ - private static final String ATTR_ACTIVATE = "activate"; //$NON-NLS-1$ - private static final String ATTR_DEACTIVATE = "deactivate"; //$NON-NLS-1$ - private static final String ATTR_MODIFIED = "modified"; //$NON-NLS-1$ - //component attributes according to schema v1.2 - private static final String ATTR_CONFIGURATION_PID = "configuration-pid"; //$NON-NLS-1$ - - private static final String TAG_IMPLEMENTATION = "implementation"; //$NON-NLS-1$ - private static final String ATTR_CLASS = "class"; //$NON-NLS-1$ - - private static final String TAG_PROPERTY = "property"; //$NON-NLS-1$ - private static final String ATTR_VALUE = "value"; //$NON-NLS-1$ - private static final String ATTR_TYPE = "type"; //$NON-NLS-1$ - - private static final String TAG_PROPERTIES = "properties"; //$NON-NLS-1$ - private static final String ATTR_ENTRY = "entry"; //$NON-NLS-1$ - - private static final String TAG_SERVICE = "service"; //$NON-NLS-1$ - private static final String ATTR_SERVICEFACTORY = "servicefactory"; //$NON-NLS-1$ - private static final String TAG_PROVIDE = "provide"; //$NON-NLS-1$ - private static final String ATTR_INTERFACE = "interface"; //$NON-NLS-1$ - - private static final String TAG_REFERENCE = "reference"; //$NON-NLS-1$ - private static final String ATTR_CARDINALITY = "cardinality"; //$NON-NLS-1$ - private static final String ATTR_POLICY = "policy"; //$NON-NLS-1$ - private static final String ATTR_TARGET = "target"; //$NON-NLS-1$ - private static final String ATTR_BIND = "bind"; //$NON-NLS-1$ - private static final String ATTR_UNBIND = "unbind"; //$NON-NLS-1$ - //reference attributes according to schema v1.2 - private static final String ATTR_UPDATED = "updated"; //$NON-NLS-1$ - private static final String ATTR_POLICY_OPTION = "policy-option"; //$NON-NLS-1$ - - /** Constant for String property type */ - public static final int STRING = 1; - /** Constant for Long property type */ - public static final int LONG = 2; - /** Constant for Integer property type */ - public static final int INTEGER = 3; - /** Constant for Short property type */ - public static final int SHORT = 4; - /** Constant for Char property type */ - public static final int CHARACTER = 5; - /** Constant for Byte property type */ - public static final int BYTE = 6; - /** Constant for Double property type */ - public static final int DOUBLE = 7; - /** Constant for Float property type */ - public static final int FLOAT = 8; - /** Constant for Boolean property type */ - public static final int BOOLEAN = 11; - - public Vector components; - - private boolean throwErrors = false; - - private Bundle bundle; - private BundleContext bc; - private ServiceComponent currentComponent; - private String closeTag; - boolean immediateSet = false; - private Hashtable namespaces = null; - private boolean rootPassed = false; - private String currentURL = null; - - public DeclarationParser() { - this(false); - } - - public DeclarationParser(boolean toThrowErrors) { - this.throwErrors = toThrowErrors; - } - - /** - * This method parses an XML file read from the given stream and converts - * the components definitions into a java object. - *

- * - * It also performs a full XML verification of the definition.� - * - * @param in - * the input stream to the XML declaration file - * @param bundle - * this is used to load the 'properties' tag - * @param components sets the components Vector where the parsed components should be placed - * @param processingURL the URL of the XML which is being processed. Will be used for debugging purposes - * @throws Exception if any unhandled exception occurs during the parsing - */ - public void parse(InputStream in, Bundle bundle, Vector components, String processingURL) throws Exception { - this.components = components; - this.bundle = bundle; - this.bc = bundle.getBundleContext(); - this.currentURL = processingURL; - rootPassed = false; - XMLParser.parseXML(in, this, -1); - - // release temporary objects - this.bundle = null; - this.bc = null; - this.currentComponent = null; - this.currentURL = null; - this.closeTag = null; - this.namespaces = null; - } - - /* - * (non-Javadoc) - * - * @see org.eclipse.equinox.internal.util.xml.ExTagListener#startTag(org.eclipse.equinox.internal.util.xml.Tag) - */ - public final void startTag(Tag tag) { - try { - processNamespacesEnter(tag); - String tagName = tag.getName(); - if (isCorrectComponentTag(tagName)) { - doCorrectComponentTag(tag, tagName); - } - } catch (IllegalArgumentException iae) { - currentComponent = null; //the component is bad - ignoring it - closeTag = null; - Activator.log(bundle.getBundleContext(), LogService.LOG_ERROR, NLS.bind(Messages.ERROR_PROCESSING_START_TAG, currentURL, bundle) + iae.getMessage(), null); - if (Activator.DEBUG) { - Activator.log.debug("[SCR] Tracing the last exception", iae); //$NON-NLS-1$ - } - if (throwErrors) { - throw new RuntimeException(NLS.bind(Messages.ERROR_PROCESSING_START_TAG, currentURL, bundle) + iae.getMessage(), iae); - } - } catch (Throwable e) { - Activator.log(bundle.getBundleContext(), LogService.LOG_ERROR, NLS.bind(Messages.ERROR_PROCESSING_START_TAG, currentURL, bundle), e); - if (throwErrors) { - throw new RuntimeException(NLS.bind(Messages.ERROR_PROCESSING_START_TAG, currentURL, bundle) + e.getMessage(), e); - } - } finally { - if (!rootPassed) { - rootPassed = true; - } - } - } - - private void doEndTag(Tag tag) throws InvalidSyntaxException { - if (currentComponent != null) { - String tagName = tag.getName().intern(); - if (tagName == TAG_IMPLEMENTATION) { - doImplementation(tag); - } else if (tagName == TAG_PROPERTY) { - doProperty(tag); - } else if (tagName == TAG_PROPERTIES) { - doProperties(tag); - } else if (tagName == TAG_SERVICE) { - doService(tag); - } else if (tagName == TAG_REFERENCE) { - doReference(tag); - } else if (tagName == TAG_PROVIDE) { - // empty - this tag is processed within the service tag - } else if (tagName == closeTag) { - // the component is completed - we can now fully validate it! - - if (!immediateSet && (currentComponent.factory == null)) { - // if unset, immediate attribute is false if service element is - // specified or true otherwise - // if component factory then immediate by default is false - currentComponent.setImmediate(currentComponent.serviceInterfaces == null); - } - currentComponent.validate(tag.getLine(), getNamespace(tag.getName())); - if (components == null) { - components = new Vector(1, 1); - } - components.addElement(currentComponent); - currentComponent = null; - closeTag = null; - } else { - IllegalArgumentException e = new IllegalArgumentException(NLS.bind(Messages.ILLEGAL_TAG_FOUND, tagName, Integer.toString(tag.getLine()))); - throw e; - } - } - } - - /* - * (non-Javadoc) - * - * @see org.eclipse.equinox.internal.util.xml.ExTagListener#endTag(org.eclipse.equinox.internal.util.xml.Tag) - */ - public final void endTag(Tag tag) { - try { - doEndTag(tag); - processNamespacesLeave(tag); - } catch (IllegalArgumentException iae) { - currentComponent = null; - closeTag = null; - Activator.log(bundle.getBundleContext(), LogService.LOG_ERROR, NLS.bind(Messages.ERROR_PROCESSING_END_TAG, currentURL, bundle) + iae.getMessage(), null); - if (Activator.DEBUG) { - Activator.log.debug("[SCR] Tracing the last exception", iae); //$NON-NLS-1$ - } - if (throwErrors) { - throw new RuntimeException(NLS.bind(Messages.ERROR_PROCESSING_END_TAG, currentURL, bundle) + iae.getMessage(), iae); - } - } catch (Throwable e) { - currentComponent = null; - closeTag = null; - Activator.log(bundle.getBundleContext(), LogService.LOG_ERROR, NLS.bind(Messages.ERROR_PROCESSING_END_TAG, currentURL, bundle), e); - if (throwErrors) { - throw new RuntimeException(NLS.bind(Messages.ERROR_PROCESSING_END_TAG, currentURL, bundle) + e.getMessage(), e); - } - } - } - - /** - * This method will return convert a string to a cardinality constant - * - * @param value - * the input string - * @return the cardinality or -1 to indicate error - */ - private int getCardinality(String value) { - if ("0..1".equals(value)) { //$NON-NLS-1$ - return ComponentReference.CARDINALITY_0_1; - } else if ("0..n".equals(value)) { //$NON-NLS-1$ - return ComponentReference.CARDINALITY_0_N; - } else if ("1..1".equals(value)) { //$NON-NLS-1$ - return ComponentReference.CARDINALITY_1_1; - } else if ("1..n".equals(value)) { //$NON-NLS-1$ - return ComponentReference.CARDINALITY_1_N; - } else { - return -1; - } - } - - private void doReference(Tag tag) throws InvalidSyntaxException { - String name = tag.getAttribute(ATTR_NAME); - String iface = tag.getAttribute(ATTR_INTERFACE); - if (iface == null) { - IllegalArgumentException e = new IllegalArgumentException(NLS.bind(Messages.NO_INTERFACE_ATTR_IN_REFERENCE_TAG, Integer.toString(tag.getLine()))); - throw e; - } - - String cardinalityS = tag.getAttribute(ATTR_CARDINALITY); - int cardinality = ComponentReference.CARDINALITY_1_1; // default - if (cardinalityS != null) { - cardinality = getCardinality(cardinalityS); - if (cardinality < 0) { - IllegalArgumentException e = new IllegalArgumentException(NLS.bind(Messages.INVALID_CARDINALITY_ATTR, cardinalityS, Integer.toString(tag.getLine()))); - throw e; - } - } // if null - default cardinality is already initialized in - // constructor - - String policyS = tag.getAttribute(ATTR_POLICY); - int policy = ComponentReference.POLICY_STATIC; // default - if (policyS != null) { - // verify the policy attribute values - if (policyS.equals("dynamic")) { //$NON-NLS-1$ - policy = ComponentReference.POLICY_DYNAMIC; - } else if (policyS.equals("static")) { //$NON-NLS-1$ - policy = ComponentReference.POLICY_STATIC; - } else { - IllegalArgumentException e = new IllegalArgumentException(NLS.bind(Messages.INVALID_POLICY_ATTR, policyS, Integer.toString(tag.getLine()))); - throw e; - } - } // if null - default policy is already initialized in constructor - - String bind = tag.getAttribute(ATTR_BIND); - String unbind = tag.getAttribute(ATTR_UNBIND); - if (bind != null) { - if (bind.equals("")) { //$NON-NLS-1$ - IllegalArgumentException e = new IllegalArgumentException(NLS.bind(Messages.INVALID_REFERENCE_TAG__BIND_ATTR_EMPTY, Integer.toString(tag.getLine()))); - throw e; - } - if (bind.equals(unbind)) { - IllegalArgumentException e = new IllegalArgumentException(NLS.bind(Messages.INVALID_REFERENCE_TAG__BIND_EQUALS_UNBIND, Integer.toString(tag.getLine()))); - throw e; - } - } - if (unbind != null && unbind.equals("")) { //$NON-NLS-1$ - IllegalArgumentException e = new IllegalArgumentException(NLS.bind(Messages.INVALID_REFERENCE_TAG__UNBIND_ATTR_EMPTY, Integer.toString(tag.getLine()))); - throw e; - } - - String updated = tag.getAttribute(ATTR_UPDATED); - if (updated != null && updated.equals("")) { //$NON-NLS-1$ - IllegalArgumentException e = new IllegalArgumentException(NLS.bind(Messages.INVALID_REFERENCE_TAG__UPDATED_ATTR_EMPTY, Integer.toString(tag.getLine()))); - throw e; - } - - String policyOption = tag.getAttribute(ATTR_POLICY_OPTION); - int policyOptionProcessed = ComponentReference.POLICY_OPTION_RELUCTANT; //default - if (policyOption != null) { - if (policyOption.equals("greedy")) { //$NON-NLS-1$ - policyOptionProcessed = ComponentReference.POLICY_OPTION_GREEDY; - } else if (policyOption.equals("reluctant")) { //$NON-NLS-1$ - policyOptionProcessed = ComponentReference.POLICY_OPTION_RELUCTANT; - } else { - IllegalArgumentException e = new IllegalArgumentException(NLS.bind(Messages.INVALID_POLICY_OPTION_ATTR, policyOption, Integer.toString(tag.getLine()))); - throw e; - } - } - - //check if the current component namespace is suitable for the latest reference attributes - if (!isNamespaceAtLeast12(closeTag)) { - if (updated != null) { - throw new IllegalArgumentException(NLS.bind(Messages.INVALID_TAG_ACCORDING_TO_NAMESPACE1_2, ATTR_UPDATED, Integer.toString(tag.getLine()))); - } - if (policyOption != null) { - throw new IllegalArgumentException(NLS.bind(Messages.INVALID_TAG_ACCORDING_TO_NAMESPACE1_2, ATTR_POLICY_OPTION, Integer.toString(tag.getLine()))); - } - } - - // the reference is autoadded in the ServiceComponent's list of - // references - // in its constructor - ComponentReference ref = new ComponentReference(currentComponent); - ref.name = name; - ref.interfaceName = iface; - ref.cardinality = cardinality; - ref.policy = policy; - ref.bind = bind; - ref.unbind = unbind; - ref.updated = updated; - ref.policy_option = policyOptionProcessed; - ref.target = tag.getAttribute(ATTR_TARGET); - // validate the target filter - if (ref.target != null) { - Activator.createFilter(ref.target); - } - } - - private void doImplementation(Tag tag) { - if (currentComponent.implementation != null) { - IllegalArgumentException e = new IllegalArgumentException(NLS.bind(Messages.INVALID_COMPONENT_TAG__MULTIPLE_IMPL_ATTRIBS, Integer.toString(tag.getLine()))); - throw e; - } - String tmp = tag.getAttribute(ATTR_CLASS); - if (tmp == null) { - IllegalArgumentException e = new IllegalArgumentException(NLS.bind(Messages.INVALID_COMPONENT_TAG__NO_CLASS_ATTR, Integer.toString(tag.getLine()))); - throw e; - } - currentComponent.implementation = tmp; - } - - private void doService(Tag tag) { - String tmp = tag.getAttribute(ATTR_SERVICEFACTORY); - if (tmp != null) { - currentComponent.serviceFactory = Boolean.valueOf(tmp).booleanValue(); - } - int size = tag.size(); - if (size == 0) { - IllegalArgumentException e = new IllegalArgumentException(NLS.bind(Messages.INVALID_SERVICE_TAG__NO_PROVIDE_TAG, Integer.toString(tag.getLine()))); - throw e; - } - if (currentComponent.serviceInterfaces != null) { - //there are already defined service interfaces. The service tag seems to be duplicated - IllegalArgumentException e = new IllegalArgumentException(NLS.bind(Messages.DUPLICATED_SERVICE_TAGS, Integer.toString(tag.getLine()))); - throw e; - } - for (int i = 0; i < size; i++) { - Tag p = tag.getTagAt(i); - String pName = p.getName().intern(); - if (pName == TAG_PROVIDE) { - String iFace = p.getAttribute(ATTR_INTERFACE); - if (iFace == null) { - IllegalArgumentException e = new IllegalArgumentException(NLS.bind(Messages.INVALID_PROVIDE_TAG__NO_INTERFACE_ATTR, Integer.toString(tag.getLine()))); - throw e; - } - if (currentComponent.serviceInterfaces == null) { - currentComponent.serviceInterfaces = new Vector(size); - } - currentComponent.serviceInterfaces.addElement(iFace); - } else { - IllegalArgumentException e = new IllegalArgumentException(NLS.bind(Messages.ILLEGAL_ELEMENT_IN_SERVICE_TAG, pName, Integer.toString(tag.getLine()))); - throw e; - } - } - } - - private void doProperty(Tag tag) { - String name = null; - try { - name = tag.getAttribute(ATTR_NAME); - if (name == null) { - IllegalArgumentException e = new IllegalArgumentException(NLS.bind(Messages.INVALID_PROPERTY_TAG__NO_NAME_ATTR, Integer.toString(tag.getLine()))); - throw e; - } - - String type = tag.getAttribute(ATTR_TYPE); - int mtType; - if (type == null || "String".equals(type)) { //$NON-NLS-1$ - mtType = STRING; - } else if ("Boolean".equals(type)) { //$NON-NLS-1$ - mtType = BOOLEAN; - } else if ("Integer".equals(type)) { //$NON-NLS-1$ - mtType = INTEGER; - } else if ("Long".equals(type)) { //$NON-NLS-1$ - mtType = LONG; - } else if ("Char".equals(type) || "Character".equals(type)) { //$NON-NLS-1$ //$NON-NLS-2$ - mtType = CHARACTER; - } else if ("Double".equals(type)) { //$NON-NLS-1$ - mtType = DOUBLE; - } else if ("Float".equals(type)) { //$NON-NLS-1$ - mtType = FLOAT; - } else if ("Byte".equals(type)) { //$NON-NLS-1$ - mtType = BYTE; - } else if ("Short".equals(type)) { //$NON-NLS-1$ - mtType = SHORT; - } else { - IllegalArgumentException e = new IllegalArgumentException(NLS.bind(Messages.INVALID_PROPERTY_TYPE, type, Integer.toString(tag.getLine()))); - throw e; - } - - String value = tag.getAttribute(ATTR_VALUE); - Object _value; - if (value != null) { - _value = makeObject(value, mtType); - } else { - // body must be specified - value = tag.getContent(); - if (value == null) { - IllegalArgumentException e = new IllegalArgumentException(Messages.INVALID_PROPERTY_TAG__NO_BODY_CONTENT); - throw e; - } - StringTokenizer tok = new StringTokenizer(value, "\n\r"); //$NON-NLS-1$ - Vector el = new Vector(10); - while (tok.hasMoreTokens()) { - String next = tok.nextToken().trim(); - if (next.length() > 0) { - el.addElement(next); - } - } - if (el.size() == 0) { - IllegalArgumentException e = new IllegalArgumentException(Messages.INVALID_PROPERTY_TAG__NO_BODY_CONTENT); - throw e; - } - String[] values = new String[el.size()]; - el.copyInto(values); - _value = makeArr(values, mtType); - } - if (currentComponent.properties == null) { - currentComponent.properties = new Properties(); - } - currentComponent.properties.put(name, _value); - } catch (IllegalArgumentException iae) { - Activator.log(bundle.getBundleContext(), LogService.LOG_ERROR, NLS.bind(Messages.ERROR_PROCESSING_PROPERTY, name, currentURL) + iae.getMessage(), null); - if (Activator.DEBUG) { - Activator.log.debug("[SCR] Tracing the last exception", iae); //$NON-NLS-1$ - } - if (throwErrors) { - throw new RuntimeException(NLS.bind(Messages.ERROR_PROCESSING_PROPERTY, name, currentURL) + iae.getMessage(), iae); - } - } catch (Throwable e) { - //logging unrecognized exception - Activator.log(bundle.getBundleContext(), LogService.LOG_ERROR, NLS.bind(Messages.ERROR_PROCESSING_PROPERTY, name, currentURL), e); - if (throwErrors) { - throw new RuntimeException(NLS.bind(Messages.ERROR_PROCESSING_PROPERTY, name, currentURL) + e.getMessage(), e); - } - } - } - - private void doProperties(Tag tag) { - String fileEntry = tag.getAttribute(ATTR_ENTRY); - if (fileEntry == null) { - IllegalArgumentException e = new IllegalArgumentException(NLS.bind(Messages.INVALID_PROPERTIES_TAG__NO_ENTRY_ATTR, Integer.toString(tag.getLine()))); - throw e; - } - - InputStream is = null; - try { - URL resource = bundle.getEntry(fileEntry); - is = resource != null ? resource.openStream() : null; - } catch (IOException ignore) { - //ignore - } - - boolean invalid = true; - // FIXME: this will not work on properties defined like - // com.prosyst.bla.component.properties - // in this case the path should be converted as - // com/prosyst/bla/component.properties - if (is != null) { - if (currentComponent.properties == null) { - currentComponent.properties = new Properties(); - } - try { - currentComponent.properties.load(is); - invalid = false; - } catch (IOException e) { - Activator.log(bundle.getBundleContext(), LogService.LOG_ERROR, Messages.ERROR_LOADING_PROPERTIES_FILE, e); - if (throwErrors) { - throw new RuntimeException(Messages.ERROR_LOADING_PROPERTIES_FILE + e, e); - } - } - } - - if (invalid) { - IllegalArgumentException e = new IllegalArgumentException(NLS.bind(Messages.INVALID_PROPERTIES_TAG__INVALID_ENTRY_VALUE, Integer.toString(tag.getLine()), fileEntry)); - throw e; - } - } - - private void doCorrectComponentTag(Tag tag, String tagName) { - closeTag = tagName.intern(); - String tmp = tag.getAttribute(ATTR_NAME); - immediateSet = false; - - currentComponent = new ServiceComponent(); - // make sure that the bundle attribute is set - it is required further - currentComponent.bundle = bundle; - currentComponent.bc = bc; - currentComponent.name = tmp; - tmp = tag.getAttribute(ATTR_AUTOENABLE); - if (tmp != null) { - currentComponent.autoenable = Boolean.valueOf(tmp).booleanValue(); - } - tmp = tag.getAttribute(ATTR_FACTORY); - if (tmp != null && tmp.length() == 0) { - tmp = null; - } - currentComponent.factory = tmp; - tmp = tag.getAttribute(ATTR_IMMEDIATE); - if (tmp != null && tmp.length() == 0) { - tmp = null; - } - if (tmp != null) { - currentComponent.immediate = Boolean.valueOf(tmp).booleanValue(); - immediateSet = true; - } - if (isNamespaceAtLeast11(tagName)) { - //processing attribute configuration-policy - tmp = tag.getAttribute(ATTR_CONF_POLICY); - if (tmp != null && tmp.length() == 0) { - tmp = null; - } - if (tmp != null) { - currentComponent.configurationPolicy = tmp.intern(); - } - //processing attribute activate - tmp = tag.getAttribute(ATTR_ACTIVATE); - if (tmp != null && tmp.length() == 0) { - tmp = null; - } - if (tmp != null) { - currentComponent.activateMethodName = tmp; - currentComponent.activateMethodDeclared = true; - } - //processing attribute deactivate - tmp = tag.getAttribute(ATTR_DEACTIVATE); - if (tmp != null && tmp.length() == 0) { - tmp = null; - } - if (tmp != null) { - currentComponent.deactivateMethodName = tmp; - currentComponent.deactivateMethodDeclared = true; - } - //processing attribute modified - tmp = tag.getAttribute(ATTR_MODIFIED); - if (tmp != null && tmp.length() == 0) { - tmp = null; - } - if (tmp != null) { - currentComponent.modifyMethodName = tmp; - } - } else { - if (tag.getAttribute(ATTR_CONF_POLICY) != null) { - throw new IllegalArgumentException(NLS.bind(Messages.INVALID_TAG_ACCORDING_TO_NAMESPACE1_0, ATTR_CONF_POLICY, Integer.toString(tag.getLine()))); - } - if (tag.getAttribute(ATTR_ACTIVATE) != null) { - throw new IllegalArgumentException(NLS.bind(Messages.INVALID_TAG_ACCORDING_TO_NAMESPACE1_0, ATTR_ACTIVATE, Integer.toString(tag.getLine()))); - } - if (tag.getAttribute(ATTR_DEACTIVATE) != null) { - throw new IllegalArgumentException(NLS.bind(Messages.INVALID_TAG_ACCORDING_TO_NAMESPACE1_0, ATTR_DEACTIVATE, Integer.toString(tag.getLine()))); - } - if (tag.getAttribute(ATTR_MODIFIED) != null) { - throw new IllegalArgumentException(NLS.bind(Messages.INVALID_TAG_ACCORDING_TO_NAMESPACE1_0, ATTR_MODIFIED, Integer.toString(tag.getLine()))); - } - } - - if (isNamespaceAtLeast12(tagName)) { - //processing attribute configuration-policy - tmp = tag.getAttribute(ATTR_CONFIGURATION_PID); - if (tmp != null && tmp.length() == 0) { - tmp = null; - } - if (tmp != null) { - currentComponent.configurationPID = tmp; - } - } else { - if (tag.getAttribute(ATTR_CONFIGURATION_PID) != null) { - throw new IllegalArgumentException(NLS.bind(Messages.INVALID_TAG_ACCORDING_TO_NAMESPACE1_2, ATTR_CONFIGURATION_PID, Integer.toString(tag.getLine()))); - } - } - - } - - private boolean isCorrectComponentTag(String tagName) { - String qualifier = getNamespaceQualifier(tagName); - String localTagName = (qualifier.length() == 0) ? tagName : tagName.substring(qualifier.length() + 1); // + one char for ':' - if (!localTagName.equals(COMPONENT_TAG_NAME)) { - return false; - } - String namespace = getCurrentNamespace(qualifier); - if (!rootPassed) { // this is the root element - return namespace.length() == 0 || namespace.equals(XMLNS_1_1) || namespace.equals(XMLNS_1_2) || namespace.equals(XMLNS_1_0); - } - // not a root element - return namespace.equals(XMLNS_1_1) || namespace.equals(XMLNS_1_2) || namespace.equals(XMLNS_1_0); - } - - /** - * Creates an object from a String value and a type, as defined by the objectType parameter. - * - * @param string The String value representation of the object. - * @param objectType Defines the type of the object to be generated - * - * @return an Object, which is of a type, corresponding to the given, - * and value - got from the string parameter. - * - * @exception IllegalArgumentException if a proper object can not be created - * due to incompatibility of objectType and value or if the parameters are not correct - * (e.g. objectType is not a valid constant). - */ - public static Object makeObject(String string, int objectType) throws IllegalArgumentException { - try { - switch (objectType) { - case STRING : { - return string; - } - case INTEGER : { - return new Integer(string); - } - case LONG : { - return new Long(string); - } - case FLOAT : { - return new Float(string); - } - case DOUBLE : { - return new Double(string); - } - case BYTE : { - return new Byte(string); - } - case SHORT : { - return new Short(string); - } - case CHARACTER : { - if (string.length() == 0) { - throw new IllegalArgumentException(Messages.MISSING_CHARACTER); - } - return new Character(string.charAt(0)); - } - case BOOLEAN : { - return Boolean.valueOf(string); - } - default : { - throw new IllegalArgumentException(NLS.bind(Messages.UNSUPPORTED_TYPE, String.valueOf(objectType))); - } - } - } catch (NumberFormatException ex) { - throw new IllegalArgumentException(NLS.bind(Messages.INCORRECT_VALUE_TYPE, string)); - } - } - - /** - * Makes an array from the string array value and the object type. - * - * @param array String array representation of an array. - * @param objectType The array's object type. - * - * @return an array of primitives or objects, whose component type corresponds to objectType, - * and value build from the string array passed. - * - * @exception IllegalArgumentException if any of the elements in the string array - * can not be converted to a proper object or primitive, or if the objectType is not a valid constant. - */ - public static Object makeArr(String[] array, int objectType) throws IllegalArgumentException { - switch (objectType) { - case STRING : { - return array; - } - case INTEGER : { - int[] ints = new int[array.length]; - for (int i = 0; i < array.length; i++) { - ints[i] = Integer.parseInt(array[i]); - } - return ints; - } - case LONG : { - long[] longs = new long[array.length]; - for (int i = 0; i < array.length; i++) { - longs[i] = Long.parseLong(array[i]); - } - return longs; - } - case FLOAT : { - float[] floats = new float[array.length]; - for (int i = 0; i < array.length; i++) { - floats[i] = Float.valueOf(array[i]).floatValue(); - } - return floats; - } - case DOUBLE : { - double[] doubles = new double[array.length]; - for (int i = 0; i < array.length; i++) { - doubles[i] = Double.valueOf(array[i]).doubleValue(); - } - return doubles; - } - case BYTE : { - byte[] bytes = new byte[array.length]; - for (int i = 0; i < array.length; i++) { - bytes[i] = Byte.parseByte(array[i]); - } - return bytes; - } - case SHORT : { - short[] shorts = new short[array.length]; - for (int i = 0; i < array.length; i++) { - shorts[i] = Short.parseShort(array[i]); - } - return shorts; - } - case CHARACTER : { - char[] chars = new char[array.length]; - for (int i = 0; i < array.length; i++) { - chars[i] = array[i].charAt(0); - } - return chars; - } - case BOOLEAN : { - boolean[] booleans = new boolean[array.length]; - for (int i = 0; i < array.length; i++) { - booleans[i] = Boolean.valueOf(array[i]).booleanValue(); - } - return booleans; - } - default : { - throw new IllegalArgumentException(NLS.bind(Messages.UNSUPPORTED_TYPE, String.valueOf(objectType))); - } - } - } - - private int getNamespace(String tagName) { - String qualifier = getNamespaceQualifier(tagName); - String namespace = getCurrentNamespace(qualifier); - if (!rootPassed) { // this is the root element - if (namespace.length() == 0) { - return ServiceComponent.NAMESPACE_1_0; - } - } - // not a root element - if (namespace.equals(XMLNS_1_0)) { - return ServiceComponent.NAMESPACE_1_0; - } else if (namespace.equals(XMLNS_1_1)) { - return ServiceComponent.NAMESPACE_1_1; - } else if (namespace.equals(XMLNS_1_2)) { - return ServiceComponent.NAMESPACE_1_2; - } - - //namespace is not known - return -1; - } - - private boolean isNamespaceAtLeast11(String tagName) { - int namespace = getNamespace(tagName); - return (namespace >= ServiceComponent.NAMESPACE_1_1); - } - - private boolean isNamespaceAtLeast12(String tagName) { - int namespace = getNamespace(tagName); - return (namespace >= ServiceComponent.NAMESPACE_1_2); - } - - private void processNamespacesEnter(Tag tag) { - Enumeration en = tag.getAttributeNames(); - while (en.hasMoreElements()) { - String attrName = (String) en.nextElement(); - if (attrName.startsWith(ATTR_XMLNS)) { - String qualifier = attrName.substring(ATTR_XMLNS.length()); - if ((qualifier.length() == 0) || // <- default namespace - ((qualifier.charAt(0) == ':') ? (qualifier = qualifier.substring(1)).length() > 0 : false)) { - - if (namespaces == null) { - namespaces = new Hashtable(); - } - Stack stack = null; - if ((stack = (Stack) namespaces.get(qualifier)) == null) { - stack = new Stack(); - namespaces.put(qualifier, stack); - } - stack.push(tag.getAttribute(attrName)); - } - } - } - } - - private String getCurrentNamespace(String qualifier) { - if (namespaces == null || qualifier == null) { - return ""; //$NON-NLS-1$ - } - Stack stack = (Stack) namespaces.get(qualifier); - if (stack == null || stack.empty()) { - return ""; //$NON-NLS-1$ - } - - return (String) stack.peek(); - } - - private void processNamespacesLeave(Tag tag) { - if (namespaces == null) { - return; - } - Enumeration en = tag.getAttributeNames(); - while (en.hasMoreElements()) { - String attrName = (String) en.nextElement(); - if (attrName.startsWith(ATTR_XMLNS)) { - String qualifier = attrName.substring(ATTR_XMLNS.length()); - if ((qualifier.length() == 0) || // <- default namespace - ((qualifier.charAt(0) == ':') ? (qualifier = qualifier.substring(1)).length() > 0 : false)) { - - Stack stack = (Stack) namespaces.get(qualifier); - if (stack != null) { - if (!stack.empty()) { - stack.pop(); - } - if (stack.empty()) { - namespaces.remove(qualifier); - } - } - } - } - } - } - - private String getNamespaceQualifier(String name) { - int index = name.indexOf(':'); - if (index < 0) { - return ""; //$NON-NLS-1$ - } - return name.substring(0, index); - } -} diff --git a/bundles/org.eclipse.equinox.ds/src/org/eclipse/equinox/internal/ds/model/ServiceComponent.java b/bundles/org.eclipse.equinox.ds/src/org/eclipse/equinox/internal/ds/model/ServiceComponent.java deleted file mode 100644 index 1cd041cc9..000000000 --- a/bundles/org.eclipse.equinox.ds/src/org/eclipse/equinox/internal/ds/model/ServiceComponent.java +++ /dev/null @@ -1,971 +0,0 @@ -/******************************************************************************* - * Copyright (c) 1997-2011 by ProSyst Software GmbH - * http://www.prosyst.com - * 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: - * ProSyst Software GmbH - initial API and implementation - * Simon Archer - bug.id = 225624 - * Bryan Hunt - bug.id = 275997 - * Lazar Kirchev - bug.id = 320377 - *******************************************************************************/ -package org.eclipse.equinox.internal.ds.model; - -import java.io.*; -import java.lang.reflect.*; -import java.util.*; -import org.apache.felix.scr.Component; -import org.apache.felix.scr.Reference; -import org.eclipse.equinox.internal.ds.*; -import org.eclipse.equinox.internal.ds.impl.ReadOnlyDictionary; -import org.eclipse.equinox.internal.util.io.Externalizable; -import org.eclipse.equinox.internal.util.io.ExternalizableDictionary; -import org.eclipse.osgi.util.NLS; -import org.osgi.framework.*; -import org.osgi.service.component.*; -import org.osgi.service.log.LogService; - -/** - * This is an OO wrapper for the XML representing the components. It also caches - * the activate and deactivate methods of the component. - * - * @author Valentin Valchev - * @author Pavlin Dobrev - * @author Stoyan Boshev - */ -public class ServiceComponent implements Externalizable, Component { - - //constants defining possible SCR namespaces XML schemas - public static final int NAMESPACE_1_0 = 0; - public static final int NAMESPACE_1_1 = 1; - public static final int NAMESPACE_1_2 = 2; - - public static final String CONF_POLICY_OPTIONAL = "optional"; //$NON-NLS-1$ - public static final String CONF_POLICY_REQUIRE = "require"; //$NON-NLS-1$ - public static final String CONF_POLICY_IGNORE = "ignore"; //$NON-NLS-1$ - - public Vector componentProps = null; - - // --- begin: XML def - public String name; - public String factory; - String implementation; // the class name - Properties properties; // property or properties - String configurationPolicy = CONF_POLICY_OPTIONAL; - String activateMethodName = "activate"; //$NON-NLS-1$ - String deactivateMethodName = "deactivate"; //$NON-NLS-1$ - public String modifyMethodName = ""; //$NON-NLS-1$ - - //Since DS 1.2 - public String configurationPID; - - // service - public Vector serviceInterfaces; // all strings - public String[] provides; // the same as above, but as String[] - public boolean serviceFactory = false; - - public Vector references; // ComponentReference - - public boolean autoenable = true; - public boolean immediate = false; - public int namespace = NAMESPACE_1_0; - // --- end: XML def - - // --- begin: cache - private boolean activateCached = false; - private boolean deactivateCached = false; - private boolean modifyCached = false; - private Method activateMethod; - private Method deactivateMethod; - private Method modifyMethod; - // --- end: cache - - // --- begin: model - public boolean enabled; - public Bundle bundle; - public BundleContext bc; - boolean activateMethodDeclared = false; - boolean deactivateMethodDeclared = false; - int state = Component.STATE_UNSATISFIED; - // --- end: model - - public HashSet componentIssues = new HashSet(1, 1); - private ReadOnlyDictionary readOnlyProps; - - public String getComponentIssues() { - if (!componentIssues.isEmpty()) { - String result = ""; //$NON-NLS-1$ - Object[] issues = componentIssues.toArray(); - for (int i = 0; i < issues.length; i++) { - result += issues[i] + "\n"; //$NON-NLS-1$ - } - return result; - } - return null; - } - - private static final Class ACTIVATE_METHODS_PARAMETERS[] = new Class[] {ComponentContext.class}; - - public ServiceComponent() { - // - } - - private final Method getMethod(Object instance, String methodName, boolean isActivate) throws Exception { - if (Activator.DEBUG) { - Activator.log.debug("ServiceComponent.getMethod(): " + methodName, null); //$NON-NLS-1$ - } - Method method = null; - int methodPriority = Integer.MAX_VALUE; - Class clazz = instance != null ? instance.getClass() : null; - - while (method == null && clazz != null) { - if (isNamespaceAtLeast11()) { - Method[] methods = clazz.getDeclaredMethods(); - for (int i = 0; i < methods.length; i++) { - if (methods[i].getName().equals(methodName)) { - Class[] params = methods[i].getParameterTypes(); - boolean accepted = true; - for (int j = 0; j < params.length; j++) { - if (params[j] == ComponentContext.class || params[j] == BundleContext.class || params[j] == Map.class) { - // correct parameter for both activate and deactivate methods - } else if (!isActivate && (params[j] == Integer.class || params[j] == int.class)) { - //we are checking int/Integer as special deactivate parameters - - } else { - //the parameter is not recognized - accepted = false; - break; - } - } - if (accepted && SCRUtil.checkMethodAccess(instance.getClass(), clazz, methods[i], true)) { - //check if the newly accepted method has higher priority than the previous one and use it - int prio = getMethodPriority(params); - if (prio < methodPriority) { - //found a method with a higher priority - method = methods[i]; - methodPriority = prio; - } - } - } - } - } else { - try { - method = clazz.getDeclaredMethod(methodName, ACTIVATE_METHODS_PARAMETERS); - if (method != null) { - if (!SCRUtil.checkMethodAccess(instance.getClass(), clazz, method, false)) { - //the method is not accessible. Stop the search - Activator.log(bc, LogService.LOG_WARNING, NLS.bind(Messages.METHOD_UNACCESSABLE, methodName, clazz), null); - componentIssues.add(NLS.bind(Messages.METHOD_UNACCESSABLE, methodName, clazz)); - method = null; - break; - } - } - } catch (NoSuchMethodException e) { - // the method activate/deactivate may not exist in the component implementation class - } - } - - if (method != null) - break; - - // search for the method in the parent classes! - clazz = clazz.getSuperclass(); - } - if (method != null) { - int modifiers = method.getModifiers(); - if (!Modifier.isPublic(modifiers)) { - SCRUtil.setAccessible(method); - } - } - return method; - } - - private int getMethodPriority(Class[] params) { - int priority = Integer.MAX_VALUE; - if (params.length == 1) { - if (params[0] == ComponentContext.class) { - priority = 0; //highest priority - } else if (params[0] == BundleContext.class) { - priority = 1; - } else if (params[0] == Map.class) { - priority = 2; - } else if (params[0] == int.class) { - priority = 3; - } else if (params[0] == Integer.class) { - priority = 4; - } - } else if (params.length >= 2) { - priority = 5; - } else if (params.length == 0) { - priority = 6; - } - return priority; - } - - void activate(Object instance, ComponentContext context) throws ComponentException { - try { - if (isNamespaceAtLeast11()) { - if (!activateCached) { - activateCached = true; - activateMethod = getMethod(instance, activateMethodName, true); - } - // invoke the method if any - if (activateMethod != null) { - Class[] paramTypes = activateMethod.getParameterTypes(); - Object[] params = null; - if (paramTypes.length == 1) { - params = SCRUtil.getObjectArray(); - } else { - params = new Object[paramTypes.length]; - } - for (int i = 0; i < params.length; i++) { - if (paramTypes[i] == ComponentContext.class) { - params[i] = context; - } else if (paramTypes[i] == BundleContext.class) { - params[i] = context.getBundleContext(); - } else if (paramTypes[i] == Map.class) { - params[i] = context.getProperties(); - } - } - - try { - activateMethod.invoke(instance, params); - } finally { - if (params.length == 1) { - SCRUtil.release(params); - } - } - } else { - if (activateMethodName != "activate") { //$NON-NLS-1$ - //the activate method is specified in the component description XML by the user. - //It is expected to find it in the implementation class - componentIssues.add("Can not activate instance of component " + this.implementation + ". The specified activate method [" + activateMethodName + "] was not found."); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ - throw new ComponentException(NLS.bind(Messages.SPECIFIED_ACTIVATE_METHOD_NOT_FOUND, instance, this)); - } - } - } else { - // retrieve the activate method from cache - if (!activateCached) { - activateCached = true; - activateMethod = getMethod(instance, "activate", true); //$NON-NLS-1$ - } - // invoke the method if any - if (activateMethod != null) { - Object[] params = SCRUtil.getObjectArray(); - params[0] = context; - try { - activateMethod.invoke(instance, params); - } finally { - SCRUtil.release(params); - } - } - } - } catch (Throwable t) { - if (t instanceof ComponentException) { - throw (ComponentException) t; - } - String cause = t.toString(); - if (t instanceof InvocationTargetException) { - cause = t.getCause().toString(); - } - componentIssues.add("Can not activate instance of component " + this.implementation + ". The activation throws: " + cause); //$NON-NLS-1$ //$NON-NLS-2$ - throw new ComponentException(NLS.bind(Messages.EXCEPTION_ACTIVATING_INSTANCE, instance, name), t); - // rethrow exception so resolver is eventually notified that - // the processed SCP is bad - } - } - - void modified(Object instance, ComponentContext context) throws ComponentException { - try { - if (isNamespaceAtLeast11()) { - if (!modifyCached) { - modifyCached = true; - if (modifyMethodName != "") { //$NON-NLS-1$ - modifyMethod = getMethod(instance, modifyMethodName, true); - } - } - // invoke the method if any - if (modifyMethod != null) { - Class[] paramTypes = modifyMethod.getParameterTypes(); - Object[] params = null; - if (paramTypes.length == 1) { - params = SCRUtil.getObjectArray(); - } else { - params = new Object[paramTypes.length]; - } - for (int i = 0; i < params.length; i++) { - if (paramTypes[i] == ComponentContext.class) { - params[i] = context; - } else if (paramTypes[i] == BundleContext.class) { - params[i] = context.getBundleContext(); - } else if (paramTypes[i] == Map.class) { - params[i] = context.getProperties(); - } - } - - try { - modifyMethod.invoke(instance, params); - } finally { - if (params.length == 1) { - SCRUtil.release(params); - } - } - } else { - if (modifyMethodName != "") { //$NON-NLS-1$ - //the modify method is specified in the component description XML by the user. - //It is expected to find it in the implementation class - throw new ComponentException(NLS.bind(Messages.CANNOT_MODIFY_INSTANCE__MODIFY_METHOD_NOT_FOUND, instance, this)); - } - } - } - } catch (Throwable t) { - if (t instanceof ComponentException) { - throw (ComponentException) t; - } - Activator.log(bc, LogService.LOG_ERROR, NLS.bind(Messages.EXCEPTION_MODIFYING_COMPONENT, instance, this), t); - } - } - - void deactivate(Object instance, ComponentContext context, int deactivateReason) { - try { - if (isNamespaceAtLeast11()) { - if (!deactivateCached) { - deactivateCached = true; - deactivateMethod = getMethod(instance, deactivateMethodName, false); - } - // invoke the method if any - if (deactivateMethod != null) { - Class[] paramTypes = deactivateMethod.getParameterTypes(); - Object[] params = null; - if (paramTypes.length == 1) { - params = SCRUtil.getObjectArray(); - } else { - params = new Object[paramTypes.length]; - } - for (int i = 0; i < params.length; i++) { - if (paramTypes[i] == ComponentContext.class) { - params[i] = context; - } else if (paramTypes[i] == BundleContext.class) { - params[i] = context.getBundleContext(); - } else if (paramTypes[i] == Map.class) { - params[i] = context.getProperties(); - } else if (paramTypes[i] == int.class) { - params[i] = new Integer(deactivateReason); - } else if (paramTypes[i] == Integer.class) { - params[i] = new Integer(deactivateReason); - } - } - - try { - deactivateMethod.invoke(instance, params); - } finally { - if (params.length == 1) { - SCRUtil.release(params); - } - } - } else { - if (deactivateMethodName != "deactivate") { //$NON-NLS-1$ - //the deactivate method is specified in the component description XML by the user. - //It is expected to find it in the implementation class - Activator.log(bc, LogService.LOG_ERROR, NLS.bind(Messages.SPECIFIED_DEACTIVATE_METHOD_NOT_FOUND, instance, this), null); - } - } - } else { - // retrieve the activate method from cache - if (!deactivateCached) { - deactivateCached = true; - deactivateMethod = getMethod(instance, "deactivate", false); //$NON-NLS-1$ - } - // invoke the method - if (deactivateMethod != null) { - Object[] params = SCRUtil.getObjectArray(); - params[0] = context; - try { - deactivateMethod.invoke(instance, params); - } finally { - SCRUtil.release(params); - } - } - } - } catch (Throwable t) { - Activator.log(bc, LogService.LOG_ERROR, NLS.bind(Messages.ERROR_DEACTIVATING_INSTANCE, this), t); - } - } - - /** - * This method is called from the XML parser to validate the component once - * it is fully loaded! - * - * @param line - * the line at which the the component definition ends - * @param _namespace specify the namespace of the component according to XML SCR schema - */ - void validate(int line, int _namespace) { - // System.out.println("Validating component " + name + " with namespace " + (namespace11 ? "1.1" : "1.0")); - this.namespace = _namespace; - if (name == null) { - if (isNamespaceAtLeast11()) { - name = implementation; - } else { - throw new IllegalArgumentException(NLS.bind(Messages.NO_NAME_ATTRIBUTE, Integer.toString(line))); - } - } - if (isNamespaceAtLeast11()) { - if (!(configurationPolicy == CONF_POLICY_OPTIONAL || configurationPolicy == CONF_POLICY_REQUIRE || configurationPolicy == CONF_POLICY_IGNORE)) { - throw new IllegalArgumentException(NLS.bind(Messages.INCORRECT_ACTIVATION_POLICY, name, Integer.toString(line))); - } - } - - if (isNamespaceAtLeast12()) { - if (configurationPID == null) { - configurationPID = name; - } - } - - if (implementation == null) { - throw new IllegalArgumentException(NLS.bind(Messages.NO_IMPLEMENTATION_ATTRIBUTE, name, Integer.toString(line))); - } - - // component factory is incompatible with service factory - if (factory != null && serviceFactory) { - throw new IllegalArgumentException(NLS.bind(Messages.INVALID_COMPONENT_FACTORY_AND_SERVICE_FACTORY, name)); - } - - if (immediate) { - if (serviceFactory) - throw new IllegalArgumentException(NLS.bind(Messages.INVALID_COMPONENT_IMMEDIATE_AND_SERVICE_FACTORY, name)); - if (factory != null) - throw new IllegalArgumentException(NLS.bind(Messages.INVALID_COMPONENT_IMMEDIATE_AND_FACTORY, name)); - } else { - if ((serviceInterfaces == null) && (factory == null)) { - throw new IllegalArgumentException(NLS.bind(Messages.INVALID_COMPONENT_NO_SERVICES_NO_IMMEDIATE, name)); - } - } - - // make sure that references are also valid - if (references != null) { - for (int i = 0; i < references.size(); i++) { - ComponentReference r = (ComponentReference) references.elementAt(i); - if (r.name == null) { - if (isNamespaceAtLeast11()) { - r.name = r.interfaceName; - } else { - throw new IllegalArgumentException(NLS.bind(Messages.COMPONENT_HAS_ILLEGAL_REFERENCE, new Object[] {name, Integer.toString(line), r})); - } - } - if (r.interfaceName == null || r.name.length() == 0 || r.interfaceName.length() == 0) { - throw new IllegalArgumentException(NLS.bind(Messages.COMPONENT_HAS_ILLEGAL_REFERENCE, new Object[] {name, Integer.toString(line), r})); - } - for (int j = i + 1; j < references.size(); j++) { - ComponentReference ref2 = (ComponentReference) references.elementAt(j); - if (r.name.equals(ref2.name)) { - throw new IllegalArgumentException(NLS.bind(Messages.DUPLICATED_REFERENCE_NAMES, name, Integer.toString(line))); - } - } - } - } - - // cache the service interfaces as String[] too. - if (serviceInterfaces != null && !serviceInterfaces.isEmpty()) { - provides = new String[serviceInterfaces.size()]; - serviceInterfaces.copyInto(provides); - } - - // make sure that the component will get automatically enabled! - enabled = autoenable; - } - - /** - * This method will instantiate the implementation class! - * - * @return instance of the component implementation class. If the components - * exports some services, the implementation must implement all of - * them - * @throws Exception - * is thrown if the implementation cannot be instantiated for - * some reasons. - */ - final Object createInstance() throws Exception { - try { - return bundle.loadClass(implementation).newInstance(); - } catch (Throwable t) { - throw new ComponentException(NLS.bind(Messages.EXCEPTION_CREATING_COMPONENT_INSTANCE, this), t); - } - } - - /** - * This method will dispose everything - */ - // TODO : this method is not used - should be removed? - public final void dispose() { - - activateCached = deactivateCached = false; - activateMethod = deactivateMethod = null; - - enabled = false; - bundle = null; - // bc = null; - - if (references != null) { - for (int i = 0; i < references.size(); i++) { - ComponentReference ref = (ComponentReference) references.elementAt(i); - ref.dispose(); - } - references.removeAllElements(); - references = null; - } - - if (properties != null) { - properties.clear(); - properties = null; - } - - if (serviceInterfaces != null) { - serviceInterfaces.removeAllElements(); - serviceInterfaces = null; - } - } - - public boolean provides(String interfaceName) { - return serviceInterfaces != null && serviceInterfaces.contains(interfaceName); - } - - public String getConfigurationPID() { - if (isNamespaceAtLeast12()) { - return configurationPID; - } - return name; - } - - /* - * (non-Javadoc) - * - * @see java.lang.Object#toString() - */ - public final String toString() { - StringBuffer buffer = new StringBuffer(); - buffer.append("Component["); //$NON-NLS-1$ - buffer.append("\n\tname = ").append(name); //$NON-NLS-1$ - if (isNamespaceAtLeast11()) { - buffer.append("\n\tactivate = ").append(activateMethodName); //$NON-NLS-1$ - buffer.append("\n\tdeactivate = ").append(deactivateMethodName); //$NON-NLS-1$ - buffer.append("\n\tmodified = ").append(modifyMethodName); //$NON-NLS-1$ - buffer.append("\n\tconfiguration-policy = ").append(configurationPolicy); //$NON-NLS-1$ - } - if (isNamespaceAtLeast12()) { - buffer.append("\n\tconfiguration-pid = ").append(configurationPID); //$NON-NLS-1$ - } - buffer.append("\n\tfactory = ").append(factory); //$NON-NLS-1$ - buffer.append("\n\tautoenable = ").append(autoenable); //$NON-NLS-1$ - buffer.append("\n\timmediate = ").append(immediate); //$NON-NLS-1$ - - buffer.append("\n\timplementation = ").append(implementation); //$NON-NLS-1$ - buffer.append("\n\tstate = ").append(SCRUtil.getStateStringRepresentation(state)); //$NON-NLS-1$ - StringBuffer buf = new StringBuffer(200); - if (properties != null) { - buf.append('{'); - Enumeration keys = properties.keys(); - while (keys.hasMoreElements()) { - Object key = keys.nextElement(); - buf.append(key).append('=').append(SCRUtil.getStringRepresentation(properties.get(key))); - if (keys.hasMoreElements()) { - buf.append(", "); //$NON-NLS-1$ - } - } - buf.append('}'); - } - buffer.append("\n\tproperties = ").append(buf.toString()); //$NON-NLS-1$ - - buffer.append("\n\tserviceFactory = ").append(serviceFactory); //$NON-NLS-1$ - buffer.append("\n\tserviceInterface = ").append(serviceInterfaces); //$NON-NLS-1$ - - if (references == null) { - buffer.append("\n\treferences = ").append("null"); //$NON-NLS-1$ //$NON-NLS-2$ - } else { - buffer.append("\n\treferences = {"); //$NON-NLS-1$ - for (int i = 0; i < references.size(); i++) { - buffer.append("\n\t\t").append(references.elementAt(i)); //$NON-NLS-1$ - } - buffer.append("\n\t}"); //$NON-NLS-1$ - } - buffer.append("\n\tlocated in bundle = ").append(bundle); //$NON-NLS-1$ - buffer.append("\n]"); //$NON-NLS-1$ - return buffer.toString(); - } - - public synchronized void writeObject(OutputStream s) throws Exception { - try { - DataOutputStream out; - if (s instanceof DataOutputStream) { - out = (DataOutputStream) s; - } else { - out = new DataOutputStream(s); - } - - boolean flag; - int count; - - out.writeUTF(name); - out.writeUTF(implementation); - out.writeBoolean(serviceFactory); - out.writeBoolean(autoenable); - out.writeBoolean(immediate); - - flag = factory != null; - out.writeBoolean(flag); - if (flag) - out.writeUTF(factory); - - count = serviceInterfaces == null ? 0 : serviceInterfaces.size(); - out.writeInt(count); - for (int i = 0; i < count; i++) { - out.writeUTF(serviceInterfaces.elementAt(i).toString()); - } - - count = references == null ? 0 : references.size(); - out.writeInt(count); - for (int i = 0; i < count; i++) { - ComponentReference ref = (ComponentReference) references.elementAt(i); - ref.writeObject(out); - } - - flag = properties != null && !properties.isEmpty(); - out.writeBoolean(flag); - if (flag) { - ExternalizableDictionary dictionary = new ExternalizableDictionary(); - dictionary.copyFrom(properties); - dictionary.writeObject(out); - } - - out.writeInt(namespace); - if (isNamespaceAtLeast11()) { - if (configurationPolicy == CONF_POLICY_OPTIONAL) { - //this is the default value. Do not write it. Just add a mark - out.writeBoolean(false); - } else { - out.writeBoolean(true); - out.writeUTF(configurationPolicy); - } - if (!activateMethodDeclared) { - //this is the default value. Do not write it. Just add a mark - out.writeBoolean(false); - } else { - out.writeBoolean(true); - out.writeUTF(activateMethodName); - } - if (!deactivateMethodDeclared) { - //this is the default value. Do not write it. Just add a mark - out.writeBoolean(false); - } else { - out.writeBoolean(true); - out.writeUTF(deactivateMethodName); - } - if (modifyMethodName == "") { //$NON-NLS-1$ - //this is the default value. Do not write it. Just add a mark - out.writeBoolean(false); - } else { - out.writeBoolean(true); - out.writeUTF(modifyMethodName); - } - } - if (isNamespaceAtLeast12()) { - if (configurationPID == name) { - out.writeBoolean(false); - } else { - out.writeBoolean(true); - out.writeUTF(configurationPID); - } - } - } catch (Exception e) { - Activator.log(null, LogService.LOG_ERROR, Messages.ERROR_WRITING_OBJECT, e); - throw e; - } - } - - /** - * Don't forget to set the bundle & the bc attributes!!!!!! - * - * @param s - * the input stream from which to read the object - * @throws Exception - * @see org.eclipse.equinox.internal.util.io.Externalizable#readObject(java.io.InputStream) - */ - public synchronized void readObject(InputStream s) throws Exception { - try { - DataInputStream in; - if (s instanceof DataInputStream) { - in = (DataInputStream) s; - } else { - in = new DataInputStream(s); - } - boolean flag; - int count; - - name = in.readUTF(); - implementation = in.readUTF(); - serviceFactory = in.readBoolean(); - autoenable = in.readBoolean(); - immediate = in.readBoolean(); - - flag = in.readBoolean(); - if (flag) - factory = in.readUTF(); - - count = in.readInt(); - if (count > 0) { - serviceInterfaces = new Vector(count); - provides = new String[count]; - for (int i = 0; i < count; i++) { - String entry = in.readUTF(); - serviceInterfaces.addElement(entry); - provides[i] = entry; - } - } - - count = in.readInt(); - if (count > 0) { - references = new Vector(count); - for (int i = 0; i < count; i++) { - ComponentReference ref = new ComponentReference(this); - ref.readObject(in); - } - } - - flag = in.readBoolean(); - if (flag) { - ExternalizableDictionary dictionary = new ExternalizableDictionary(); - dictionary.readObject(in); - Properties props = new Properties(); - for (Enumeration keys = dictionary.keys(); keys.hasMoreElements();) { - String key = (String) keys.nextElement(); - props.put(key, dictionary.get(key)); - } - properties = props; - } - namespace = in.readInt(); - if (isNamespaceAtLeast11()) { - flag = in.readBoolean(); - if (flag) { - configurationPolicy = in.readUTF(); - if (configurationPolicy.equals(CONF_POLICY_IGNORE)) { - configurationPolicy = CONF_POLICY_IGNORE; - } else { - configurationPolicy = CONF_POLICY_REQUIRE; - } - } - flag = in.readBoolean(); - if (flag) { - activateMethodName = in.readUTF(); - activateMethodDeclared = true; - } - flag = in.readBoolean(); - if (flag) { - deactivateMethodName = in.readUTF(); - deactivateMethodDeclared = true; - } - flag = in.readBoolean(); - if (flag) - modifyMethodName = in.readUTF(); - } - if (isNamespaceAtLeast12()) { - flag = in.readBoolean(); - if (flag) { - configurationPID = in.readUTF(); - } else { - configurationPID = name; - } - } - } catch (Exception e) { - Activator.log(null, LogService.LOG_ERROR, Messages.ERROR_READING_OBJECT, e); - throw e; - } - } - - public ServiceComponentProp getComponentPropByPID(String pid) { - if (componentProps != null) { - for (int i = 0; i < componentProps.size(); i++) { - ServiceComponentProp scp = (ServiceComponentProp) componentProps.elementAt(i); - if (scp.getProperties() != null) { - if (pid.equals(scp.getProperties().get(Constants.SERVICE_PID))) { - return scp; - } - } - } - } - return null; - } - - public void addServiceComponentProp(ServiceComponentProp scp) { - if (componentProps == null) { - componentProps = new Vector(1); - } - componentProps.addElement(scp); - } - - /** - * Return the ServiceComponentProp object created for this component. Note there might be more than one SCP objects. - * This method will return always the first one - * @return the ServiceComponentProp object created for this component - */ - public ServiceComponentProp getServiceComponentProp() { - if (componentProps != null) { - synchronized (componentProps) { - if (!componentProps.isEmpty()) { - return (ServiceComponentProp) componentProps.elementAt(0); - } - } - } - return null; - } - - public boolean isNamespaceAtLeast11() { - return namespace >= NAMESPACE_1_1; - } - - public boolean isNamespaceAtLeast12() { - return namespace >= NAMESPACE_1_2; - } - - public boolean isImmediate() { - return immediate; - } - - public void setImmediate(boolean immediate) { - this.immediate = immediate; - } - - public String getConfigurationPolicy() { - return configurationPolicy; - } - - public void disable() { - if (getState() == STATE_DISPOSED) { - throw new IllegalStateException(Messages.COMPONENT_DISPOSED); - } else if (getState() != STATE_DISABLED) { - InstanceProcess.resolver.mgr.disableComponent(name, bundle); - } - } - - public void enable() { - if (getState() == STATE_DISPOSED) { - throw new IllegalStateException(Messages.COMPONENT_DISPOSED); - } else if (getState() == STATE_DISABLED) { - InstanceProcess.resolver.mgr.enableComponent(name, bundle); - } - } - - public String getActivate() { - return activateMethodName; - } - - public Bundle getBundle() { - return bundle; - } - - public String getClassName() { - return implementation; - } - - public ComponentInstance getComponentInstance() { - if (componentProps != null && !componentProps.isEmpty()) { - //get the first built compoent's instance - Vector instances = ((ServiceComponentProp) componentProps.elementAt(0)).instances; - if (!instances.isEmpty()) { - return (ComponentInstance) instances.elementAt(0); - } - } - //The component is not yet built - return null; - } - - public String getDeactivate() { - return deactivateMethodName; - } - - public String getFactory() { - return factory; - } - - public long getId() { - if (componentProps != null && !componentProps.isEmpty()) { - //get the first built component's ID - return ((Long) ((ServiceComponentProp) componentProps.elementAt(0)).properties.get(ComponentConstants.COMPONENT_ID)).longValue(); - } - //The component is not yet given an ID by the SRC because it is not active - return -1; - } - - public String getModified() { - if (!isNamespaceAtLeast11()) { - return null; - } - return modifyMethodName; - } - - public String getName() { - return name; - } - - public Dictionary getProperties() { - if (readOnlyProps == null) { - readOnlyProps = new ReadOnlyDictionary(properties); - } else { - // the scp properties may have been modified by configuration - // update the instance with the current properties - readOnlyProps.updateDelegate(properties); - } - return readOnlyProps; - } - - public Reference[] getReferences() { - if (references != null && !references.isEmpty()) { - org.apache.felix.scr.Reference[] res = new org.apache.felix.scr.Reference[references.size()]; - references.copyInto(res); - return res; - } - return null; - } - - public String[] getServices() { - return provides; - } - - public int getState() { - //check if there is at least one SCP created and return its state - if (componentProps != null && !componentProps.isEmpty()) { - //get the first component's state - return ((ServiceComponentProp) componentProps.elementAt(0)).getState(); - } - //return the current state of the component - return state; - } - - public boolean isActivateDeclared() { - if (!isNamespaceAtLeast11()) { - return false; - } - return activateMethodDeclared; - } - - public boolean isDeactivateDeclared() { - if (!isNamespaceAtLeast11()) { - return false; - } - return deactivateMethodDeclared; - } - - public boolean isDefaultEnabled() { - return autoenable; - } - - public boolean isServiceFactory() { - return serviceFactory; - } - - public void setState(int newState) { - state = newState; - } -} \ No newline at end of file diff --git a/bundles/org.eclipse.equinox.ds/src/org/eclipse/equinox/internal/ds/model/ServiceComponentProp.java b/bundles/org.eclipse.equinox.ds/src/org/eclipse/equinox/internal/ds/model/ServiceComponentProp.java deleted file mode 100644 index 0d888d56a..000000000 --- a/bundles/org.eclipse.equinox.ds/src/org/eclipse/equinox/internal/ds/model/ServiceComponentProp.java +++ /dev/null @@ -1,928 +0,0 @@ -/******************************************************************************* - * Copyright (c) 1997-2012 by ProSyst Software GmbH - * http://www.prosyst.com - * 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: - * ProSyst Software GmbH - initial API and implementation - * Joerg-Christian Boehme - bug.id = 246757 - *******************************************************************************/ -package org.eclipse.equinox.internal.ds.model; - -import java.security.*; -import java.util.*; -import org.apache.felix.scr.Component; -import org.eclipse.equinox.internal.ds.*; -import org.eclipse.equinox.internal.ds.impl.*; -import org.eclipse.osgi.util.NLS; -import org.osgi.framework.*; -import org.osgi.service.component.*; -import org.osgi.service.log.LogService; - -/** - * The ServiceComponentProp represents a ServiceComponent mapped to it's CM - * properties. - * - * When the ServiceComponent contains plain CM properties, the mapping of - * ServiceComponentProp to ServiceComponent is 1:1. - * - * However, when the ServiceComponent is a ManagedServiceFactory, there are so - * many ServiceComponentProp objects created as many are the configurations - * associated with the component. - * - * @author Valentin Valchev - * @author Stoyan Boshev - * @author Pavlin Dobrev - */ - -public class ServiceComponentProp implements Component, PrivilegedExceptionAction { - - public ServiceRegistration registration; - public String name; - public ServiceComponent serviceComponent; - public Hashtable properties; - public Vector instances = new Vector(2); // ComponentInstance objects - public BundleContext bc; - public Vector references; - - // This flag is used to check whether the component is a component factory. - // Since the component factory creates new ServiceComponentProp objects they - // have to - // be marked as non component factory components in order to prevent newly - // registered - // component factories as services. - protected boolean isComponentFactory = false; - - //Holds the component's state - private int state = STATE_UNSATISFIED; - - /** - * List of names (Strings) of Component Configurations we should not - * activate during the activation of this Component Configuration. This is - * populated by the {@link org.eclipse.equinox.internal.ds.Resolver Resolver} - * and used by - * {@link org.eclipse.equinox.internal.ds.InstanceProcess InstanceProcess}. - */ - protected Vector delayActivateSCPNames; - - private SCRManager mgr; - private ReadOnlyDictionary readOnlyProps; - - // next free component id - private static long componentid = 0; - - public ServiceComponentProp(ServiceComponent serviceComponent, Dictionary configProperties, SCRManager mgr) { - - this.serviceComponent = serviceComponent; - this.name = serviceComponent.name; - this.bc = serviceComponent.bc; - - properties = initProperties(configProperties, null); - - isComponentFactory = serviceComponent.factory != null; - - // used for component context - this.mgr = mgr; - } - - /** - * This method will dispose the service component instance. Along with the - * service component itself and the properties files. - */ - public void dispose(int deactivateReason) { - if (Activator.DEBUG) { - Activator.log.debug("ServiceComponentProp.dispose(): " + name, null); //$NON-NLS-1$ - } - try { - while (!instances.isEmpty()) { - ComponentInstanceImpl current = (ComponentInstanceImpl) instances.firstElement(); - dispose(current, deactivateReason); - current.dispose(); - } - } finally { - setState(STATE_UNSATISFIED); - } - } - - /** - * getProperties - * - * @return Dictionary properties - */ - public Dictionary getProperties() { - if (readOnlyProps == null) { - readOnlyProps = new ReadOnlyDictionary(properties != null ? properties : serviceComponent.properties); - } else { - // the scp properties may have been modified by configuration - // update the instance with the current properties - readOnlyProps.updateDelegate(properties != null ? properties : serviceComponent.properties); - } - return readOnlyProps; - } - - /** - * This method will call the activate method on the specified object. - * - * @param usingBundle - * the bundle that is using the component - this has only means - * when the component is factory - * @param componentInstance - * the component instance which will be activated. - * @throws Exception - * could be thrown if the activate fails for some reason but NOT - * in case, if the instance doesn't define an activate method. - */ - public void activate(Bundle usingBundle, ComponentInstanceImpl componentInstance) throws Exception { - if (Activator.DEBUG) { - Activator.log.debug("~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ServiceComponentProp.activate(): name: " + name, null); //$NON-NLS-1$ - Activator.log.debug("~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ServiceComponentProp.activate(): using bundle: " + (usingBundle != null ? usingBundle.getSymbolicName() : null), null); //$NON-NLS-1$ - Activator.log.debug("~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ServiceComponentProp.activate(): instance: " + componentInstance.toString(), null); //$NON-NLS-1$ - } - - // call the activate method on the Service Component - serviceComponent.activate(componentInstance.getInstance(), componentInstance.getComponentContext()); - } - - /** - * This method will call the deactivate method on the specified Object. - * Notice, that this is not the ComponentInstance object, but the real - * instance. - * - * @param componentInstance - * component instance wrapper - */ - private void deactivate(ComponentInstanceImpl componentInstance, int deactivateReason) { - if (Activator.DEBUG) { - Activator.log.debug("ServiceComponentProp.deactivate(): " + name, null); //$NON-NLS-1$ - } - serviceComponent.deactivate(componentInstance.getInstance(), componentInstance.getComponentContext(), deactivateReason); - } - - /** - * This method will update the properties of the component - * - * @param newProps - * the new properties - * @throws Exception - * could be thrown if the modify method fails for some reason but NOT - * in case, if the instance doesn't define modify method - */ - public void modify(Dictionary newProps) throws Exception { - if (Activator.DEBUG) { - Activator.log.debug("~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ServiceComponentProp.modify(): name: " + name, null); //$NON-NLS-1$ - } - Hashtable oldProperties = null; - if (references != null && references.size() > 0) { - oldProperties = (Hashtable) properties.clone(); - } - //1. update the properties - properties = initProperties(newProps, (Long) properties.get(ComponentConstants.COMPONENT_ID)); - //2. call the modify method on the Service Component for all instances of this scp - for (int i = 0; i < instances.size(); i++) { - ComponentInstanceImpl componentInstance = (ComponentInstanceImpl) instances.elementAt(i); - Activator.log.debug("~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ServiceComponentProp.modify(): instance: " + componentInstance.toString(), null); //$NON-NLS-1$ - serviceComponent.modified(componentInstance.getInstance(), componentInstance.getComponentContext()); - } - //3. modify the bound services if necessary - if (oldProperties != null) { - handleBoundServicesUpdate(oldProperties, properties); - } - - //4. if the component configuration is registered as a service, - // modify the service’s service properties - if (registration != null) { - registration.setProperties(getPublicServiceProperties()); - } - } - - /** - * Call the bind method for each of the Referenced Services in this Service - * Component - * - * @param componentInstance - * @return true if all mandatory references are bound - * @throws Exception - */ - public boolean bind(ComponentInstance componentInstance) throws Exception { - // Get all the required service Reference Descriptions for this ServiceComponent - // call the Bind method if the Reference Description includes one - if (references != null) { - for (int i = 0; i < references.size(); i++) { - Reference ref = (Reference) references.elementAt(i); - ClassCircularityError ccError = null; - if (ref.reference.bind != null) { - try { - bindReference(ref, componentInstance); - } catch (ClassCircularityError cce) { - ccError = cce; - Activator.log(bc, LogService.LOG_ERROR, NLS.bind(Messages.ERROR_BINDING_REFERENCE, ref.reference), cce); - } - if (ref.reference.bindMethod == null || ccError != null || !ref.isBound()) { - //the bind method is not found and called for some reason or it has thrown exception - Activator.log(null, ref.isOptional() ? LogService.LOG_DEBUG : LogService.LOG_ERROR, "Could not bind a reference of component " + name + ". The reference is: " + ref.reference, null); //$NON-NLS-1$ //$NON-NLS-2$ - if (ccError != null) { - //unbind the already bound references - for (int j = i - 1; j >= 0; j--) { - ref = (Reference) references.elementAt(j); - if (ref.reference.unbind != null) { - unbindReference(ref, componentInstance); - } - } - //rethrow the error so it is further processed according to the use case - throw ccError; - } - // continue nevertheless the bind is unsuccessful - see bug 388961 - } - } else { - if (Activator.DEBUG) { - Activator.log.debug("ServiceComponentProp.bind(): the folowing reference doesn't specify bind method: " + ref.reference.name, null); //$NON-NLS-1$ - } - } - } - } - return true; - } - - /** - * Call the unbind method for each of the Referenced Services in this - * Serivce Component - * - * @param componentInstance - * the object which unbind method(s) will be called, if ANY! - */ - public void unbind(ComponentInstance componentInstance) { - // call the unBind method if the Reference Description includes one - if (references != null) { - for (int i = references.size() - 1; i >= 0; i--) { - Reference ref = (Reference) references.elementAt(i); - if (ref.reference.unbind != null) { - unbindReference(ref, componentInstance); - } - } - } - } - - public Object createInstance() throws Exception { - assertCreateSingleInstance(); - return serviceComponent.createInstance(); - } - - boolean locked = false; - int waiting = 0; - - Bundle bundle; - Object inst; - - synchronized void lock(Bundle usingBundle, Object instance) { - while (locked) { - try { - waiting++; - wait(); - } catch (Exception _) { - // - } - waiting--; - } - locked = true; - bundle = usingBundle; - inst = instance; - } - - synchronized void unlock() { - locked = false; - bundle = null; - inst = null; - if (waiting > 0) - notifyAll(); - } - - public Object run() throws Exception { - Bundle b = this.bundle; - Object instance = inst; - unlock(); - return build(b, instance, false); - } - - public ComponentInstanceImpl build(Bundle usingBundle, Object instance, boolean security) throws Exception { - if (getState() == STATE_DISPOSED) { - if (Activator.DEBUG) { - Activator.log.debug("Cannot build component, because it is already disposed: " + this, null); //$NON-NLS-1$ - } - return null; - } - - if (security) { - this.lock(usingBundle, instance); - try { - return (ComponentInstanceImpl) AccessController.doPrivileged(this); - } catch (PrivilegedActionException pae) { - // - } - } - ComponentInstanceImpl componentInstance = null; - if (instance == null) { - if (!serviceComponent.serviceFactory) { - // it is a plain service, this is because this method - // is also called from ServiceReg - if (instances.isEmpty()) { - instance = createInstance(); - } else { - componentInstance = (ComponentInstanceImpl) instances.firstElement(); - } - } else { - instance = createInstance(); - } - } - if (componentInstance == null) { - componentInstance = new ComponentInstanceImpl(instance, this); - componentInstance.setComponentContext(new ComponentContextImpl(this, usingBundle, componentInstance, mgr)); - instances.addElement(componentInstance); - if (bind(componentInstance)) { - try { - activate(usingBundle, componentInstance); - } catch (Exception e) { - //must unbind and dispose this component instance - InstanceProcess.resolver.removeFromSatisfiedList(this); - if (instances.removeElement(componentInstance)) { - unbind(componentInstance); - } - throw e; - } - } else { - //must remove from satisfied list and remove the instance - InstanceProcess.resolver.removeFromSatisfiedList(this); - instances.removeElement(componentInstance); - throw new ComponentException(NLS.bind(Messages.COMPONENT_WAS_NOT_BUILT, serviceComponent)); - } - } - setState(Component.STATE_ACTIVE); - return componentInstance; - } - - public void disposeObj(Object obj, int deactivateReason) { - ComponentInstanceImpl ci = null; - synchronized (instances) { - for (int i = 0; i < instances.size(); i++) { - ci = (ComponentInstanceImpl) instances.elementAt(i); - if (ci.getInstance() == obj) { - break; - } - ci = null; - } - } - if (ci != null) { - dispose(ci, deactivateReason); - return; - } - throw new RuntimeException(NLS.bind(Messages.INVALID_OBJECT, obj, name)); - } - - public void dispose(ComponentInstanceImpl componentInstance, int deactivateReason) { - if (!instances.removeElement(componentInstance)) { - return; //the instance is already disposed - } - deactivate(componentInstance, deactivateReason); - unbind(componentInstance); - if (instances.isEmpty()) { - //there are no active instances. The component is lazy enabled now - setState(Component.STATE_REGISTERED); - } - } - - /** - * Call the bind method for this referenceDescription - * - * @param componentReference - * @param componentInstance - * @throws Exception - * - */ - public void bindReference(Reference reference, ComponentInstance componentInstance) throws Exception { - - if (Activator.DEBUG) { - Activator.log.debug("ServiceComponentProp.bindReference(): component " + serviceComponent.name + " -> " + reference.reference, null); //$NON-NLS-1$ //$NON-NLS-2$ - } - - ServiceReference[] serviceReferences = null; - - // if there is a published service, then get the ServiceObject and call bind - try { - // get all registered services using this target filter - serviceReferences = bc.getServiceReferences(reference.reference.interfaceName, reference.getTarget()); - } catch (Exception e) { - Activator.log(bc, LogService.LOG_ERROR, NLS.bind(Messages.CANNOT_GET_REFERENCES, reference.reference.interfaceName), e); - throw e; - // rethrow exception so resolver is eventually notified that this SCP is bad - } - - // bind only if there is at least ONE service - if (serviceReferences != null && serviceReferences.length > 0) { - // the component binds to the first available service only! - if (reference.reference.bind != null) { - switch (reference.reference.cardinality) { - case ComponentReference.CARDINALITY_1_1 : - case ComponentReference.CARDINALITY_0_1 : - for (int i = 0; i < serviceReferences.length; i++) { - ServiceReference oldBoundService = (reference.reference.policy_option == ComponentReference.POLICY_OPTION_GREEDY && reference.reference.serviceReferences.size() > 0 ? (ServiceReference) reference.reference.serviceReferences.keys().nextElement() : null); - boolean bound = reference.reference.bind(reference, componentInstance, serviceReferences[i]); - if (bound) { - if (oldBoundService != null) { - //unbind the previous bound service reference in case we are handling service reference update due to greedy policy option - reference.reference.unbind(reference, componentInstance, oldBoundService); - } - break; - } - } - break; - case ComponentReference.CARDINALITY_1_N : - case ComponentReference.CARDINALITY_0_N : - // bind to all services - for (int i = 0; i < serviceReferences.length; i++) { - reference.reference.bind(reference, componentInstance, serviceReferences[i]); - } - break; - } - } else if (reference.reference.policy == ComponentReference.POLICY_STATIC) { - //in case there is no bind method for static reference save the current matching service references - reference.setBoundServiceReferences(serviceReferences); - } - } else { - if (Activator.DEBUG) { - Activator.log.debug("ServiceComponentProp.bindReference(): The service is not yet registered, but it is already instantiated", null); //$NON-NLS-1$ - } - } - } - - /** - * Handles the update of the bound services in case the target properties have changed - * @param oldProps the old component properties - * @param newProps the new component properties - */ - private void handleBoundServicesUpdate(Hashtable oldProps, Dictionary newProps) { - Enumeration keys = oldProps.keys(); - Vector checkedFilters = new Vector(); - //check for changed target filters in the properties - while (keys.hasMoreElements()) { - String key = (String) keys.nextElement(); - if (key.endsWith(".target")) { //$NON-NLS-1$ - checkedFilters.addElement(key); - String newFilter = (String) newProps.get(key); - Reference reference = null; - String refName = key.substring(0, key.length() - ".target".length()); //$NON-NLS-1$ - for (int i = 0; i < references.size(); i++) { - reference = (Reference) references.elementAt(i); - if (reference.reference.name.equals(refName)) { - break; - } - reference = null; - } - //check if there is a reference corresponding to the target property - if (reference != null && reference.reference.policy == ComponentReference.POLICY_DYNAMIC) { - if (newFilter != null) { - if (!newFilter.equals(oldProps.get(key))) { - //the filter differs the old one - update the reference bound services - processReferenceBoundServices(reference, newFilter); - } - } else { - //the target filter is removed. using the default one - processReferenceBoundServices(reference, "(objectClass=" + reference.reference.interfaceName + ")"); //$NON-NLS-1$ //$NON-NLS-2$ - } - } - } - } - //now check for newly added target filters - keys = newProps.keys(); - while (keys.hasMoreElements()) { - String key = (String) keys.nextElement(); - if (key.endsWith(".target") && !checkedFilters.contains(key)) { //$NON-NLS-1$ - Reference reference = null; - String refName = key.substring(0, key.length() - ".target".length()); //$NON-NLS-1$ - for (int i = 0; i < references.size(); i++) { - reference = (Reference) references.elementAt(i); - if (reference.reference.name.equals(refName)) { - break; - } - reference = null; - } - //check if there is a reference corresponding to the target property - if (reference != null && reference.reference.policy == ComponentReference.POLICY_DYNAMIC) { - processReferenceBoundServices(reference, (String) newProps.get(key)); - } - } - } - } - - private void processReferenceBoundServices(Reference reference, String newTargetFilter) { - reference.setTarget(newTargetFilter); - ServiceReference[] refs = null; - try { - refs = bc.getServiceReferences(reference.reference.interfaceName, newTargetFilter); - } catch (InvalidSyntaxException e) { - Activator.log(bc, LogService.LOG_WARNING, "[SCR] " + NLS.bind(Messages.INVALID_TARGET_FILTER, newTargetFilter), e); //$NON-NLS-1$ - return; - } - - if (refs == null) { - //must remove all currently bound services - if (reference.reference.bind != null) { - if (reference.reference.serviceReferences.size() > 0) { - for (int i = 0; i < instances.size(); i++) { - ComponentInstance componentInstance = (ComponentInstance) instances.elementAt(i); - unbindReference(reference, componentInstance); - } - } - } - } else { - //find out which services has to be bound and which unbound - if (reference.reference.bind != null) { - Vector servicesToUnbind = new Vector(); - Enumeration keys = reference.reference.serviceReferences.keys(); - while (keys.hasMoreElements()) { - Object serviceRef = keys.nextElement(); - boolean found = false; - for (int i = 0; i < refs.length; i++) { - if (refs[i] == serviceRef) { - found = true; - break; - } - } - if (!found) { - //the bound service reference is not already in the satisfied references set. - servicesToUnbind.addElement(serviceRef); - } - } - if ((reference.reference.cardinality == ComponentReference.CARDINALITY_0_N || reference.reference.cardinality == ComponentReference.CARDINALITY_1_N) && (reference.reference.serviceReferences.size() - servicesToUnbind.size()) < refs.length) { - //there are more services to bind - for (int i = 0; i < refs.length; i++) { - keys = reference.reference.serviceReferences.keys(); - boolean found = false; - while (keys.hasMoreElements()) { - Object serviceRef = keys.nextElement(); - if (serviceRef == refs[i]) { - found = true; - break; - } - } - if (!found) { - for (int j = 0; j < instances.size(); j++) { - ComponentInstance componentInstance = (ComponentInstance) instances.elementAt(j); - try { - reference.reference.bind(reference, componentInstance, refs[i]); - } catch (Exception e) { - Activator.log(null, LogService.LOG_ERROR, NLS.bind(Messages.ERROR_BINDING_REFERENCE, reference), e); - } - } - } - } - } - //finally unbind all services that do not match the target filter - for (int i = 0; i < servicesToUnbind.size(); i++) { - for (int j = 0; j < instances.size(); j++) { - ComponentInstance componentInstance = (ComponentInstance) instances.elementAt(j); - try { - unbindDynamicReference(reference, componentInstance, (ServiceReference) servicesToUnbind.elementAt(i)); - } catch (Exception e) { - Activator.log(null, LogService.LOG_ERROR, NLS.bind(Messages.ERROR_UNBINDING_REFERENCE2, reference), e); - } - } - } - } - } - } - - /** - * Call the unbind method for this Reference Description - * - * @param reference - * @param componentInstance - */ - public void unbindReference(Reference reference, ComponentInstance componentInstance) { - - // unbind the services ONLY if unbind method is specified! - if (reference.reference.unbind == null) { - return; - } - - // ok, proceed! - - if (Activator.DEBUG) { - Activator.log.debug("ServiceComponentProp.unbindReference(): component " + serviceComponent.name + " <- " + reference.reference, null); //$NON-NLS-1$ //$NON-NLS-2$ - } - - Enumeration serviceReferences = reference.reference.serviceReferences.keys(); - while (serviceReferences.hasMoreElements()) { - reference.reference.unbind(reference, componentInstance, (ServiceReference) serviceReferences.nextElement()); - } - } - - /** - * Call the unbind method for this Reference Description - * - * @param ref - * @param instance - * @param serviceObject - * @throws Exception - */ - public void unbindDynamicReference(Reference ref, ComponentInstance instance, ServiceReference serviceReference) throws Exception { - if (Activator.DEBUG) { - Activator.log.debug("ServiceComponentProp.unbindDynamicReference(): component = " + name + ", reference = " + ref.reference.name, null); //$NON-NLS-1$ //$NON-NLS-2$ - } - // check if we need to rebind - switch (ref.reference.cardinality) { - case ComponentReference.CARDINALITY_0_1 : - case ComponentReference.CARDINALITY_1_1 : - if (ref.reference.bind != null) { - bindReference(ref, instance); - } - } - ref.reference.unbind(ref, instance, serviceReference); - } - - /** - * Call the updated method for this Reference - * - * @param ref the reference - * @param instance the component instance - * @param serviceReference the service reference which properties have changed - */ - public void updatedReference(Reference ref, ComponentInstance instance, ServiceReference serviceReference) { - if (Activator.DEBUG) { - Activator.log.debug("ServiceComponentProp.updatedReference(): component = " + name + ", reference = " + ref.reference.name, null); //$NON-NLS-1$ //$NON-NLS-2$ - } - ref.reference.updated(ref, instance, serviceReference); - } - - // -- begin helper methods - /** - * Initialize Properties for this Component - * - * The property elements provide default or supplemental property values if - * not overridden by the properties retrieved from Configuration Admin - * - * @param configProperties - * the configuration properties - * @param componentId specifies the component ID. If null, a new one will be generated - * @return the fully initialized properties - */ - private Hashtable initProperties(Dictionary configProperties, Long componentId) { - Hashtable result = null; - // default component service properties - Properties propertyDescriptions = serviceComponent.properties; - if (propertyDescriptions != null && !propertyDescriptions.isEmpty()) { - result = (Hashtable) propertyDescriptions.clone(); - } - - // set the component.name - if (result == null) { - result = new Hashtable(7); - } - - // put the references in the properties - if (serviceComponent.references != null) { - ComponentReference ref; - for (int i = 0; i < serviceComponent.references.size(); i++) { - ref = (ComponentReference) serviceComponent.references.elementAt(i); - if (ref.target != null) { - result.put(ref.name + ComponentConstants.REFERENCE_TARGET_SUFFIX, ref.target); - } - } - } - - // properties from Configuration Admin - if (configProperties != null && !configProperties.isEmpty()) { - for (Enumeration keys = configProperties.keys(); keys.hasMoreElements();) { - Object key = keys.nextElement(); - Object val = configProperties.get(key); - result.put(key, val); - } - } - - // always set the component name & the id - Long nextId = (componentId == null) ? new Long(getNewComponentID()) : componentId; - result.put(ComponentConstants.COMPONENT_ID, nextId); - result.put(ComponentConstants.COMPONENT_NAME, serviceComponent.name); - - if (serviceComponent.provides != null) { - String[] provides = new String[serviceComponent.provides.length]; - System.arraycopy(serviceComponent.provides, 0, provides, 0, provides.length); - result.put(Constants.OBJECTCLASS, provides); - } - return result; - } - - private void assertCreateSingleInstance() { - if (!serviceComponent.serviceFactory && !instances.isEmpty()) { - throw new ComponentException(NLS.bind(Messages.INSTANCE_ALREADY_CREATED, name)); - } - } - - public String toString() { - StringBuffer buffer = new StringBuffer(); - buffer.append("ServiceComponentProp["); //$NON-NLS-1$ - buffer.append("\n\tname = ").append(name); //$NON-NLS-1$ - buffer.append("\n\tstate = ").append(SCRUtil.getStateStringRepresentation(state)); //$NON-NLS-1$ - StringBuffer buf = new StringBuffer(200); - if (properties != null) { - buf.append('{'); - Enumeration keys = properties.keys(); - while (keys.hasMoreElements()) { - Object key = keys.nextElement(); - buf.append(key).append('=').append(SCRUtil.getStringRepresentation(properties.get(key))); - if (keys.hasMoreElements()) { - buf.append(", "); //$NON-NLS-1$ - } - } - buf.append('}'); - } - buffer.append("\n\tproperties = ").append(buf.toString()); //$NON-NLS-1$ - buffer.append("]"); //$NON-NLS-1$ - return buffer.toString(); - } - - public void setRegistration(ServiceRegistration reg) { - registration = reg; - } - - /** - * Removes the private properties and returns the public properties that are set to the registered service provided by this component - * @return the public properties used in the registration of the service which is provided by this component - */ - public Hashtable getPublicServiceProperties() { - //remove the private properties from the component properties before registering as service - Hashtable publicProps = (Hashtable) properties.clone(); - Enumeration keys = properties.keys(); - while (keys.hasMoreElements()) { - String key = (String) keys.nextElement(); - if (key.startsWith(".")) { //$NON-NLS-1$ - publicProps.remove(key); - } - } - return publicProps; - } - - /** - * Add a new Component Configuration name we should not activate in order to - * prevent a cycle. - * - * @see ServiceComponentProp#delayActivateSCPNames - */ - public void setDelayActivateSCPName(String scpName) { - if (Activator.DEBUG) { - Activator.log.debug("Setting delay activate SCP: " + scpName, null); //$NON-NLS-1$ - } - if (delayActivateSCPNames == null) { - delayActivateSCPNames = new Vector(1); - delayActivateSCPNames.addElement(scpName); - } else if (!delayActivateSCPNames.contains(scpName)) { - delayActivateSCPNames.addElement(scpName); - } - } - - public Vector getDelayActivateSCPNames() { - return delayActivateSCPNames; - } - - public boolean isComponentFactory() { - return isComponentFactory; - } - - // used by the ComponentFactoryImpl to mark component configs created by it - // that - // they are not component factories. This avoids subsecuent registrations of - // the same component factory. - public void setComponentFactory(boolean isComponentFactory) { - this.isComponentFactory = isComponentFactory; - } - - static synchronized long getNewComponentID() { - return componentid++; - } - - public boolean isKindOfFactory() { - return serviceComponent.serviceFactory; - } - - public synchronized int getState() { - return state; - } - - public synchronized void setState(int state) { - this.state = state; - } - - public void disable() { - if (getState() == STATE_DISPOSED) { - throw new IllegalStateException(Messages.COMPONENT_DISPOSED); - } else if (getState() != STATE_DISABLED) { - mgr.disableComponent(serviceComponent.name, serviceComponent.bundle); - } - } - - public void enable() { - if (getState() == STATE_DISPOSED) { - throw new IllegalStateException(Messages.COMPONENT_DISPOSED); - } else if (getState() == STATE_DISABLED) { - mgr.enableComponent(serviceComponent.name, serviceComponent.bundle); - } - } - - public String getActivate() { - return serviceComponent.activateMethodName; - } - - public Bundle getBundle() { - return serviceComponent.bundle; - } - - public String getClassName() { - return serviceComponent.implementation; - } - - public ComponentInstance getComponentInstance() { - if (!instances.isEmpty()) { - //TODO we have multiple instances when the component is service factory - //Perhaps we have to list in ScrService Component for each instance - return (ComponentInstance) instances.firstElement(); - } - return null; - } - - public String getConfigurationPolicy() { - return serviceComponent.configurationPolicy; - } - - public String getDeactivate() { - return serviceComponent.deactivateMethodName; - } - - public String getFactory() { - return serviceComponent.factory; - } - - public long getId() { - return ((Long) properties.get(ComponentConstants.COMPONENT_ID)).longValue(); - } - - public String getModified() { - if (!serviceComponent.isNamespaceAtLeast11()) { - return null; - } - return serviceComponent.modifyMethodName; - } - - public String getName() { - return serviceComponent.name; - } - - public org.apache.felix.scr.Reference[] getReferences() { - if (references != null && !references.isEmpty()) { - org.apache.felix.scr.Reference[] res = new org.apache.felix.scr.Reference[references.size()]; - references.copyInto(res); - return res; - } - return null; - } - - public String[] getServices() { - return serviceComponent.provides; - } - - public boolean isActivateDeclared() { - if (!serviceComponent.isNamespaceAtLeast11()) { - return false; - } - return serviceComponent.activateMethodDeclared; - } - - public boolean isDeactivateDeclared() { - if (!serviceComponent.isNamespaceAtLeast11()) { - return false; - } - return serviceComponent.deactivateMethodDeclared; - } - - public boolean isDefaultEnabled() { - return serviceComponent.autoenable; - } - - public boolean isImmediate() { - return serviceComponent.isImmediate(); - } - - public boolean isServiceFactory() { - return serviceComponent.serviceFactory; - } - - //Some helper methods according to the component's state - public boolean isBuilt() { - return state == STATE_ACTIVATING || state == STATE_ACTIVE || state == STATE_FACTORY || state == STATE_REGISTERED; - } - - public boolean isUnsatisfied() { - return state == STATE_UNSATISFIED || state == STATE_DEACTIVATING || state == STATE_DISABLED || state == STATE_DISPOSING || state == STATE_DISPOSED; - } - -} diff --git a/bundles/org.eclipse.equinox.ds/src/org/eclipse/equinox/internal/ds/storage/file/DBObject.java b/bundles/org.eclipse.equinox.ds/src/org/eclipse/equinox/internal/ds/storage/file/DBObject.java deleted file mode 100644 index 1f2620321..000000000 --- a/bundles/org.eclipse.equinox.ds/src/org/eclipse/equinox/internal/ds/storage/file/DBObject.java +++ /dev/null @@ -1,70 +0,0 @@ -/******************************************************************************* - * Copyright (c) 1997-2009 by ProSyst Software GmbH - * http://www.prosyst.com - * 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: - * ProSyst Software GmbH - initial API and implementation - *******************************************************************************/ -package org.eclipse.equinox.internal.ds.storage.file; - -import java.io.*; -import java.util.Vector; -import org.eclipse.equinox.internal.ds.model.ServiceComponent; - -/** - * Used for serialization of the DS components - * - * @author Nina Ruseva - * @author Pavlin Dobrev - */ - -public class DBObject implements Serializable { - private static final long serialVersionUID = 1L; - - public DBObject() { - // - } - - public Vector components; - - public DBObject(Vector components) { - this.components = components; - } - - public void writeObject(OutputStream out) throws Exception { - DataOutputStream dataOut; - if (out instanceof DataOutputStream) { - dataOut = (DataOutputStream) out; - } else { - dataOut = new DataOutputStream(out); - } - dataOut.writeInt(components == null ? 0 : components.size()); - if (components != null && components.size() > 0) { - for (int k = 0; k < components.size(); k++) { - ((ServiceComponent) components.elementAt(k)).writeObject(dataOut); - } - } - } - - public void readObject(InputStream in) throws Exception { - DataInputStream dataIn; - if (in instanceof DataInputStream) { - dataIn = (DataInputStream) in; - } else { - dataIn = new DataInputStream(in); - } - - int size = dataIn.readInt(); - components = new Vector(); - for (int k = 0; k < size; k++) { - ServiceComponent component = new ServiceComponent(); - component.readObject(dataIn); - components.addElement(component); - } - - } -} diff --git a/bundles/org.eclipse.equinox.ds/src/org/eclipse/equinox/internal/ds/storage/file/FileStorage.java b/bundles/org.eclipse.equinox.ds/src/org/eclipse/equinox/internal/ds/storage/file/FileStorage.java deleted file mode 100644 index 5c889e1b5..000000000 --- a/bundles/org.eclipse.equinox.ds/src/org/eclipse/equinox/internal/ds/storage/file/FileStorage.java +++ /dev/null @@ -1,258 +0,0 @@ -/******************************************************************************* - * Copyright (c) 1997, 2013 by ProSyst Software GmbH and others. - * http://www.prosyst.com - * 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: - * ProSyst Software GmbH - initial API and implementation - *******************************************************************************/ -package org.eclipse.equinox.internal.ds.storage.file; - -import java.io.*; -import java.net.URL; -import java.net.URLConnection; -import java.util.*; -import org.eclipse.equinox.internal.ds.*; -import org.eclipse.equinox.internal.ds.model.ServiceComponent; -import org.eclipse.equinox.internal.util.io.ExternalizableDictionary; -import org.eclipse.osgi.util.ManifestElement; -import org.eclipse.osgi.util.NLS; -import org.osgi.framework.*; -import org.osgi.service.component.ComponentConstants; -import org.osgi.service.log.LogService; - -/** - * This class implements a cache for the parsed component XML descriptions. - * - * @author Pavlin Dobrev - * @author Stoyan Boshev - */ - -public class FileStorage extends ComponentStorage { - - //TODO: this constant should be public and shared across other bundles that use the same property. - //Probably it should be in the supplement bundle? - public static final String PROP_CHECK_CONFIG = "osgi.checkConfiguration"; //$NON-NLS-1$ - - private static String CUSTOM_DB_NAME = "SCR"; //$NON-NLS-1$ - private BundleContext bc = null; - private ExternalizableDictionary data = new ExternalizableDictionary(); - private StringBuffer pathBuffer = new StringBuffer(); - private String separator; - private boolean isDirty = false; - - public FileStorage(BundleContext bc) { - this.bc = bc; - separator = bc.getProperty("path.separator"); //$NON-NLS-1$ - File file = bc.getDataFile(CUSTOM_DB_NAME); - FileInputStream fis = null; - try { - if (file != null && file.exists()) { - data.readObject(new BufferedInputStream(fis = new FileInputStream(file))); - } - } catch (IOException e) { - Activator.log(null, LogService.LOG_ERROR, NLS.bind(Messages.ERROR_LOADING_DATA_FILE, file.getAbsolutePath()), e); - } catch (Exception e) { - Activator.log(null, LogService.LOG_ERROR, NLS.bind(Messages.ERROR_LOADING_DATA_FILE, file.getAbsolutePath()), e); - } finally { - if (fis != null) { - try { - fis.close(); - } catch (Exception e) { - // ignore - } - } - } - } - - public Vector loadComponentDefinitions(Bundle bundle, String dsHeader) { - try { - Vector components = null; - if (!Activator.DBSTORE) { - return parseXMLDeclaration(bundle, dsHeader); - } - - long lastModified; - // if not dev mode, we simply use the bundle's timestamp - if (!Activator.getBoolean(PROP_CHECK_CONFIG)) { - lastModified = bundle.getLastModified(); - } else { - lastModified = getLastModifiedTimestamp(bundle); - } - - String[] dbBundlePath = new String[1]; - dbBundlePath[0] = String.valueOf(bundle.getBundleId()); - - String lastModifiedValue = (String) data.get(getPath(dbBundlePath)); - if (lastModifiedValue == null) { - components = processXMLDeclarations(bundle, dsHeader, dbBundlePath, lastModified); - } else { - long dbLastModified = Long.parseLong(lastModifiedValue); - if (lastModified != dbLastModified) { - components = processXMLDeclarations(bundle, dsHeader, dbBundlePath, lastModified); - } else { - try { - components = loadComponentsFromDB(bundle); - } catch (Throwable t) { - Activator.log(null, LogService.LOG_ERROR, Messages.ERROR_LOADING_COMPONENTS, t); - //backup plan - parse the bundle's component XML declarations - components = processXMLDeclarations(bundle, dsHeader, dbBundlePath, lastModified); - } - } - } - return components; - } catch (Throwable e) { - Activator.log(null, LogService.LOG_ERROR, NLS.bind(Messages.PROCESSING_BUNDLE_FAILED, Long.toString(bundle.getBundleId()), bundle), e); - return null; - } - } - - private Vector processXMLDeclarations(Bundle bundle, String dsHeader, String[] dbBundlePath, long lastModified) throws Exception { - Vector components = parseXMLDeclaration(bundle, dsHeader); - if (components != null && components.size() != 0) { - data.put(getPath(dbBundlePath), "" + lastModified); //$NON-NLS-1$ - saveComponentDefinitions(components, bundle.getBundleId()); - } - return components; - } - - private Vector loadComponentsFromDB(Bundle bundle) throws Exception { - String[] dbCompPath = new String[] {null, "COMPONENTS"}; //$NON-NLS-1$ - ServiceComponent currentComponent = null; - long bundleId = bundle.getBundleId(); - dbCompPath[0] = String.valueOf(bundleId); - DBObject value = new DBObject(); - byte[] byteArr = (byte[]) data.get(getPath(dbCompPath)); - ByteArrayInputStream tmpIn = new ByteArrayInputStream(byteArr); - value.readObject(tmpIn); - Vector components = value.components; - if (components == null) { - return null; - } - for (int i = 0; i < components.size(); i++) { - currentComponent = (ServiceComponent) components.elementAt(i); - currentComponent.bundle = bundle; - currentComponent.bc = bundle.getBundleContext(); - } - return components; - } - - public void deleteComponentDefinitions(long bundleID) { - String[] dbBundlePath = new String[1]; - dbBundlePath[0] = String.valueOf(bundleID); - data.remove(getPath(dbBundlePath)); - String[] dbCompPath = new String[] {null, "COMPONENTS"}; //$NON-NLS-1$ - dbCompPath[0] = String.valueOf(bundleID); - data.remove(getPath(dbCompPath)); - File file = bc.getDataFile(CUSTOM_DB_NAME); - if (file != null && file.exists()) { - //delete the file to prevent leaving old information in it - file.delete(); - } - isDirty = true; - } - - private void saveComponentDefinitions(Vector components, long bundleID) throws Exception { - try { - if (components == null || components.size() == 0) { - return; - } - String[] dbCompPath = new String[] {null, "COMPONENTS"}; //$NON-NLS-1$ - dbCompPath[0] = String.valueOf(bundleID); - - DBObject tmpObj = new DBObject(components); - ByteArrayOutputStream buf = new ByteArrayOutputStream(); - tmpObj.writeObject(buf); - data.put(getPath(dbCompPath), buf.toByteArray()); - isDirty = true; - } catch (Exception e) { - Activator.log(null, LogService.LOG_ERROR, Messages.ERROR_SAVING_COMPONENT_DEFINITIONS, e); - } - } - - public void stop() { - if (isDirty) { - saveFile(); - } - } - - private void saveFile() { - FileOutputStream fos = null; - try { - File file = bc.getDataFile(CUSTOM_DB_NAME); - if (file == null) { - //save operation is not possible - return; - } - fos = new FileOutputStream(file); - try { - data.writeObject(fos); - isDirty = false; - } catch (Exception e) { - Activator.log(null, LogService.LOG_ERROR, Messages.ERROR_WRITING_OBJECT, e); - } - } catch (FileNotFoundException e) { - Activator.log(null, LogService.LOG_ERROR, Messages.FILE_DOESNT_EXIST_OR_DIRECTORY, e); - } finally { - if (fos != null) { - try { - fos.close(); - } catch (IOException e) { - //ignore - } - } - } - } - - private String getPath(String path[]) { - synchronized (pathBuffer) { - pathBuffer.setLength(0); - for (int i = 0; i < path.length; i++) { - pathBuffer.append(path[i]).append(separator); - } - return pathBuffer.toString(); - } - } - - /** - * The last modified timestamp of the bundle. Should only be called in development mode - * - * @param bundle - * @return the last modified timestamp of the bundle - */ - protected long getLastModifiedTimestamp(Bundle bundle) { - if (bundle == null) - return 0; - long result = 0; - Collection/**/urls = computeComponentDefinitionUrls(bundle, parseManifestHeader(bundle)); - for (Iterator/**/i = urls.iterator(); i.hasNext();) { - URL url = (URL) i.next(); - try { - URLConnection connection = url.openConnection(); - long lastModified = connection.getLastModified(); - if (lastModified > result) - result = lastModified; - } catch (IOException e) { - //last modified cannot be calculated. should force reparse - return Long.MAX_VALUE; - } - } - return result; - } - - private ManifestElement[] parseManifestHeader(Bundle bundle) { - Dictionary headers = bundle.getHeaders(""); //$NON-NLS-1$ - String files = (String) headers.get(ComponentConstants.SERVICE_COMPONENT); - if (files == null) - return new ManifestElement[0]; - try { - return ManifestElement.parseHeader(ComponentConstants.SERVICE_COMPONENT, files); - } catch (BundleException e) { - Activator.log(bundle.getBundleContext(), LogService.LOG_ERROR, Messages.ERROR_PARSING_MANIFEST_HEADER, e); - return new ManifestElement[0]; - } - } -} diff --git a/bundles/org.eclipse.equinox.ds/src/org/eclipse/equinox/internal/util/io/Externalizable.java b/bundles/org.eclipse.equinox.ds/src/org/eclipse/equinox/internal/util/io/Externalizable.java deleted file mode 100644 index 8ab19fa13..000000000 --- a/bundles/org.eclipse.equinox.ds/src/org/eclipse/equinox/internal/util/io/Externalizable.java +++ /dev/null @@ -1,37 +0,0 @@ -/******************************************************************************* - * Copyright (c) 1997, 2008 by ProSyst Software GmbH - * http://www.prosyst.com - * 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: - * ProSyst Software GmbH - initial API and implementation - *******************************************************************************/ -package org.eclipse.equinox.internal.util.io; - -import java.io.InputStream; -import java.io.OutputStream; - -/** - * Interface for custom serialization. Classes that implements this interface - * must have public empty constructor so deserialization can be done. - * - * @author Pavlin Dobrev - * @version 1.0 - */ - -public interface Externalizable { - - /** - * Use this method for serialization of object state. - */ - public void writeObject(OutputStream oStream) throws Exception; - - /** - * Use this method to deserializion of object state. - */ - public void readObject(InputStream iStream) throws Exception; - -} diff --git a/bundles/org.eclipse.equinox.ds/src/org/eclipse/equinox/internal/util/io/ExternalizableDictionary.java b/bundles/org.eclipse.equinox.ds/src/org/eclipse/equinox/internal/util/io/ExternalizableDictionary.java deleted file mode 100644 index fad662590..000000000 --- a/bundles/org.eclipse.equinox.ds/src/org/eclipse/equinox/internal/util/io/ExternalizableDictionary.java +++ /dev/null @@ -1,759 +0,0 @@ -/******************************************************************************* - * Copyright (c) 1997, 2008 by ProSyst Software GmbH - * http://www.prosyst.com - * 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: - * ProSyst Software GmbH - initial API and implementation - *******************************************************************************/ -package org.eclipse.equinox.internal.util.io; - -import java.io.*; -import java.lang.reflect.Array; -import java.util.*; - -/** - * This class implements a hashtable, which serves the needs of - * ConfigurationManagement of capsulation of configuration properties with - * String keys, which are case insentive at lookup (at get, remove, put - * operations) but preserve the last case of keys. - * - * The implementaion of the Externalizable interface allows remote transfer of - * those properties. - * - * @author Pavlin Dobrev - * @version 1.0 - */ - -public class ExternalizableDictionary extends Dictionary implements Externalizable, Cloneable { - - private static Class[] CLASSES = new Class[] {ExternalizableDictionary.class}; - private HashtableEntry table[]; - private int count; - private int threshold; - private float loadFactor; - private static int MIN_CAPACITY = 5; - - ClassLoader loader; - - /** - * Constructs a new, empty dictionary with the specified initial capacity - * and the specified load factor. - * - * @param initialCapacity - * the initial capacity of the hashtable. when 0 is passed for - * capacity, minimum possible capacity is used; i.e. when the - * object is read as externalizable, then the table is created - * with the written size. - * @param loadFactor - * a number between 0.0 and 1.0. - * @exception IllegalArgumentException - * if the initial capacity is less than zero, or if the load - * factor is less than or equal to zero. - */ - public ExternalizableDictionary(int initialCapacity, float loadFactor) { - if ((initialCapacity < 0) || (loadFactor <= 0.0)) { - throw new IllegalArgumentException(); - } - this.loadFactor = loadFactor; - if (initialCapacity > 0) - initTable(initialCapacity); - } - - private void initTable(int initialCapacity) { - table = new HashtableEntry[initialCapacity]; - threshold = (int) (initialCapacity * loadFactor); - } - - /** - * Constructs a new, empty dictionary with the wanted capacity and default - * load factor. - */ - public ExternalizableDictionary(int initialCapacity) { - this(initialCapacity, 0.75f); - } - - /** - * Constructs a new, empty dictionary with a default capacity and load - * factor. - */ - public ExternalizableDictionary() { - this(101, 0.75f); - } - - public ClassLoader setClassLaoder(ClassLoader loader) { - ClassLoader tmp = this.loader; - this.loader = loader; - return tmp; - } - - public ClassLoader setClassLoader(ClassLoader loader) { - ClassLoader tmp = this.loader; - this.loader = loader; - return tmp; - } - - public Class[] remoteInterfaces() { - return CLASSES; - } - - /** - * Gets the size of the elements in the dictionary. - * - * @return size of hashtable - */ - public int size() { - return count; - } - - /** - * Checks if there is any element in the dictionary. - * - * @return true if empty. - */ - public boolean isEmpty() { - return count == 0; - } - - /** - * Gets an enumeration with dictionary's keys. - * - * @return an enumeration with dictionary's keys. - */ - public synchronized Enumeration keys() { - return new HashtableEnumerator(table, true); - } - - /** - * Gets an enumeration with dictionary's values. - * - * @return an enumeration with dictionary's values. - */ - public synchronized Enumeration elements() { - return new HashtableEnumerator(table, false); - } - - private int hashCode(String key) { - return key.toLowerCase().hashCode(); - } - - /** - * Gets the value corresponding to this key or any of its case - * representations. - * - * @param key - * String key - * @return object value or null if none - */ - public synchronized Object get(Object key) { - if (table != null) { - HashtableEntry tab[] = table; - int hash = hashCode((String) key); - int index = (hash & 0x7FFFFFFF) % tab.length; - for (HashtableEntry e = tab[index]; e != null; e = e.next) { - if ((e.hash == hash) && e.key.equalsIgnoreCase((String) key)) { - return e.value; - } - } - } - return null; - } - - protected void rehash() { - int oldCapacity = table.length; - HashtableEntry oldTable[] = table; - - int newCapacity = oldCapacity * 2 + 1; - HashtableEntry newTable[] = new HashtableEntry[newCapacity]; - - threshold = (int) (newCapacity * loadFactor); - table = newTable; - - for (int i = oldCapacity; i-- > 0;) { - for (HashtableEntry old = oldTable[i]; old != null;) { - HashtableEntry e = old; - old = old.next; - int index = (e.hash & 0x7FFFFFFF) % newCapacity; - e.next = newTable[index]; - newTable[index] = e; - } - } - } - - /** - * Puts the key and the value in the table. If there already is a key equal - * ignore case to the one passed the new value exchhanes the old one. - * - * @param key - * String key - * @param value - * object to put - * @return old value if any, or null if none - * @exception IllegalArgumentException - * if key is not a string - */ - public synchronized Object put(Object key, Object value) throws IllegalArgumentException { - - if (value == null) { - throw new NullPointerException(); - } - if (table == null) - initTable(MIN_CAPACITY); - try { - // Makes sure the key is not already in the hashtable. - int hash = hashCode((String) key); - int index; - HashtableEntry[] tab = null; - do { - tab = table; - index = (hash & 0x7FFFFFFF) % tab.length; - for (HashtableEntry e = tab[index]; e != null; e = e.next) { - if ((e.hash == hash) && e.key.equalsIgnoreCase((String) key)) { - Object old = e.value; - e.value = value; - return old; - } - } - if (count >= threshold) { - // Rehash the table if the threshold is exceeded - rehash(); - continue; - } - break; - } while (true); - - // Creates the new entry. - HashtableEntry e = new HashtableEntry(); - e.hash = hash; - e.key = (String) key; - e.value = value; - e.next = tab[index]; - tab[index] = e; - count++; - return null; - } catch (ClassCastException cce) { - throw new IllegalArgumentException("Non string keys are not accepted!"); - } - } - - /** - * Removes the key and its corresponding value. Key is searched case - * insensitively. - * - * @param key - * string key - * @return object removed or null if none - * @exception IllegalArgumentException - * if key is not s string - */ - public synchronized Object remove(Object key) throws IllegalArgumentException { - - if (table == null) - return null; - try { - HashtableEntry tab[] = table; - int hash = hashCode((String) key); - int index = (hash & 0x7FFFFFFF) % tab.length; - for (HashtableEntry e = tab[index], prev = null; e != null; prev = e, e = e.next) { - if ((e.hash == hash) && e.key.equalsIgnoreCase((String) key)) { - if (prev != null) { - prev.next = e.next; - } else { - tab[index] = e.next; - } - count--; - return e.value; - } - } - return null; - } catch (ClassCastException cce) { - throw new IllegalArgumentException("Non string keys are not accepted!"); - } - } - - /** - * Clears all elements from the distionary. - */ - public synchronized void clear() { - if (table == null) - return; - for (int index = table.length; --index >= 0;) { - table[index] = null; - } - count = 0; - } - - /** - * Creates a shallow copy of this hashtable. The keys and values themselves - * are not cloned. - * - * @return a new CMDictioanry with the same fields - */ - public synchronized Object clone() { - try { - ExternalizableDictionary cmDict = (ExternalizableDictionary) super.clone(); - if (table != null) { - cmDict.table = new HashtableEntry[table.length]; - for (int i = table.length; i-- > 0;) { - cmDict.table[i] = (table[i] != null) ? (HashtableEntry) table[i].clone() : null; - } - } - return cmDict; - } catch (CloneNotSupportedException e) { - // this shouldn't happen, since we are Cloneable - throw new InternalError(); - } - } - - /** - * Compares the specified Object with this Dictionary for equality, - * - * @return true if the specified Object is equal to this Dictionary. - */ - - public synchronized boolean equals(Object o) { - if (o == this) - return true; - if (!(o instanceof Dictionary)) - return false; - Dictionary dict = (Dictionary) o; - int max = size(); - if (dict.size() != max) - return false; - Enumeration k = keys(); - Enumeration e = elements(); - for (int i = 0; i < max; i++) { - Object key = k.nextElement(); - Object value = e.nextElement(); - if (!value.equals(dict.get(key))) { - return false; - } - } - return true; - } - - /** - * Makes a string represntation of this object. - * - * @return string represntation of this object - */ - public synchronized String toString() { - int max = size() - 1; - StringBuffer buf = new StringBuffer(); - Enumeration k = keys(); - Enumeration e = elements(); - buf.append('{'); - for (int i = 0; i <= max; i++) { - String s1 = (String) k.nextElement(); - String s2 = e.nextElement().toString(); - buf.append(s1); - buf.append('='); - buf.append(s2); - if (i < max) { - buf.append(','); - buf.append(' '); - } - } - buf.append('}'); - return buf.toString(); - } - - /** - * Writes this object to the stream passed. The object can be loaded again - * via its readObject method. - * - * @param os - * strream to write data to. - * @exception Exception - * if error of any kind occurs - */ - public synchronized void writeObject(OutputStream os) throws Exception { - Enumeration keys = keys(); - Enumeration values = elements(); - PDataStream.writeInt(size(), os); - // dictionary is never empty: - // it either has elements or is null - while (keys.hasMoreElements()) { - PDataStream.writeUTF((String) keys.nextElement(), os); - writeValue(values.nextElement(), os); - } - } - - private static void writeValue(Object value, OutputStream os) throws IOException { - - if (value == null) { - os.write(-1); - } else { - Class valueClass = value.getClass(); - // write 0 for a single value, 1 for array, and 2 for Vector - if (valueClass.isArray()) { - os.write(1); - int length = Array.getLength(value); - PDataStream.writeInt(length, os); - Class componentType = valueClass.getComponentType(); - if (componentType.isPrimitive()) { - // primitive - PDataStream.writeBoolean(true, os); - // 1: int;2: long; 3: byte; 4: boolean; 5: character; 6: - // short; 7: float; 8: double - writePrimitiveArray(componentType, value, length, os); - } else { - PDataStream.writeBoolean(false, os); - PDataStream.writeUTF(componentType.getName(), os); - Object[] oArr = (Object[]) value; - for (int i = 0; i < length; i++) { - writeValue(oArr[i], os); - } - } - } else if (valueClass.equals(Vector.class)) { - os.write(2); - int size = ((Vector) value).size(); - PDataStream.writeInt(size, os); - for (int i = 0; i < size; i++) { - writeValue(((Vector) value).elementAt(i), os); - } - } else { - os.write(0); - writeRealObject(value, valueClass, os); - } - } - } - - private static Object readValue(InputStream is, ClassLoader loader) throws Exception { - byte type = (byte) is.read(); - if (type == -1) { - return null; - } - Class vClass = null; - if (type == 2) { - int length = PDataStream.readInt(is); - Vector v = new Vector(length); - for (int i = 0; i < length; i++) { - v.insertElementAt(readValue(is, loader), i); - } - return v; - } else if (type == 0) { - return readRealObject((byte) is.read(), is, loader); - } else { - int length = PDataStream.readInt(is); - boolean primitive = PDataStream.readBoolean(is); - if (primitive) { - return readPrimitiveArray(length, is); - } - vClass = loader == null ? Class.forName(PDataStream.readUTF(is)) : loader.loadClass(PDataStream.readUTF(is)); - Object array = Array.newInstance(vClass, length); - for (int i = 0; i < length; i++) { - Array.set(array, i, readValue(is, loader)); - } - return array; - } - } - - /** - * Reads the data from the InputStream and loads the data in the table. - * - * @param is - * stream to read dictionary's data from - * @exception Exception - * if an error of any kind occurs while reading - */ - public synchronized void readObject(InputStream is) throws Exception { - try { - int size = PDataStream.readInt(is); - if (table == null) { - if (size > 0) { - initTable(size); - } else - initTable(MIN_CAPACITY); - } - for (int i = 0; i < size; i++) { - put(PDataStream.readUTF(is), readValue(is, loader)); - } - } catch (Exception e) { - throw e; - } - } - - // 1: int;2: long; 3: byte; 4: boolean; 5: character; - // 6: short; 7: float; 8: double - private static void writePrimitiveArray(Class componentType, Object array, int length, OutputStream os) throws IOException { - - if (componentType.equals(Integer.TYPE)) { - int[] ints = (int[]) array; - os.write(1); - for (int i = 0; i < length; i++) { - PDataStream.writeInt(ints[i], os); - } - } else if (componentType.equals(Long.TYPE)) { - os.write(2); - long[] longs = (long[]) array; - for (int i = 0; i < length; i++) { - PDataStream.writeLong(longs[i], os); - } - } else if (componentType.equals(Byte.TYPE)) { - os.write(3); - os.write((byte[]) array); - } else if (componentType.equals(Boolean.TYPE)) { - os.write(4); - boolean[] booleans = (boolean[]) array; - for (int i = 0; i < length; i++) { - PDataStream.writeBoolean(booleans[i], os); - } - } else if (componentType.equals(Character.TYPE)) { - os.write(5); - char[] chars = (char[]) array; - for (int i = 0; i < length; i++) { - PDataStream.writeChar(chars[i], os); - } - } else if (componentType.equals(Short.TYPE)) { - os.write(6); - short[] shorts = (short[]) array; - for (int i = 0; i < length; i++) { - PDataStream.writeShort(shorts[i], os); - } - } else if (componentType.equals(Float.TYPE)) { - os.write(7); - float[] floats = (float[]) array; - for (int i = 0; i < length; i++) { - PDataStream.writeFloat(floats[i], os); - } - } else if (componentType.equals(Double.TYPE)) { - os.write(8); - double[] doubles = (double[]) array; - for (int i = 0; i < length; i++) { - PDataStream.writeDouble(doubles[i], os); - } - } else { - throw new IllegalArgumentException("Unsupported Primitive Type: " + componentType); - } - } - - private static Object readPrimitiveArray(int length, InputStream is) throws IOException { - byte type = (byte) is.read(); - if (type == 1) { - int[] ints = new int[length]; - for (int i = 0; i < length; i++) { - ints[i] = PDataStream.readInt(is); - } - return ints; - } else if (type == 2) { - long[] longs = new long[length]; - for (int i = 0; i < length; i++) { - longs[i] = PDataStream.readLong(is); - } - return longs; - } else if (type == 3) { - byte[] bytes = new byte[length]; - is.read(bytes); - return bytes; - } else if (type == 4) { - boolean[] booleans = new boolean[length]; - for (int i = 0; i < length; i++) { - booleans[i] = PDataStream.readBoolean(is); - } - return booleans; - } else if (type == 5) { - char[] chars = new char[length]; - for (int i = 0; i < length; i++) { - chars[i] = PDataStream.readChar(is); - } - return chars; - } else if (type == 6) { - short[] shorts = new short[length]; - for (int i = 0; i < length; i++) { - shorts[i] = PDataStream.readShort(is); - } - return shorts; - } else if (type == 7) { - float[] floats = new float[length]; - for (int i = 0; i < length; i++) { - floats[i] = PDataStream.readFloat(is); - } - return floats; - } else if (type == 8) { - double[] doubles = new double[length]; - for (int i = 0; i < length; i++) { - doubles[i] = PDataStream.readDouble(is); - } - return doubles; - } else { - throw new IllegalArgumentException("Trying to read unsupported primitive type: " + type); - } - } - - // only if this is an object (not primitive) and non null! - private static void writeRealObject(Object value, Class vClass, OutputStream os) throws IOException { - try { - if (vClass.equals(String.class)) { - os.write(0); - PDataStream.writeUTF((String) value, os); - } else if (vClass.equals(Integer.class)) { - os.write(1); - PDataStream.writeInt(((Integer) value).intValue(), os); - } else if (vClass.equals(Long.class)) { - os.write(2); - PDataStream.writeLong(((Long) value).longValue(), os); - } else if (vClass.equals(Byte.class)) { - os.write(3); - os.write(((Byte) value).byteValue()); - } else if (vClass.equals(Boolean.class)) { - os.write(4); - PDataStream.writeBoolean(((Boolean) value).booleanValue(), os); - } else if (vClass.equals(Character.class)) { - os.write(5); - PDataStream.writeChar(((Character) value).charValue(), os); - } else if (vClass.equals(Short.class)) { - os.write(6); - PDataStream.writeShort(((Short) value).shortValue(), os); - } else if (vClass.equals(Float.class)) { - os.write(7); - PDataStream.writeFloat(((Float) value).floatValue(), os); - } else if (vClass.equals(Double.class)) { - os.write(8); - PDataStream.writeDouble(((Double) value).doubleValue(), os); - } else if (Externalizable.class.isAssignableFrom(vClass)) { - os.write(11); - String name = vClass.getName(); - PDataStream.writeUTF(name, os); - Externalizable tmp = (Externalizable) value; - tmp.writeObject(os); - } else { - os.write(12); - ObjectOutputStream out = new ObjectOutputStream(os); - out.writeObject(value); - } - } catch (Exception exc) { - throw new IOException(exc.toString()); - } - } - - private static Object readRealObject(byte type, InputStream is, ClassLoader loader) throws IOException { - try { - if (type == 0) { - return PDataStream.readUTF(is); - } else if (type == 1) { - return new Integer(PDataStream.readInt(is)); - } else if (type == 2) { - return new Long(PDataStream.readLong(is)); - } else if (type == 3) { - return new Byte((byte) is.read()); - } else if (type == 4) { - return PDataStream.readBoolean(is) ? Boolean.TRUE : Boolean.FALSE; - } else if (type == 5) { - return new Character(PDataStream.readChar(is)); - } else if (type == 6) { - return new Short(PDataStream.readShort(is)); - } else if (type == 7) { - return new Float(PDataStream.readFloat(is)); - } else if (type == 8) { - return new Double(PDataStream.readDouble(is)); - } else if (type == 11) { - String name = PDataStream.readUTF(is); - Class c = loader == null ? Class.forName(name) : loader.loadClass(name); - if (Externalizable.class.isAssignableFrom(c)) { - Externalizable obj = (Externalizable) c.newInstance(); - obj.readObject(is); - return obj; - } - throw new IOException("Could not read object " + name); - } else if (type == 12) { - ObjectInputStream in = loader == null ? new ObjectInputStream(is) : (ObjectInputStream) new XObjectInputStream(loader, is); - return in.readObject(); - } - } catch (ClassNotFoundException cnfe) { - throw new IOException("Could not find class " + cnfe.toString()); - } catch (Exception exc) { - throw exc instanceof IOException ? (IOException) exc : new IOException("Could not read object " + exc.toString()); - } - throw new IllegalArgumentException("Unsupported Typed Object: " + type); - } - - /** - * - * - * @param props - * @exception IllegalArgumentException - */ - public synchronized void copyFrom(Dictionary props) throws IllegalArgumentException { - Enumeration keys = props.keys(); - Enumeration values = props.elements(); - while (keys.hasMoreElements()) { - put(keys.nextElement(), values.nextElement()); - } - } - -} - -class HashtableEntry { - int hash; - String key; - Object value; - HashtableEntry next; - - protected Object clone() { - HashtableEntry entry = new HashtableEntry(); - entry.hash = hash; - entry.key = key; - entry.value = value; - entry.next = (next != null) ? (HashtableEntry) next.clone() : null; - return entry; - } -} - -class HashtableEnumerator implements Enumeration { - boolean keys; - int index; - HashtableEntry table[]; - HashtableEntry entry; - - HashtableEnumerator(HashtableEntry table[], boolean keys) { - this.table = table; - this.keys = keys; - this.index = table.length; - } - - public boolean hasMoreElements() { - if (table == null) - return false; - if (entry != null) { - return true; - } - while (index-- > 0) { - if ((entry = table[index]) != null) { - return true; - } - } - return false; - } - - public Object nextElement() { - if (table != null) { - if (entry == null) { - while ((index-- > 0) && ((entry = table[index]) == null)); - } - if (entry != null) { - HashtableEntry e = entry; - entry = e.next; - return keys ? e.key : e.value; - } - } - throw new NoSuchElementException("HashtableEnumerator"); - } -} - -class XObjectInputStream extends ObjectInputStream { - - ClassLoader loader; - - public XObjectInputStream(ClassLoader loader, InputStream is) throws IOException { - super(is); - this.loader = loader; - } - - protected Class resolveClass(ObjectStreamClass v) throws ClassNotFoundException { - return loader.loadClass(v.getName()); - } -} diff --git a/bundles/org.eclipse.equinox.ds/src/org/eclipse/equinox/internal/util/io/PDataStream.java b/bundles/org.eclipse.equinox.ds/src/org/eclipse/equinox/internal/util/io/PDataStream.java deleted file mode 100644 index f3e17b9c6..000000000 --- a/bundles/org.eclipse.equinox.ds/src/org/eclipse/equinox/internal/util/io/PDataStream.java +++ /dev/null @@ -1,236 +0,0 @@ -/******************************************************************************* - * Copyright (c) 1997, 2008 by ProSyst Software GmbH - * http://www.prosyst.com - * 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: - * ProSyst Software GmbH - initial API and implementation - *******************************************************************************/ -package org.eclipse.equinox.internal.util.io; - -import java.io.*; - -/** - * @author Pavlin Dobrev - * @author Georgi Andreev - * @version 1.0 - */ -public final class PDataStream { - - public static void writeInt(int i, OutputStream os) throws IOException { - os.write((i >>> 24) & 0xFF); - os.write((i >>> 16) & 0xFF); - os.write((i >>> 8) & 0xFF); - os.write(i & 0xFF); - } - - public static void writeLong(long l, OutputStream os) throws IOException { - os.write((int) (l >>> 56) & 0xFF); - os.write((int) (l >>> 48) & 0xFF); - os.write((int) (l >>> 40) & 0xFF); - os.write((int) (l >>> 32) & 0xFF); - os.write((int) (l >>> 24) & 0xFF); - os.write((int) (l >>> 16) & 0xFF); - os.write((int) (l >>> 8) & 0xFF); - os.write((int) (l & 0xFF)); - } - - public static void writeShort(short s, OutputStream os) throws IOException { - os.write((s >>> 8) & 0xFF); - os.write(s & 0xFF); - } - - public static void writeChar(char ch, OutputStream os) throws IOException { - os.write((ch >>> 8) & 0xFF); - os.write(ch & 0xFF); - } - - public static void writeBoolean(boolean b, OutputStream os) throws IOException { - os.write(b ? 1 : 0); - } - - public static void writeByte(byte b, OutputStream os) throws IOException { - os.write(b); - } - - public static void writeBytes(String str, OutputStream os) throws IOException { - byte[] b = str.getBytes(); - os.write(b); - } - - public static void writeString(String str, OutputStream os) throws IOException { - if (str == null) { - writeBoolean(false, os); - } else { - writeBoolean(true, os); - writeUTF(str, os); - } - } - - public static void writeUTF(String str, OutputStream os) throws IOException { - int strlen = str.length(); - int utflen = 0; - for (int i = 0; i < strlen; i++) { - int ch = str.charAt(i); - if ((ch >= 0x0001) && (ch <= 0x007F)) { - utflen++; - } else if (ch > 0x07FF) { - utflen += 3; - } else { - utflen += 2; - } - } - if (utflen > 65535) - throw new UTFDataFormatException(); - os.write((utflen >>> 8) & 0xFF); - os.write(utflen & 0xFF); - for (int i = 0; i < strlen; i++) { - int ch = str.charAt(i); - if ((ch >= 0x0001) && (ch <= 0x007F)) { - os.write(ch); - } else if (ch > 0x07FF) { - os.write(0xE0 | ((ch >> 12) & 0x0F)); - os.write(0x80 | ((ch >> 6) & 0x3F)); - os.write(0x80 | (ch & 0x3F)); - } else { - os.write(0xC0 | ((ch >> 6) & 0x1F)); - os.write(0x80 | (ch & 0x3F)); - } - } - } - - public static void writeChars(String str, OutputStream os) throws IOException { - int len = str.length(); - for (int i = 0; i < len; i++) { - int ch = str.charAt(i); - os.write((ch >>> 8) & 0xFF); - os.write(ch & 0xFF); - } - } - - public static void writeDouble(double d, OutputStream os) throws IOException { - writeLong(Double.doubleToLongBits(d), os); - } - - public static void writeFloat(float f, OutputStream os) throws IOException { - writeInt(Float.floatToIntBits(f), os); - } - - public static int readInt(InputStream is) throws IOException { - int ch1 = is.read(); - int ch2 = is.read(); - int ch3 = is.read(); - int ch4 = is.read(); - if ((ch1 | ch2 | ch3 | ch4) < 0) { - throw new IOException("Read Error"); - } - return (ch1 << 24) | (ch2 << 16) | (ch3 << 8) | ch4; - } - - public static char readChar(InputStream is) throws IOException { - int ch1 = is.read(); - int ch2 = is.read(); - if ((ch1 | ch2) < 0) - throw new IOException("Read Error"); - return (char) ((ch1 << 8) | ch2); - } - - public static short readShort(InputStream is) throws IOException { - int ch1 = is.read(); - int ch2 = is.read(); - if ((ch1 | ch2) < 0) - throw new IOException("Read Error"); - return (short) ((ch1 << 8) | ch2); - } - - public static long readLong(InputStream is) throws IOException { - return ((long) (readInt(is)) << 32) | (readInt(is) & 0xFFFFFFFFL); - } - - public static boolean readBoolean(InputStream is) throws IOException { - int ch = is.read(); - if (ch < 0) { - throw new EOFException(); - } - return (ch != 0); - } - - public static byte readByte(InputStream is) throws IOException { - int ch = is.read(); - if (ch < 0) - throw new EOFException(); - return (byte) (ch); - } - - public static int readUnsignedByte(InputStream is) throws IOException { - int ch = is.read(); - if (ch < 0) - throw new EOFException(); - return ch; - } - - public static double readDouble(InputStream is) throws IOException { - return Double.longBitsToDouble(readLong(is)); - } - - public static float readFloat(InputStream is) throws IOException { - return Float.intBitsToFloat(readInt(is)); - } - - public static String readString(InputStream is) throws IOException { - if (readBoolean(is)) - return readUTF(is); - return null; - } - - public static String readUTF(InputStream is) throws IOException { - int utflen = readShort(is); - char str[] = new char[utflen]; - int cnt = 0; - int strlen = 0; - while (cnt < utflen) { - int c = readUnsignedByte(is); - int char2, char3; - switch (c >> 4) { - case 0 : - case 1 : - case 2 : - case 3 : - case 4 : - case 5 : - case 6 : - case 7 : - cnt++; - str[strlen++] = (char) c; - break; - case 12 : - case 13 : - cnt += 2; - if (cnt > utflen) - throw new UTFDataFormatException(); - char2 = readUnsignedByte(is); - if ((char2 & 0xC0) != 0x80) - throw new UTFDataFormatException(); - str[strlen++] = (char) (((c & 0x1F) << 6) | (char2 & 0x3F)); - break; - case 14 : - cnt += 3; - if (cnt > utflen) - throw new UTFDataFormatException(); - char2 = readUnsignedByte(is); - char3 = readUnsignedByte(is); - if (((char2 & 0xC0) != 0x80) || ((char3 & 0xC0) != 0x80)) - throw new UTFDataFormatException(); - str[strlen++] = (char) (((c & 0x0F) << 12) | ((char2 & 0x3F) << 6) | (char3 & 0x3F)); - break; - default : - throw new UTFDataFormatException(); - } - } - return new String(str, 0, strlen); - } - -} diff --git a/bundles/org.eclipse.equinox.ds/src/org/eclipse/equinox/internal/util/io/package.html b/bundles/org.eclipse.equinox.ds/src/org/eclipse/equinox/internal/util/io/package.html deleted file mode 100644 index 48eb1795c..000000000 --- a/bundles/org.eclipse.equinox.ds/src/org/eclipse/equinox/internal/util/io/package.html +++ /dev/null @@ -1,9 +0,0 @@ - - - - - - - -

The package contains utilities for easily transfer of objects

- diff --git a/bundles/org.eclipse.equinox.ds/src/org/eclipse/equinox/internal/util/string/CharBuffer.java b/bundles/org.eclipse.equinox.ds/src/org/eclipse/equinox/internal/util/string/CharBuffer.java deleted file mode 100644 index e34b323cd..000000000 --- a/bundles/org.eclipse.equinox.ds/src/org/eclipse/equinox/internal/util/string/CharBuffer.java +++ /dev/null @@ -1,163 +0,0 @@ -/******************************************************************************* - * Copyright (c) 1997, 2008 by ProSyst Software GmbH - * http://www.prosyst.com - * 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: - * ProSyst Software GmbH - initial API and implementation - *******************************************************************************/ -package org.eclipse.equinox.internal.util.string; - -/** - * Class which stores text in a char array buffer - * and allows inserting, deleting, removing, appending etc. - * actions with the stored text. - * - * @author Pavlin Dobrev - * @author Georgi Andreev - * @version 1.0 - */ -public class CharBuffer { - - private char value[]; - private int cnt; - - public CharBuffer() { - this(16); - } - - public CharBuffer(int len) { - value = new char[len]; - } - - public int length() { - return cnt; - } - - public void ensureCapacity(int minCapacity) { - if (minCapacity > value.length) - expandCapacity(minCapacity); - } - - private void expandCapacity(int minCapacity) { - int capacity = (value.length + 1) * 2; - if (minCapacity > capacity) { - capacity = minCapacity; - } - char newVal[] = new char[capacity]; - System.arraycopy(value, 0, newVal, 0, cnt); - value = newVal; - } - - public void setLength(int newLen) { - if (newLen > value.length) - expandCapacity(newLen); - if (cnt < newLen) { - for (; cnt < newLen; cnt++) { - value[cnt] = '\0'; - } - } else { - cnt = newLen; - } - } - - public char charAt(int index) { - if ((index < 0) || (index >= cnt)) - throw new StringIndexOutOfBoundsException(index); - return value[index]; - } - - public void setCharAt(int index, char ch) { - if ((index < 0) || (index >= cnt)) - throw new StringIndexOutOfBoundsException(index); - value[index] = ch; - } - - public void append(String str) { - if (str == null) - str = String.valueOf(str); - int len = str.length(); - int newcnt = cnt + len; - if (newcnt > value.length) - expandCapacity(newcnt); - str.getChars(0, len, value, cnt); - cnt = newcnt; - } - - public void append(char str[], int offset, int len) { - int newcnt = cnt + len; - if (newcnt > value.length) - expandCapacity(newcnt); - System.arraycopy(str, offset, value, cnt, len); - cnt = newcnt; - } - - public void append(char str[]) { - append(str, 0, str.length); - } - - public void append(char c) { - int newcount = cnt + 1; - if (newcount > value.length) - expandCapacity(newcount); - value[cnt++] = c; - } - - public String substring(int start, int end) { - return new String(value, start, end - start); - } - - public String trim() { - int len = cnt; - int st = 0; - int off = 0; - char[] newVal = value; - - while ((st < len) && (newVal[off + st] <= ' ')) - st++; - while ((st < len) && (newVal[off + len - 1] <= ' ')) - len--; - - return ((st > 0) || (len < cnt)) ? substring(st, len) : toString(); - } - - public boolean equals(int offset, String with) { - int len = with.length(); - if (offset >= cnt || offset + len != cnt) - return false; - - for (int i = offset; i < cnt; i++) { - if (value[i] != with.charAt(i - offset)) - return false; - } - - return true; - } - - public void getChars(int srcStart, int srcEnd, char dest[], int destStart) { - if ((srcStart < 0) || (srcStart >= cnt)) - throw new StringIndexOutOfBoundsException(srcStart); - if ((srcEnd < 0) || (srcEnd > cnt)) - throw new StringIndexOutOfBoundsException(srcEnd); - - if (srcStart < srcEnd) - System.arraycopy(value, srcStart, dest, destStart, srcEnd - srcStart); - else if (srcStart > srcEnd) - throw new StringIndexOutOfBoundsException(srcEnd - srcStart); - } - - public String toString() { - return new String(value, 0, cnt); - } - - public char[] getValue() { - char[] retVal; - retVal = new char[cnt]; - System.arraycopy(value, 0, retVal, 0, cnt); - return retVal; - } - -} diff --git a/bundles/org.eclipse.equinox.ds/src/org/eclipse/equinox/internal/util/string/package.html b/bundles/org.eclipse.equinox.ds/src/org/eclipse/equinox/internal/util/string/package.html deleted file mode 100644 index 7b10755c3..000000000 --- a/bundles/org.eclipse.equinox.ds/src/org/eclipse/equinox/internal/util/string/package.html +++ /dev/null @@ -1,18 +0,0 @@ - - - - - Package-level Javadoc - - -

This package provides more efficent analog to java.lang.StringBuffer class. -

-

Bundles wishing to use this package must list the package -in the Import-Package header of the bundle's manifest. -For example: -

-
-Import-Package: org.eclipse.equinox.util.string; specification-version=1.0
-
- - diff --git a/bundles/org.eclipse.equinox.ds/src/org/eclipse/equinox/internal/util/xml/ExTagListener.java b/bundles/org.eclipse.equinox.ds/src/org/eclipse/equinox/internal/util/xml/ExTagListener.java deleted file mode 100644 index 9ef305617..000000000 --- a/bundles/org.eclipse.equinox.ds/src/org/eclipse/equinox/internal/util/xml/ExTagListener.java +++ /dev/null @@ -1,43 +0,0 @@ -/******************************************************************************* - * Copyright (c) 1997, 2008 by ProSyst Software GmbH - * http://www.prosyst.com - * 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: - * ProSyst Software GmbH - initial API and implementation - *******************************************************************************/ - -package org.eclipse.equinox.internal.util.xml; - -/** - * The XMLReader invokes methods of this listener either when the tag is just - * opened or when the tag is just closed. - * - * @author Ivan Dimitrov - * @author Pavlin Dobrev - * @version 1.0 - */ - -public interface ExTagListener { - - /** - * Invoked when a tag is opened - * - * @param aTag - * tag - * @throws IllegalArgumentException - */ - public void startTag(Tag aTag) throws IllegalArgumentException; - - /** - * Invoked when a tag is closed - * - * @param aTag - * tag - * @throws IllegalArgumentException - */ - public void endTag(Tag aTag) throws IllegalArgumentException; -} diff --git a/bundles/org.eclipse.equinox.ds/src/org/eclipse/equinox/internal/util/xml/Tag.java b/bundles/org.eclipse.equinox.ds/src/org/eclipse/equinox/internal/util/xml/Tag.java deleted file mode 100644 index c850f137e..000000000 --- a/bundles/org.eclipse.equinox.ds/src/org/eclipse/equinox/internal/util/xml/Tag.java +++ /dev/null @@ -1,109 +0,0 @@ -/******************************************************************************* - * Copyright (c) 1997, 2008 by ProSyst Software GmbH - * http://www.prosyst.com - * 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: - * ProSyst Software GmbH - initial API and implementation - *******************************************************************************/ -package org.eclipse.equinox.internal.util.xml; - -import java.util.Enumeration; - -/** - * @author Ivan Dimitrov - * @author Pavlin Dobrev - * @version 1.0 - */ - -public interface Tag { - /** - * Returns an attribute value for an attribute with a given name (aAttrName) - * - * @param aAttrName - * the name of attribute - * @return Attribute value for attribute with name given by attrName or null - * if there is no such an attribute - */ - public String getAttribute(String aAttrName); - - /** - * Returns an Enumeration of all the attributes' names for attributes belong - * to the tag object - * - * @return Enumeration that contains the attribute names of the attributes - * for this tag. If there is no attributes then the method returns - * Empty enumeration - */ - public Enumeration getAttributeNames(); - - /** - * Returns an Enumeration that contains the attribute values for the - * attributes that belong to the tag object - * - * @return EEnumeration that contains the attribute values for the - * attributes that belong to the tag object. If there is no - * attributes then the method returns Empty enumeration - */ - public Enumeration getAttributeValues(); - - /** - * Returns the name of the tag - * - * @return the name of the tag - */ - public String getName(); - - /** - * Returns a tag content - * - * @return tag content. If the tag does not have a content, the method - * returns empty string - */ - public String getContent(); - - /** - * Returns the line in the XML file where the tag definition starts - * - * @return the line in the XML file where the tag definition starts - */ - public int getLine(); - - /** - * Returns the number of the child tags of this tag - * - * @return child tags number - */ - public int size(); - - /** - * Returns the child tag at a given position in order that is equivalent to - * the order of child tags defined in the XML file - * - * @param aPosition - * child tag's position - * @return the child tag at a given position - */ - public Tag getTagAt(int aPosition); - - /** - * Returns the content of a child tag with index position equals to aPos but - * only if its name is equal to aName. Otherwise the method throws an - * exception - * - * @param aPos - * index of the tag in its parent list - * @param aName - * the name of the tag - * @return tag content - * @throws NullPointerException - * if there is no tag on the given position - * @throws IllegalArgumentException - * if the name of the tag on the given position does not match - * the requested name - */ - public String getContent(int aPos, String aName); -} diff --git a/bundles/org.eclipse.equinox.ds/src/org/eclipse/equinox/internal/util/xml/TagClass.java b/bundles/org.eclipse.equinox.ds/src/org/eclipse/equinox/internal/util/xml/TagClass.java deleted file mode 100644 index b2a405929..000000000 --- a/bundles/org.eclipse.equinox.ds/src/org/eclipse/equinox/internal/util/xml/TagClass.java +++ /dev/null @@ -1,296 +0,0 @@ -/******************************************************************************* - * Copyright (c) 1997, 2008 by ProSyst Software GmbH - * http://www.prosyst.com - * 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: - * ProSyst Software GmbH - initial API and implementation - *******************************************************************************/ -package org.eclipse.equinox.internal.util.xml; - -import java.util.Vector; -import org.eclipse.equinox.internal.ds.Activator; -import org.eclipse.equinox.internal.util.string.CharBuffer; - -/** - * Class corresponding to one XML tag, containing its tag name, attributes, - * content string and tree of the sub tags. - * - * @author Ivan Dimitrov - * @author Pavlin Dobrev - * @version 1.0 - */ - -public class TagClass { - - private static final String INTERN_TAGCONTENT = "xml.intern.tagcontent"; - private static boolean fInternTagContent = Activator.getBoolean(INTERN_TAGCONTENT); - - private CharBuffer fContent = null; - private String fName = null; - private Vector fTags = null; - String fAttributes = null; - private int fLine = -1; - protected boolean fInline = false; - - /** - * Creates an empty tag node - */ - public TagClass() { - // Do nothing here - } - - /** - * Creates tag node with specified name - * - * @param name - * tag name - */ - public TagClass(String name) { - fName = name; - } - - /** - * Creates tag node with specified name - * - * @param line - * the line in the XML file where the tags begin. - * @param name - * tag name - */ - public TagClass(int line, String name) { - fLine = line; - fName = name; - } - - /** - * Creates tag node with specified name and content string - * - * @param name - * tag name - * @param contentStr - * content string of the tag - */ - public TagClass(String name, String contentStr) { - setup(-1, name, contentStr); - } - - /** - * Creates tag node with specified name and content string - * - * @param line - * the line in the XML file where the tags begin. - * @param name - * tag name - * @param contentStr - * content string of the tag - */ - public TagClass(int line, String name, String contentStr) { - setup(line, name, contentStr); - } - - private void setup(int line, String name, String contentStr) { - fLine = line; - fName = name; - if (contentStr != null && contentStr.length() > 0) { - fContent = new CharBuffer(contentStr.length()); - fContent.append(contentStr); - } - } - - /** - * Appends the 'toAppend' CharBuffer content to the content buffer - * - * @param toAppend - * CharBuffer content to append - */ - protected void appendContent(CharBuffer toAppend) { - if (fContent == null) { - fContent = new CharBuffer(); - } - fContent.append(toAppend.getValue()); - } - - /** - * Appends the 'toAppend' string to the content buffer - * - * @param toAppend - * string to append - */ - protected void appendContent(String toAppend) { - if (fContent == null) { - fContent = new CharBuffer(); - } - fContent.append(toAppend); - } - - /** - * Returns content string of the tag - * - * @return tag content note: The content that is to be returned will be - * trimmed first - */ - /* - * Implementation Note: The content string is not suitable to be interned - * with String().intern() because it is more often to be unique and the - * benefit will be much smaller than expected. - */ - public String getContent() { - String result = ""; - if (fContent != null) { - result = fContent.trim(); - if (fInternTagContent) { - result = result.intern(); - } - } - return result; - // TODO -oIvan: Should not it be null instead of empty string?... - // Plamen: Yes it have to be null insted of "" because the old one used - // to return null. - // Ivan Dimitrov: The metatyping code relies on the fact that the - // content is never null - } - - /** - * Returns the content of a child tag with index position equals to aPos but - * only if its name is equal to aName. Otherwise the method throws an - * exception - * - * @param aPos - * index of the tag in its parent list - * @param aName - * the name of the tag - * @return tag content - * @throws NullPointerException - * if there is no tag on the given position - * @throws IllegalArgumentException - * if the name of the tag on the given position does not match - * the requested name - */ - public String getContent(int aPos, String aName) { - TagClass child = getTagAt(aPos); - if (child == null) - throw new NullPointerException("There is no such a tag. [Parent tag name] = [" + aName + "], [child tag index] = " + aPos + ", [child tag name] = [" + aName + ']'); - - if (child.getName().equals(aName)) - return child.getContent(); - - throw new IllegalArgumentException("There is no such a tag. [Parent tag name] = [" + aName + "], [child tag index] = " + aPos + ", [child tag name] = [" + aName + ']'); - } - - /** - * Returns the internal content buffer - * - * @return internal content buffer as CharBuffer - */ - protected CharBuffer getContentBuffer() { - if (fContent == null) { - fContent = new CharBuffer(); - } - return fContent; - } - - /** - * Returns name of the tag - * - * @return tag name - */ - public String getName() { - return fName; - } - - /** - * Sets the name of the tag - * - * @param aName - * name of the tag - */ - protected void setName(String aName) { - fName = aName; - } - - /** - * Returns string with all attribute names and values of the tag, as is in - * the XML content. - * - * @return tag name and its attributes - */ - public String getAttributes() { - return (fAttributes != null) ? fAttributes : ""; - } - - /** - * Returns an attribute value for an attribute with a given name (attrName) - * - * @param attrName - * the name of attribute - * @return Attribute value for attribute with name given by attrName or null - * if there is no such an attribute - * @throws NullPointerException - * if attrName is null - */ - public String getAttribute(String attrName) { - return XMLUtil.getAttributeValue(fAttributes, attrName, 0); - } - - /** - * Adds a child tag to this one - * - * @param aTag - * a tag to be added as a child tag - */ - public void addTag(TagClass aTag) { - if (fTags == null) { - fTags = new Vector(5, 5); - } - fTags.addElement(aTag); - } - - /** - * Returns sub tag of this one at a given position - * - * @param aPos - * position of the searched tag - * @return a child tag at a given position in the child-tags set or null if - * there is no such a tag - */ - public TagClass getTagAt(int aPos) { - return (fTags == null) ? null : (TagClass) fTags.elementAt(aPos); - } - - /** - * Returns children tags count - * - * @return sub tags count - */ - public int size() { - return (fTags == null) ? 0 : fTags.size(); - } - - /** - * Returns the line in the XML file where the tags begin. - * - * @return Returns the line. - */ - public int getLine() { - return fLine; - } - - /** - * Sets the tag line number (the line in the XML file where the current tag - * starts) - * - * @param aLine - * current tag line number - */ - protected void setLine(int aLine) { - fLine = aLine; - } - - protected void setInline() { - fInline = true; - } -} diff --git a/bundles/org.eclipse.equinox.ds/src/org/eclipse/equinox/internal/util/xml/TagListener.java b/bundles/org.eclipse.equinox.ds/src/org/eclipse/equinox/internal/util/xml/TagListener.java deleted file mode 100644 index 4c1e8cd78..000000000 --- a/bundles/org.eclipse.equinox.ds/src/org/eclipse/equinox/internal/util/xml/TagListener.java +++ /dev/null @@ -1,34 +0,0 @@ -/******************************************************************************* - * Copyright (c) 1997, 2008 by ProSyst Software GmbH - * http://www.prosyst.com - * 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: - * ProSyst Software GmbH - initial API and implementation - *******************************************************************************/ -package org.eclipse.equinox.internal.util.xml; - -/** - * This interface is used while parsing xml files. It's method is invoked on - * every closing tag. - * - * @author Pavlin Dobrev - * @version 1.0 - */ - -public interface TagListener { - - /** - * Invoked when a tag has been closed - * - * @param tag - * tag with its content and its subtags - * @throws IllegalArgumentException - * may be thrown while proccessing the tag structure - */ - public void useTag(TagClass tag) throws IllegalArgumentException; - -} diff --git a/bundles/org.eclipse.equinox.ds/src/org/eclipse/equinox/internal/util/xml/XMLParser.java b/bundles/org.eclipse.equinox.ds/src/org/eclipse/equinox/internal/util/xml/XMLParser.java deleted file mode 100644 index 3b36d3000..000000000 --- a/bundles/org.eclipse.equinox.ds/src/org/eclipse/equinox/internal/util/xml/XMLParser.java +++ /dev/null @@ -1,121 +0,0 @@ -/******************************************************************************* - * Copyright (c) 1997, 2008 by ProSyst Software GmbH - * http://www.prosyst.com - * 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: - * ProSyst Software GmbH - initial API and implementation - *******************************************************************************/ -package org.eclipse.equinox.internal.util.xml; - -import java.io.*; -import org.eclipse.equinox.internal.util.xml.impl.XMLParserImpl; - -/** - *

- * Class used for reading of xml files, creating tree structure of 'TagClass' - * for each xml tag. When reader reaches a closed tag it notifies a given - * 'TagListener' and sends the last tag to it. If closing tag does not - * correspond with the last open IllegalArgumentException is thrown. There is a - * debug property 'xml.debug' used to dump an Exceptions occurred while - * operation is running. - *

- * - *

- * The parser, in general, is a simple XML parser that implements - * "Recursive descent" parsing method. - * - * Known limitations:
- * - *

- *  Currently this XMLParser does not support the following special tags:
- *  1. <?TAG_NAME ..... ?>   or also "Processing Instructions"
- *  2. <!DOCTYPE .... >
- *  3. <!ELEMENT .... >
- *  4. <!ATTLIST .... >
- *  5. <!ENTITY .... >
- * 
- * - *
- * The parser skippes these tags (it searches for '>' symbol and closes the - * 'special' tag).
- * - * @author Ivan Dimitrov - * @author Pavlin Dobrev - * @version 1.0 - */ - -public class XMLParser { - - /** - * Parses a XML file given through aInputStream and during the parsing - * notifies aListener for close-tag and open-tag events
- *
- * Note: The XMLReader does not close the passed Reader or InputStream - * - * @param aInputStream - * an InputStream to read the XML file from - * @param aListener - * ExTagListener that will be notified on close-tag and open-tag - * events - * @param aLevel - * indicates the tag level that the listener will be invoked for. - * For example if the XML is:
- * - *
-	 *  <a>
-	 *    <b>
-	 *      <c />
-	 *    </b>
-	 *  </a>
-	 * 
- * - *
- * and the passed aLevel is 2 then the listener will be invoked - * only for tags that have level 2, i.e. in our example the - * listener will be invoked only for tag <b>
- *
    - *
  • Value less than 0 indicates "invoke listener for all - * tags no matter what are their levels"
  • - *
  • Value of 0 indicates that the listener must not be - * invoked in general no matter what is the tag level
  • - *
  • Value greater than 0 indicates the tag level that the - * listener will be invoked for
  • - * description - * @throws IOException - * if some IO error occurs when reading the XML file or if a - * parser error occurs. - */ - public static void parseXML(InputStream aInputStream, ExTagListener aListener, int aLevel) throws IOException { - XMLParserImpl xml = new XMLParserImpl(aInputStream, aListener); - xml.setLevel(aLevel); - xml.parseXML(); - } - - /** - * Parses a XML file given through aReader and during the parsing notifies - * aListener for close-tag and open-tag events
    - *
    - * Note: The XMLReader does not close the passed Reader or InputStream - * - * @param aReader - * aReader to read the XML file from - * @param aListener - * ExTagListener that will be notified on close-tag and open-tag - * events - * @param aLevel - * see parseXML(Reader aReader, TagListener aListener, int aLevel - * description - * @throws IOException - * if some IO error occurs when reading the XML file or if a - * parser error occurs. - */ - public static void parseXML(Reader aReader, ExTagListener aListener, int aLevel) throws IOException { - XMLParserImpl xml = new XMLParserImpl(aReader, aListener); - xml.setLevel(aLevel); - xml.parseXML(); - } -} diff --git a/bundles/org.eclipse.equinox.ds/src/org/eclipse/equinox/internal/util/xml/XMLReader.java b/bundles/org.eclipse.equinox.ds/src/org/eclipse/equinox/internal/util/xml/XMLReader.java deleted file mode 100644 index e324bd562..000000000 --- a/bundles/org.eclipse.equinox.ds/src/org/eclipse/equinox/internal/util/xml/XMLReader.java +++ /dev/null @@ -1,1329 +0,0 @@ -/******************************************************************************* - * Copyright (c) 1997, 2008 by ProSyst Software GmbH - * http://www.prosyst.com - * 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: - * ProSyst Software GmbH - initial API and implementation - *******************************************************************************/ -package org.eclipse.equinox.internal.util.xml; - -import java.io.*; -import org.eclipse.equinox.internal.ds.Activator; -import org.eclipse.equinox.internal.util.string.CharBuffer; - -/** - *

    - * Class used for reading of xml files, creating tree structure of 'TagClass' - * for each xml tag. When reader reaches a closed tag it notifies a given - * 'TagListener' and sends the last tag to it. If closing tag does not - * correspond with the last open IllegalArgumentException is thrown. There is a - * debug property 'xml.debug' used to dump an Exceptions occurred while - * operation is running. - *

    - * - *

    - * The parser, in general, is a simple XML parser that implements - * "Recursive descent" parsing method. - * - * Known limitations:
    - * - *

    - *  Currently this XMLParser does not support the following special tags:
    - *  1. <?TAG_NAME ..... ?>   or also "Processing Instructions"
    - *  2. <!DOCTYPE .... >
    - *  3. <!ELEMENT .... >
    - *  4. <!ATTLIST .... >
    - *  5. <!ENTITY .... >
    - * 
    - * - *
    - * The parser skippes these tags (it searches for '>' symbol and closes the - * 'special' tag).
    - * - * @author Ivan Dimitrov - * @author Pavlin Dobrev - * @version 1.0 - */ - -public class XMLReader { - - private static final String DEBUG = "equinox.ds.xml.debug"; - private static final String SET_OLD_BEHAVIOUR = "equinox.ds.xml.oldbehaviour"; - private static final String SET_OLD_LEVELS = "equinox.ds.xml.oldlevels"; - private static final String INTERN_ATTRIBUTES = "equinox.ds.xml.intern.attributes"; - - private static final String CDATA = "CDATA"; - private static final String XML = "xml"; - private static final String VERSION = "version"; - private static final String ENCODING = "encoding"; - private static final String STANDALONE = "standalone"; - - private static final String ERR_EOS = "End-of-stream reached before the end of XML."; - private static final String ERR_ENTITY_EXPECTED = "Entity reference or Character reference expected."; - private static final String ERR_EQUAL_EXPECTED = "'=' expected."; - private static final String ERR_QUOT_EXPECTED = "''' or '\"' expected."; - private static final String ERR_GT_EXPECTED = "'>' expected."; - private static final String ERR_LT_EXPECTED = "'<' expected."; - private static final String ERR_CLOSE_TAG1_EXPECTED = "'/' or tag name expected."; - private static final String ERR_CLOSE_TAG2_EXPECTED = "'>', '/>' or more attributes expected."; - private static final String ERR_CLOSE_TAG3_EXPECTED = "'?>' expected."; - private static final String ERR_CONTENT_EXPECTED = "Content data, new tag or closing tag expected."; - private static final String ERR_QUESTIONMARK_EXPECTED = "'?' expected."; - private static final String ERR_ILLEGAL_CHARACTER = "Illegal character."; - private static final String ERR_TAGNAME_EXPECTED = "Tag name expected."; - private static final String ERR_TAGNAME2_EXPECTED = "Tag name, '?' or '!' expected."; - private static final String ERR_DASH_EXPECTED = "'-' expected."; - private static final String ERR_COMMENT_CLOSE_EXPECTED = "'-->' expected."; - private static final String ERR_CDATA_EXPECTED = "'CDATA' expected."; - private static final String ERR_OPENSQBRACKET_EXPECTED = "'[' expected."; - private static final String ERR_CLOSE_CDATA_EXPECTED = "']]>' expected."; - private static final String ERR_SEMICOLON_EXPECTED = "';' expected."; - private static final String ERR_XMLPROLOG_EXPECTED = "XML prolog '' expected."; - private static final String ERR_STANDALONE_EXPECTED = "'standalone' attribute expected."; - - private static final boolean fDebug = Activator.getBoolean(DEBUG); - private static final boolean fOldBehaviour = Activator.getBoolean(SET_OLD_BEHAVIOUR); - private static final boolean fOldLevels = Activator.getBoolean(SET_OLD_LEVELS); - private static final boolean fInternAttributes = Activator.getBoolean(INTERN_ATTRIBUTES); - - private String fDefaultEncoding = "UTF-8"; - - // private CharBuffer c; - private CharBuffer temp = new CharBuffer(); - private CharBuffer temp2 = null; - - protected Reader fReader = null; - protected InputStream fStream = null; - - protected char currentChar = 0; - protected TagListener fTagListener; - - protected int fLine = 1; - protected int fPos = 0; - - protected int fLevel = -1; - protected int fCurrentLevel = 1; - - private String fVersion = "1.0"; - private String fEncoding = "UTF-8"; - private String fStandalone = "no"; - - protected static final String[] fNew_entities = {"amp", "apos", "lt", "gt", "quot"}; - protected static final char[] fNew_ent_chars = {'&', '\'', '<', '>', '"'}; - - protected static final String[] fOld_entities = {"amp", "nbsp", "crlf", "tab", "lt", "gt", "quot", "apos"}; - protected static final char[] fOld_ent_chars = {'&', ' ', '\n', '\t', '<', '>', '"', '\''}; - - /** - * An empty default constructor - */ - public XMLReader() { - // - } - - /** - * Constructs a new XMLReader.
    - *
    - * Note: The XMLReader does not close the passed Reader or InputStream - * - * @param aInputStream - * an InputStream to read the XML file from - * @param aListener - * TagListener that will be notified on tag close event - * @throws IOException - */ - public XMLReader(InputStream aInputStream, TagListener aListener) { - fStream = aInputStream; - fTagListener = aListener; - } - - /** - * Constructs a new XMLReader.
    - *
    - * Note: The XMLReader does not close the passed Reader or InputStream - * - * @param aReader - * a reader that will be used to read the XML file from - * @param aListener - * TagListener that will be notified on tag close event - */ - public XMLReader(Reader aReader, TagListener aListener) { - fReader = aReader; - fTagListener = aListener; - } - - /** - * Parses a XML file given through aInputStream and during the parsing - * notifies aListener for close-tag events
    - *
    - * Note: The XMLReader does not close the passed Reader or InputStream - * - * @param aInputStream - * an InputStream to read the XML file from - * @param aListener - * TagListener that will be notified on close-tag events - * @throws IOException - */ - public static void read(InputStream aInputStream, TagListener aListener) throws IOException { - parseXML(aInputStream, aListener, -1); - } - - /** - * Parses a XML file given through aInputStream and during the parsing - * notifies aListener for close-tag events
    - *
    - * Note: The XMLReader does not close the passed Reader or InputStream - * - * @param aInputStream - * an InputStream to read the XML file from - * @param aListener - * TagListener that will be notified on close-tag events - * @param aLevel - * see parseXML(Reader aReader, TagListener aListener, int aLevel - * description - * @throws IOException - */ - public static void read(InputStream aInputStream, TagListener aListener, int aLevel) throws IOException { - parseXML(aInputStream, aListener, aLevel); - } - - /** - * Parses a XML file given through aReader and during the parsing notifies - * aListener for close-tag events
    - *
    - * Note: The XMLReader does not close the passed Reader or InputStream - * - * @param aReader - * a Reader to read the XML file from - * @param aListener - * TagListener that will be notified on close-tag events - * @throws IOException - */ - public static void read(Reader aReader, TagListener aListener) throws IOException { - parseXML(aReader, aListener, -1); - } - - /** - * Parses a XML file given through aReader and during the parsing notifies - * aListener for close-tag events
    - *
    - * Note: The XMLReader does not close the passed Reader or InputStream - * - * @param aReader - * a Reader to read the XML file from - * @param aListener - * TagListener that will be notified on close-tag events - * @param aLevel - * see parseXML(Reader aReader, TagListener aListener, int aLevel - * description - * @throws IOException - */ - public static void read(Reader aReader, TagListener aListener, int aLevel) throws IOException { - parseXML(aReader, aListener, aLevel); - } - - /** - * Sets the parser's encoding. If there is a current encoding associated - * with the parser the method returns immediately - * - * @param aEncoding - * new encoding to be set - * @throws UnsupportedEncodingException - * if the encoding is not supported. - */ - protected void setEncoding(String aEncoding) { - if (fReader == null) { - try { - fReader = new InputStreamReader(fStream, aEncoding); - } catch (Exception e) { - if (fDebug) { - System.err.println("[XMLReader] Failed setting the encoding \"" + aEncoding + "\", continue parsing with the default one."); - } - fReader = new InputStreamReader(fStream); - } - } - } - - /** - * Sets the level of tags bellow which the listener will be notified for. - * For internal use only. - * - * @param aLevel - */ - protected void setLevel(int aLevel) { - fLevel = aLevel; - } - - /* A helper function to reuse a temp CharBuffers without recreating it */ - protected CharBuffer getCharBuffer() { - if (temp.length() <= 0) { - return temp; - } else if (temp2 == null) { - temp2 = new CharBuffer(0); - return temp2; - } else if (temp2.length() <= 0) { - return temp2; - } - return new CharBuffer(0); - } - - protected char prev_char = 0; - protected char[] fBuffer = new char[4096]; - protected int fBufferLen = 0; - protected int fBufferPos = 0; - - /** - * Reads the next char from the input stream and sets it to private field - * currentChar - * - * @return true if the next char is successfully read of false if - * End-Of-Stream is reached - * @throws IOException - * if some error occurs during reading the character or if the - * caller tries to read beyond the End-Of-Stream. - */ - protected boolean getNextChar() throws IOException { - // // Reading characters without buffering - // int ichar = 0; - // int count = 0; - // while (ichar == 0 && count < 100) { - // ichar = fReader.read(); - // count++; - // } - // - // if (ichar == 0) - // throw new IOException("Failed to read from the input file."); - // - // if (ichar < 0 && prev_char == 0) - // throw new IOException(ERR_EOS); - // - // char ch = (char) ichar; - - char ch; - - if (fReader == null) { // If there is no associated reader, - int ach = fStream.read(); // then reads from the InputStream until - if (ach < 0) { // the rigth encoding is recognized - ach = 0; - } - - ch = (char) ach; - if (ch == 0 && prev_char == 0) { - throw new IOException(ERR_EOS); - } - } else { - if (fBufferLen < 0) { - throw new IOException(ERR_EOS); - } - - if ((fBufferPos) >= fBufferLen) { - // Refetch the buffer - fBufferLen = 0; - fBufferPos = 0; - int count = 0; - while (fBufferLen == 0 && count < 100) { - fBufferLen = fReader.read(fBuffer); - count++; - } - - ch = (fBufferLen > 0) ? fBuffer[fBufferPos++] : 0; - - if (fBufferLen == 0) { - fBufferLen = -1; - } - } else { - ch = fBuffer[fBufferPos++]; - } - } - - prev_char = currentChar; - currentChar = ch; - fPos++; - - switch (ch) { - case '\n' : - if (prev_char != '\r') { - fLine++; - } - fPos = 0; - break; - case '\r' : - fPos = 0; - fLine++; - break; - } - return (currentChar != 0); - } - - /** - * Parses the attribute value and if it's successful then adds it to the - * CharBuffer. If there are EntityReferences of CharReferences in the - * attribute value, they will be turned to their equivalent symbols.
    - * attr_value ::= (acceptable_char | EntityRef | CharRef)* - quot_symbol - * - * @see parse_attr - * @see parse_CharRef - * @see parse_EntityRef - */ - protected void parse_attr_value(CharBuffer sb, char quot) throws IOException { - while (currentChar != quot && currentChar != '<') { - if (accept_char('&')) { - if (!parse_CharRef(sb)) { - if (!parse_EntityRef(sb, true)) { - err(fPos - 1, ERR_ENTITY_EXPECTED); - } - } - } else { - sb.append(currentChar); - - if (!getNextChar()) { - break; - } - } - } - } - - /** - * Parses an attribute with the given simplified grammar:
    - * - *
    -	 * attribute ::= S* + attr_name + S* + '=' + S* + ('\'' + (attr_value - '\'') + '\'')) | ('"' + (attr_value - '"') + '"'))
    -	 * attr_value ::= (acceptable_char | EntityRef | CharRef)*
    -	 * attr_name ::= identifier
    -	 * 
    - * - * @param aParent - * the parent tag where the correctly parsed attribute will be - * added - * @throws IOException - * @see parse_identifier - * @see parse_attr_value - */ - protected boolean parse_attr(CharBuffer cb) throws IOException { - clearWhiteSpaces(); - - cb.append(' '); - int length = parse_identifier(cb); - - if (length > 0) { - clearWhiteSpaces(); - - if (!accept_char('=')) { - err(ERR_EQUAL_EXPECTED); - } - - cb.append('='); - clearWhiteSpaces(); - - char quot = 0; - if (accept_char('"')) { - quot = '"'; - } else if (accept_char('\'')) { - quot = '\''; - } else { - err(ERR_QUOT_EXPECTED); - } - - cb.append(quot); - parse_attr_value(cb, quot); - - if (!accept_char(quot)) { - err("'" + quot + "' expected."); - } - - cb.append(quot); - return true; - } - return false; - } - - /** - * Parses a tag attribute list with the following simplified grammar: - * - *
    -	 * attr_list ::= attribute*
    -	 * @param aParent the parent tag that the parsed attributes will be added to
    -	 * @return true if at least one attribute is parsed correctly and false otherwise
    -	 * @throws IOException
    -	 * @see parse_attr
    -	 * 
    -	 */
    -	protected boolean parse_attr_list(TagClass aParent) throws IOException {
    -		boolean result = false;
    -
    -		CharBuffer cb = getCharBuffer();
    -		cb.append(aParent.getName());
    -		while (parse_attr(cb)) {
    -			result = true;
    -		}
    -
    -		aParent.fAttributes = ((fInternAttributes) ? cb.toString().intern() : cb.toString());
    -		cb.setLength(0);
    -		return result;
    -	}
    -
    -	private static final char bA = 'A' - 1;
    -	private static final char aZ = 'Z' + 1;
    -	private static final char ba = 'a' - 1;
    -	private static final char az = 'z' + 1;
    -	private static final char b0 = '0' - 1;
    -	private static final char a9 = '9' + 1;
    -
    -	/**
    -	 * This method returns true is the passed character may be used as starting
    -	 * character for tag name and attribute name
    -	 * 
    -	 * @param ch
    -	 *            the tested character
    -	 * @return true if the character could be used as starting character for a
    -	 *         tag name and an attribute name and false otherwise
    -	 */
    -	public final static boolean isNameStartChar(char ch) {
    -		return (ch > bA && ch < aZ) || (ch > ba && ch < az) || (ch == ':') || (ch == '_') || (ch > 0xBF && ch < 0xD7) || (ch > 0xD7 && ch < 0xF7) || (ch > 0xF7 && ch < 0x300) || (ch > 0x36F && ch < 0x37E) || (ch > 0x37E && ch < 0x2000) || (ch > 0x200B && ch < 0x200E) || (ch > 0x206F && ch < 0x2190) || (ch > 0x2BFF && ch < 0x2FF0) || (ch > 0x3000 && ch < 0xD800) || (ch > 0xF900 && ch < 0xFDD0) || (ch > 0xFDEF && ch < 0xFFFE) || (ch > 0x0FFFF && ch < 0xF0000);
    -	}
    -
    -	/**
    -	 * This method returns true if the passed characted may be used as part of a
    -	 * tag name or an attribute name
    -	 * 
    -	 * @param ch
    -	 *            the tested character
    -	 * @return true is the characted could be used as part of a tag name or an
    -	 *         attribute name and false otherwise
    -	 */
    -	public final static boolean isNameChar(char ch) {
    -		return (ch == '-') || (ch == '.') || (ch == 0xB7) || (ch > b0 && ch < a9) || isNameStartChar(ch) || (ch > 0x02FF && ch < 0x0370) || (ch > 0x203E && ch < 0x2041);
    -	}
    -
    -	/**
    -	 * Parses an identifier.
    -	 * 
    -	 * @return an identifier as a string if it is parsed successfully and null
    -	 *         otherwise
    -	 * @throws IOException
    -	 *             if an exception occurs during read operations from the Reader
    -	 *             or the InputStream
    -	 */
    -	protected String parse_identifier() throws IOException {
    -		if (isNameStartChar(currentChar)) {
    -			CharBuffer sb = getCharBuffer();
    -
    -			while (isNameChar(currentChar)) {
    -				sb.append(currentChar);
    -
    -				if (!getNextChar()) {
    -					break;
    -				}
    -			}
    -			String result = sb.toString().intern();
    -			sb.setLength(0);
    -			return result;
    -		}
    -		return null;
    -	}
    -
    -	/**
    -	 * Parses an identifier and places it into the passed CharBuffer
    -	 * 
    -	 * @param cb
    -	 *            CharBuffer where the parsed identifier will be placed into
    -	 * @return the length of the parsed identifier
    -	 * @throws IOException
    -	 *             if an exception occurs during read operations from the Reader
    -	 *             or the InputStream
    -	 */
    -	protected int parse_identifier(CharBuffer cb) throws IOException {
    -		if (isNameStartChar(currentChar)) {
    -			int length = 0;
    -			while (isNameChar(currentChar)) {
    -				cb.append(currentChar);
    -				length++;
    -
    -				if (!getNextChar()) {
    -					break;
    -				}
    -			}
    -
    -			return length;
    -		}
    -		return 0;
    -	}
    -
    -	/**
    -	 * Parses a tag name and if it is successfully parsed the method sets it as
    -	 * a name of the parent tag
    -	 * 
    -	 * @param aParent
    -	 *            parent tag
    -	 * @return true if the name is parsed successfully and false otherwise
    -	 * @throws IOException
    -	 * @see parse_identifier
    -	 */
    -	protected boolean parse_tag_name(TagClass aParent) throws IOException {
    -		String name = parse_identifier();
    -		if (name != null) {
    -			aParent.setName(name);
    -		}
    -		return name != null;
    -	}
    -
    -	/**
    -	 * Helper function that notify listeners depending on certain conditions
    -	 * such as if the tag event is on-close or on-open
    -	 * 
    -	 * @param aTag
    -	 *            The tag that the notification event is valid for.
    -	 * @param isStart
    -	 *            true if the event is on-open and false if it is on-close
    -	 */
    -	protected void notifyListeners(TagClass aTag) {
    -		try {
    -			if (fLevel <= 0 || fLevel == fCurrentLevel) {
    -				fTagListener.useTag(aTag);
    -			}
    -		} catch (RuntimeException re) {
    -			if (fDebug) {
    -				System.err.println("An outside exception occurred while processing a tag on line " + aTag.getLine() + ", the tag name is: " + aTag.getName() + ", the level is: " + fCurrentLevel);
    -				re.printStackTrace(System.err);
    -			}
    -			throw re;
    -		}
    -	}
    -
    -	/**
    -	 * Parses a normal tag. There are two cases - (1) the tag has separate open
    -	 * and close tag elements and (2) the tag is simple suchas <tag_name ...
    -	 * />
    -	 * 
    -	 * @param aParent
    -	 *            The parent tag that this tag will be added to if the parsing
    -	 *            is successful
    -	 * @return true on success and false otherwise
    -	 * @throws IOException
    -	 * @see clearWhiteSpaces
    -	 * @see parse_tag_name
    -	 * @see parse_attr_list
    -	 * @see notifyListeners
    -	 * @see accept_char
    -	 * @see accept_seq
    -	 * @see parse_PCDATA
    -	 */
    -	protected boolean parse_tag_normal(TagClass aParent) throws IOException {
    -		// Looking for a tag_name (identifier)
    -		if (isNameStartChar(currentChar)) {
    -			TagClass tag = new TagClass();
    -			tag.setLine(fLine);
    -
    -			parse_tag_name(tag);
    -			parse_attr_list(tag);
    -
    -			clearWhiteSpaces();
    -
    -			if (accept_char('/')) {
    -				if (!accept_char('>')) {
    -					err(ERR_GT_EXPECTED);
    -				}
    -				tag.setInline();
    -				aParent.addTag(tag);
    -
    -				if (!fOldBehaviour) {
    -					notifyListeners(tag);
    -				}
    -
    -				return true;
    -			} else if (accept_char('>')) {
    -
    -				while (true) {
    -					clearWhiteSpaces();
    -					int pos = fPos;
    -					if (currentChar == '<') { // Normal tag, Special tag or
    -						// closing tag
    -						if (!parse_tag(tag)) { // It may be a special tag.
    -							if (!accept_char('/')) {
    -								err(pos + 1, ERR_CLOSE_TAG1_EXPECTED);
    -							}
    -
    -							// trying to accept: tag_name + S* + '>'
    -							pos = fPos;
    -							if (!accept_seq(tag.getName())) {
    -								err(pos, '\'' + tag.getName() + "' string expected.");
    -							}
    -
    -							clearWhiteSpaces();
    -							if (!accept_char('>')) {
    -								err(ERR_GT_EXPECTED);
    -							}
    -
    -							aParent.addTag(tag);
    -
    -							notifyListeners(tag);
    -
    -							return true;
    -						}
    -					} else {
    -						if (!parse_PCDATA(tag))
    -							break;
    -					}
    -				}
    -				err(ERR_CONTENT_EXPECTED);
    -			} else {
    -				err(ERR_CLOSE_TAG2_EXPECTED);
    -			}
    -		}
    -		return false;
    -	}
    -
    -	/**
    -	 * Parses special tags, such that begins with:
    - * - *
    
    -	 * <!--         comments
    -	 * <!tag_name   Parsing instructions
    -	 * <![          CDATA element
    -	 * <?           DOCTYPE, etc.
    -	 * 
    - * - * @param aParent - * The parent tag that this tag will be added to if the parsing - * is successful - * @return true on success and false otherwise - * @throws IOException - * @see accept_char - * @see clearWhiteSpaces - * @see parse_tag_CDATA - * @see parse_tag_name - * @see parse_comment - */ - protected boolean parse_tag_special(TagClass aParent) throws IOException { - if (accept_char('!')) { - - TagClass tag = new TagClass(); - - if (parse_tag_name(tag)) { - clearWhiteSpaces(); - - while (true) { - if (accept_char('>')) { - clearWhiteSpaces(); - return true; - } - getNextChar(); - } - } else if (parse_tag_CDATA(aParent)) { // parse CDATA tag - return true; - } else if (parse_comment(tag)) { - return true; - } - } else if (accept_char('?')) { - TagClass tag = new TagClass(); - - int pos = fPos; - if (parse_tag_name(tag)) { - if (tag.getName().equals(XML)) { - err(pos - 2, ERR_XMLPROLOG_EXPECTED); - } - - char prevCh = 0; - while (true) { - if (currentChar == '>') { - if (prevCh == '?') { - accept_char('>'); - clearWhiteSpaces(); - return true; - } - } - prevCh = currentChar; - getNextChar(); - } - - } - err(pos, ERR_TAGNAME_EXPECTED); - } - return false; - } - - /** - * Parses an attribute value and returns it as a string - * - * @return the parsed attribute value as a string. - * @throws IOException - * if an exception occurs during read operations from the Reader - * or the InputStream - */ - protected String getAttrValue() throws IOException { - CharBuffer cb = getCharBuffer(); - - clearWhiteSpaces(); - accept_char('='); - clearWhiteSpaces(); - - if (currentChar != '\'' && currentChar != '"') { - err(ERR_QUOT_EXPECTED); - } - - char quot = currentChar; - accept_char(quot); - parse_attr_value(cb, quot); - - if (!accept_char(quot)) { - err("'" + quot + "' expected."); - } - - String result = cb.toString(); - cb.setLength(0); - clearWhiteSpaces(); - return result; - } - - /** - * Parses the XML prolog tag, i.e.
    - * <?xml version="..." encoding="..." standalone="..." ?>
    - * - * @param parent - * the parent tag (in this case this is the root "fake" tag, - * which the listeners will never be informed for...) - * @throws IOException - * if an exception occurs during read operations from the Reader - * or the InputStream - */ - protected boolean parse_xml_prolog(TagClass parent) throws IOException { - if (accept_char('?')) { - TagClass tag = new TagClass(); - - if (parse_tag_name(tag)) { - if (tag.getName().equalsIgnoreCase(XML)) { - if (fOldLevels) - fCurrentLevel++; - - clearWhiteSpaces(); - - int pos = fPos; - - String s = parse_identifier(); - - boolean bEncoding = false; - boolean bStandalone = false; - - if (VERSION.equals(s)) { - fVersion = getAttrValue(); - s = parse_identifier(); - } else { - err(pos, ERR_VERSION_EXPECTED); - } - - if (ENCODING.equals(s)) { - fEncoding = getAttrValue().toUpperCase(); - s = parse_identifier(); - bEncoding = true; - } - - if (STANDALONE.equals(s)) { - fStandalone = getAttrValue(); - s = parse_identifier(); - bStandalone = true; - } - - if (s != null) { - if (bEncoding && bStandalone) - err(ERR_CLOSE_TAG3_EXPECTED); - - if (!bEncoding && !bStandalone) - err(ERR_ENCODING_STANDALONE_EXPECTED); - - if (bEncoding) - err(ERR_STANDALONE_EXPECTED); - err(ERR_CLOSE_TAG3_EXPECTED); - } - - clearWhiteSpaces(); - pos = fPos; - if (!accept_seq("?>")) - err(pos, ERR_CLOSE_TAG3_EXPECTED); - return true; - } - - char prevCh = 0; - - while (true) { - if (currentChar == '>') { - if (prevCh == '?') { - accept_char('>'); - clearWhiteSpaces(); - - return true; - } - err(ERR_QUESTIONMARK_EXPECTED); - } else if (currentChar == '<') { - err(ERR_ILLEGAL_CHARACTER + " ('<')"); - } - prevCh = currentChar; - getNextChar(); - } - - } - } - return false; - } - - /** - * Parses a comment. The grammar is:
    - * Comment ::= '<!--' ((Char - '-') | ('-' (Char - '-')))* '-->'
    - * Note that the grammar does not allow a comment ending in --->. The - * following example is not well-formed.
    - * - * <!-- B+, B, or B---> - * - * @param aParent - * The parent tag - * @return true on success and false otherwise - * @throws IOException - * @see accept_char - */ - protected boolean parse_comment(TagClass aParent) throws IOException { - if (accept_char('-')) { - if (!accept_char('-')) { - err(ERR_DASH_EXPECTED); - } - - while (true) { - if (accept_char('-')) { - if (accept_char('-')) { - if (accept_char('>')) { - break; - } - - err(ERR_GT_EXPECTED); - } - } - - if (!getNextChar()) { - err(ERR_COMMENT_CLOSE_EXPECTED); - } - } - return true; - } - return false; - } - - /** - * Parses either normal or special tag - * - * @param aParent - * The parent tag that the successfully parsed tag will (if it is - * normal tag or CDATA element) be added - * @return true on success and false otherwise - * @throws IOException - * @see accept_cahr - * @see parse_tag_normal - * @see parse_tag_special - * @see clearWhiteSpaces - */ - protected boolean parse_tag(TagClass aParent) throws IOException { - clearWhiteSpaces(); - try { - fCurrentLevel++; - - if (accept_char('<')) { - if (parse_tag_normal(aParent) || parse_tag_special(aParent)) { - return true; - } - } - return false; - } finally { - fCurrentLevel--; - } - } - - /** - * Parses the content of the tag (including sub-tags and sub-elements) - * - * @param aParent - * The parent tag that the content and tags will be added to - * @return true on success and false otherwise - * @throws IOException - * @see parse_PCDATA - * @see parse_tag - */ - protected boolean parse_content(TagClass aParent) throws IOException { - return (parse_PCDATA(aParent) || parse_tag(aParent)); - } - - /** - * Parses a CDATA tag (or CDATA content element). - * - * @param aParent - * The parent tag that the content will be added to - * @return true on success and false otherwise - * @throws IOException - */ - protected boolean parse_tag_CDATA(TagClass aParent) throws IOException { - if (accept_char('[')) { - int pos = fPos; - if (!accept_seq(CDATA)) - err(pos, ERR_CDATA_EXPECTED); - - if (!accept_char('[')) - err(ERR_OPENSQBRACKET_EXPECTED); - - do { - if (currentChar != '>') { - aParent.getContentBuffer().append(currentChar); - } else { - CharBuffer sb = aParent.getContentBuffer(); - int l = sb.length(); - - if (l >= 2) { - if (sb.charAt(l - 1) == ']' && sb.charAt(l - 2) == ']') { - sb.setLength(l - 2); // Truncates the extra "]]" - // symbols appended at the - // end - - getNextChar(); - return true; - } - } - sb.append(currentChar); - } - } while (getNextChar()); - - err(fPos - 1, ERR_CLOSE_CDATA_EXPECTED); - } - return false; - } - - /** - * Parses PCDATA content (Parseable Content DATA). The EntityRefs and - * CharRefs that are parsed will be turned to its symbol equivalent. - * - * @param aParent - * The parent tag that the PCDATA will be added to - * @return true on success and false otherwise - * @throws IOException - * @see accept_char - * @see parse_CharRef - * @see parse_EntityRef - */ - protected boolean parse_PCDATA(TagClass aParent) throws IOException { - boolean result = false; - while (currentChar != '<') { - result = true; - - CharBuffer sbContent = aParent.getContentBuffer(); - - if (accept_char('&')) { - int pos = fPos; - - if (!parse_CharRef(sbContent)) - if (!parse_EntityRef(sbContent, false)) - err(pos - 1, ERR_ENTITY_EXPECTED); - - } else { - sbContent.append(currentChar); - - if (!getNextChar()) - break; - } - } - return result; - } - - /** - * Accepts one character from the input stream and if it's successful moves - * one character forward. - * - * @param ch - * The character that should be accepted - * @return true on success and false otherwise - * @throws IOException - */ - protected boolean accept_char(char ch) throws IOException { - if (currentChar == ch) { - getNextChar(); - return true; - } - return false; - } - - /** - * Accepts a sequence of characters given by seq parameter. If the sequence - * is accepted successfully then the currentChar field will contain the - * character immediately after the accepted sequence. - * - * @param seq - * The character sequence that should be accepted - * @return true on success and false otherwise - * @throws IOException - */ - protected boolean accept_seq(String seq) throws IOException { - for (int i = 0; i < seq.length(); i++) { - if (!accept_char(seq.charAt(i))) - return false; - } - return true; - } - - private static final String[] fEntities = (fOldBehaviour) ? fOld_entities : fNew_entities; - private static final char[] fEnt_chars = (fOldBehaviour) ? fOld_ent_chars : fNew_ent_chars; - - /** - * - * EntityRef ::= '&' + EntityValue + ';'
    - * EntityValue ::= 'amp' | 'quot' | 'apos' | 'gt' | 'lt' | identifier - *
    - * - * @param sb - * The string buffer that the recognized entity will be appended - * to - * @throws IOException - * @return true on success and false otherwise - * @see parse_identifier - * @see accept_char - */ - protected boolean parse_EntityRef(CharBuffer sb, boolean inAttribute) throws IOException { - String ent = parse_identifier(); - - if (!accept_char(';')) { - err(ERR_SEMICOLON_EXPECTED); - } - - if (!inAttribute) { - int length = fEntities.length; - for (int i = 0; i < length; i++) { - if (fEntities[i] == ent) { // 'ent' is interned by - // parse_identifier() function - sb.append(fEnt_chars[i]); - return true; - } - } - } - - sb.append('&'); - if (ent != null) { - sb.append(ent); - } - sb.append(';'); - - return true; - } - - /** - * Parses a CharReference and if it is successful then appends it to the - * passed CharBuffer - * - * @param sb - * CharBuffer that the parsed CharReference will be added to - * @return true on success and false otherwise - * @throws IOException - */ - protected boolean parse_CharRef(CharBuffer sb) throws IOException { - if (accept_char('#')) { - // TODO - Postponed... - while (currentChar != ';') { - getNextChar(); - } - - if (!accept_char(';')) { - err(fPos - 1, ERR_SEMICOLON_EXPECTED); - } - - return true; - } - return false; - } - - /** - * Clears the white spaces starting from the current position - * - * @throws IOException - */ - protected void clearWhiteSpaces() throws IOException { - while (Character.isWhitespace(currentChar)) { - if (!getNextChar()) - break; - } - } - - /** - * Throws an IOException with a given message. The current line number and - * line position are appended to the error message - * - * @param message - * The message of the exception - * @throws IOException - */ - protected void err(String message) throws IOException { - err(fPos, message); - } - - /** - * Throws an IOException with the given message for the given line position. - * The current line number and position (pos) are appended to the exception - * message - * - * @param pos - * The line position that the error will be reported for - * @param message - * @throws IOException - */ - protected void err(int pos, String message) throws IOException { - throw new IOException("[Line: " + fLine + ", Pos: " + pos + "] " + message); - } - - /** - * Initiates parsing of the XML file given through aInputStream or aReader - * in the given constructor when creating XMLReader object. - * - * @throws IOException - * if an error occurs during reading the XML file or if a - * parsing error eccurs. - */ - protected void parseXML() throws IOException { - TagClass rootTag = new TagClass(); - - try { - getNextChar(); - clearWhiteSpaces(); - - boolean start = false; - - while (accept_char('<')) { - start = true; - int pos = fPos; - - if (fPos == 2 && fLine == 1) { - if (parse_xml_prolog(rootTag)) { - // System.out.println("XML Prolog found."); - // System.out.println("XML Version: " + fVersion + ", - // encoding: " + fEncoding); - setEncoding(fEncoding); - clearWhiteSpaces(); - continue; - } - } else { - setEncoding(fDefaultEncoding); - } - - if (!parse_tag_special(rootTag)) { - if (parse_tag_normal(rootTag)) { - // TODO da se proveri dali e dostignat kraja na file-a, - // ako ne e - - // togava ot tuk natatuk moje da ima samo komentari. - return; - } - err(pos, ERR_TAGNAME2_EXPECTED); - } - - clearWhiteSpaces(); - } - - if (!start) { - err(ERR_LT_EXPECTED); - } - } catch (IOException ioe) { - if (fDebug) { - ioe.printStackTrace(System.err); - } - - throw ioe; - } - } - - /** - * Parses a XML file given through aInputStream and during the parsing - * notifies aListener for close-tag events
    - *
    - * Note: The XMLReader does not close the passed Reader or InputStream - * - * @param aInputStream - * an InputStream to read the XML file from - * @param aListener - * TagListener that will be notified on close-tag event - * @param aLevel - * see parseXML(Reader aReader, TagListener aListener, int aLevel - * description - * @throws IOException - * if some IO error occurs when reading the XML file or if a - * parser error occurs. - */ - public static void parseXML(InputStream aInputStream, TagListener aListener, int aLevel) throws IOException { - XMLReader xml = new XMLReader(aInputStream, aListener); - xml.setLevel(aLevel); - xml.parseXML(); - } - - /** - * Parses a XML file given through aReader and during the parsing notifies - * aListener for close-tag events
    - *
    - * Note: The XMLReader does not close the passed Reader or InputStream - * - * @param aReader - * a reader that will be used to read the XML file from - * @param aListener - * TagListener that will be notified on close-tag event - * @param aLevel - * indicates the tag level that the listener will be invoked for. - * For example if the XML is:
    - * - *
    -	 *  <a>
    -	 *    <b>
    -	 *      <c />
    -	 *    </b>
    -	 *  </a>
    -	 * 
    - * - *
    - * and the passed aLevel is 2 then the listener will be invoked - * only for tags that have level 2, i.e. in our example the - * listener will be invoked only for tag <b>
    - *
      - *
    • Value less than 0 indicates "invoke listener for all - * tags no matter what are their levels"
    • - *
    • Value of 0 indicates that the listener must not be - * invoked in general no matter what is the tag level
    • - *
    • Value greater than 0 indicates the tag level that the - * listener will be invoked for
    • - * @throws IOException - * if some IO error occurs when reading the XML file or if a - * parser error occurs. - */ - public static void parseXML(Reader aReader, TagListener aListener, int aLevel) throws IOException { - XMLReader xml = new XMLReader(aReader, aListener); - xml.setLevel(aLevel); - xml.parseXML(); - } - - /** - * Returns the XML version attribute - * - * @return the XML file version attribute - */ - public String getVersion() { - return fVersion; - } - - /** - * Returns the XML encoding attribute - * - * @return the XML encoding attribute - */ - public String getEncoding() { - return fEncoding; - } - - /** - * Returns the value of XML standalone attribute - * - * @return the value of XML standalone attribute - */ - public String getStandalone() { - return fStandalone; - } -} diff --git a/bundles/org.eclipse.equinox.ds/src/org/eclipse/equinox/internal/util/xml/XMLUtil.java b/bundles/org.eclipse.equinox.ds/src/org/eclipse/equinox/internal/util/xml/XMLUtil.java deleted file mode 100644 index 30f9a39dd..000000000 --- a/bundles/org.eclipse.equinox.ds/src/org/eclipse/equinox/internal/util/xml/XMLUtil.java +++ /dev/null @@ -1,363 +0,0 @@ -/******************************************************************************* - * Copyright (c) 1997, 2008 by ProSyst Software GmbH - * http://www.prosyst.com - * 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: - * ProSyst Software GmbH - initial API and implementation - *******************************************************************************/ -package org.eclipse.equinox.internal.util.xml; - -import java.util.Vector; - -import org.eclipse.equinox.internal.util.string.CharBuffer; - -/** - * Class with utility methods for extracting attributes from xml tags - * - * @author Pavlin Dobrev - * @version 1.0 - */ - -public class XMLUtil { - - /** - * Coded chars placed in the xml content. - */ - public static String[] coded = {"&", " ", "&crlf;", "&tab;", "<", ">", """, "'"}; - - /** - * Corresponding decoded chars. First five of them cannot exist in plain - * (decoded) form in the xml content, but the rest can be eighter coded or - * decoded - */ - public static String[] decoded = {"&", " ", "\n", "\t", "<", ">", "\"", "'"}; - - /** - * Replaces specified strings in a source string with corresponding strings - * - * @param str - * source string - * @param toBeReplaced - * array of strings which will be replaced with the next - * parameter - * @param replaceWith - * array of the strings corresponding to "toBeReplaced" - * parameter. the length should be equal - * @param length - * specify how many parameters of the string array will be - * replaced, the rest of "toBeReplaced" parameter will not. - * @return replaced string - */ - public static String replaceChars(String str, String[] toBeReplaced, String[] replaceWith, int length) { - - /* - * first 5 characters are not allowed to exists in such form in xml, the - * rest remains the same - */ - CharBuffer strBuf; - for (int i = 0; i < length; i++) { - strBuf = new CharBuffer(); - replace(str, toBeReplaced[i], replaceWith[i], strBuf); - str = strBuf.toString(); - } - return str; - } - - /** - * Replaces a specified string in a source string with a corresponding - * string and adds the result in a buffer. - * - * @param src - * source string - * @param toBeReplaced - * string which will be replaced with the next parameter - * @param toReplaceWith - * the string corresponding to "toBeReplaced" parameter. - * @param strBuf - * here is added the replaced source string. - */ - public static void replace(String src, String toBeReplaced, String toReplaceWith, CharBuffer strBuf) { - - int j; - int pos = 0; - int length = toBeReplaced.length(); - while (((j = src.indexOf(toBeReplaced, pos)) > -1)) { - strBuf.append(src.substring(pos, j)); - strBuf.append(toReplaceWith); - pos = j + length; - } - strBuf.append(src.substring(pos)); - } - - /** - * Converts special xml chars to valid string e.g. "&lt;" becomes "<" - * and "&gt;" becomes ">" - * - * @param src - * source string which is coded - * @return decoded string - */ - public static String getDecoded(String src) { - int begin = src.indexOf('&'); - if (begin == -1) { - /* - * improve speed when there is not any coded string (each coded - * string begins with '&') - */ - return src; - } - int end = src.indexOf(';', begin); - if (end == -1) { - /* - * improve speed when there is not any coded string (each coded - * string ends with ';') - */ - return src; - } - int lastBegin = 0; - CharBuffer strBuf = new CharBuffer(); - while (begin != -1) { - end = src.indexOf(';', begin); /* - * this is used on the second turn - * of the cycle - */ - if (end == -1) { - strBuf.append(src.substring(begin)); - return strBuf.toString(); - } - strBuf.append(src.substring(lastBegin, begin)); - String part = src.substring(begin, end + 1); - boolean found = false; - for (int i = 0; i < decoded.length; i++) { - if (part.equals(coded[i])) { - strBuf.append(decoded[i]); - begin += part.length(); - lastBegin = begin; - begin = src.indexOf('&', lastBegin); - found = true; - break; /* - * one word replaced, go on searching with rest of - * the src - */ - } - } - if (!found) { - strBuf.append(part); - begin += part.length(); - lastBegin = begin; - begin = src.indexOf('&', begin); - } - } - strBuf.append(src.substring(lastBegin)); - return strBuf.toString().intern(); - } - - /** - * Extracts the name of the tag, from string containing the name and - * attributes - * - * @param tagAndAttributes - * string containing the name and attributes - * @return tag name string separated by space from the tag attributes - * @deprecated use TagClass.getName() instead - */ - public static String getTagName(String tagAndAttributes) { - int nameIndex = tagAndAttributes.indexOf(' '); - if (nameIndex != -1) { - int tabIndex = tagAndAttributes.indexOf('\t'); - if (tabIndex > -1 && tabIndex < nameIndex) { - return tagAndAttributes.substring(0, tabIndex); - } - return tagAndAttributes.substring(0, nameIndex); - } - - nameIndex = tagAndAttributes.indexOf('/'); - if (nameIndex != -1) { - return tagAndAttributes.substring(0, nameIndex); - } - return tagAndAttributes; - } - - public static boolean isEmptyTag(String tagName) { - return '/' == tagName.charAt(tagName.length() - 1); - } - - /** - * Checks whether the tag name string between < and >, ends with "/". - * - * @param tagName - * string between < and > chars - * @return true if and only if string ends with "/" - */ - - protected static final String[] f_entities = {"amp", "nbsp", "crlf", "tab", "lt", "gt", "quot", "apos"}; - protected static final char[] f_ent_chars = {'&', ' ', '\n', '\t', '<', '>', '"', '\''}; - - private static boolean substituteEntity(String ent, CharBuffer cb) { - for (int j = 0; j < f_entities.length; j++) { - if (f_entities[j].equals(ent)) { - cb.append(f_ent_chars[j]); - return true; - } - } - return false; - } - - /** - * Extracts an attribute value for a specified attribute name from tag - * string. - * - * @param tag - * whole tag name - * @param att - * attribute name - * @return value of the attribute if exists otherwise return null - * @deprecated use TagClass.getAttrList() and TagClass.getAttribute(String - * attr) instead - */ - public static String getAttributeValue(String tag, String att, int begin) { - if (att.length() == 0) - return null; - - int start = 0; - while (start >= 0) { - start = tag.indexOf(att, start); - - if (start >= 0) { - // Checks if leading and trailing chars are valid attr_name - // chars - boolean b1 = (start > 0) ? XMLReader.isNameChar(tag.charAt(start - 1)) : true; - boolean b2 = ((start + att.length() + 1) < tag.length()) ? XMLReader.isNameChar(tag.charAt(start + att.length())) : true; - - start += att.length(); - if (!b1 && !b2) { - start = tag.indexOf('=', start) + 1; - if (start <= 0) - return null; - - while (start < tag.length() && Character.isWhitespace(tag.charAt(start))) { - start++; - } - - char quot = tag.charAt(start); - int end = tag.indexOf(quot, start + 1); - if ((start != -1) && (end > start)) { - int pos = tag.indexOf('&', start + 1); - if (pos < 0 || pos > end) - return tag.substring(start + 1, end).intern(); - - CharBuffer cb = new CharBuffer(); - - char ch; - for (int i = (start + 1); i < end; i++) { - ch = tag.charAt(i); - if (ch == '&') { - pos = tag.indexOf(';', i); - String ent = tag.substring(i + 1, pos); - - if (substituteEntity(ent, cb)) { - i = pos; - continue; - } - - cb.append('&'); - cb.append(ent); - cb.append(';'); - i = pos; - continue; - } - cb.append(ch); - } - - return cb.toString().intern(); - } - start = end; - } - } - } - return null; - } - - /** - * Extracts attribute names from tag string. - * - * @param tag - * whole tag name - * @return A vector with all attribute names - * @deprecated use TagClass.getAttrList() instead - */ - public static Vector getAttributeNames(String tag) { - Vector names = new Vector(); - int start = tag.indexOf(' '); /* avoid name of this tag */ - int end; - while (start != -1) { - end = tag.indexOf('=', start + 1); - if (end == -1) { - break; - } - names.addElement(tag.substring(start + 1, end)); - start = tag.indexOf('"', end + 1); - if (start == -1) { - break; - } - start = tag.indexOf('"', start + 1); - if (start == -1) { - break; - } - start = tag.indexOf(' ', start + 1); - } - return names; - } - - /** - * Extracts attribute values from tag string. - * - * @param tag - * whole tag name - * @return A vector with all attribute values - * @deprecated use TagClass.getAttrList() instead - */ - public static Vector getAttributeValues(String tag) { - Vector values = new Vector(); - int start = tag.indexOf('='); - int end; - while (start != -1) { - start = tag.indexOf('"', start + 1); - end = tag.indexOf('"', start + 1); - if ((start == -1) || (end == -1)) { - break; - } - values.addElement(tag.substring(start + 1, end).intern()); - start = tag.indexOf('=', end + 1); - } - return values; - } - - /** - * Returns content of the specified subtag. - * - * @param tag - * parent tag - * @param pos - * position of the searched tag in child array of the parent tag - * @param name - * name of the searched tag - * @return content of the specified subtag - * @exception IllegalArgumentException - * if the specified name does not match the name of the tag - * at specified position - * @deprecated use TagClass.getContent(int pos, String name) instead - */ - - public static String getContent(TagClass tag, int pos, String name) throws IllegalArgumentException { - TagClass subTag = tag.getTagAt(pos); - if (subTag.getName().equals(name)) { - return subTag.getContent(); - } - throw new IllegalArgumentException("Missing subtag " + name + " in " + tag.getName()); - } -} diff --git a/bundles/org.eclipse.equinox.ds/src/org/eclipse/equinox/internal/util/xml/XmlSerializer.java b/bundles/org.eclipse.equinox.ds/src/org/eclipse/equinox/internal/util/xml/XmlSerializer.java deleted file mode 100644 index e1b1b92ba..000000000 --- a/bundles/org.eclipse.equinox.ds/src/org/eclipse/equinox/internal/util/xml/XmlSerializer.java +++ /dev/null @@ -1,444 +0,0 @@ -/******************************************************************************* - * Copyright (c) 1997, 2008 by ProSyst Software GmbH - * http://www.prosyst.com - * 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: - * ProSyst Software GmbH - initial API and implementation - *******************************************************************************/ -package org.eclipse.equinox.internal.util.xml; - -import java.io.*; -import java.util.Vector; - -/** - * XmlSerializer is an utility class, that simplifies creation of XML files. It - * is designed to be similar to the XML Pull API serializer. - * - * @author Valentin Valchev - * @author Pavlin Dobrev - * @version 1.0 - */ - -public class XmlSerializer { - - private Writer writer; // underlying writer - private Vector stack; // of XML entity names - private StringWriter attrsWriter; // current attribute writer - private StringBuffer attrs; // current attribute string - private boolean empty; // is the current node empty - private boolean closed; // is the current node closed... - private String indentString; - private boolean prologWritten; - - /** - * Opens and initializes XML output on top of existing Writer. - * - * @param writer - * the output writer - * @return self - */ - public XmlSerializer setOutput(Writer writer) { - this.writer = writer; - this.closed = true; - this.prologWritten = false; - if (stack == null) { - stack = new Vector(5); - } else { - stack.removeAllElements(); - } - if (attrs != null) { - attrs.setLength(0); - } - return this; - } - - /** - * Set to use binary output stream with given encoding. - * - * @param os - * the output stream - * @param encoding - * the output encoding - * @throws IOException - * @see #setOutput(Writer) - * @throws NullPointerException - * is output stream is null - */ - public void setOutput(OutputStream os, String encoding) throws IOException { - if (os == null) - throw new NullPointerException("output stream can not be null"); - Writer writer = encoding != null ? // - new OutputStreamWriter(os, encoding) - : // - new OutputStreamWriter(os); - setOutput(writer); - } - - /** - * Writes XML prolog code: - * - *
      -	 *        <?xml version="1.0"?>
      -	 * 
      - * - * @param encoding - * the selected encoding. If null encoding - * attribute is not written. - * @param standalone - * if the XML is stand-alone, no DTD or schema - * @return self - * @throws IOException - * on I/O error - * @throws IllegalStateException - * if prolog code is already written - */ - public XmlSerializer startDocument(String encoding, Boolean standalone) throws IOException { - if (prologWritten) { - throw new IllegalStateException("Prolog already written"); - } - writer.write(""); - prologWritten = true; - return this; - } - - /** - * Close this writer. It does not close the underlying writer, but does - * throw an exception if there are as yet unclosed tags. - * - * @throws IllegalStateException - * if tags are not closed - */ - public void endDocument() { - if (!stack.isEmpty()) { - throw new IllegalStateException("Tags are not all closed. Possibly, '" + pop() + "' is unclosed. "); - } - } - - /** - * Returns the current depth of the element. Outside the root element, the - * depth is 0. The depth is incremented by 1 when startTag() is called. The - * depth is decremented after the call to endTag() event was observed. - * - *
      -	 *        <!-- outside -->     0
      -	 *        <root>               1
      -	 *          sometext                 1
      -	 *            <foobar>         2
      -	 *            </foobar>        2
      -	 *        </root>              1
      -	 *        <!-- outside -->     0
      -	 * 
      - * - * @return the current level - */ - public int getDepth() { - return stack.size(); - } - - /** - * Begin to output an entity. - * - * @param name - * name of entity. - * @return self - * @throws IOException - * on I/O error - */ - public XmlSerializer startTag(String name) throws IOException { - if (!prologWritten) { - startDocument(null, null); - } - closeOpeningTag(); - closed = false; - indent(); - writer.write("<"); - writer.write(name); - stack.addElement(name); - empty = true; - return this; - } - - /** - * End the current entity silently without validating if correct tag is - * closed. - * - * @return self - * @throws IOException - * @deprecated see {@link #endTag(String)} - */ - public XmlSerializer endTag() throws IOException { - return endTag(null); - } - - /** - * End the current entity. This will throw an exception if it is called when - * there is not a currently open entity. - * - * @param aName - * tag to close. This is used mostly for validation - * @return self - * @throws IOException - * on I/O error - * @throws IllegalStateException - * if no entity waits to be closed - * @throws IllegalArgumentException - * if expected element name is not the same - */ - public XmlSerializer endTag(String aName) throws IOException { - - if (stack.isEmpty()) { - throw new IllegalStateException("Called endEntity too many times."); - } - String name = pop(); - if (name != null) { - if (aName != null && !aName.equals(name)) { - throw new IllegalArgumentException("Expected element name '" + name + "', not '" + aName + "'"); - } - if (empty) { - writeAttributes(); - writer.write("/>"); - } else { - indent(); - writer.write(""); - } - empty = false; - } - return this; - } - - /** - * Write an attribute out for the current entity. Any XML characters in the - * value are escaped. Calls to attribute() MUST follow a call to startTag() - * immediately. - * - * @param localName - * name of attribute. - * @param value - * value of attribute. - * @return self - * @throws IOException - * on I/O error - * @throws IllegalStateException - * if opening tag is closed - */ - public XmlSerializer attribute(String localName, String value) throws IOException { - if (closed) { - throw new IllegalStateException("Opening tag is already closed"); - } - if (localName == null) { - throw new IllegalArgumentException("Attribute name is null"); - } - if (value == null) - value = ""; - if (attrsWriter == null) { - attrsWriter = new StringWriter(); - attrs = attrsWriter.getBuffer(); - } - attrs.append(" "); - attrs.append(localName); - attrs.append("=\""); - writeEscape(value, attrsWriter); - attrs.append("\""); - return this; - } - - /** - * Output body text. Any XML characters are escaped. - * - * @param text - * the body text - * @return self - * @throws IOException - * on I/O error - */ - public XmlSerializer text(String text) throws IOException { - closeOpeningTag(); - if (text != null && text.length() > 0) { - indent(); - empty = false; - writeEscape(text, writer); - } - return this; - } - - /** - * Writes raw, CDATA section - * - * @param text - * the data - * @return self - * @throws IOException - * on I/O error - */ - public XmlSerializer cdsect(String text) throws IOException { - closeOpeningTag(); - writer.write(""); - return this; - } - - /** - * Writes XML comment code - * - * @param text - * the comment - * @return self - * @throws IOException - * on I/O error - */ - public XmlSerializer comment(String text) throws IOException { - closeOpeningTag(); - writer.write(""); - return this; - } - - /** - * Writes DOCTYPE declaration. The document must be open prior calling that - * method. - * - * @param text - * declaration - * @return self - * @throws IOException - * on I/O error - * @throws IllegalStateException - * if document is not open or start tag is already started - */ - public XmlSerializer docdecl(String text) throws IOException { - if (!prologWritten) { - throw new IllegalStateException("Document is not open"); - } - if (getDepth() != 0) { - throw new IllegalStateException("Cannot add DOCTYPE after start tag has been opened!"); - } - closeOpeningTag(); - writer.write(""); - return this; - } - - /** - * Enables/disables indentation - * - * @param indent - * an indentation string or null to disable - * indentation. - */ - public void setIndent(boolean indent) { - this.indentString = indent ? "\t" : null; - } - - // close off the opening tag - private void closeOpeningTag() throws IOException { - if (!this.closed) { - writeAttributes(); - closed = true; - writer.write(">"); - } - } - - // write out all current attributes - private void writeAttributes() throws IOException { - if (attrs != null) { - writer.write(attrs.toString()); - attrs.setLength(0); - empty = false; - } - } - - private final String pop() { - int location = stack.size() - 1; - String ret = (String) stack.elementAt(location); - stack.removeElementAt(location); - return ret; - } - - private final void indent() throws IOException { - if (indentString != null) { - writer.write('\n'); - for (int i = 0; i < stack.size(); i++) { - writer.write(indentString); - } - } - } - - private final void writeEscape(String text, Writer out) throws IOException { - // escape '<', '&', '>', ', " - char[] buf = text.toCharArray(); - int len = buf.length; - int pos = 0; - for (int i = 0; i < len; i++) { - final char ch = buf[i]; - - if (ch == '&') { - if (i > pos) - out.write(buf, pos, i - pos); - out.write("&"); - pos = i + 1; - } else if (ch == '<') { - if (i > pos) - out.write(buf, pos, i - pos); - out.write("<"); - pos = i + 1; - } else if (ch == '>') { - if (i > pos) - out.write(buf, pos, i - pos); - out.write(">"); - pos = i + 1; - } else if (ch == '"') { - if (i > pos) - out.write(buf, pos, i - pos); - out.write("&guot;"); - pos = i + 1; - } else if (ch == '\'') { - if (i > pos) - out.write(buf, pos, i - pos); - out.write("'"); - pos = i + 1; - } else if (ch < 32) { - // in XML 1.0 only legal character are #x9 | #xA | #xD - if (ch == 9 || ch == 10 || ch == 13) { - // pass through - } else { - throw new IllegalStateException("character " + ch + " (" + Integer.toString(ch) + ") is not allowed in output"); - } - } - } - if (len > pos) { - out.write(buf, pos, len - pos); - } - } - - /* - * public static void main(String[] args) throws IOException { XmlSerializer - * o = new XmlSerializer(); Writer x = new java.io.StringWriter(); - * o.setIndent(true); o.setOutput(x); o.startDocument("UTF-8", null)// - * .startTag("test")// .startTag("inner")// .attribute("attribute", - * "value").text("text & ' < > \\\" ;[")// .comment("this is an embedded - * comment inside the inner body")// .endTag("inner")// - * .startTag("entry").cdsect("testing [] > < & ;").endTag("entry")// - * .endTag("test")// .endDocument(); System.out.println(x); } - */ - -} diff --git a/bundles/org.eclipse.equinox.ds/src/org/eclipse/equinox/internal/util/xml/impl/TagImpl.java b/bundles/org.eclipse.equinox.ds/src/org/eclipse/equinox/internal/util/xml/impl/TagImpl.java deleted file mode 100644 index ca3e01f4c..000000000 --- a/bundles/org.eclipse.equinox.ds/src/org/eclipse/equinox/internal/util/xml/impl/TagImpl.java +++ /dev/null @@ -1,381 +0,0 @@ -/******************************************************************************* - * Copyright (c) 1997, 2008 by ProSyst Software GmbH - * http://www.prosyst.com - * 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: - * ProSyst Software GmbH - initial API and implementation - *******************************************************************************/ -package org.eclipse.equinox.internal.util.xml.impl; - -import java.io.*; -import java.util.*; -import org.eclipse.equinox.internal.util.string.CharBuffer; -import org.eclipse.equinox.internal.util.xml.Tag; - -/** - * @author Ivan Dimitrov - * @author Pavlin Dobrev - * @version 1.0 - */ - -public class TagImpl implements Tag { - - private CharBuffer fContent = null; - private String fContentString = null; - private String fName = null; - private Hashtable fAttributes = null; - private Vector fTags = null; - private int fLine = -1; - protected boolean fInline = false; - - /** - * A hashtable enumerator class for empty hash tables, specializes the - * general Enumerator - */ - private static Enumeration fEmptyEnumeration = new Enumeration() { - public boolean hasMoreElements() { - return false; - } - - public Object nextElement() { - throw new NoSuchElementException("Hashtable Enumerator"); - } - }; - - /** - * - */ - public TagImpl() { - super(); - } - - /* - * (non-Javadoc) - * - * @see org.eclipse.equinox.internal.util.xml.Tag#getAttribute(java.lang.String) - */ - public String getAttribute(String aAttrName) { - return (String) ((fAttributes != null) ? fAttributes.get(aAttrName) : null); - } - - /* - * (non-Javadoc) - * - * @see org.eclipse.equinox.internal.util.xml.Tag#getAttributes() - */ - public Enumeration getAttributeNames() { - return (fAttributes != null) ? fAttributes.keys() : fEmptyEnumeration; - } - - /* - * (non-Javadoc) - * - * @see org.eclipse.equinox.internal.util.xml.Tag#getAttributeValues() - */ - public Enumeration getAttributeValues() { - return (fAttributes != null) ? fAttributes.elements() : fEmptyEnumeration; - } - - /* - * (non-Javadoc) - * - * @see org.eclipse.equinox.internal.util.xml.Tag#getName() - */ - public String getName() { - return fName; - } - - /** - * @see org.eclipse.equinox.internal.util.xml.Tag#getContent() note: The content that - * is to be returned will be trimmed first - */ - public String getContent() { - if (fContentString != null) { - return fContentString; - } else if (fContent != null) { - fContentString = fContent.trim(); - fContent = null; - return fContentString; - } - return ""; - } - - /* - * (non-Javadoc) - * - * @see org.eclipse.equinox.internal.util.xml.Tag#getLine() - */ - public int getLine() { - return fLine; - } - - /* - * (non-Javadoc) - * - * @see org.eclipse.equinox.internal.util.xml.Tag#size() - */ - public int size() { - return (fTags != null) ? fTags.size() : 0; - } - - /* - * (non-Javadoc) - * - * @see org.eclipse.equinox.internal.util.xml.Tag#getTagAt(int) - */ - public Tag getTagAt(int aPosition) { - return (Tag) fTags.elementAt(aPosition); - } - - protected void setName(String aName) { - fName = aName; - } - - protected void addAttribute(String aAttrName, String aAttrValue) { - if (fAttributes == null) { - fAttributes = new Hashtable(1); - } - fAttributes.put(aAttrName, aAttrValue); - } - - protected void addTag(Tag aTag) { - if (fTags == null) { - fTags = new Vector(2, 3); - } - fTags.addElement(aTag); - } - - protected void appendContent(CharBuffer toAppend) { - if (fContent == null) { - fContent = new CharBuffer(toAppend.length()); - } - fContent.append(toAppend.getValue()); - } - - protected void appendContent(String toAppend) { - if (fContent == null) { - fContent = new CharBuffer(toAppend.length()); - } - fContent.append(toAppend); - } - - protected CharBuffer getContentBuffer() { - if (fContent == null) { - fContent = new CharBuffer(5); - } - return fContent; - } - - protected void setLine(int aLine) { - fLine = aLine; - } - - /* - * (non-Javadoc) - * - * @see org.eclipse.equinox.internal.util.xml.Tag#getContent(int, java.lang.String) - */ - public String getContent(int aPos, String aName) { - Tag child = getTagAt(aPos); - if (child == null) - throw new NullPointerException("There is no such a tag. [Parent tag name] = [" + aName + "], [child tag index] = " + aPos + ", [child tag name] = [" + aName + ']'); - - if (child.getName().equals(aName)) - return child.getContent(); - - throw new IllegalArgumentException("There is no such a tag. [Parent tag name] = [" + aName + "], [child tag index] = " + aPos + ", [child tag name] = [" + aName + ']'); - } - - /* begin serialization see FR [ 13325 ] XML: Make Tag externalizable */ - - /** - * @see org.eclipse.equinox.internal.util.io.Externalizable#readObject(java.io.InputStream) - */ - public void readObject(InputStream is) throws Exception { - if (!(is instanceof ObjectInput)) { - is = new ObjectInputStream(is); - } - readExternal((ObjectInput) is); - } - - /** - * @see org.eclipse.equinox.internal.util.io.Externalizable#writeObject(java.io.OutputStream) - */ - public void writeObject(OutputStream os) throws Exception { - if (!(os instanceof ObjectOutput)) { - os = new ObjectOutputStream(os); - } - writeExternal((ObjectOutput) os); - os.flush(); - } - - /** - * @param input - * @throws IOException - * @throws ClassNotFoundException - */ - public void readExternal(ObjectInput input) throws IOException, ClassNotFoundException { - fName = input.readUTF(); - /* read content */ - boolean hasContent = input.readBoolean(); - if (hasContent) { - fContentString = input.readUTF(); - } - int size; - /* read attributes */ - size = input.readInt(); - if (size > 0) { - fAttributes = new Hashtable(size, 1); - for (int i = 0; i < size; i++) { - String key = input.readUTF(); - String val = input.readUTF(); - fAttributes.put(key, val); - } - } - /* read elements */ - size = input.readInt(); - if (size > 0) { - fTags = new Vector(size); - for (int i = 0; i < size; i++) { - TagImpl tag = new TagImpl(); - tag.readExternal(input); - fTags.addElement(tag); - } - } - } - - /** - * @param output - * @throws IOException - */ - public void writeExternal(ObjectOutput output) throws IOException { - output.writeUTF(fName); - /* write content */ - String content = null; - if (fContentString != null) { - content = fContentString; - } else if (fContent != null) { - content = fContent.trim(); - } - if (content != null) { - output.writeBoolean(true); - output.writeUTF(content); - } else { - output.writeBoolean(false); - } - /* write attributes */ - if (fAttributes != null) { - output.writeInt(fAttributes.size()); - for (Enumeration e = fAttributes.keys(); e.hasMoreElements();) { - String key = (String) e.nextElement(); - String val = (String) fAttributes.get(key); - output.writeUTF(key); - output.writeUTF(val); - } - } else { - output.writeInt(0); - } - /* write elements */ - if (fTags != null) { - output.writeInt(fTags.size()); - for (int i = 0, size = fTags.size(); i < size; i++) { - TagImpl current = (TagImpl) fTags.elementAt(i); - current.writeExternal(output); - } - } else { - output.writeInt(0); - } - output.flush(); - } - - /* begin simple, utility method for debugging */ - - /** - * Writes the tag as formatted XML into the given writer. - * - * @param out - * the output writer, where tag is serialized to XML - * @param level - * the initial level. If set to negative value, the indent - * /formatting/ of the XML is disable, and it is written on a - * single line. Otherwise, the level is used to calculate the - * offset from the left margin. - * @throws IOException - * on I/O error - */ - public void writeXml(Writer out, int level) throws IOException { - boolean indent = level >= 0; - for (int i = 0; indent && i < level; i++) - out.write(' '); /* indent */ - out.write('<'); - out.write(fName); - if (fAttributes != null) { - for (Enumeration e = fAttributes.keys(); e.hasMoreElements();) { - out.write(' '); - String key = (String) e.nextElement(); - String val = (String) fAttributes.get(key); - out.write(key); - out.write("=\""); - out.write(val); - out.write('"'); - } - } - /* don't use getContent() - this will demolish the buffer */ - String content = null; - if (fContentString != null) { - content = fContentString; - } else if (fContent != null) { - content = fContent.trim(); - } - boolean isShort = content == null && fTags == null; - if (isShort) { - /* close immediately */ - out.write("/>"); - if (indent) - out.write('\n'); - } else { - out.write('>'); - if (indent) - out.write('\n'); - /* write elements */ - for (int i = 0; fTags != null && i < fTags.size(); i++) { - TagImpl child = (TagImpl) fTags.elementAt(i); - child.writeXml(out, level < 0 ? -1 : (level + 1)); - } - /* write contents */ - if (content != null) { - for (int i = 0; indent && i < level + 1; i++) - out.write(' '); /* indent */ - out.write(content); - if (indent) - out.write('\n'); - } - /* write closing tag */ - for (int i = 0; indent && i < level; i++) - out.write(' '); /* indent */ - out.write("'); - if (indent) - out.write('\n'); - } - } - - /** - * @see java.lang.Object#toString() - */ - public String toString() { - StringWriter out = new StringWriter(); - try { - writeXml(out, 0); - } catch (IOException e) { - /* this will never happen */ - } - return out.toString(); - } - -} diff --git a/bundles/org.eclipse.equinox.ds/src/org/eclipse/equinox/internal/util/xml/impl/XMLParserImpl.java b/bundles/org.eclipse.equinox.ds/src/org/eclipse/equinox/internal/util/xml/impl/XMLParserImpl.java deleted file mode 100644 index 7384a783f..000000000 --- a/bundles/org.eclipse.equinox.ds/src/org/eclipse/equinox/internal/util/xml/impl/XMLParserImpl.java +++ /dev/null @@ -1,1219 +0,0 @@ -/******************************************************************************* - * Copyright (c) 1997, 2010 by ProSyst Software GmbH - * http://www.prosyst.com - * 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: - * ProSyst Software GmbH - initial API and implementation - *******************************************************************************/ -package org.eclipse.equinox.internal.util.xml.impl; - -import java.io.*; -import org.eclipse.equinox.internal.ds.Activator; -import org.eclipse.equinox.internal.util.string.CharBuffer; -import org.eclipse.equinox.internal.util.xml.ExTagListener; - -/** - *

      - * Class used for reading of xml files, creating tree structure of 'TagImpl' for - * each xml tag. When reader reaches a closed tag it notifies a given - * 'TagListener' and sends the last tag to it. If closing tag does not - * correspond with the last open IllegalArgumentException is thrown. There is a - * debug property 'xml.debug' used to dump an Exceptions occurred while - * operation is running. - *

      - * - *

      - * The parser, in general, is a simple XML parser that implements - * "Recursive descent" parsing method. - * - * Known limitations:
      - * - *

      - *  Currently this XMLParser does not support the following special tags:
      - *  1. <?TAG_NAME ..... ?>   or also "Processing Instructions"
      - *  2. <!DOCTYPE .... >
      - *  3. <!ELEMENT .... >
      - *  4. <!ATTLIST .... >
      - *  5. <!ENTITY .... >
      - * 
      - * - *
      - * The parser skips these tags (it searches for '>' symbol and closes the - * 'special' tag).
      - * - * @author Ivan Dimitrov - * @author Pavlin Dobrev - * @version 1.0 - */ - -public class XMLParserImpl { - - private static final String DEBUG = "xml.debug"; - private static final String INTERN_ATTRIBUTES = "xml.intern.attributes"; - - private static final String CDATA = "CDATA"; - private static final String XML = "xml"; - private static final String VERSION = "version"; - private static final String ENCODING = "encoding"; - private static final String STANDALONE = "standalone"; - - private static final String ERR_EOS = "End-of-stream reached before the end of XML."; - private static final String ERR_ENTITY_EXPECTED = "Entity reference or Character reference expected."; - private static final String ERR_EQUAL_EXPECTED = "'=' expected."; - private static final String ERR_QUOT_EXPECTED = "''' or '\"' expected."; - private static final String ERR_GT_EXPECTED = "'>' expected."; - private static final String ERR_LT_EXPECTED = "'<' expected."; - private static final String ERR_CLOSE_TAG1_EXPECTED = "'/' or tag name expected."; - private static final String ERR_CLOSE_TAG2_EXPECTED = "'>', '/>' or more attributes expected."; - private static final String ERR_CLOSE_TAG3_EXPECTED = "'?>' expected."; - private static final String ERR_CONTENT_EXPECTED = "Content data, new tag or closing tag expected."; - private static final String ERR_QUESTIONMARK_EXPECTED = "'?' expected."; - private static final String ERR_ILLEGAL_CHARACTER = "Illegal character."; - private static final String ERR_TAGNAME_EXPECTED = "Tag name expected."; - private static final String ERR_TAGNAME2_EXPECTED = "Tag name, '?' or '!' expected."; - private static final String ERR_DASH_EXPECTED = "'-' expected."; - private static final String ERR_COMMENT_CLOSE_EXPECTED = "'-->' expected."; - private static final String ERR_CDATA_EXPECTED = "'CDATA' expected."; - private static final String ERR_OPENSQBRACKET_EXPECTED = "'[' expected."; - private static final String ERR_CLOSE_CDATA_EXPECTED = "']]>' expected."; - private static final String ERR_SEMICOLON_EXPECTED = "';' expected."; - private static final String ERR_XMLPROLOG_EXPECTED = "XML prolog '' expected."; - private static final String ERR_STANDALONE_EXPECTED = "'standalone' attribute expected."; - - protected static final boolean fDebug = Activator.getBoolean(DEBUG); - protected static final boolean fInternAttributes = Activator.getBoolean(INTERN_ATTRIBUTES); - - private String fDefaultEncoding = "UTF-8"; - - // private CharBuffer c; - private CharBuffer temp = new CharBuffer(); - private CharBuffer temp2 = null; - - protected Reader fReader = null; - protected InputStream fStream = null; - - protected char currentChar = 0; - protected ExTagListener fExTagListener; - - protected int fLine = 1; - protected int fPos = 0; - - protected int fLevel = -1; - protected int fCurrentLevel = 1; - - private String fVersion = "1.0"; - private String fEncoding = "UTF-8"; - private String fStandalone = "yes"; - - /** - * An empty default constructor - * - */ - public XMLParserImpl() { - // - } - - /** - * Constructs a new XMLReader.
      - *
      - * Note: The XMLReader does not close the passed Reader or InputStream - * - * @param aInputStream - * an InputStream to read the XML file from - * @param aListener - * ExTagListener that will be notified on tag-open or tag-close - * events - * @throws IOException - */ - public XMLParserImpl(InputStream aInputStream, ExTagListener aListener) { - fStream = aInputStream; - fExTagListener = aListener; - } - - /** - * Constructs a new XMLReader.
      - *
      - * Note: The XMLReader does not close the passed Reader or InputStream - * - * @param aReader - * a Reader to read the XML file from - * @param aListener - * ExTagListener that will be notified on tag-open or tag-close - * events - */ - public XMLParserImpl(Reader aReader, ExTagListener aListener) { - fReader = aReader; - fExTagListener = aListener; - } - - /** - * Sets the level of tags bellow which the listener will be notified for. - * For internal use only. - * - * @param aLevel - */ - public void setLevel(int aLevel) { - fLevel = aLevel; - } - - /** - * Sets the parser's encoding. If there is a current encoding associated - * with the parser the method returns immediately - * - * @param aEncoding - * new encoding to be set - * @throws UnsupportedEncodingException - * if the encoding is not supported. - */ - protected void setEncoding(String aEncoding) { - if (fReader == null) { - try { - fReader = new InputStreamReader(fStream, aEncoding); - } catch (Exception e) { - if (fDebug) { - System.err.println("[XMLParserImpl] Failed setting the encoding \"" + aEncoding + "\", continue parsing with the default one."); - } - fReader = new InputStreamReader(fStream); - } - } - } - - /* A helper function to reuse a temp CharBuffers without recreating it */ - protected CharBuffer getCharBuffer() { - if (temp.length() <= 0) { - return temp; - } else if (temp2 == null) { - temp2 = new CharBuffer(0); - return temp2; - } else if (temp2.length() <= 0) { - return temp2; - } - return new CharBuffer(0); - } - - protected char prev_char = 0; - private char[] fBuffer = new char[4096]; - private int fBufferLen = 0; - private int fBufferPos = 0; - - /** - * Reads the next char from the input stream and sets it to private field - * currentChar - * - * @return true if the next char is successfully read of false if - * End-Of-Stream is reached - * @throws IOException - * if some error occurs during reading the character or if the - * caller tries to read beyond the End-Of-Stream. - */ - protected boolean getNextChar() throws IOException { - // // Reading characters without buffering - // int ichar = 0; - // int count = 0; - // while (ichar == 0 && count < 100) { - // ichar = fReader.read(); - // count++; - // } - // - // if (ichar == 0) - // throw new IOException("Failed to read from the input file."); - // - // if (ichar < 0 && prev_char == 0) - // throw new IOException(ERR_EOS); - // - // char ch = (char) ichar; - - char ch; - - if (fReader == null) { // If there is no associated reader, - int ach = fStream.read(); // then reads from the InputStream until - if (ach < 0) { // the rigth encoding is recognized - ach = 0; - } - - ch = (char) ach; - if (ch == 0 && prev_char == 0) { - throw new IOException(ERR_EOS); - } - } else { - // Buffered reading - if (fBufferLen < 0) { - throw new IOException(ERR_EOS); - } - - if ((fBufferPos) >= fBufferLen) { - // Refetch the buffer - fBufferLen = 0; - fBufferPos = 0; - int count = 0; - while (fBufferLen == 0 && count < 100) { - fBufferLen = fReader.read(fBuffer); - count++; - } - - ch = (fBufferLen > 0) ? fBuffer[fBufferPos++] : 0; - - if (fBufferLen == 0) { - fBufferLen = -1; - } - } else { - ch = fBuffer[fBufferPos++]; - } - } - - prev_char = currentChar; - currentChar = ch; - fPos++; - - switch (ch) { - case '\n' : - if (prev_char != '\r') { - fLine++; - } - fPos = 0; - break; - case '\r' : - fPos = 0; - fLine++; - break; - } - return (currentChar != 0); - } - - /** - * Parses the attribute value and if it's successful then adds it to the - * CharBuffer. If there are EntityReferences of CharReferences in the - * attribute value, they will be turned to their equivalent symbols.
      - * attr_value ::= (acceptable_char | EntityRef | CharRef)* - quot_symbol - * - * @see parse_attr - * @see parse_CharRef - * @see parse_EntityRef - */ - protected void parse_attr_value(CharBuffer sb, char quot) throws IOException { - while (currentChar != quot && currentChar != '<') { - if (accept_char('&')) { - if (!parse_CharRef(sb)) { - if (!parse_EntityRef(sb)) { - err(fPos - 1, ERR_ENTITY_EXPECTED); - } - } - } else { - sb.append(currentChar); - - if (!getNextChar()) { - break; - } - } - } - } - - /** - * Parses an attribute with the given simplified grammar:
      - * - *
      -	 * attribute ::= S* + attr_name + S* + '=' + S* + ('\'' + (attr_value - '\'') + '\'')) | ('"' + (attr_value - '"') + '"'))
      -	 * attr_value ::= (acceptable_char | EntityRef | CharRef)*
      -	 * attr_name ::= identifier
      -	 * 
      - * - * @param aParent - * the parent tag where the correctly parsed attribute will be - * added - * @throws IOException - * @see parse_identifier - * @see parse_attr_value - */ - protected boolean parse_attr(TagImpl aParent) throws IOException { - clearWhiteSpaces(); - - String attrName = parse_identifier(); - - if (attrName != null) { - clearWhiteSpaces(); - - if (!accept_char('=')) { - err(ERR_EQUAL_EXPECTED); - } - - clearWhiteSpaces(); - - char quot = 0; - if (accept_char('"')) { - quot = '"'; - } else if (accept_char('\'')) { - quot = '\''; - } else { - err(ERR_QUOT_EXPECTED); - } - - CharBuffer sb = getCharBuffer(); - parse_attr_value(sb, quot); - - if (!accept_char(quot)) { - err("'" + quot + "' expected."); - } - - String attrValue = sb.toString(); - - if (fInternAttributes) { - attrValue = attrValue.intern(); - } - - aParent.addAttribute(attrName, attrValue); - sb.setLength(0); - return true; - } - return false; - } - - /** - * Parses a tag attribute list with the following simplified grammar: - * - *
      -	 * attr_list ::= attribute*
      -	 * @param aParent the parent tag that the parsed attributes will be added to
      -	 * @return true if at least one attribute is parsed correctly and false otherwise
      -	 * @throws IOException
      -	 * @see parse_attr
      -	 * 
      -	 */
      -	protected boolean parse_attr_list(TagImpl aParent) throws IOException {
      -		boolean result = false;
      -		while (parse_attr(aParent)) {
      -			result = true;
      -		}
      -		return result;
      -	}
      -
      -	private static final char bA = 'A' - 1;
      -	private static final char aZ = 'Z' + 1;
      -	private static final char ba = 'a' - 1;
      -	private static final char az = 'z' + 1;
      -	private static final char b0 = '0' - 1;
      -	private static final char a9 = '9' + 1;
      -
      -	/**
      -	 * This method returns true is the passed character may be used as starting
      -	 * character for tag name and attribute name
      -	 * 
      -	 * @param ch
      -	 *            the tested character
      -	 * @return true if the character could be used as starting character for a
      -	 *         tag name and an attribute name and false otherwise
      -	 */
      -	protected final boolean isNameStartChar(char ch) {
      -		return (ch > bA && ch < aZ) || (ch > ba && ch < az) || (ch == ':') || (ch == '_') || (ch > 0xBF && ch < 0xD7) || (ch > 0xD7 && ch < 0xF7) || (ch > 0xF7 && ch < 0x300) || (ch > 0x36F && ch < 0x37E) || (ch > 0x37E && ch < 0x2000) || (ch > 0x200B && ch < 0x200E) || (ch > 0x206F && ch < 0x2190) || (ch > 0x2BFF && ch < 0x2FF0) || (ch > 0x3000 && ch < 0xD800) || (ch > 0xF900 && ch < 0xFDD0) || (ch > 0xFDEF && ch < 0xFFFE) || (ch > 0x0FFFF && ch < 0xF0000);
      -	}
      -
      -	/**
      -	 * This method returns true if the passed characted may be used as part of a
      -	 * tag name or an attribute name
      -	 * 
      -	 * @param ch
      -	 *            the tested character
      -	 * @return true is the characted could be used as part of a tag name or an
      -	 *         attribute name and false otherwise
      -	 */
      -	protected final boolean isNameChar(char ch) {
      -		return (ch == '-') || (ch == '.') || (ch == 0xB7) || (ch > b0 && ch < a9) || isNameStartChar(ch) || (ch > 0x02FF && ch < 0x0370) || (ch > 0x203E && ch < 0x2041);
      -	}
      -
      -	/**
      -	 * Parses an identifier.
      -	 * 
      -	 * @return an identifier if it is parsed successfully and null otherwise
      -	 * @throws IOException
      -	 */
      -	protected String parse_identifier() throws IOException {
      -		if (isNameStartChar(currentChar)) {
      -			CharBuffer sb = getCharBuffer();
      -
      -			while (isNameChar(currentChar)) {
      -				sb.append(currentChar);
      -
      -				if (!getNextChar()) {
      -					break;
      -				}
      -			}
      -			String result = sb.toString().intern();
      -			sb.setLength(0);
      -			return result;
      -		}
      -		return null;
      -	}
      -
      -	/**
      -	 * Parses a tag name and if it is successfully parsed the method sets it as
      -	 * a name of the parent tag
      -	 * 
      -	 * @param aParent
      -	 *            parent tag
      -	 * @return true if the name is parsed successfully and false otherwise
      -	 * @throws IOException
      -	 * @see parse_identifier
      -	 */
      -	protected boolean parse_tag_name(TagImpl aParent) throws IOException {
      -		String name = parse_identifier();
      -		if (name != null) {
      -			aParent.setName(name);
      -		}
      -		return name != null;
      -	}
      -
      -	/**
      -	 * Helper function that notify listeners depending on certain conditions
      -	 * such as if the tag event is on-close or on-open
      -	 * 
      -	 * @param aTag
      -	 *            The tag that the notification event is valid for.
      -	 * @param isStart
      -	 *            true if the event is on-open and false if it is on-close
      -	 */
      -	protected void notifyListeners(TagImpl aTag, boolean isStart) {
      -		try {
      -			if (isStart) {
      -				fExTagListener.startTag(aTag);
      -			} else {
      -				fExTagListener.endTag(aTag);
      -			}
      -		} catch (RuntimeException re) {
      -			if (fDebug) {
      -				System.err.println("An outside exception occurred while processing a tag on line " + aTag.getLine() + ", the tag name is: " + aTag.getName());
      -				re.printStackTrace(System.err);
      -			}
      -			throw re;
      -		}
      -	}
      -
      -	/**
      -	 * Parses a normal tag. There are two cases - (1) the tag has separate open
      -	 * and close tag elements and (2) the tag is simple suchas <tag_name ...
      -	 * />
      -	 * 
      -	 * @param aParent
      -	 *            The parent tag that this tag will be added to if the parsing
      -	 *            is successful
      -	 * @return true on success and false otherwise
      -	 * @throws IOException
      -	 * @see clearWhiteSpaces
      -	 * @see parse_tag_name
      -	 * @see parse_attr_list
      -	 * @see notifyListeners
      -	 * @see accept_char
      -	 * @see accept_seq
      -	 * @see parse_PCDATA
      -	 */
      -	protected boolean parse_tag_normal(TagImpl aParent) throws IOException {
      -		// Looking for a tag_name (identifier)
      -		if (isNameStartChar(currentChar)) {
      -			TagImpl tag = new TagImpl();
      -			tag.setLine(fLine);
      -
      -			parse_tag_name(tag);
      -			parse_attr_list(tag);
      -
      -			clearWhiteSpaces();
      -
      -			if (accept_char('/')) {
      -				if (!accept_char('>')) {
      -					err(ERR_GT_EXPECTED);
      -				}
      -				aParent.addTag(tag);
      -
      -				if ((fLevel <= 0 || fLevel == fCurrentLevel)) {
      -					notifyListeners(tag, true);
      -					notifyListeners(tag, false);
      -				}
      -
      -				return true;
      -			} else if (accept_char('>')) {
      -
      -				notifyListeners(tag, true);
      -
      -				while (true) {
      -					clearWhiteSpaces();
      -					int pos = fPos;
      -					if (currentChar == '<') { // Normal tag, Special tag or
      -						// closing tag
      -						if (!parse_tag(tag)) { // It may be a special tag.
      -							if (!accept_char('/')) {
      -								err(pos + 1, ERR_CLOSE_TAG1_EXPECTED);
      -							}
      -
      -							// trying to accept: tag_name + S* + '>'
      -							pos = fPos;
      -							if (!accept_seq(tag.getName())) {
      -								err(pos, '\'' + tag.getName() + "' string expected.");
      -							}
      -
      -							clearWhiteSpaces();
      -							if (!accept_char('>')) {
      -								err(ERR_GT_EXPECTED);
      -							}
      -
      -							aParent.addTag(tag);
      -
      -							if (fLevel <= 0 || fLevel == fCurrentLevel) {
      -								notifyListeners(tag, false);
      -							}
      -
      -							return true;
      -						}
      -					} else {
      -						if (!parse_PCDATA(tag)) {
      -							break;
      -						}
      -					}
      -				}
      -				err(ERR_CONTENT_EXPECTED);
      -			} else {
      -				err(ERR_CLOSE_TAG2_EXPECTED);
      -			}
      -		}
      -		return false;
      -	}
      -
      -	/**
      -	 * Returns true if the specified attribute is already parsed and false
      -	 * otherwise
      -	 * 
      -	 * @param aTag
      -	 *            the which attribute will be examined.
      -	 * @param attrName
      -	 *            an attribute name
      -	 * @return true if the specified attribute is already parsed and false
      -	 *         otherwise
      -	 */
      -	protected boolean accept_attr(TagImpl aTag, String attrName) {
      -		return aTag.getAttribute(attrName) != null;
      -	}
      -
      -	/**
      -	 * Parses the XML prolog tag, i.e.
      - * <?xml version="..." encoding="..." standalone="..." ?>
      - * - * @param parent - * the parent tag (in this case this is the root "fake" tag, - * which the listeners will never be informed for...) - * @throws IOException - * if an exception occurs during read operations from the Reader - * or the InputStream - */ - protected boolean parse_xml_prolog(TagImpl parent) throws IOException { - if (accept_char('?')) { - TagImpl tag = new TagImpl(); - - if (parse_tag_name(tag)) { - if (tag.getName().equalsIgnoreCase(XML)) { - clearWhiteSpaces(); - - int pos = fPos; - - if (parse_attr(tag)) { - String s = tag.getAttribute(VERSION); - - if (s == null) { - err(pos, ERR_VERSION_EXPECTED); - } - - fVersion = s; - - clearWhiteSpaces(); - pos = fPos; - if (parse_attr(tag)) { - clearWhiteSpaces(); - - if (accept_attr(tag, ENCODING)) { - fEncoding = tag.getAttribute(ENCODING); - - pos = fPos; - if (parse_attr(tag)) { - clearWhiteSpaces(); - if (accept_attr(tag, STANDALONE)) { - fStandalone = tag.getAttribute(STANDALONE); - } else { - err(pos, ERR_STANDALONE_EXPECTED); - } - } - } else if (accept_attr(tag, STANDALONE)) { - fStandalone = tag.getAttribute(STANDALONE); - } else { - err(pos, ERR_ENCODING_STANDALONE_EXPECTED); - } - } - - clearWhiteSpaces(); - pos = fPos; - if (!accept_seq("?>")) { - err(pos, ERR_CLOSE_TAG3_EXPECTED); - } - } else { - err(pos, ERR_VERSION_EXPECTED); - } - clearWhiteSpaces(); - return true; - } - - char prevCh = 0; - - while (true) { - if (currentChar == '>') { - if (prevCh == '?') { - accept_char('>'); - clearWhiteSpaces(); - - return true; - } - err(ERR_QUESTIONMARK_EXPECTED); - } else if (currentChar == '<') { - err(ERR_ILLEGAL_CHARACTER + " ('<')"); - } - prevCh = currentChar; - getNextChar(); - } - } - } - return false; - } - - /** - * Parses special tags, such that begins with:
      - * - *
      
      -	 * <!--         comments
      -	 * <!tag_name   Parsing instructions
      -	 * <![          CDATA element
      -	 * <?           DOCTYPE, etc.
      -	 * 
      - * - * @param aParent - * The parent tag that this tag will be added to if the parsing - * is successful - * @return true on success and false otherwise - * @throws IOException - * @see accept_char - * @see clearWhiteSpaces - * @see parse_tag_CDATA - * @see parse_tag_name - * @see parse_comment - */ - protected boolean parse_tag_special(TagImpl aParent) throws IOException { - if (accept_char('!')) { - - TagImpl tag = new TagImpl(); - - if (parse_tag_name(tag)) { - clearWhiteSpaces(); - - while (true) { - if (accept_char('>')) { - clearWhiteSpaces(); - return true; - } - getNextChar(); - } - } else if (parse_tag_CDATA(aParent)) { // parse CDATA tag - return true; - } else if (parse_comment(tag)) { - return true; - } - } else if (accept_char('?')) { - TagImpl tag = new TagImpl(); - - int pos = fPos; - if (parse_tag_name(tag)) { - if (tag.getName().equals(XML)) { - err(pos - 2, ERR_XMLPROLOG_EXPECTED); - } - - char prevCh = 0; - while (true) { - if (currentChar == '>') { - if (prevCh == '?') { - accept_char('>'); - clearWhiteSpaces(); - return true; - } - } - prevCh = currentChar; - getNextChar(); - } - - } else { - err(pos, ERR_TAGNAME_EXPECTED); - } - } - return false; - } - - /** - * Parses a comment. The grammar is:
      - * Comment ::= '<!--' ((Char - '-') | ('-' (Char - '-')))* '-->'
      - * Note that the grammar does not allow a comment ending in --->. The - * following example is not well-formed.
      - * - * <!-- B+, B, or B---> - * - * @param aParent - * The parent tag - * @return true on success and false otherwise - * @throws IOException - * @see accept_char - */ - protected boolean parse_comment(TagImpl aParent) throws IOException { - if (accept_char('-')) { - if (!accept_char('-')) { - err(ERR_DASH_EXPECTED); - } - - while (true) { - if (accept_char('-')) { - if (accept_char('-')) { - if (accept_char('>')) { - break; - } - err(ERR_GT_EXPECTED); - } - } - - if (!getNextChar()) { - err(ERR_COMMENT_CLOSE_EXPECTED); - } - } - return true; - } - return false; - } - - /** - * Parses either normal or special tag - * - * @param aParent - * The parent tag that the successfully parsed tag will (if it is - * normal tag or CDATA element) be added - * @return true on success and false otherwise - * @throws IOException - * @see accept_cahr - * @see parse_tag_normal - * @see parse_tag_special - * @see clearWhiteSpaces - */ - protected boolean parse_tag(TagImpl aParent) throws IOException { - clearWhiteSpaces(); - try { - fCurrentLevel++; - - if (accept_char('<')) { - if (parse_tag_normal(aParent) || parse_tag_special(aParent)) { - return true; - } - } - return false; - } finally { - fCurrentLevel--; - } - } - - /** - * Parses the content of the tag (including sub-tags and sub-elements) - * - * @param aParent - * The parent tag that the content and tags will be added to - * @return true on success and false otherwise - * @throws IOException - * @see parse_PCDATA - * @see parse_tag - */ - protected boolean parse_content(TagImpl aParent) throws IOException { - return (parse_PCDATA(aParent) || parse_tag(aParent)); - } - - /** - * Parses a CDATA tag (or CDATA content element). - * - * @param aParent - * The parent tag that the content will be added to - * @return true on success and false otherwise - * @throws IOException - */ - protected boolean parse_tag_CDATA(TagImpl aParent) throws IOException { - if (accept_char('[')) { - int pos = fPos; - - if (!accept_seq(CDATA)) { - err(pos, ERR_CDATA_EXPECTED); - } - - if (!accept_char('[')) { - err(ERR_OPENSQBRACKET_EXPECTED); - } - - do { - if (currentChar != '>') { - aParent.getContentBuffer().append(currentChar); - } else { - CharBuffer sb = aParent.getContentBuffer(); - int l = sb.length(); - - if (l >= 2) { - if (sb.charAt(l - 1) == ']' && sb.charAt(l - 2) == ']') { - sb.setLength(l - 2); // Truncates the extra "]]" - // symbols appended at the - // end - - getNextChar(); - return true; - } - } - sb.append(currentChar); - } - } while (getNextChar()); - - err(fPos - 1, ERR_CLOSE_CDATA_EXPECTED); - } - return false; - } - - /** - * Parses PCDATA content (Parseable Content DATA). The EntityRefs and - * CharRefs that are parsed will be turned to its symbol equivalent. - * - * @param aParent - * The parent tag that the PCDATA will be added to - * @return true on success and false otherwise - * @throws IOException - * @see accept_char - * @see parse_CharRef - * @see parse_EntityRef - */ - protected boolean parse_PCDATA(TagImpl aParent) throws IOException { - boolean result = false; - while (currentChar != '<') { - result = true; - - CharBuffer sbContent = aParent.getContentBuffer(); - - if (accept_char('&')) { - int pos = fPos; - if (!parse_CharRef(sbContent)) { - if (!parse_EntityRef(sbContent)) { - err(pos - 1, ERR_ENTITY_EXPECTED); - } - } - } else { - sbContent.append(currentChar); - - if (!getNextChar()) { - break; - } - } - } - return result; - } - - /** - * Accepts one character from the input stream and if it's successful moves - * one character forward. - * - * @param ch - * The character that should be accepted - * @return true on success and false otherwise - * @throws IOException - */ - protected boolean accept_char(char ch) throws IOException { - if (currentChar == ch) { - getNextChar(); - return true; - } - return false; - } - - /** - * Accepts a sequence of characters given by seq parameter. If the sequence - * is accepted successfully then the currentChar field will contain the - * character immediately after the accepted sequence. - * - * @param seq - * The character sequence that should be accepted - * @return true on success and false otherwise - * @throws IOException - */ - protected boolean accept_seq(String seq) throws IOException { - for (int i = 0; i < seq.length(); i++) { - if (!accept_char(seq.charAt(i))) { - return false; - } - } - return true; - } - - protected static final String[] entities = {"amp", "apos", "lt", "gt", "quot"}; - protected static final char[] ent_chars = {'&', '\'', '<', '>', '"'}; - - /** - * - * EntityRef ::= '&' + EntityValue + ';'
      - * EntityValue ::= 'amp' | 'quot' | 'apos' | 'gt' | 'lt' | identifier - *
      - * - * @param sb - * The string buffer that the recognized entity will be appended - * to - * @throws IOException - * @return true on success and false otherwise - * @see parse_identifier - * @see accept_char - */ - protected boolean parse_EntityRef(CharBuffer sb) throws IOException { - String ent = parse_identifier(); - - if (!accept_char(';')) { - err(ERR_SEMICOLON_EXPECTED); - } - - int length = entities.length; - for (int i = 0; i < length; i++) { - if (entities[i] == ent) { // 'ent' is interned by - // parse_identifier() function - sb.append(ent_chars[i]); - return true; - } - } - - sb.append('&'); - - if (ent != null && ent.length() > 0) { - sb.append(ent); - } - - sb.append(';'); - - return true; - } - - /** - * Parses a CharReference and if it is successful then appends it to the - * passed CharBuffer - * - * @param sb - * CharBuffer that the parsed CharReference will be added to - * @return true on success and false otherwise - * @throws IOException - */ - protected boolean parse_CharRef(CharBuffer sb) throws IOException { - if (accept_char('#')) { - // TODO - Postponed... - while (currentChar != ';') { - getNextChar(); - } - - if (!accept_char(';')) { - err(fPos - 1, ERR_SEMICOLON_EXPECTED); - } - - return true; - } - return false; - } - - /** - * Clears the white spaces starting from the current position - * - * @throws IOException - */ - protected void clearWhiteSpaces() throws IOException { - while (Character.isWhitespace(currentChar)) { - if (!getNextChar()) { - break; - } - } - } - - /** - * Throws an IOException with a given message. The current line number and - * line position are appended to the error message - * - * @param message - * The message of the exception - * @throws IOException - */ - protected void err(String message) throws IOException { - err(fPos, message); - } - - /** - * Throws an IOException with the given message for the given line position. - * The current line number and position (pos) are appended to the exception - * message - * - * @param pos - * The line position that the error will be reported for - * @param message - * @throws IOException - */ - protected void err(int pos, String message) throws IOException { - throw new IOException("[Line: " + fLine + ", Pos: " + pos + "] " + message); - } - - /** - * Initiates parsing of the XML file given through aInputStream or aReader - * in the given constructor when creating XMLReader object. - * - * @throws IOException - * if an error occurs during reading the XML file or if a - * parsing error eccurs. - */ - public void parseXML() throws IOException { - TagImpl rootTag = new TagImpl(); - - try { - getNextChar(); - clearWhiteSpaces(); - - boolean start = false; - - while (accept_char('<')) { - start = true; - int pos = fPos; - - if (fPos == 2 && fLine == 1) { - if (parse_xml_prolog(rootTag)) { - // System.out.println("XML Prolog found."); - // System.out.println("XML Version: " + fVersion + ", - // encoding: " + fEncoding); - setEncoding(fEncoding); - clearWhiteSpaces(); - continue; - } - } else { - setEncoding(fDefaultEncoding); - } - - if (!parse_tag_special(rootTag)) { - if (parse_tag_normal(rootTag)) { - // TODO da se proveri dali e dostignat kraja na file-a, - // ako ne e - togava ot tuk natatuk moje da ima samo - // komentari. - return; - } - err(pos, ERR_TAGNAME2_EXPECTED); - } - - clearWhiteSpaces(); - } - - if (!start) { - err(ERR_LT_EXPECTED); - } - } catch (IOException ioe) { - if (fDebug) { - ioe.printStackTrace(System.err); - } - - throw ioe; - } - } - - /** - * Parses a XML file given through aInputStream and during the parsing - * notifies aListener for close-tag and open-tag events
      - *
      - * Note: The XMLReader does not close the passed Reader or InputStream - * - * @param aInputStream - * an InputStream to read the XML file from - * @param aListener - * ExTagListener that will be notified on close-tag and open-tag - * events - * @param aLevel - * indicates the tag level that the listener will be invoked for. - * For example if the XML is:
      - * - *
      -	 *  <a>
      -	 *    <b>
      -	 *      <c />
      -	 *    </b>
      -	 *  </a>
      -	 * 
      - * - *
      - * and the passed aLevel is 2 then the listener will be invoked - * only for tags that have level 2, i.e. in our example the - * listener will be invoked only for tag <b>
      - *
        - *
      • Value less than 0 indicates "invoke listener for all - * tags no matter what are their levels"
      • - *
      • Value of 0 indicates that the listener must not be - * invoked in general no matter what is the tag level
      • - *
      • Value greater than 0 indicates the tag level that the - * listener will be invoked for
      • - * description - * @throws IOException - * if some IO error occurs when reading the XML file or if a - * parser error occurs. - */ - public static void parseXML(InputStream aInputStream, ExTagListener aListener, int aLevel) throws IOException { - XMLParserImpl xml = new XMLParserImpl(aInputStream, aListener); - xml.setLevel(aLevel); - xml.parseXML(); - } - - /** - * Parses a XML file given through aReader and during the parsing notifies - * aListener for close-tag and open-tag events
        - *
        - * Note: The XMLReader does not close the passed Reader or InputStream - * - * @param aReader - * aReader to read the XML file from - * @param aListener - * ExTagListener that will be notified on close-tag and open-tag - * events - * @param aLevel - * see parseXML(Reader aReader, ExTagListener aListener, int - * aLevel description - * @throws IOException - * if some IO error occurs when reading the XML file or if a - * parser error occurs. - */ - public static void parseXML(Reader aReader, ExTagListener aListener, int aLevel) throws IOException { - XMLParserImpl xml = new XMLParserImpl(aReader, aListener); - xml.setLevel(aLevel); - xml.parseXML(); - } - - /** - * Returns the XML version attribute - * - * @return the XML file version attribute - */ - public String getVersion() { - return fVersion; - } - - /** - * Returns the XML encoding attribute - * - * @return the XML encoding attribute - */ - public String getEncoding() { - return fEncoding; - } - - /** - * Returns the value of XML standalone attribute - * - * @return the value of XML standalone attribute - */ - public String getStandalone() { - return fStandalone; - } -} diff --git a/bundles/org.eclipse.equinox.ds/src/org/eclipse/equinox/internal/util/xml/package.html b/bundles/org.eclipse.equinox.ds/src/org/eclipse/equinox/internal/util/xml/package.html deleted file mode 100644 index 2de2f74f9..000000000 --- a/bundles/org.eclipse.equinox.ds/src/org/eclipse/equinox/internal/util/xml/package.html +++ /dev/null @@ -1,12 +0,0 @@ - - - - - - - - - -

        The org.eclipse.equinox.util.xml package contains classes that can read and parse a XML document. Through the XMLReader class you can read a XML from an input stream or through a reader. To get aware of every read tag, you should pass a TagListener implementation as an argument in the chosen read method of XMLReader. When the end of a tag is reached, the TagListener will received an instance of TagClass that represents this tag. To read the name, content, attributes and a child tag at a specific index, you can use TagClass and XMLUtil. With XMLUtil you can also replace a tag. You cannot create new XMLs with the XML utilities.

        - - -- cgit v1.2.3