From 2410d8844182e057fd59ea4139b9a7d61413bbea Mon Sep 17 00:00:00 2001 From: rfeng Date: Tue, 8 Jul 2008 23:10:31 +0000 Subject: Make the ServiceDiscovery pluggable and add support for OSGi-based service discoverer git-svn-id: http://svn.us.apache.org/repos/asf/tuscany@675040 13f79535-47bb-0310-9956-ffa450edef68 --- .../axis2/impl/Axis2SCABindingProviderFactory.java | 3 +- .../impl/Axis2SCAReferenceBindingProvider.java | 5 +- .../axis2/impl/Axis2SCAServiceBindingProvider.java | 5 +- .../sca/axis2/impl/Axis2SCAServiceProvider.java | 3 +- .../ws/axis2/Axis2BindingProviderFactory.java | 4 +- .../ws/axis2/Axis2ReferenceBindingProvider.java | 5 +- .../ws/axis2/Axis2ServiceBindingProvider.java | 7 +- .../sca/binding/ws/axis2/Axis2ServiceClient.java | 15 +- .../sca/binding/ws/axis2/Axis2ServiceProvider.java | 12 +- java/sca/modules/contribution-osgi/pom.xml | 6 + ...DefaultStAXArtifactProcessorExtensionPoint.java | 2 +- .../DefaultURLArtifactProcessorExtensionPoint.java | 2 +- .../DefaultValidationSchemaExtensionPoint.java | 2 +- ...faultEndpointResolverFactoryExtensionPoint.java | 4 - .../DefaultProviderFactoryExtensionPoint.java | 1 - .../java/impl/BeanJavaImplementationImpl.java | 6 +- .../tuscany/sca/core/invocation/PhaseManager.java | 2 +- .../databinding/xmlbeans/XMLBeansDataBinding.java | 43 ++- java/sca/modules/extensibility-eclipse/LICENSE | 205 ++++++++++++ java/sca/modules/extensibility-eclipse/NOTICE | 5 + java/sca/modules/extensibility-eclipse/pom.xml | 70 ++++ .../equinox/EquinoxServiceDiscoverer.java | 253 ++++++++++++++ .../equinox/EquinoxServiceDiscovererTestCase.java | 144 ++++++++ .../resources/dependency/app-1.0.0-v20070423.jar | Bin 0 -> 73523 bytes .../dependency/common-3.3.0-v20070426.jar | Bin 0 -> 92736 bytes .../dependency/contenttype-3.2.100-v20070319.jar | Bin 0 -> 82727 bytes .../resources/dependency/jobs-3.3.0-v20070423.jar | Bin 0 -> 81726 bytes .../dependency/preferences-3.2.100-v20070522.jar | Bin 0 -> 103444 bytes .../dependency/registry-3.3.0-v20070522.jar | Bin 0 -> 160885 bytes .../dependency/runtime-3.3.100-v20070530.jar | Bin 0 -> 73300 bytes .../src/test/resources/test-bundle.jar | Bin 0 -> 11920 bytes java/sca/modules/extensibility-osgi/LICENSE | 205 ++++++++++++ java/sca/modules/extensibility-osgi/NOTICE | 5 + java/sca/modules/extensibility-osgi/pom.xml | 66 ++++ .../extensibility/osgi/OSGiServiceDiscoverer.java | 252 ++++++++++++++ .../osgi/OSGiServiceDiscovererTestCase.java | 104 ++++++ .../src/test/resources/test-bundle.jar | Bin 0 -> 11920 bytes .../extensibility/ClasspathServiceDiscover.java | 237 ++++++++++++++ .../sca/extensibility/ServiceDeclaration.java | 118 ++----- .../sca/extensibility/ServiceDiscoverer.java | 34 ++ .../sca/extensibility/ServiceDiscovery.java | 273 ++++------------ .../ClasspathServiceDiscovererTestCase.java | 61 ++++ .../sca/extension/helper/impl/DiscoveryUtils.java | 38 +-- .../invocation/JavaImplementationProvider.java | 3 +- .../JavaImplementationProviderFactory.java | 5 +- .../java/module/JavaRuntimeModuleActivator.java | 3 +- .../implementation/java/JavaImplementation.java | 4 +- .../java/impl/JavaImplementationImpl.java | 6 +- java/sca/modules/osgi-runtime/pom.xml | 68 ++-- .../sca/osgi/runtime/OSGiBundleActivator.java | 364 ++++++++++----------- .../util/PolicyHandlerDefinitionsLoader.java | 17 +- .../sca/policy/util/PolicyHandlerTuple.java | 32 +- .../sca/policy/util/PolicyHandlerUtils.java | 50 ++- java/sca/modules/pom.xml | 2 + 54 files changed, 2091 insertions(+), 660 deletions(-) create mode 100644 java/sca/modules/extensibility-eclipse/LICENSE create mode 100644 java/sca/modules/extensibility-eclipse/NOTICE create mode 100644 java/sca/modules/extensibility-eclipse/pom.xml create mode 100644 java/sca/modules/extensibility-eclipse/src/main/java/org/apache/tuscany/sca/extensibility/equinox/EquinoxServiceDiscoverer.java create mode 100644 java/sca/modules/extensibility-eclipse/src/test/java/org/apache/tuscany/sca/extensibility/equinox/EquinoxServiceDiscovererTestCase.java create mode 100644 java/sca/modules/extensibility-eclipse/src/test/resources/dependency/app-1.0.0-v20070423.jar create mode 100644 java/sca/modules/extensibility-eclipse/src/test/resources/dependency/common-3.3.0-v20070426.jar create mode 100644 java/sca/modules/extensibility-eclipse/src/test/resources/dependency/contenttype-3.2.100-v20070319.jar create mode 100644 java/sca/modules/extensibility-eclipse/src/test/resources/dependency/jobs-3.3.0-v20070423.jar create mode 100644 java/sca/modules/extensibility-eclipse/src/test/resources/dependency/preferences-3.2.100-v20070522.jar create mode 100644 java/sca/modules/extensibility-eclipse/src/test/resources/dependency/registry-3.3.0-v20070522.jar create mode 100644 java/sca/modules/extensibility-eclipse/src/test/resources/dependency/runtime-3.3.100-v20070530.jar create mode 100644 java/sca/modules/extensibility-eclipse/src/test/resources/test-bundle.jar create mode 100644 java/sca/modules/extensibility-osgi/LICENSE create mode 100644 java/sca/modules/extensibility-osgi/NOTICE create mode 100644 java/sca/modules/extensibility-osgi/pom.xml create mode 100644 java/sca/modules/extensibility-osgi/src/main/java/org/apache/tuscany/sca/extensibility/osgi/OSGiServiceDiscoverer.java create mode 100644 java/sca/modules/extensibility-osgi/src/test/java/org/apache/tuscany/sca/extensibility/osgi/OSGiServiceDiscovererTestCase.java create mode 100644 java/sca/modules/extensibility-osgi/src/test/resources/test-bundle.jar create mode 100644 java/sca/modules/extensibility/src/main/java/org/apache/tuscany/sca/extensibility/ClasspathServiceDiscover.java create mode 100644 java/sca/modules/extensibility/src/main/java/org/apache/tuscany/sca/extensibility/ServiceDiscoverer.java create mode 100644 java/sca/modules/extensibility/src/test/java/org/apache/tuscany/sca/extensibility/ClasspathServiceDiscovererTestCase.java (limited to 'java') diff --git a/java/sca/modules/binding-sca-axis2/src/main/java/org/apache/tuscany/sca/binding/sca/axis2/impl/Axis2SCABindingProviderFactory.java b/java/sca/modules/binding-sca-axis2/src/main/java/org/apache/tuscany/sca/binding/sca/axis2/impl/Axis2SCABindingProviderFactory.java index 47359c3484..b105696b5d 100644 --- a/java/sca/modules/binding-sca-axis2/src/main/java/org/apache/tuscany/sca/binding/sca/axis2/impl/Axis2SCABindingProviderFactory.java +++ b/java/sca/modules/binding-sca-axis2/src/main/java/org/apache/tuscany/sca/binding/sca/axis2/impl/Axis2SCABindingProviderFactory.java @@ -20,7 +20,6 @@ package org.apache.tuscany.sca.binding.sca.axis2.impl; import java.util.List; -import java.util.Map; import org.apache.tuscany.sca.binding.sca.DistributedSCABinding; import org.apache.tuscany.sca.core.ExtensionPointRegistry; @@ -41,7 +40,7 @@ import org.apache.tuscany.sca.runtime.RuntimeComponentService; public class Axis2SCABindingProviderFactory implements BindingProviderFactory { private ExtensionPointRegistry extensionPoints; - private Map> policyHandlerClassnames = null; + private List policyHandlerClassnames = null; public Axis2SCABindingProviderFactory(ExtensionPointRegistry extensionPoints) { this.extensionPoints = extensionPoints; diff --git a/java/sca/modules/binding-sca-axis2/src/main/java/org/apache/tuscany/sca/binding/sca/axis2/impl/Axis2SCAReferenceBindingProvider.java b/java/sca/modules/binding-sca-axis2/src/main/java/org/apache/tuscany/sca/binding/sca/axis2/impl/Axis2SCAReferenceBindingProvider.java index 93ad1d30e5..22f926b73e 100644 --- a/java/sca/modules/binding-sca-axis2/src/main/java/org/apache/tuscany/sca/binding/sca/axis2/impl/Axis2SCAReferenceBindingProvider.java +++ b/java/sca/modules/binding-sca-axis2/src/main/java/org/apache/tuscany/sca/binding/sca/axis2/impl/Axis2SCAReferenceBindingProvider.java @@ -21,15 +21,14 @@ package org.apache.tuscany.sca.binding.sca.axis2.impl; import java.net.URI; import java.util.List; -import java.util.Map; import java.util.logging.Logger; import org.apache.axiom.om.OMElement; import org.apache.tuscany.sca.assembly.Binding; import org.apache.tuscany.sca.assembly.SCABinding; import org.apache.tuscany.sca.binding.sca.DistributedSCABinding; -import org.apache.tuscany.sca.binding.ws.WebServiceBindingFactory; import org.apache.tuscany.sca.binding.ws.WebServiceBinding; +import org.apache.tuscany.sca.binding.ws.WebServiceBindingFactory; import org.apache.tuscany.sca.binding.ws.axis2.Axis2ReferenceBindingProvider; import org.apache.tuscany.sca.binding.ws.wsdlgen.BindingWSDLGenerator; import org.apache.tuscany.sca.contribution.ModelFactoryExtensionPoint; @@ -71,7 +70,7 @@ public class Axis2SCAReferenceBindingProvider implements ReferenceBindingProvide RuntimeComponentReference reference, DistributedSCABinding binding, ExtensionPointRegistry extensionPoints, - Map> policyHandlerClassnames) { + List policyHandlerClassnames) { ServletHostExtensionPoint servletHosts = extensionPoints.getExtensionPoint(ServletHostExtensionPoint.class); ServletHost servletHost = servletHosts.getServletHosts().get(0); diff --git a/java/sca/modules/binding-sca-axis2/src/main/java/org/apache/tuscany/sca/binding/sca/axis2/impl/Axis2SCAServiceBindingProvider.java b/java/sca/modules/binding-sca-axis2/src/main/java/org/apache/tuscany/sca/binding/sca/axis2/impl/Axis2SCAServiceBindingProvider.java index 0ecbf60395..58a50d46dc 100644 --- a/java/sca/modules/binding-sca-axis2/src/main/java/org/apache/tuscany/sca/binding/sca/axis2/impl/Axis2SCAServiceBindingProvider.java +++ b/java/sca/modules/binding-sca-axis2/src/main/java/org/apache/tuscany/sca/binding/sca/axis2/impl/Axis2SCAServiceBindingProvider.java @@ -20,14 +20,13 @@ package org.apache.tuscany.sca.binding.sca.axis2.impl; import java.util.List; -import java.util.Map; import java.util.logging.Logger; import org.apache.axiom.om.OMElement; import org.apache.tuscany.sca.assembly.SCABinding; import org.apache.tuscany.sca.binding.sca.DistributedSCABinding; -import org.apache.tuscany.sca.binding.ws.WebServiceBindingFactory; import org.apache.tuscany.sca.binding.ws.WebServiceBinding; +import org.apache.tuscany.sca.binding.ws.WebServiceBindingFactory; import org.apache.tuscany.sca.binding.ws.axis2.Axis2ServiceProvider; import org.apache.tuscany.sca.binding.ws.wsdlgen.BindingWSDLGenerator; import org.apache.tuscany.sca.contribution.ModelFactoryExtensionPoint; @@ -63,7 +62,7 @@ public class Axis2SCAServiceBindingProvider implements ServiceBindingProvider { RuntimeComponentService service, DistributedSCABinding binding, ExtensionPointRegistry extensionPoints, - Map> policyHandlerClassnames) { + List policyHandlerClassnames) { ServletHostExtensionPoint servletHosts = extensionPoints.getExtensionPoint(ServletHostExtensionPoint.class); ServletHost servletHost = servletHosts.getServletHosts().get(0); diff --git a/java/sca/modules/binding-sca-axis2/src/main/java/org/apache/tuscany/sca/binding/sca/axis2/impl/Axis2SCAServiceProvider.java b/java/sca/modules/binding-sca-axis2/src/main/java/org/apache/tuscany/sca/binding/sca/axis2/impl/Axis2SCAServiceProvider.java index 42f7676ecb..cf13d821f7 100644 --- a/java/sca/modules/binding-sca-axis2/src/main/java/org/apache/tuscany/sca/binding/sca/axis2/impl/Axis2SCAServiceProvider.java +++ b/java/sca/modules/binding-sca-axis2/src/main/java/org/apache/tuscany/sca/binding/sca/axis2/impl/Axis2SCAServiceProvider.java @@ -20,7 +20,6 @@ package org.apache.tuscany.sca.binding.sca.axis2.impl; import java.util.List; -import java.util.Map; import org.apache.tuscany.sca.assembly.Binding; import org.apache.tuscany.sca.assembly.SCABinding; @@ -59,7 +58,7 @@ public class Axis2SCAServiceProvider extends Axis2ServiceProvider { WebServiceBinding wsBinding, ServletHost servletHost, MessageFactory messageFactory, - Map> policyHandlerClassnames) { + List policyHandlerClassnames) { super(component, service, diff --git a/java/sca/modules/binding-ws-axis2/src/main/java/org/apache/tuscany/sca/binding/ws/axis2/Axis2BindingProviderFactory.java b/java/sca/modules/binding-ws-axis2/src/main/java/org/apache/tuscany/sca/binding/ws/axis2/Axis2BindingProviderFactory.java index 83df3481ce..eb5f01a70b 100644 --- a/java/sca/modules/binding-ws-axis2/src/main/java/org/apache/tuscany/sca/binding/ws/axis2/Axis2BindingProviderFactory.java +++ b/java/sca/modules/binding-ws-axis2/src/main/java/org/apache/tuscany/sca/binding/ws/axis2/Axis2BindingProviderFactory.java @@ -19,7 +19,6 @@ package org.apache.tuscany.sca.binding.ws.axis2; import java.util.List; -import java.util.Map; import org.apache.tuscany.sca.binding.ws.WebServiceBinding; import org.apache.tuscany.sca.contribution.ModelFactoryExtensionPoint; @@ -27,7 +26,6 @@ import org.apache.tuscany.sca.core.ExtensionPointRegistry; import org.apache.tuscany.sca.databinding.DataBindingExtensionPoint; import org.apache.tuscany.sca.host.http.ServletHost; import org.apache.tuscany.sca.host.http.ServletHostExtensionPoint; -import org.apache.tuscany.sca.invocation.MessageFactory; import org.apache.tuscany.sca.policy.util.PolicyHandlerDefinitionsLoader; import org.apache.tuscany.sca.policy.util.PolicyHandlerTuple; import org.apache.tuscany.sca.provider.BindingProviderFactory; @@ -48,7 +46,7 @@ public class Axis2BindingProviderFactory implements BindingProviderFactory> policyHandlerClassnames = null; + private List policyHandlerClassnames = null; private DataBindingExtensionPoint dataBindings; public Axis2BindingProviderFactory(ExtensionPointRegistry extensionPoints) { diff --git a/java/sca/modules/binding-ws-axis2/src/main/java/org/apache/tuscany/sca/binding/ws/axis2/Axis2ReferenceBindingProvider.java b/java/sca/modules/binding-ws-axis2/src/main/java/org/apache/tuscany/sca/binding/ws/axis2/Axis2ReferenceBindingProvider.java index d4e3f47e6d..8f8cb5f392 100644 --- a/java/sca/modules/binding-ws-axis2/src/main/java/org/apache/tuscany/sca/binding/ws/axis2/Axis2ReferenceBindingProvider.java +++ b/java/sca/modules/binding-ws-axis2/src/main/java/org/apache/tuscany/sca/binding/ws/axis2/Axis2ReferenceBindingProvider.java @@ -19,13 +19,12 @@ package org.apache.tuscany.sca.binding.ws.axis2; import java.util.List; -import java.util.Map; import org.apache.axiom.om.OMElement; import org.apache.tuscany.sca.binding.ws.WebServiceBinding; import org.apache.tuscany.sca.contribution.ModelFactoryExtensionPoint; -import org.apache.tuscany.sca.host.http.ServletHost; import org.apache.tuscany.sca.databinding.DataBindingExtensionPoint; +import org.apache.tuscany.sca.host.http.ServletHost; import org.apache.tuscany.sca.interfacedef.InterfaceContract; import org.apache.tuscany.sca.interfacedef.Operation; import org.apache.tuscany.sca.invocation.Invoker; @@ -46,7 +45,7 @@ public class Axis2ReferenceBindingProvider implements ReferenceBindingProvider { WebServiceBinding wsBinding, ServletHost servletHost, ModelFactoryExtensionPoint modelFactories, - Map> policyHandlerClassnames, + List policyHandlerClassnames, DataBindingExtensionPoint dataBindings) { MessageFactory messageFactory = modelFactories.getFactory(MessageFactory.class); diff --git a/java/sca/modules/binding-ws-axis2/src/main/java/org/apache/tuscany/sca/binding/ws/axis2/Axis2ServiceBindingProvider.java b/java/sca/modules/binding-ws-axis2/src/main/java/org/apache/tuscany/sca/binding/ws/axis2/Axis2ServiceBindingProvider.java index e35972ea00..3bdf33ea28 100644 --- a/java/sca/modules/binding-ws-axis2/src/main/java/org/apache/tuscany/sca/binding/ws/axis2/Axis2ServiceBindingProvider.java +++ b/java/sca/modules/binding-ws-axis2/src/main/java/org/apache/tuscany/sca/binding/ws/axis2/Axis2ServiceBindingProvider.java @@ -19,15 +19,12 @@ package org.apache.tuscany.sca.binding.ws.axis2; import java.util.List; -import java.util.Map; - -import javax.xml.namespace.QName; import org.apache.axiom.om.OMElement; import org.apache.tuscany.sca.binding.ws.WebServiceBinding; import org.apache.tuscany.sca.contribution.ModelFactoryExtensionPoint; -import org.apache.tuscany.sca.host.http.ServletHost; import org.apache.tuscany.sca.databinding.DataBindingExtensionPoint; +import org.apache.tuscany.sca.host.http.ServletHost; import org.apache.tuscany.sca.interfacedef.InterfaceContract; import org.apache.tuscany.sca.invocation.MessageFactory; import org.apache.tuscany.sca.policy.util.PolicyHandlerTuple; @@ -46,7 +43,7 @@ public class Axis2ServiceBindingProvider implements ServiceBindingProvider { WebServiceBinding wsBinding, ServletHost servletHost, ModelFactoryExtensionPoint modelFactories, - Map> policyHandlerClassnames, + List policyHandlerClassnames, DataBindingExtensionPoint dataBindings) { MessageFactory messageFactory = modelFactories.getFactory(MessageFactory.class); diff --git a/java/sca/modules/binding-ws-axis2/src/main/java/org/apache/tuscany/sca/binding/ws/axis2/Axis2ServiceClient.java b/java/sca/modules/binding-ws-axis2/src/main/java/org/apache/tuscany/sca/binding/ws/axis2/Axis2ServiceClient.java index f972b412b0..d81aaf374c 100644 --- a/java/sca/modules/binding-ws-axis2/src/main/java/org/apache/tuscany/sca/binding/ws/axis2/Axis2ServiceClient.java +++ b/java/sca/modules/binding-ws-axis2/src/main/java/org/apache/tuscany/sca/binding/ws/axis2/Axis2ServiceClient.java @@ -22,8 +22,6 @@ import static org.apache.tuscany.sca.binding.ws.axis2.AxisPolicyHelper.SOAP12_IN import static org.apache.tuscany.sca.binding.ws.axis2.AxisPolicyHelper.isIntentRequired; import java.io.IOException; -import java.net.URI; -import java.net.URISyntaxException; import java.net.URL; import java.security.AccessController; import java.security.PrivilegedAction; @@ -39,16 +37,9 @@ import javax.wsdl.BindingOperation; import javax.wsdl.Definition; import javax.wsdl.Import; import javax.wsdl.Port; -import javax.wsdl.PortType; -import javax.wsdl.Service; -import javax.wsdl.WSDLException; -import javax.wsdl.extensions.ExtensibilityElement; import javax.wsdl.extensions.soap.SOAPAddress; -import javax.wsdl.extensions.soap.SOAPBinding; import javax.wsdl.extensions.soap.SOAPOperation; import javax.wsdl.extensions.soap12.SOAP12Address; -import javax.wsdl.extensions.soap12.SOAP12Binding; -import javax.wsdl.factory.WSDLFactory; import javax.xml.namespace.QName; import javax.xml.stream.FactoryConfigurationError; import javax.xml.stream.XMLInputFactory; @@ -80,8 +71,6 @@ import org.apache.tuscany.sca.assembly.AbstractContract; import org.apache.tuscany.sca.binding.ws.WebServiceBinding; import org.apache.tuscany.sca.host.http.ServletHost; import org.apache.tuscany.sca.interfacedef.Operation; -import org.apache.tuscany.sca.interfacedef.wsdl.WSDLDefinition; -import org.apache.tuscany.sca.interfacedef.wsdl.WSDLInterface; import org.apache.tuscany.sca.invocation.Invoker; import org.apache.tuscany.sca.invocation.MessageFactory; import org.apache.tuscany.sca.policy.PolicySet; @@ -101,7 +90,7 @@ public class Axis2ServiceClient { private AbstractContract contract; private WebServiceBinding wsBinding; private ServiceClient serviceClient; - Map> policyHandlerClassnames = null; + List policyHandlerClassnames = null; private List policyHandlerList = new ArrayList(); public Axis2ServiceClient(RuntimeComponent component, @@ -109,7 +98,7 @@ public class Axis2ServiceClient { WebServiceBinding wsBinding, ServletHost servletHost, MessageFactory messageFactory, - Map> policyHandlerClassnames) { + List policyHandlerClassnames) { this.component = component; this.contract = contract; diff --git a/java/sca/modules/binding-ws-axis2/src/main/java/org/apache/tuscany/sca/binding/ws/axis2/Axis2ServiceProvider.java b/java/sca/modules/binding-ws-axis2/src/main/java/org/apache/tuscany/sca/binding/ws/axis2/Axis2ServiceProvider.java index de6f7c2c21..7939ff0c67 100644 --- a/java/sca/modules/binding-ws-axis2/src/main/java/org/apache/tuscany/sca/binding/ws/axis2/Axis2ServiceProvider.java +++ b/java/sca/modules/binding-ws-axis2/src/main/java/org/apache/tuscany/sca/binding/ws/axis2/Axis2ServiceProvider.java @@ -19,7 +19,6 @@ package org.apache.tuscany.sca.binding.ws.axis2; -import java.io.IOException; import java.lang.reflect.InvocationTargetException; import java.net.URI; import java.net.URISyntaxException; @@ -44,21 +43,14 @@ import javax.wsdl.extensions.UnknownExtensibilityElement; import javax.wsdl.extensions.soap.SOAPAddress; import javax.wsdl.extensions.soap12.SOAP12Address; import javax.xml.namespace.QName; -import javax.xml.stream.FactoryConfigurationError; -import javax.xml.stream.XMLInputFactory; -import javax.xml.stream.XMLStreamException; -import javax.xml.stream.XMLStreamReader; -import javax.xml.transform.dom.DOMSource; import org.apache.axiom.om.OMAbstractFactory; import org.apache.axiom.om.OMElement; import org.apache.axiom.om.OMFactory; -import org.apache.axiom.om.impl.builder.StAXOMBuilder; import org.apache.axiom.soap.SOAPHeader; import org.apache.axis2.AxisFault; import org.apache.axis2.Constants; import org.apache.axis2.addressing.AddressingConstants; -import org.apache.axis2.addressing.EndpointReferenceHelper; import org.apache.axis2.context.ConfigurationContext; import org.apache.axis2.context.MessageContext; import org.apache.axis2.deployment.util.Utils; @@ -129,7 +121,7 @@ public class Axis2ServiceProvider { private ConfigurationContext configContext; private JMSSender jmsSender; private JMSListener jmsListener; - private Map> policyHandlerClassnames = null; + private List policyHandlerClassnames = null; private List policyHandlerList = new ArrayList(); private Map urlMap = new HashMap(); private Map addressMap = new HashMap(); @@ -165,7 +157,7 @@ public class Axis2ServiceProvider { WebServiceBinding wsBinding, ServletHost servletHost, MessageFactory messageFactory, - Map> policyHandlerClassnames) { + List policyHandlerClassnames) { this.component = component; this.contract = contract; diff --git a/java/sca/modules/contribution-osgi/pom.xml b/java/sca/modules/contribution-osgi/pom.xml index 9e3c5b6917..5622978bd9 100644 --- a/java/sca/modules/contribution-osgi/pom.xml +++ b/java/sca/modules/contribution-osgi/pom.xml @@ -40,6 +40,12 @@ tuscany-osgi-runtime 1.4-SNAPSHOT + + + org.apache.tuscany.sca + tuscany-contribution-java + 1.4-SNAPSHOT + org.apache.tuscany.sca diff --git a/java/sca/modules/contribution/src/main/java/org/apache/tuscany/sca/contribution/processor/DefaultStAXArtifactProcessorExtensionPoint.java b/java/sca/modules/contribution/src/main/java/org/apache/tuscany/sca/contribution/processor/DefaultStAXArtifactProcessorExtensionPoint.java index bfd0be4541..db4833886d 100644 --- a/java/sca/modules/contribution/src/main/java/org/apache/tuscany/sca/contribution/processor/DefaultStAXArtifactProcessorExtensionPoint.java +++ b/java/sca/modules/contribution/src/main/java/org/apache/tuscany/sca/contribution/processor/DefaultStAXArtifactProcessorExtensionPoint.java @@ -41,11 +41,11 @@ import org.apache.tuscany.sca.core.ExtensionPointRegistry; import org.apache.tuscany.sca.core.UtilityExtensionPoint; import org.apache.tuscany.sca.extensibility.ServiceDeclaration; import org.apache.tuscany.sca.extensibility.ServiceDiscovery; -import org.apache.tuscany.sca.policy.PolicyFactory; import org.apache.tuscany.sca.monitor.Monitor; import org.apache.tuscany.sca.monitor.MonitorFactory; import org.apache.tuscany.sca.monitor.Problem; import org.apache.tuscany.sca.monitor.Problem.Severity; +import org.apache.tuscany.sca.policy.PolicyFactory; /** * The default implementation of an extension point for StAX artifact processors. diff --git a/java/sca/modules/contribution/src/main/java/org/apache/tuscany/sca/contribution/processor/DefaultURLArtifactProcessorExtensionPoint.java b/java/sca/modules/contribution/src/main/java/org/apache/tuscany/sca/contribution/processor/DefaultURLArtifactProcessorExtensionPoint.java index b27404271e..045c201638 100644 --- a/java/sca/modules/contribution/src/main/java/org/apache/tuscany/sca/contribution/processor/DefaultURLArtifactProcessorExtensionPoint.java +++ b/java/sca/modules/contribution/src/main/java/org/apache/tuscany/sca/contribution/processor/DefaultURLArtifactProcessorExtensionPoint.java @@ -37,8 +37,8 @@ import org.apache.tuscany.sca.core.ExtensionPointRegistry; import org.apache.tuscany.sca.core.UtilityExtensionPoint; import org.apache.tuscany.sca.extensibility.ServiceDeclaration; import org.apache.tuscany.sca.extensibility.ServiceDiscovery; -import org.apache.tuscany.sca.monitor.MonitorFactory; import org.apache.tuscany.sca.monitor.Monitor; +import org.apache.tuscany.sca.monitor.MonitorFactory; import org.apache.tuscany.sca.monitor.Problem; import org.apache.tuscany.sca.monitor.Problem.Severity; diff --git a/java/sca/modules/contribution/src/main/java/org/apache/tuscany/sca/contribution/processor/DefaultValidationSchemaExtensionPoint.java b/java/sca/modules/contribution/src/main/java/org/apache/tuscany/sca/contribution/processor/DefaultValidationSchemaExtensionPoint.java index 1625984ed0..a6631f498e 100644 --- a/java/sca/modules/contribution/src/main/java/org/apache/tuscany/sca/contribution/processor/DefaultValidationSchemaExtensionPoint.java +++ b/java/sca/modules/contribution/src/main/java/org/apache/tuscany/sca/contribution/processor/DefaultValidationSchemaExtensionPoint.java @@ -68,7 +68,7 @@ public class DefaultValidationSchemaExtensionPoint implements ValidationSchemaEx // Find each schema for (ServiceDeclaration schemaDeclaration: schemaDeclarations) { - URL url = schemaDeclaration.getResource(); + URL url = schemaDeclaration.getResource(schemaDeclaration.getClassName()); if (url == null) { throw new IllegalArgumentException(new FileNotFoundException(schemaDeclaration.getClassName())); } diff --git a/java/sca/modules/core-spi/src/main/java/org/apache/tuscany/sca/endpointresolver/DefaultEndpointResolverFactoryExtensionPoint.java b/java/sca/modules/core-spi/src/main/java/org/apache/tuscany/sca/endpointresolver/DefaultEndpointResolverFactoryExtensionPoint.java index 41735261e6..2849c27c1a 100644 --- a/java/sca/modules/core-spi/src/main/java/org/apache/tuscany/sca/endpointresolver/DefaultEndpointResolverFactoryExtensionPoint.java +++ b/java/sca/modules/core-spi/src/main/java/org/apache/tuscany/sca/endpointresolver/DefaultEndpointResolverFactoryExtensionPoint.java @@ -28,13 +28,9 @@ import java.util.Set; import org.apache.tuscany.sca.assembly.Binding; import org.apache.tuscany.sca.assembly.Endpoint; -import org.apache.tuscany.sca.assembly.Implementation; import org.apache.tuscany.sca.core.ExtensionPointRegistry; import org.apache.tuscany.sca.extensibility.ServiceDeclaration; import org.apache.tuscany.sca.extensibility.ServiceDiscovery; -import org.apache.tuscany.sca.runtime.RuntimeComponent; -import org.apache.tuscany.sca.runtime.RuntimeComponentReference; -import org.apache.tuscany.sca.runtime.RuntimeComponentService; /** * Default implementation of a provider factory extension point. diff --git a/java/sca/modules/core-spi/src/main/java/org/apache/tuscany/sca/provider/DefaultProviderFactoryExtensionPoint.java b/java/sca/modules/core-spi/src/main/java/org/apache/tuscany/sca/provider/DefaultProviderFactoryExtensionPoint.java index 51e5e91589..dfc3ddb468 100644 --- a/java/sca/modules/core-spi/src/main/java/org/apache/tuscany/sca/provider/DefaultProviderFactoryExtensionPoint.java +++ b/java/sca/modules/core-spi/src/main/java/org/apache/tuscany/sca/provider/DefaultProviderFactoryExtensionPoint.java @@ -27,7 +27,6 @@ import java.util.Map; import java.util.Set; import org.apache.tuscany.sca.assembly.Binding; -import org.apache.tuscany.sca.assembly.Endpoint; import org.apache.tuscany.sca.assembly.Implementation; import org.apache.tuscany.sca.core.ExtensionPointRegistry; import org.apache.tuscany.sca.extensibility.ServiceDeclaration; diff --git a/java/sca/modules/core-spring/src/main/java/org/apache/tuscany/sca/core/spring/implementation/java/impl/BeanJavaImplementationImpl.java b/java/sca/modules/core-spring/src/main/java/org/apache/tuscany/sca/core/spring/implementation/java/impl/BeanJavaImplementationImpl.java index 27dc7ec6c7..7fc82d8711 100644 --- a/java/sca/modules/core-spring/src/main/java/org/apache/tuscany/sca/core/spring/implementation/java/impl/BeanJavaImplementationImpl.java +++ b/java/sca/modules/core-spring/src/main/java/org/apache/tuscany/sca/core/spring/implementation/java/impl/BeanJavaImplementationImpl.java @@ -59,7 +59,7 @@ public class BeanJavaImplementationImpl extends BeanBaseJavaImplementationImpl i private long maxAge = -1; private long maxIdleTime = -1; private JavaScopeImpl scope = JavaScopeImpl.STATELESS; - private Map> policyHandlerClassNames = null; + private List policyHandlerClassNames = null; protected BeanJavaImplementationImpl(BeanDefinitionRegistry beanRegistry) { super(beanRegistry); @@ -165,11 +165,11 @@ public class BeanJavaImplementationImpl extends BeanBaseJavaImplementationImpl i this.maxIdleTime = maxIdleTime; } - public Map> getPolicyHandlerClassNames() { + public List getPolicyHandlerClassNames() { return policyHandlerClassNames; } - public void setPolicyHandlerClassNames(Map> policyHandlerClassNames) { + public void setPolicyHandlerClassNames(List policyHandlerClassNames) { this.policyHandlerClassNames = policyHandlerClassNames; } } diff --git a/java/sca/modules/core/src/main/java/org/apache/tuscany/sca/core/invocation/PhaseManager.java b/java/sca/modules/core/src/main/java/org/apache/tuscany/sca/core/invocation/PhaseManager.java index 4c98066fa2..4f7778d3f7 100644 --- a/java/sca/modules/core/src/main/java/org/apache/tuscany/sca/core/invocation/PhaseManager.java +++ b/java/sca/modules/core/src/main/java/org/apache/tuscany/sca/core/invocation/PhaseManager.java @@ -144,7 +144,7 @@ public class PhaseManager { for (ServiceDeclaration d : services) { if (log.isLoggable(Level.FINE)) { - log.fine(d.getResource() + ": " + d.getAttributes()); + log.fine(d.getLocation() + ": " + d.getAttributes()); } String name = d.getAttributes().get("name"); if (name == null) { diff --git a/java/sca/modules/databinding-xmlbeans/src/main/java/org/apache/tuscany/sca/databinding/xmlbeans/XMLBeansDataBinding.java b/java/sca/modules/databinding-xmlbeans/src/main/java/org/apache/tuscany/sca/databinding/xmlbeans/XMLBeansDataBinding.java index 94e74321c4..15616979c2 100644 --- a/java/sca/modules/databinding-xmlbeans/src/main/java/org/apache/tuscany/sca/databinding/xmlbeans/XMLBeansDataBinding.java +++ b/java/sca/modules/databinding-xmlbeans/src/main/java/org/apache/tuscany/sca/databinding/xmlbeans/XMLBeansDataBinding.java @@ -19,10 +19,18 @@ package org.apache.tuscany.sca.databinding.xmlbeans; +import java.lang.reflect.Field; + +import javax.xml.namespace.QName; + +import org.apache.tuscany.sca.databinding.WrapperHandler; import org.apache.tuscany.sca.databinding.impl.BaseDataBinding; import org.apache.tuscany.sca.interfacedef.DataType; import org.apache.tuscany.sca.interfacedef.Operation; +import org.apache.tuscany.sca.interfacedef.util.XMLType; +import org.apache.xmlbeans.SchemaType; import org.apache.xmlbeans.XmlObject; +import org.osoa.sca.ServiceRuntimeException; /** * XMLBeans DataBinding @@ -31,15 +39,44 @@ import org.apache.xmlbeans.XmlObject; */ public class XMLBeansDataBinding extends BaseDataBinding { public static final String NAME = XmlObject.class.getName(); - public static final String[] ALIASES = { "xmlbeans" }; - + public static final String[] ALIASES = {"xmlbeans"}; + public XMLBeansDataBinding() { super(NAME, XmlObject.class); } + @Override + public WrapperHandler getWrapperHandler() { + return new XMLBeansWrapperHandler(); + } + + @Override + public boolean introspect(DataType type, Operation operation) { + if (XmlObject.class.isAssignableFrom(type.getPhysical())) { + Class cls = type.getPhysical(); + SchemaType schemaType = null; + try { + Field f = cls.getField("type"); + schemaType = (SchemaType)f.get(null); + } catch (Throwable e) { + throw new ServiceRuntimeException(e); + } + QName typeName = schemaType.getName(); + Object logical = type.getLogical(); + QName elementName = null; + if (logical instanceof XMLType) { + elementName = ((XMLType)logical).getElementName(); + } + type.setLogical(new XMLType(elementName, typeName)); + type.setMetaData(SchemaType.class, schemaType); + return true; + } + return false; + } + @Override public Object copy(Object object, DataType dataType, Operation operation) { - return ((XmlObject) object).copy(); + return ((XmlObject)object).copy(); } } diff --git a/java/sca/modules/extensibility-eclipse/LICENSE b/java/sca/modules/extensibility-eclipse/LICENSE new file mode 100644 index 0000000000..6e529a25c4 --- /dev/null +++ b/java/sca/modules/extensibility-eclipse/LICENSE @@ -0,0 +1,205 @@ + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed 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. + + + diff --git a/java/sca/modules/extensibility-eclipse/NOTICE b/java/sca/modules/extensibility-eclipse/NOTICE new file mode 100644 index 0000000000..65c52d01c7 --- /dev/null +++ b/java/sca/modules/extensibility-eclipse/NOTICE @@ -0,0 +1,5 @@ +Copyright (c) 2005 - 2008 The Apache Software Foundation + +This product includes software developed by +The Apache Software Foundation (http://www.apache.org/). + diff --git a/java/sca/modules/extensibility-eclipse/pom.xml b/java/sca/modules/extensibility-eclipse/pom.xml new file mode 100644 index 0000000000..9c12119fcc --- /dev/null +++ b/java/sca/modules/extensibility-eclipse/pom.xml @@ -0,0 +1,70 @@ + + + + 4.0.0 + + org.apache.tuscany.sca + tuscany-modules + 1.4-SNAPSHOT + ../pom.xml + + tuscany-extensibility-eclipse + Apache Tuscany SCA Extensibility for Eclipse Equinox + + + org.apache.tuscany.sca + tuscany-extensibility + 1.4-SNAPSHOT + + + + org.eclipse + osgi + 3.3.0-v20070530 + compile + + + + + + + + org.apache.felix + maven-bundle-plugin + + + ${tuscany.version} + + org.apache.tuscany.sca.extensibility.equinox + ${pom.name} + org.apache.tuscany.sca.extensibility.equinox* + + + + + + \ No newline at end of file diff --git a/java/sca/modules/extensibility-eclipse/src/main/java/org/apache/tuscany/sca/extensibility/equinox/EquinoxServiceDiscoverer.java b/java/sca/modules/extensibility-eclipse/src/main/java/org/apache/tuscany/sca/extensibility/equinox/EquinoxServiceDiscoverer.java new file mode 100644 index 0000000000..bf1b5c07eb --- /dev/null +++ b/java/sca/modules/extensibility-eclipse/src/main/java/org/apache/tuscany/sca/extensibility/equinox/EquinoxServiceDiscoverer.java @@ -0,0 +1,253 @@ +/* + * 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.tuscany.sca.extensibility.equinox; + +import java.io.BufferedReader; +import java.io.IOException; +import java.io.InputStream; +import java.io.InputStreamReader; +import java.net.URL; +import java.security.AccessController; +import java.security.PrivilegedAction; +import java.security.PrivilegedActionException; +import java.security.PrivilegedExceptionAction; +import java.util.Enumeration; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Map; +import java.util.Set; +import java.util.StringTokenizer; +import java.util.logging.Level; +import java.util.logging.Logger; + +import org.apache.tuscany.sca.extensibility.ServiceDeclaration; +import org.apache.tuscany.sca.extensibility.ServiceDiscoverer; +import org.osgi.framework.Bundle; +import org.osgi.framework.BundleContext; + +/** + * The ServiceDiscoverer that find META-INF/services/... in installed bundles + */ +public class EquinoxServiceDiscoverer implements ServiceDiscoverer { + private static final Logger logger = Logger.getLogger(EquinoxServiceDiscoverer.class.getName()); + private BundleContext context; + + public EquinoxServiceDiscoverer(BundleContext context) { + this.context = context; + } + + public static class ServiceDeclarationImpl implements ServiceDeclaration { + private Bundle bundle; + private URL url; + private String className; + private Class javaClass; + private Map attributes; + + public ServiceDeclarationImpl(Bundle bundle, URL url, String className, Map attributes) { + super(); + this.bundle = bundle; + this.url = url; + this.className = className; + this.attributes = attributes; + } + + public Map getAttributes() { + return attributes; + } + + public String getClassName() { + return className; + } + + public Class loadClass() throws ClassNotFoundException { + if (className == null) { + return null; + } + if (javaClass == null) { + javaClass = loadClass(className); + } + return javaClass; + } + + public Class loadClass(String className) throws ClassNotFoundException { + return bundle.loadClass(className); + } + + public URL getLocation() { + return url; + } + + public URL getResource(final String name) { + return AccessController.doPrivileged(new PrivilegedAction() { + public URL run() { + return bundle.getResource(name); + } + }); + } + + public String toString() { + StringBuffer sb = new StringBuffer(); + sb.append("Bundle: ").append(EquinoxServiceDiscoverer.toString(bundle)); + sb.append(" Resource: ").append(url); + sb.append(" Attributes: ").append(attributes); + return sb.toString(); + } + + } + + private static String toString(Bundle b) { + StringBuffer sb = new StringBuffer(); + sb.append(b.getBundleId()).append(" ").append(b.getSymbolicName()); + int s = b.getState(); + if ((s & Bundle.UNINSTALLED) != 0) { + sb.append(" UNINSTALLED"); + } + if ((s & Bundle.INSTALLED) != 0) { + sb.append(" INSTALLED"); + } + if ((s & Bundle.RESOLVED) != 0) { + sb.append(" RESOLVED"); + } + if ((s & Bundle.STARTING) != 0) { + sb.append(" STARTING"); + } + if ((s & Bundle.STOPPING) != 0) { + sb.append(" STOPPING"); + } + if ((s & Bundle.ACTIVE) != 0) { + sb.append(" ACTIVE"); + } + return sb.toString(); + + } + + /** + * Parse a service declaration in the form class;attr=value,attr=value and + * return a map of attributes + * + * @param declaration + * @return a map of attributes + */ + protected static Map parseServiceDeclaration(String declaration) { + Map attributes = new HashMap(); + int index = declaration.indexOf(';'); + if (index != -1) { + attributes.put("class", declaration.substring(0, index).trim()); + declaration = declaration.substring(index); + } else { + int j = declaration.indexOf('='); + if (j == -1) { + attributes.put("class", declaration.trim()); + return attributes; + } else { + declaration = ";" + declaration; + } + } + StringTokenizer tokens = new StringTokenizer(declaration); + for (; tokens.hasMoreTokens();) { + String key = tokens.nextToken("=").substring(1).trim(); + if (key == null) + break; + String value = tokens.nextToken(",").substring(1).trim(); + if (value == null) + break; + attributes.put(key, value); + } + return attributes; + } + + @SuppressWarnings("unchecked") + public Set discover(String serviceName) { + boolean debug = logger.isLoggable(Level.FINE); + Set descriptors = new HashSet(); + + serviceName = "META-INF/services/" + serviceName; + + int index = serviceName.lastIndexOf('/'); + String path = serviceName.substring(0, index); + String file = serviceName.substring(index + 1); + + for (Bundle bundle : context.getBundles()) { + Enumeration urls = bundle.findEntries(path, file, false); + while (urls != null && urls.hasMoreElements()) { + final URL url = urls.nextElement(); + if (debug) { + logger.fine("Reading service provider file: " + url.toExternalForm()); + } + try { + // Allow privileged access to open URL stream. Add FilePermission to added to security + // policy file. + InputStream is; + try { + is = AccessController.doPrivileged(new PrivilegedExceptionAction() { + public InputStream run() throws IOException { + return url.openStream(); + } + }); + } catch (PrivilegedActionException e) { + throw (IOException)e.getException(); + } + BufferedReader reader = null; + try { + reader = new BufferedReader(new InputStreamReader(is)); + int count = 0; + while (true) { + String line = reader.readLine(); + if (line == null) + break; + line = line.trim(); + if (!line.startsWith("#") && !"".equals(line)) { + String reg = line.trim(); + if (debug) { + logger.fine("Registering service provider: " + reg); + } + + Map attributes = parseServiceDeclaration(reg); + String className = attributes.get("class"); + if (className == null) { + // Add a unique class name to prevent equals() from returning true + className = "_class_" + count; + count++; + } + ServiceDeclarationImpl descriptor = + new ServiceDeclarationImpl(bundle, url, className, attributes); + descriptors.add(descriptor); + + } + } + } finally { + if (reader != null) { + try { + reader.close(); + } catch (IOException e) { + // Ignore + } + } + } + } catch (IOException e) { + logger.log(Level.SEVERE, e.getMessage(), e); + } + } + } + return descriptors; + + } + +} diff --git a/java/sca/modules/extensibility-eclipse/src/test/java/org/apache/tuscany/sca/extensibility/equinox/EquinoxServiceDiscovererTestCase.java b/java/sca/modules/extensibility-eclipse/src/test/java/org/apache/tuscany/sca/extensibility/equinox/EquinoxServiceDiscovererTestCase.java new file mode 100644 index 0000000000..8ebe733450 --- /dev/null +++ b/java/sca/modules/extensibility-eclipse/src/test/java/org/apache/tuscany/sca/extensibility/equinox/EquinoxServiceDiscovererTestCase.java @@ -0,0 +1,144 @@ +/* + * 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.tuscany.sca.extensibility.equinox; + +import java.io.BufferedInputStream; +import java.io.File; +import java.io.FileInputStream; +import java.io.InputStream; +import java.lang.reflect.Method; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Set; +import java.util.jar.JarInputStream; +import java.util.jar.Manifest; + +import junit.framework.Assert; + +import org.apache.tuscany.sca.extensibility.ServiceDeclaration; +import org.eclipse.core.runtime.adaptor.EclipseStarter; +import org.junit.AfterClass; +import org.junit.BeforeClass; +import org.junit.Test; +import org.osgi.framework.Bundle; +import org.osgi.framework.BundleContext; + +/** + * + */ +public class EquinoxServiceDiscovererTestCase { + private static EquinoxServiceDiscoverer discoverer; + private static Bundle testBundle; + + private static String getState(Bundle b) { + StringBuffer sb = new StringBuffer(); + int s = b.getState(); + if ((s & Bundle.UNINSTALLED) != 0) { + sb.append("UNINSTALLED "); + } + if ((s & Bundle.INSTALLED) != 0) { + sb.append("INSTALLED "); + } + if ((s & Bundle.RESOLVED) != 0) { + sb.append("RESOLVED "); + } + if ((s & Bundle.STARTING) != 0) { + sb.append("STARTING "); + } + if ((s & Bundle.STOPPING) != 0) { + sb.append("STOPPING "); + } + if ((s & Bundle.ACTIVE) != 0) { + sb.append("ACTIVE "); + } + return sb.toString(); + + } + + /** + * @throws java.lang.Exception + */ + @BeforeClass + public static void setUpBeforeClass() throws Exception { + String args[] = {}; + Map props = new HashMap(); + EclipseStarter.setInitialProperties(props); + BundleContext context = EclipseStarter.startup(args, null); + + InputStream is = EquinoxServiceDiscovererTestCase.class.getResourceAsStream("/test-bundle.jar"); + testBundle = context.installBundle("test-bundle", is); + is.close(); + discoverer = new EquinoxServiceDiscoverer(context); + File dep = new File("target/test-classes/dependency"); + List bundles = new ArrayList(); + for (File f : dep.listFiles()) { + BufferedInputStream bis = new BufferedInputStream(new FileInputStream(f)); + bis.mark(8192); + JarInputStream jis = new JarInputStream(bis); + Manifest manifest = jis.getManifest(); + if (manifest == null || manifest.getMainAttributes().getValue("Bundle-Name") == null) { + bis.close(); + continue; + } + bis.reset(); + Bundle b = context.installBundle(f.getName(), bis); + System.out.println("Installed "+b.getSymbolicName() + " [" + getState(b) + "]"); + bundles.add(b); + is.close(); + } + for (Bundle b : bundles) { + b.start(); + System.out.println("Started "+b.getSymbolicName() + " [" + getState(b) + "]"); + // Get the Platform.getExtensionRegistry() + if ("org.eclipse.core.runtime".equals(b.getSymbolicName())) { + // The Platform class loaded by the bundle is different that the one + // on the classpath + Class cls = b.loadClass("org.eclipse.core.runtime.Platform"); + Method m = cls.getMethod("getExtensionRegistry"); + Object reg = m.invoke(cls); + System.out.println(reg); + } + } + } + + /** + * @throws java.lang.Exception + */ + @AfterClass + public static void tearDownAfterClass() throws Exception { + if (testBundle != null) { + // Uninstall the bundle to clean up the cache + testBundle.uninstall(); + } + EclipseStarter.shutdown(); + } + + @Test + public void testDiscovery() { + Set descriptors = + discoverer.discover("org.apache.tuscany.sca.endpointresolver.EndpointResolverFactory"); + Assert.assertEquals(1, descriptors.size()); + descriptors = discoverer.discover("notthere"); + Assert.assertEquals(0, descriptors.size()); + } + +} diff --git a/java/sca/modules/extensibility-eclipse/src/test/resources/dependency/app-1.0.0-v20070423.jar b/java/sca/modules/extensibility-eclipse/src/test/resources/dependency/app-1.0.0-v20070423.jar new file mode 100644 index 0000000000..41ed3dace0 Binary files /dev/null and b/java/sca/modules/extensibility-eclipse/src/test/resources/dependency/app-1.0.0-v20070423.jar differ diff --git a/java/sca/modules/extensibility-eclipse/src/test/resources/dependency/common-3.3.0-v20070426.jar b/java/sca/modules/extensibility-eclipse/src/test/resources/dependency/common-3.3.0-v20070426.jar new file mode 100644 index 0000000000..aca3f73bb3 Binary files /dev/null and b/java/sca/modules/extensibility-eclipse/src/test/resources/dependency/common-3.3.0-v20070426.jar differ diff --git a/java/sca/modules/extensibility-eclipse/src/test/resources/dependency/contenttype-3.2.100-v20070319.jar b/java/sca/modules/extensibility-eclipse/src/test/resources/dependency/contenttype-3.2.100-v20070319.jar new file mode 100644 index 0000000000..0f9e7cbd23 Binary files /dev/null and b/java/sca/modules/extensibility-eclipse/src/test/resources/dependency/contenttype-3.2.100-v20070319.jar differ diff --git a/java/sca/modules/extensibility-eclipse/src/test/resources/dependency/jobs-3.3.0-v20070423.jar b/java/sca/modules/extensibility-eclipse/src/test/resources/dependency/jobs-3.3.0-v20070423.jar new file mode 100644 index 0000000000..6183e2b8b0 Binary files /dev/null and b/java/sca/modules/extensibility-eclipse/src/test/resources/dependency/jobs-3.3.0-v20070423.jar differ diff --git a/java/sca/modules/extensibility-eclipse/src/test/resources/dependency/preferences-3.2.100-v20070522.jar b/java/sca/modules/extensibility-eclipse/src/test/resources/dependency/preferences-3.2.100-v20070522.jar new file mode 100644 index 0000000000..8ca9b2f63a Binary files /dev/null and b/java/sca/modules/extensibility-eclipse/src/test/resources/dependency/preferences-3.2.100-v20070522.jar differ diff --git a/java/sca/modules/extensibility-eclipse/src/test/resources/dependency/registry-3.3.0-v20070522.jar b/java/sca/modules/extensibility-eclipse/src/test/resources/dependency/registry-3.3.0-v20070522.jar new file mode 100644 index 0000000000..18bd4f831f Binary files /dev/null and b/java/sca/modules/extensibility-eclipse/src/test/resources/dependency/registry-3.3.0-v20070522.jar differ diff --git a/java/sca/modules/extensibility-eclipse/src/test/resources/dependency/runtime-3.3.100-v20070530.jar b/java/sca/modules/extensibility-eclipse/src/test/resources/dependency/runtime-3.3.100-v20070530.jar new file mode 100644 index 0000000000..aede6bbc3e Binary files /dev/null and b/java/sca/modules/extensibility-eclipse/src/test/resources/dependency/runtime-3.3.100-v20070530.jar differ diff --git a/java/sca/modules/extensibility-eclipse/src/test/resources/test-bundle.jar b/java/sca/modules/extensibility-eclipse/src/test/resources/test-bundle.jar new file mode 100644 index 0000000000..a4dc54170e Binary files /dev/null and b/java/sca/modules/extensibility-eclipse/src/test/resources/test-bundle.jar differ diff --git a/java/sca/modules/extensibility-osgi/LICENSE b/java/sca/modules/extensibility-osgi/LICENSE new file mode 100644 index 0000000000..6e529a25c4 --- /dev/null +++ b/java/sca/modules/extensibility-osgi/LICENSE @@ -0,0 +1,205 @@ + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed 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. + + + diff --git a/java/sca/modules/extensibility-osgi/NOTICE b/java/sca/modules/extensibility-osgi/NOTICE new file mode 100644 index 0000000000..65c52d01c7 --- /dev/null +++ b/java/sca/modules/extensibility-osgi/NOTICE @@ -0,0 +1,5 @@ +Copyright (c) 2005 - 2008 The Apache Software Foundation + +This product includes software developed by +The Apache Software Foundation (http://www.apache.org/). + diff --git a/java/sca/modules/extensibility-osgi/pom.xml b/java/sca/modules/extensibility-osgi/pom.xml new file mode 100644 index 0000000000..0109b1430e --- /dev/null +++ b/java/sca/modules/extensibility-osgi/pom.xml @@ -0,0 +1,66 @@ + + + + 4.0.0 + + org.apache.tuscany.sca + tuscany-modules + 1.4-SNAPSHOT + ../pom.xml + + tuscany-extensibility-osgi + Apache Tuscany SCA Extensibility for OSGi + + + org.apache.tuscany.sca + tuscany-extensibility + 1.4-SNAPSHOT + + + org.apache.felix + org.osgi.core + 1.0.1 + + + org.apache.felix + org.apache.felix.framework + 1.0.4 + test + + + + + + org.apache.felix + maven-bundle-plugin + + + ${tuscany.version} + + org.apache.tuscany.sca.extensibility + + ${pom.name} + org.apache.tuscany.sca.extensibility.osgi* + + + + + + \ No newline at end of file diff --git a/java/sca/modules/extensibility-osgi/src/main/java/org/apache/tuscany/sca/extensibility/osgi/OSGiServiceDiscoverer.java b/java/sca/modules/extensibility-osgi/src/main/java/org/apache/tuscany/sca/extensibility/osgi/OSGiServiceDiscoverer.java new file mode 100644 index 0000000000..240ef6bcd5 --- /dev/null +++ b/java/sca/modules/extensibility-osgi/src/main/java/org/apache/tuscany/sca/extensibility/osgi/OSGiServiceDiscoverer.java @@ -0,0 +1,252 @@ +/* + * 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.tuscany.sca.extensibility.osgi; + +import java.io.BufferedReader; +import java.io.IOException; +import java.io.InputStream; +import java.io.InputStreamReader; +import java.net.URL; +import java.security.AccessController; +import java.security.PrivilegedAction; +import java.security.PrivilegedActionException; +import java.security.PrivilegedExceptionAction; +import java.util.Enumeration; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Map; +import java.util.Set; +import java.util.StringTokenizer; +import java.util.logging.Level; +import java.util.logging.Logger; + +import org.apache.tuscany.sca.extensibility.ServiceDeclaration; +import org.apache.tuscany.sca.extensibility.ServiceDiscoverer; +import org.osgi.framework.Bundle; +import org.osgi.framework.BundleContext; + +/** + * The ServiceDiscoverer that find META-INF/services/... in installed bundles + */ +public class OSGiServiceDiscoverer implements ServiceDiscoverer { + private static final Logger logger = Logger.getLogger(OSGiServiceDiscoverer.class.getName()); + private BundleContext context; + + public OSGiServiceDiscoverer(BundleContext context) { + this.context = context; + } + + public static class ServiceDeclarationImpl implements ServiceDeclaration { + private Bundle bundle; + private URL url; + private String className; + private Class javaClass; + private Map attributes; + + public ServiceDeclarationImpl(Bundle bundle, URL url, String className, Map attributes) { + super(); + this.bundle = bundle; + this.url = url; + this.className = className; + this.attributes = attributes; + } + + public Map getAttributes() { + return attributes; + } + + public String getClassName() { + return className; + } + + public Class loadClass() throws ClassNotFoundException { + if (className == null) { + return null; + } + if (javaClass == null) { + javaClass = loadClass(className); + } + return javaClass; + } + + public Class loadClass(String className) throws ClassNotFoundException { + return bundle.loadClass(className); + } + + public URL getLocation() { + return url; + } + + public URL getResource(final String name) { + return AccessController.doPrivileged(new PrivilegedAction() { + public URL run() { + return bundle.getResource(name); + } + }); + } + + public String toString() { + StringBuffer sb = new StringBuffer(); + sb.append("Bundle: ").append(OSGiServiceDiscoverer.toString(bundle)); + sb.append(" Resource: ").append(url); + sb.append(" Attributes: ").append(attributes); + return sb.toString(); + } + + } + + private static String toString(Bundle b) { + StringBuffer sb = new StringBuffer(); + sb.append(b.getBundleId()).append(" ").append(b.getSymbolicName()); + int s = b.getState(); + if ((s & Bundle.UNINSTALLED) != 0) { + sb.append(" UNINSTALLED"); + } + if ((s & Bundle.INSTALLED) != 0) { + sb.append(" INSTALLED"); + } + if ((s & Bundle.RESOLVED) != 0) { + sb.append(" RESOLVED"); + } + if ((s & Bundle.STARTING) != 0) { + sb.append(" STARTING"); + } + if ((s & Bundle.STOPPING) != 0) { + sb.append(" STOPPING"); + } + if ((s & Bundle.ACTIVE) != 0) { + sb.append(" ACTIVE"); + } + return sb.toString(); + + } + + /** + * Parse a service declaration in the form class;attr=value,attr=value and + * return a map of attributes + * + * @param declaration + * @return a map of attributes + */ + protected static Map parseServiceDeclaration(String declaration) { + Map attributes = new HashMap(); + int index = declaration.indexOf(';'); + if (index != -1) { + attributes.put("class", declaration.substring(0, index).trim()); + declaration = declaration.substring(index); + } else { + int j = declaration.indexOf('='); + if (j == -1) { + attributes.put("class", declaration.trim()); + return attributes; + } else { + declaration = ";" + declaration; + } + } + StringTokenizer tokens = new StringTokenizer(declaration); + for (; tokens.hasMoreTokens();) { + String key = tokens.nextToken("=").substring(1).trim(); + if (key == null) + break; + String value = tokens.nextToken(",").substring(1).trim(); + if (value == null) + break; + attributes.put(key, value); + } + return attributes; + } + + @SuppressWarnings("unchecked") + public Set discover(String serviceName) { + boolean debug = logger.isLoggable(Level.FINE); + Set descriptors = new HashSet(); + + serviceName = "META-INF/services/" + serviceName; + + int index = serviceName.lastIndexOf('/'); + String path = serviceName.substring(0, index); + String file = serviceName.substring(index + 1); + + for (Bundle bundle : context.getBundles()) { + Enumeration urls = bundle.findEntries(path, file, false); + while (urls != null && urls.hasMoreElements()) { + final URL url = urls.nextElement(); + if (debug) { + logger.fine("Reading service provider file: " + url.toExternalForm()); + } + try { + // Allow privileged access to open URL stream. Add FilePermission to added to security + // policy file. + InputStream is; + try { + is = AccessController.doPrivileged(new PrivilegedExceptionAction() { + public InputStream run() throws IOException { + return url.openStream(); + } + }); + } catch (PrivilegedActionException e) { + throw (IOException)e.getException(); + } + BufferedReader reader = null; + try { + reader = new BufferedReader(new InputStreamReader(is)); + int count = 0; + while (true) { + String line = reader.readLine(); + if (line == null) + break; + line = line.trim(); + if (!line.startsWith("#") && !"".equals(line)) { + String reg = line.trim(); + if (debug) { + logger.fine("Registering service provider: " + reg); + } + + Map attributes = parseServiceDeclaration(reg); + String className = attributes.get("class"); + if (className == null) { + // Add a unique class name to prevent equals() from returning true + className = "_class_" + count; + count++; + } + ServiceDeclarationImpl descriptor = + new ServiceDeclarationImpl(bundle, url, className, attributes); + descriptors.add(descriptor); + } + } + } finally { + if (reader != null) { + try { + reader.close(); + } catch (IOException e) { + // Ignore + } + } + } + } catch (IOException e) { + logger.log(Level.SEVERE, e.getMessage(), e); + } + } + } + return descriptors; + + } + +} diff --git a/java/sca/modules/extensibility-osgi/src/test/java/org/apache/tuscany/sca/extensibility/osgi/OSGiServiceDiscovererTestCase.java b/java/sca/modules/extensibility-osgi/src/test/java/org/apache/tuscany/sca/extensibility/osgi/OSGiServiceDiscovererTestCase.java new file mode 100644 index 0000000000..a5cb794d87 --- /dev/null +++ b/java/sca/modules/extensibility-osgi/src/test/java/org/apache/tuscany/sca/extensibility/osgi/OSGiServiceDiscovererTestCase.java @@ -0,0 +1,104 @@ +/* + * 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.tuscany.sca.extensibility.osgi; + +import java.io.InputStream; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Set; + +import junit.framework.Assert; + +import org.apache.felix.framework.Felix; +import org.apache.felix.framework.cache.BundleCache; +import org.apache.felix.framework.util.FelixConstants; +import org.apache.tuscany.sca.extensibility.ServiceDeclaration; +import org.junit.AfterClass; +import org.junit.BeforeClass; +import org.junit.Test; +import org.osgi.framework.Bundle; +import org.osgi.framework.BundleActivator; +import org.osgi.framework.BundleContext; +import org.osgi.framework.Constants; + +/** + * + */ +public class OSGiServiceDiscovererTestCase { + private static Felix felix; + private static OSGiServiceDiscoverer discoverer; + private static Bundle testBundle; + + /** + * @throws java.lang.Exception + */ + @BeforeClass + public static void setUpBeforeClass() throws Exception { + // Create a configuration property map. + Map configMap = new HashMap(); + // Configure the Felix instance to be embedded. + configMap.put(FelixConstants.EMBEDDED_EXECUTION_PROP, "true"); + // Add core OSGi packages to be exported from the class path + // via the system bundle. + configMap.put(Constants.FRAMEWORK_SYSTEMPACKAGES, + "org.osgi.framework; version=1.3.0," + "org.osgi.service.packageadmin; version=1.2.0," + + "org.osgi.service.startlevel; version=1.0.0," + + "org.osgi.service.url; version=1.0.0"); + // Explicitly specify the directory to use for caching bundles. + configMap.put(BundleCache.CACHE_PROFILE_DIR_PROP, "target/.felix"); + List list = new ArrayList(); + + // Now create an instance of the framework with + // our configuration properties and activator. + Felix felix = new Felix(configMap, list); + + // Now start Felix instance. + felix.start(); + BundleContext context = felix.getBundleContext(); + InputStream is = OSGiServiceDiscovererTestCase.class.getResourceAsStream("/test-bundle.jar"); + testBundle = context.installBundle("test-bundle", is); + is.close(); + discoverer = new OSGiServiceDiscoverer(context); + } + + /** + * @throws java.lang.Exception + */ + @AfterClass + public static void tearDownAfterClass() throws Exception { + if (felix != null) { + // Uninstall the bundle to clean up the cache + testBundle.uninstall(); + felix.stop(); + } + } + + @Test + public void testDiscovery() { + Set descriptors = + discoverer.discover("org.apache.tuscany.sca.endpointresolver.EndpointResolverFactory"); + Assert.assertEquals(1, descriptors.size()); + descriptors = discoverer.discover("notthere"); + Assert.assertEquals(0, descriptors.size()); + } + +} diff --git a/java/sca/modules/extensibility-osgi/src/test/resources/test-bundle.jar b/java/sca/modules/extensibility-osgi/src/test/resources/test-bundle.jar new file mode 100644 index 0000000000..a4dc54170e Binary files /dev/null and b/java/sca/modules/extensibility-osgi/src/test/resources/test-bundle.jar differ diff --git a/java/sca/modules/extensibility/src/main/java/org/apache/tuscany/sca/extensibility/ClasspathServiceDiscover.java b/java/sca/modules/extensibility/src/main/java/org/apache/tuscany/sca/extensibility/ClasspathServiceDiscover.java new file mode 100644 index 0000000000..c83a7d9172 --- /dev/null +++ b/java/sca/modules/extensibility/src/main/java/org/apache/tuscany/sca/extensibility/ClasspathServiceDiscover.java @@ -0,0 +1,237 @@ +/* + * 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.tuscany.sca.extensibility; + +import java.io.BufferedReader; +import java.io.IOException; +import java.io.InputStream; +import java.io.InputStreamReader; +import java.lang.ref.WeakReference; +import java.net.URL; +import java.security.AccessController; +import java.security.PrivilegedAction; +import java.security.PrivilegedActionException; +import java.security.PrivilegedExceptionAction; +import java.util.Collections; +import java.util.HashMap; +import java.util.HashSet; +import java.util.List; +import java.util.Map; +import java.util.Set; +import java.util.StringTokenizer; +import java.util.logging.Level; +import java.util.logging.Logger; + +/** + * + */ +public class ClasspathServiceDiscover implements ServiceDiscoverer { + + public class ServiceDeclarationImpl implements ServiceDeclaration { + private URL url; + private String className; + private Class javaClass; + private Map attributes; + + public ServiceDeclarationImpl(URL url, String className, Map attributes) { + super(); + this.url = url; + this.className = className; + this.attributes = attributes; + } + + public Map getAttributes() { + return attributes; + } + + public String getClassName() { + return className; + } + + public URL getLocation() { + return url; + } + + public Class loadClass() throws ClassNotFoundException { + if (className == null) { + return null; + } + if (javaClass == null) { + javaClass = loadClass(className); + } + return javaClass; + } + + public Class loadClass(String className) throws ClassNotFoundException { + return getClassLoader().loadClass(className); + } + + private ClasspathServiceDiscover getOuterType() { + return ClasspathServiceDiscover.this; + } + + public String toString() { + StringBuffer sb = new StringBuffer(); + sb.append("ClassLoader: ").append(getClassLoader()); + sb.append(" Attributes: ").append(attributes); + return sb.toString(); + } + + public URL getResource(final String name) { + return AccessController.doPrivileged(new PrivilegedAction() { + public URL run() { + return getClassLoader().getResource(name); + } + }); + } + + } + + private WeakReference classLoaderReference; + private static final Logger logger = Logger.getLogger(ClasspathServiceDiscover.class.getName()); + + public ClasspathServiceDiscover() { + // ClassLoader classLoader = Thread.currentThread().getContextClassLoader(); + ClassLoader classLoader = ClasspathServiceDiscover.class.getClassLoader(); + this.classLoaderReference = new WeakReference(classLoader); + } + + public ClasspathServiceDiscover(ClassLoader classLoader) { + this.classLoaderReference = new WeakReference(classLoader); + } + + protected List getResources(final String name) throws IOException { + try { + return AccessController.doPrivileged(new PrivilegedExceptionAction>() { + public List run() throws IOException { + return Collections.list(getClassLoader().getResources(name)); + } + }); + } catch (PrivilegedActionException e) { + throw (IOException)e.getException(); + } + } + + private ClassLoader getClassLoader() { + return classLoaderReference.get(); + } + + /** + * Parse a service declaration in the form class;attr=value,attr=value and + * return a map of attributes + * + * @param declaration + * @return a map of attributes + */ + protected static Map parseServiceDeclaration(String declaration) { + Map attributes = new HashMap(); + int index = declaration.indexOf(';'); + if (index != -1) { + attributes.put("class", declaration.substring(0, index).trim()); + declaration = declaration.substring(index); + } else { + int j = declaration.indexOf('='); + if (j == -1) { + attributes.put("class", declaration.trim()); + return attributes; + } else { + declaration = ";" + declaration; + } + } + StringTokenizer tokens = new StringTokenizer(declaration); + for (; tokens.hasMoreTokens();) { + String key = tokens.nextToken("=").substring(1).trim(); + if (key == null) + break; + String value = tokens.nextToken(",").substring(1).trim(); + if (value == null) + break; + attributes.put(key, value); + } + return attributes; + } + + public Set discover(String serviceName) { + Set descriptors = new HashSet(); + + String name = "META-INF/services/" + serviceName; + boolean debug = logger.isLoggable(Level.FINE); + try { + for (final URL url : getResources(name)) { + if (debug) { + logger.fine("Reading service provider file: " + url.toExternalForm()); + } + + // Allow privileged access to open URL stream. Add FilePermission to added to security + // policy file. + InputStream is; + try { + is = AccessController.doPrivileged(new PrivilegedExceptionAction() { + public InputStream run() throws IOException { + return url.openStream(); + } + }); + } catch (PrivilegedActionException e) { + throw (IOException)e.getException(); + } + BufferedReader reader = null; + try { + reader = new BufferedReader(new InputStreamReader(is)); + int count = 0; + while (true) { + String line = reader.readLine(); + if (line == null) + break; + line = line.trim(); + if (!line.startsWith("#") && !"".equals(line)) { + String reg = line.trim(); + if (debug) { + logger.fine("Registering service provider: " + reg); + } + + Map attributes = parseServiceDeclaration(reg); + String className = attributes.get("class"); + if (className == null) { + // Add a unique class name to prevent equals() from returning true + className = "_class_" + count; + count++; + } + ServiceDeclarationImpl descriptor = new ServiceDeclarationImpl(url, className, attributes); + descriptors.add(descriptor); + } + } + } finally { + if (reader != null) { + try { + reader.close(); + } catch (IOException e) { + // Ignore + } + } + } + } + } catch (IOException e) { + logger.log(Level.SEVERE, e.getMessage(), e); + } + return descriptors; + + } + +} diff --git a/java/sca/modules/extensibility/src/main/java/org/apache/tuscany/sca/extensibility/ServiceDeclaration.java b/java/sca/modules/extensibility/src/main/java/org/apache/tuscany/sca/extensibility/ServiceDeclaration.java index 4b25f2adc2..403b6aa7a7 100644 --- a/java/sca/modules/extensibility/src/main/java/org/apache/tuscany/sca/extensibility/ServiceDeclaration.java +++ b/java/sca/modules/extensibility/src/main/java/org/apache/tuscany/sca/extensibility/ServiceDeclaration.java @@ -19,7 +19,6 @@ package org.apache.tuscany.sca.extensibility; -import java.lang.ref.WeakReference; import java.net.URL; import java.util.Map; @@ -30,107 +29,40 @@ import java.util.Map; * * @version $Rev$ $Date$ */ -public class ServiceDeclaration { - - private WeakReference classLoader; - - private String className; - - private Map attributes; - - /** - * Service declaration constructor - * - * @param className Service implementation class name - * @param classLoader ClassLoader corresponding to this service - * implementation - * @param attributes Optional attributes for this service declaration - */ - public ServiceDeclaration(String className, ClassLoader classLoader, Map attributes) { - - this.className = className; - this.classLoader = new WeakReference(classLoader); - this.attributes = attributes; - } - +public interface ServiceDeclaration { /** - * Load this service implementation class - * - * @return Class + * Load a java class in the same context as the service definition + * @param className The class name + * @return The loaded class * @throws ClassNotFoundException */ - @SuppressWarnings("unchecked") - public Class loadClass() throws ClassNotFoundException { - - return Class.forName(className, true, classLoader.get()); - } - + Class loadClass(String className) throws ClassNotFoundException; /** - * Load another class using the ClassLoader of this service implementation - * - * @param anotherClassName - * @return Class - * @throws ClassNotFoundException + * Get the java class for the service impl + * @return The java class */ - public Class loadClass(String anotherClassName) throws ClassNotFoundException { - - return Class.forName(anotherClassName, true, classLoader.get()); - } - - /** - * Return the resource corresponding to this service implementation class - * - * @return resource URL - */ - public URL getResource() { - return classLoader.get().getResource(className); - } - + Class loadClass() throws ClassNotFoundException; /** - * ClassLoader associated with this service declaration - * - * @return ClassLoader + * Get all attributes (name=value pairs) defined for the given entry + * @return All attributes keyed by name */ - public ClassLoader getClassLoader() { - return classLoader.get(); - } - + Map getAttributes(); + + URL getLocation(); + + String getClassName(); + + URL getResource(String name); + /** - * Service implementation class corresponding to this declaration - * - * @return The Service implementation class corresponding to this declaration + * The service descriptor might be hashed + * @param obj Another object + * @return */ - public String getClassName() { - return className; - } - + boolean equals(Object obj); /** - * Attributes specified for this declaration - * - * @return attributes + * The service descriptor might be hashed + * @return */ - public Map getAttributes() { - return attributes; - } - - /** - * Equals method used to ensure that each service declaration is stored only - * once in a set of declarations. - */ - @Override - public boolean equals(Object o) { - if (!(o instanceof ServiceDeclaration)) - return false; - ServiceDeclaration s = (ServiceDeclaration)o; - if (!className.equals(s.className)) - return false; - else if (!classLoader.equals(s.classLoader)) - return false; - else if (attributes == null) - return s.attributes == null; - else - return attributes.equals(s.attributes); - - } - + int hashCode(); } diff --git a/java/sca/modules/extensibility/src/main/java/org/apache/tuscany/sca/extensibility/ServiceDiscoverer.java b/java/sca/modules/extensibility/src/main/java/org/apache/tuscany/sca/extensibility/ServiceDiscoverer.java new file mode 100644 index 0000000000..31f2cf600e --- /dev/null +++ b/java/sca/modules/extensibility/src/main/java/org/apache/tuscany/sca/extensibility/ServiceDiscoverer.java @@ -0,0 +1,34 @@ +/* + * 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.tuscany.sca.extensibility; + +import java.util.Set; + +/** + * + */ +public interface ServiceDiscoverer { + /** + * Discover the service descriptors by name + * @param serviceName + * @return A set of service descriptors + */ + Set discover(String serviceName); +} diff --git a/java/sca/modules/extensibility/src/main/java/org/apache/tuscany/sca/extensibility/ServiceDiscovery.java b/java/sca/modules/extensibility/src/main/java/org/apache/tuscany/sca/extensibility/ServiceDiscovery.java index 45a4494f24..412774c83b 100644 --- a/java/sca/modules/extensibility/src/main/java/org/apache/tuscany/sca/extensibility/ServiceDiscovery.java +++ b/java/sca/modules/extensibility/src/main/java/org/apache/tuscany/sca/extensibility/ServiceDiscovery.java @@ -19,23 +19,9 @@ package org.apache.tuscany.sca.extensibility; -import java.io.BufferedReader; import java.io.IOException; -import java.io.InputStream; -import java.io.InputStreamReader; -import java.net.URL; -import java.security.AccessController; -import java.security.PrivilegedActionException; -import java.security.PrivilegedExceptionAction; -import java.util.ArrayList; -import java.util.Collections; -import java.util.HashMap; import java.util.HashSet; -import java.util.Hashtable; -import java.util.Map; import java.util.Set; -import java.util.StringTokenizer; -import java.util.logging.Level; import java.util.logging.Logger; /** @@ -50,9 +36,10 @@ import java.util.logging.Logger; public class ServiceDiscovery { private static final Logger logger = Logger.getLogger(ServiceDiscovery.class.getName()); - private static ServiceDiscovery instance; + private final static ServiceDiscovery instance = new ServiceDiscovery(); - private HashSet registeredClassLoaders; + private static ServiceDiscoverer discoverer; + private Set registeredClassLoaders = new HashSet(); /** * Get an instance of Service discovery, one instance is created per @@ -61,15 +48,29 @@ public class ServiceDiscovery { * @return */ public static ServiceDiscovery getInstance() { - - if (instance == null) { - instance = new ServiceDiscovery(); - instance.registeredClassLoaders = new HashSet(); - instance.registeredClassLoaders.add(ServiceDiscovery.class.getClassLoader()); - } +// +// if (instance == null) { +// instance = new ServiceDiscovery(); +// instance.registeredClassLoaders = new HashSet(); +// instance.registeredClassLoaders.add(ServiceDiscovery.class.getClassLoader()); +// } return instance; } - + + public static ServiceDiscoverer getServiceDiscoverer() { + if (discoverer == null) { + discoverer = new ClasspathServiceDiscover(); + } + return discoverer; + } + + public static void setServiceDiscoverer(ServiceDiscoverer sd) { + if (discoverer != null) { + throw new IllegalStateException("The ServiceDiscoverer cannot be reset"); + } + discoverer = sd; + } + /** * Register a ClassLoader with this discovery mechanism. Tuscany extension * ClassLoaders are registered here. @@ -96,14 +97,10 @@ public class ServiceDiscovery { * @return set of service declarations * @throws IOException */ - public synchronized Set getServiceDeclarations(String name) throws IOException { - - Set classSet = new HashSet(); - - for (ClassLoader classLoader : registeredClassLoaders) { - getServiceClasses(classLoader, name, classSet, true); - } - return classSet; + public Set getServiceDeclarations(String name) throws IOException { + // Set classSet = new HashSet(); + Set services = getServiceDiscoverer().discover(name); + return services; } /** @@ -126,185 +123,55 @@ public class ServiceDiscovery { * @throws IOException * @throws ClassNotFoundException */ - public synchronized Class loadFirstServiceClass(Class serviceInterface) throws IOException, ClassNotFoundException { + public Class loadFirstServiceClass(Class serviceInterface) throws IOException, ClassNotFoundException { + Set services = getServiceDiscoverer().discover(serviceInterface.getName()); + if(services.isEmpty()) { + return null; + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - Set classSet = new HashSet(); - for (ClassLoader classLoader : registeredClassLoaders) { - getServiceClasses(classLoader, serviceInterface.getName(), classSet, false); - if (classSet.size() > 0) - break; - } - if (classSet.size() > 0) - return classSet.iterator().next().loadClass(); - else - return null; - } - /** - * Returns a unique list of resource URLs of name META-INF/services/ - * Each URL is associated with the first ClassLoader that it was visible - * from - * - * @param name Name of resource - * @return Table of URLs with associated ClassLoaders - * @throws IOException - */ - public synchronized Hashtable> getServiceResources(final String name) throws IOException { - - Hashtable> resourceTable = new Hashtable>(); - - HashSet allURLs = new HashSet(); - for (final ClassLoader classLoader : registeredClassLoaders) { - HashSet urls = new HashSet(); - resourceTable.put(classLoader, urls); - boolean debug = logger.isLoggable(Level.FINE); - if (debug) { - logger.fine("Discovering service resources using class loader " + classLoader); - } - // Allow privileged access to read META-INF/services/*. Add FilePermission to added to security policy file. - ArrayList urlList; - try { - // FIXME J2 Security - promote this to callers of this method - urlList = AccessController.doPrivileged(new PrivilegedExceptionAction>() { - public ArrayList run() throws IOException { - return Collections.list(classLoader.getResources("META-INF/services/" + name)); - } - }); - } catch (PrivilegedActionException e) { - throw (IOException)e.getException(); - } - - for (URL url : urlList) { - if (allURLs.contains(url)) - continue; - urls.add(url); - } - allURLs.addAll(urls); - } - return resourceTable; - } - /** - * Parse a service declaration in the form class;attr=value,attr=value and - * return a map of attributes - * - * @param declaration - * @return a map of attributes - */ - private Map parseServiceDeclaration(String declaration) { - Map attributes = new HashMap(); - int index = declaration.indexOf(';'); - if (index != -1) { - attributes.put("class", declaration.substring(0, index).trim()); - declaration = declaration.substring(index); - } else { - int j = declaration.indexOf('='); - if (j == -1) { - attributes.put("class", declaration.trim()); - return attributes; - } else { - declaration = ";" + declaration; - } - } - StringTokenizer tokens = new StringTokenizer(declaration); - for (; tokens.hasMoreTokens();) { - String key = tokens.nextToken("=").substring(1).trim(); - if (key == null) - break; - String value = tokens.nextToken(",").substring(1).trim(); - if (value == null) - break; - attributes.put(key, value); - } - return attributes; - } - /** - * Load the service class whose name specified in a configuration file - * - * @param classLoader - * @param name The name of the service class - * @param classSet Populate this set with classes extends/implements the - * service class - * @throws IOException - */ - private void getServiceClasses(final ClassLoader classLoader, - final String name, - Set classSet, - boolean findAllClasses) throws IOException { - - boolean debug = logger.isLoggable(Level.FINE); - if (debug) { - logger.fine("Discovering service providers using class loader " + classLoader); - } - // Allow privileged access to read META-INF/services/*. Add FilePermission to added to - // security policy file. - ArrayList urlList; - try { - urlList = AccessController.doPrivileged(new PrivilegedExceptionAction>() { - public ArrayList run() throws IOException { - return Collections.list(classLoader.getResources("META-INF/services/" + name)); - } - }); - } catch (PrivilegedActionException e) { - throw (IOException)e.getException(); - } - - for (final URL url : urlList) { - if (debug) { - logger.fine("Reading service provider file: " + url.toExternalForm()); - } - - // Allow privileged access to open URL stream. Add FilePermission to added to security - // policy file. - InputStream is; - try { - is = AccessController.doPrivileged(new PrivilegedExceptionAction() { - public InputStream run() throws IOException { - return url.openStream(); - } - }); - } catch (PrivilegedActionException e) { - throw (IOException)e.getException(); - } - BufferedReader reader = null; - try { - reader = new BufferedReader(new InputStreamReader(is)); - while (true) { - String line = reader.readLine(); - if (line == null) - break; - line = line.trim(); - if (!line.startsWith("#") && !"".equals(line)) { - String reg = line.trim(); - if (debug) { - logger.fine("Registering service provider: " + reg); - } - - Map attributes = parseServiceDeclaration(reg); - String className = attributes.get("class"); - ServiceDeclaration serviceClass = new ServiceDeclaration(className, classLoader, attributes); - classSet.add(serviceClass); - - if (!findAllClasses) - break; - } - } - } finally { - if (reader != null) - reader.close(); - if (is != null) { - try { - is.close(); - } catch (IOException ioe) { - } - } - } - if (!findAllClasses && classSet.size() > 0) - break; } + return services.iterator().next().loadClass(); } } diff --git a/java/sca/modules/extensibility/src/test/java/org/apache/tuscany/sca/extensibility/ClasspathServiceDiscovererTestCase.java b/java/sca/modules/extensibility/src/test/java/org/apache/tuscany/sca/extensibility/ClasspathServiceDiscovererTestCase.java new file mode 100644 index 0000000000..cf203cce7a --- /dev/null +++ b/java/sca/modules/extensibility/src/test/java/org/apache/tuscany/sca/extensibility/ClasspathServiceDiscovererTestCase.java @@ -0,0 +1,61 @@ +/* + * 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.tuscany.sca.extensibility; + +import java.util.Set; + +import junit.framework.Assert; + +import org.junit.AfterClass; +import org.junit.BeforeClass; +import org.junit.Test; + +/** + * Test Case for ClasspathServiceDiscover + */ +public class ClasspathServiceDiscovererTestCase { + private static ClasspathServiceDiscover discover; + + /** + * @throws java.lang.Exception + */ + @BeforeClass + public static void setUpBeforeClass() throws Exception { + discover = new ClasspathServiceDiscover(ClasspathServiceDiscover.class.getClassLoader()); + } + + @Test + public void testDiscovery() { + Set discriptors = + discover.discover("org.apache.tuscany.sca.core.ModuleActivatorExtensionPoint"); + Assert.assertEquals(1, discriptors.size()); + discriptors = + discover.discover("notthere"); + Assert.assertEquals(0, discriptors.size()); + } + + /** + * @throws java.lang.Exception + */ + @AfterClass + public static void tearDownAfterClass() throws Exception { + } + +} diff --git a/java/sca/modules/extension-helper/src/main/java/org/apache/tuscany/sca/extension/helper/impl/DiscoveryUtils.java b/java/sca/modules/extension-helper/src/main/java/org/apache/tuscany/sca/extension/helper/impl/DiscoveryUtils.java index 9d772c8ae8..720d409a44 100644 --- a/java/sca/modules/extension-helper/src/main/java/org/apache/tuscany/sca/extension/helper/impl/DiscoveryUtils.java +++ b/java/sca/modules/extension-helper/src/main/java/org/apache/tuscany/sca/extension/helper/impl/DiscoveryUtils.java @@ -38,23 +38,24 @@ import org.apache.tuscany.sca.extensibility.ServiceDiscovery; */ public class DiscoveryUtils { - @SuppressWarnings("unchecked") + @SuppressWarnings("unchecked") public static List discoverActivators(Class activatorClass, ExtensionPointRegistry registry) { List activators; - try { - Set activatorClasses = ServiceDiscovery.getInstance().getServiceDeclarations(activatorClass); - activators = new ArrayList(); - for (ServiceDeclaration declaration : activatorClasses) { - try { - Class c = (Class)declaration.loadClass(); - activators.add(c.cast(instantiateActivator(c, registry))); - } catch (Throwable e) { - e.printStackTrace(); // TODO: log - } - } - } catch (IOException e) { - throw new RuntimeException(e); - } + try { + Set activatorClasses = + ServiceDiscovery.getInstance().getServiceDeclarations(activatorClass); + activators = new ArrayList(); + for (ServiceDeclaration declaration : activatorClasses) { + try { + Class c = (Class)declaration.loadClass(); + activators.add(c.cast(instantiateActivator(c, registry))); + } catch (Throwable e) { + e.printStackTrace(); // TODO: log + } + } + } catch (IOException e) { + throw new RuntimeException(e); + } return activators; } @@ -63,18 +64,18 @@ public class DiscoveryUtils { if (cs.length != 1) { throw new RuntimeException("Activator must have only one constructors"); } - + Class[] paramTypes = cs[0].getParameterTypes(); Object[] extensions = new Object[paramTypes.length]; - for (int i=0; i< paramTypes.length; i++) { + for (int i = 0; i < paramTypes.length; i++) { if ("org.apache.tuscany.sca.host.http.ServletHost".equals(paramTypes[i].getName())) { extensions[i] = getServletHost(registry); } else { extensions[i] = registry.getExtensionPoint(paramTypes[i]); } } - + try { return cs[0].newInstance(extensions); @@ -109,5 +110,4 @@ public class DiscoveryUtils { } } - } diff --git a/java/sca/modules/implementation-java-runtime/src/main/java/org/apache/tuscany/sca/implementation/java/invocation/JavaImplementationProvider.java b/java/sca/modules/implementation-java-runtime/src/main/java/org/apache/tuscany/sca/implementation/java/invocation/JavaImplementationProvider.java index 821a0999af..e9eea607c9 100644 --- a/java/sca/modules/implementation-java-runtime/src/main/java/org/apache/tuscany/sca/implementation/java/invocation/JavaImplementationProvider.java +++ b/java/sca/modules/implementation-java-runtime/src/main/java/org/apache/tuscany/sca/implementation/java/invocation/JavaImplementationProvider.java @@ -21,7 +21,6 @@ package org.apache.tuscany.sca.implementation.java.invocation; import java.lang.reflect.Method; import java.util.List; -import java.util.Map; import org.apache.tuscany.sca.assembly.Service; import org.apache.tuscany.sca.context.ComponentContextFactory; @@ -64,7 +63,7 @@ public class JavaImplementationProvider implements ScopedImplementationProvider JavaPropertyValueObjectFactory propertyValueObjectFactory, ComponentContextFactory componentContextFactory, RequestContextFactory requestContextFactory, - Map> policyHandlerClassNames) { + List policyHandlerClassNames) { super(); this.implementation = implementation; this.requestContextFactory = requestContextFactory; diff --git a/java/sca/modules/implementation-java-runtime/src/main/java/org/apache/tuscany/sca/implementation/java/invocation/JavaImplementationProviderFactory.java b/java/sca/modules/implementation-java-runtime/src/main/java/org/apache/tuscany/sca/implementation/java/invocation/JavaImplementationProviderFactory.java index fd0fc94770..9b78439012 100644 --- a/java/sca/modules/implementation-java-runtime/src/main/java/org/apache/tuscany/sca/implementation/java/invocation/JavaImplementationProviderFactory.java +++ b/java/sca/modules/implementation-java-runtime/src/main/java/org/apache/tuscany/sca/implementation/java/invocation/JavaImplementationProviderFactory.java @@ -20,7 +20,6 @@ package org.apache.tuscany.sca.implementation.java.invocation; import java.util.List; -import java.util.Map; import org.apache.tuscany.sca.context.ComponentContextFactory; import org.apache.tuscany.sca.context.RequestContextFactory; @@ -42,14 +41,14 @@ public class JavaImplementationProviderFactory implements ImplementationProvider private ProxyFactory proxyService; private ComponentContextFactory componentContextFactory; private RequestContextFactory requestContextFactory; - private Map> policyHandlerClassNames = null; + private List policyHandlerClassNames = null; public JavaImplementationProviderFactory(ProxyFactory proxyService, DataBindingExtensionPoint dataBindingRegistry, JavaPropertyValueObjectFactory propertyValueObjectFactory, ComponentContextFactory componentContextFactory, RequestContextFactory requestContextFactory, - Map> policyHandlerClassNames) { + List policyHandlerClassNames) { super(); this.proxyService = proxyService; this.dataBindingRegistry = dataBindingRegistry; diff --git a/java/sca/modules/implementation-java-runtime/src/main/java/org/apache/tuscany/sca/implementation/java/module/JavaRuntimeModuleActivator.java b/java/sca/modules/implementation-java-runtime/src/main/java/org/apache/tuscany/sca/implementation/java/module/JavaRuntimeModuleActivator.java index 384fef5c09..111b008b96 100644 --- a/java/sca/modules/implementation-java-runtime/src/main/java/org/apache/tuscany/sca/implementation/java/module/JavaRuntimeModuleActivator.java +++ b/java/sca/modules/implementation-java-runtime/src/main/java/org/apache/tuscany/sca/implementation/java/module/JavaRuntimeModuleActivator.java @@ -20,7 +20,6 @@ package org.apache.tuscany.sca.implementation.java.module; import java.util.List; -import java.util.Map; import org.apache.tuscany.sca.context.ComponentContextFactory; import org.apache.tuscany.sca.context.ContextFactoryExtensionPoint; @@ -77,7 +76,7 @@ public class JavaRuntimeModuleActivator implements ModuleActivator { ComponentContextFactory componentContextFactory = contextFactories.getFactory(ComponentContextFactory.class); RequestContextFactory requestContextFactory = contextFactories.getFactory(RequestContextFactory.class); - Map> policyHandlerClassNames = null; + List policyHandlerClassNames = null; policyHandlerClassNames = PolicyHandlerDefinitionsLoader.loadPolicyHandlerClassnames(); ProxyFactory proxyFactory = new ExtensibleProxyFactory(proxyFactories); diff --git a/java/sca/modules/implementation-java/src/main/java/org/apache/tuscany/sca/implementation/java/JavaImplementation.java b/java/sca/modules/implementation-java/src/main/java/org/apache/tuscany/sca/implementation/java/JavaImplementation.java index c49ef21547..2ad7edbd6f 100644 --- a/java/sca/modules/implementation-java/src/main/java/org/apache/tuscany/sca/implementation/java/JavaImplementation.java +++ b/java/sca/modules/implementation-java/src/main/java/org/apache/tuscany/sca/implementation/java/JavaImplementation.java @@ -188,11 +188,11 @@ public interface JavaImplementation extends BaseJavaImplementation { /** * @return the map of a policy handler class names */ - Map> getPolicyHandlerClassNames(); + List getPolicyHandlerClassNames(); /** * @param policyHandlerClassNames Map of policyhandler class names */ - void setPolicyHandlerClassNames(Map> policyHandlerClassNames); + void setPolicyHandlerClassNames(List policyHandlerClassNames); } diff --git a/java/sca/modules/implementation-java/src/main/java/org/apache/tuscany/sca/implementation/java/impl/JavaImplementationImpl.java b/java/sca/modules/implementation-java/src/main/java/org/apache/tuscany/sca/implementation/java/impl/JavaImplementationImpl.java index 8aa62ae62c..375896cf26 100644 --- a/java/sca/modules/implementation-java/src/main/java/org/apache/tuscany/sca/implementation/java/impl/JavaImplementationImpl.java +++ b/java/sca/modules/implementation-java/src/main/java/org/apache/tuscany/sca/implementation/java/impl/JavaImplementationImpl.java @@ -51,7 +51,7 @@ public class JavaImplementationImpl extends BaseJavaImplementationImpl implement private long maxAge = -1; private long maxIdleTime = -1; private JavaScopeImpl scope = JavaScopeImpl.STATELESS; - private Map> policyHandlerClassNames = null; + private List policyHandlerClassNames = null; protected JavaImplementationImpl() { super(); @@ -157,11 +157,11 @@ public class JavaImplementationImpl extends BaseJavaImplementationImpl implement this.maxIdleTime = maxIdleTime; } - public Map> getPolicyHandlerClassNames() { + public List getPolicyHandlerClassNames() { return policyHandlerClassNames; } - public void setPolicyHandlerClassNames(Map> policyHandlerClassNames) { + public void setPolicyHandlerClassNames(List policyHandlerClassNames) { this.policyHandlerClassNames = policyHandlerClassNames; } diff --git a/java/sca/modules/osgi-runtime/pom.xml b/java/sca/modules/osgi-runtime/pom.xml index cf3a379c13..2b90e85d2d 100644 --- a/java/sca/modules/osgi-runtime/pom.xml +++ b/java/sca/modules/osgi-runtime/pom.xml @@ -1,24 +1,23 @@ - 4.0.0 org.apache.tuscany.sca @@ -26,54 +25,45 @@ 1.4-SNAPSHOT ../pom.xml - tuscany-osgi-runtime Apache Tuscany OSGi Runtime Helper Library - - org.apache.felix org.apache.felix.main 1.0.4 - - org.apache.tuscany.sca - tuscany-host-embedded + tuscany-core-spi 1.4-SNAPSHOT - - org.easymock - easymock - 2.2 - test + org.apache.tuscany.sca + tuscany-extensibility-osgi + 1.4-SNAPSHOT - - - - org.apache.felix maven-bundle-plugin - ${tuscany.version} - org.apache.tuscany.sca.osgi.runtime + org.apache.tuscany.sca.osgi.runtime + ${pom.name} - org.apache.tuscany.sca.osgi.runtime* - org.apache.tuscany.sca.osgi.runtime.OSGiBundleActivator - org.apache.felix.main,org.eclipse.core.runtime.adaptor + org.apache.tuscany.sca.osgi.runtime* + + org.apache.tuscany.sca.osgi.runtime.OSGiBundleActivator + + org.apache.felix.main,org.eclipse.core.runtime.adaptor + - - + \ No newline at end of file diff --git a/java/sca/modules/osgi-runtime/src/main/java/org/apache/tuscany/sca/osgi/runtime/OSGiBundleActivator.java b/java/sca/modules/osgi-runtime/src/main/java/org/apache/tuscany/sca/osgi/runtime/OSGiBundleActivator.java index 1b10ef40e5..7c484ddddb 100644 --- a/java/sca/modules/osgi-runtime/src/main/java/org/apache/tuscany/sca/osgi/runtime/OSGiBundleActivator.java +++ b/java/sca/modules/osgi-runtime/src/main/java/org/apache/tuscany/sca/osgi/runtime/OSGiBundleActivator.java @@ -5,9 +5,9 @@ import java.net.URL; import java.util.Collections; import java.util.Enumeration; import java.util.HashSet; -import java.util.concurrent.ConcurrentHashMap; import org.apache.tuscany.sca.extensibility.ServiceDiscovery; +import org.apache.tuscany.sca.extensibility.osgi.OSGiServiceDiscoverer; import org.osgi.framework.Bundle; import org.osgi.framework.BundleActivator; import org.osgi.framework.BundleContext; @@ -20,162 +20,159 @@ import org.osgi.framework.BundleListener; * @version $Rev$ $Date$ */ public class OSGiBundleActivator implements BundleActivator, BundleListener { - - private static final String TUSCANY_SCA_BUNDLE_PREFIX = "org.apache.tuscany.sca"; - private static final String TUSCANY_3RD_PARTY_BUNDLE_PREFIX = "org.apache.tuscany.sca.3rdparty"; - private OSGiRuntime runtime; - private ConcurrentHashMap serviceDiscoveryClassLoaders = new ConcurrentHashMap(); - private BundleClassLoader threadContextClassLoader; - private ClassLoader origTCCL; - private Bundle thisBundle; - - public void start(BundleContext bundleContext) throws Exception { - - initializeTuscanyClassLoaders(bundleContext); - - runtime = OSGiRuntime.findRuntime(); - runtime.setBundleContext(bundleContext); + + private static final String TUSCANY_SCA_BUNDLE_PREFIX = "org.apache.tuscany.sca"; + private static final String TUSCANY_3RD_PARTY_BUNDLE_PREFIX = "org.apache.tuscany.sca.3rdparty"; + private OSGiRuntime runtime; + /* + private ConcurrentHashMap serviceDiscoveryClassLoaders = + new ConcurrentHashMap(); + */ + private BundleClassLoader threadContextClassLoader; + private ClassLoader origTCCL; + private Bundle thisBundle; + + public void start(BundleContext bundleContext) throws Exception { + + initializeTuscanyClassLoaders(bundleContext); + + runtime = OSGiRuntime.findRuntime(); + runtime.setBundleContext(bundleContext); runtime.setContextClassLoader(threadContextClassLoader); - runtime.initialize(); - - } + runtime.initialize(); + + } + + public void stop(BundleContext bundleContext) throws Exception { - public void stop(BundleContext bundleContext) throws Exception { - // runtime.shutdown(); if (Thread.currentThread().getContextClassLoader() == threadContextClassLoader) - Thread.currentThread().setContextClassLoader(origTCCL); - } - - /** - * Create a bundle ClassLoader which has visibility of all Tuscany related - * bundles. Use this ClassLoader as TCCL, and the Tuscany service discovery - * ClassLoader. - * - * @param bundleContext - */ - private void initializeTuscanyClassLoaders(BundleContext bundleContext) { - - thisBundle = bundleContext.getBundle(); - - origTCCL = Thread.currentThread().getContextClassLoader(); - - threadContextClassLoader = new BundleClassLoader(thisBundle, origTCCL); - - Thread.currentThread().setContextClassLoader(threadContextClassLoader); - + Thread.currentThread().setContextClassLoader(origTCCL); + } + + /** + * Create a bundle ClassLoader which has visibility of all Tuscany related + * bundles. Use this ClassLoader as TCCL, and the Tuscany service discovery + * ClassLoader. + * + * @param bundleContext + */ + private void initializeTuscanyClassLoaders(BundleContext bundleContext) { + + OSGiServiceDiscoverer discoverer = new OSGiServiceDiscoverer(bundleContext); + ServiceDiscovery.setServiceDiscoverer(discoverer); + thisBundle = bundleContext.getBundle(); + + origTCCL = Thread.currentThread().getContextClassLoader(); + + threadContextClassLoader = new BundleClassLoader(thisBundle, origTCCL); + + Thread.currentThread().setContextClassLoader(threadContextClassLoader); + ClassLoader cl = new BundleClassLoader(thisBundle, null); - ServiceDiscovery.getInstance().registerClassLoader(cl); - serviceDiscoveryClassLoaders.put(thisBundle, cl); - - Bundle[] bundles = bundleContext.getBundles(); - for (Bundle bundle : bundles) { - updateBundleClassLoader(bundle); - } - bundleContext.addBundleListener(this); - - } - - /** - * Add an installed bundle to the list of bundles in the service discovery classpath - * if the installed bundle is a Tuscany bundle using the same Core-SPI bundle. - * Since the bundle containing this activator is in Tuscany Runtime, this bundle - * will provide access to Runtime and its dependencies (SPI, SCA-API). Third party - * bundles don't need to be in the service discovery classpath, since they will be automatically - * imported by bundles which require them. That leaves Tuscany extension bundles, - * which are added to the service discovery classpath here. - * - * 3rd party bundle should be explicitly added to TCCL since classes from these - * bundles use TCCL to load other classes from the bundle. - * - * Load one class from the bundle to check if the new bundle matches this runtime bundle. - * - * @param bundle - */ - private void updateBundleClassLoader(Bundle bundle) { - - if (bundle.getSymbolicName().startsWith(TUSCANY_SCA_BUNDLE_PREFIX)) { - - - // This may be the third party bundle. - if (bundle.getSymbolicName().startsWith(TUSCANY_3RD_PARTY_BUNDLE_PREFIX)) { - - threadContextClassLoader.addBundle(bundle); - } - else { - + // ServiceDiscovery.getInstance().registerClassLoader(cl); + // serviceDiscoveryClassLoaders.put(thisBundle, cl); + + Bundle[] bundles = bundleContext.getBundles(); + for (Bundle bundle : bundles) { + updateBundleClassLoader(bundle); + } + bundleContext.addBundleListener(this); + + } + + /** + * Add an installed bundle to the list of bundles in the service discovery classpath + * if the installed bundle is a Tuscany bundle using the same Core-SPI bundle. + * Since the bundle containing this activator is in Tuscany Runtime, this bundle + * will provide access to Runtime and its dependencies (SPI, SCA-API). Third party + * bundles don't need to be in the service discovery classpath, since they will be automatically + * imported by bundles which require them. That leaves Tuscany extension bundles, + * which are added to the service discovery classpath here. + * + * 3rd party bundle should be explicitly added to TCCL since classes from these + * bundles use TCCL to load other classes from the bundle. + * + * Load one class from the bundle to check if the new bundle matches this runtime bundle. + * + * @param bundle + */ + private void updateBundleClassLoader(Bundle bundle) { + + if (bundle.getSymbolicName().startsWith(TUSCANY_SCA_BUNDLE_PREFIX)) { + + // This may be the third party bundle. + if (bundle.getSymbolicName().startsWith(TUSCANY_3RD_PARTY_BUNDLE_PREFIX)) { + + threadContextClassLoader.addBundle(bundle); + } else { + String thisBundleVersion = (String)thisBundle.getHeaders().get("Bundle-Version"); String bundleVersion = (String)bundle.getHeaders().get("Bundle-Version"); - + if (thisBundleVersion == null || bundleVersion == null || thisBundleVersion.equals(bundleVersion)) { - + if (!threadContextClassLoader.bundles.contains(bundle)) { ClassLoader cl = new BundleClassLoader(bundle, null); - ServiceDiscovery.getInstance().registerClassLoader(cl); - serviceDiscoveryClassLoaders.put(bundle, cl); - threadContextClassLoader.addBundle(bundle); + // ServiceDiscovery.getInstance().registerClassLoader(cl); + // serviceDiscoveryClassLoaders.put(bundle, cl); + threadContextClassLoader.addBundle(bundle); } } - } - } else { - threadContextClassLoader.addBundle(bundle); - } - } - - - /** - * Handle bundle install/uninstall events - */ - public void bundleChanged(BundleEvent event) { - - Bundle bundle = event.getBundle(); - if (event.getType() == BundleEvent.UNINSTALLED) { - ClassLoader cl = serviceDiscoveryClassLoaders.get(bundle); - if (cl != null) { - ServiceDiscovery.getInstance().unregisterClassLoader(cl); } - threadContextClassLoader.removeBundle(bundle); - } - else if (event.getType() == BundleEvent.INSTALLED) { - updateBundleClassLoader(bundle); - } - } - - - - - /** - * Bundle ClassLoader that searches a bundle classpath consisting of - * a list of bundles. The parent ClassLoader is searched only if a class - * cannot be loaded from the bundle classpath. Tuscany bundles are - * dynamically added and removed from the bundle classpath when the bundles - * are installed and uninstalled. - * - * No ordering of bundles is maintained at the moment. - * - */ - private static class BundleClassLoader extends ClassLoader { - - private HashSet bundles; - - BundleClassLoader(Bundle bundle, ClassLoader parent) { - super(parent); - this.bundles = new HashSet(); - bundles.add(bundle); - } - - private synchronized void addBundle(Bundle bundle) { - bundles.add(bundle); - } - - private synchronized void removeBundle(Bundle bundle) { - if (bundles.contains(bundle)) - bundles.remove(bundle); - } - - - @Override + } else { + threadContextClassLoader.addBundle(bundle); + } + } + + /** + * Handle bundle install/uninstall events + */ + public void bundleChanged(BundleEvent event) { + + Bundle bundle = event.getBundle(); + if (event.getType() == BundleEvent.UNINSTALLED) { +// ClassLoader cl = serviceDiscoveryClassLoaders.get(bundle); +// if (cl != null) { +// ServiceDiscovery.getInstance().unregisterClassLoader(cl); +// } + threadContextClassLoader.removeBundle(bundle); + } else if (event.getType() == BundleEvent.INSTALLED) { + updateBundleClassLoader(bundle); + } + } + + /** + * Bundle ClassLoader that searches a bundle classpath consisting of + * a list of bundles. The parent ClassLoader is searched only if a class + * cannot be loaded from the bundle classpath. Tuscany bundles are + * dynamically added and removed from the bundle classpath when the bundles + * are installed and uninstalled. + * + * No ordering of bundles is maintained at the moment. + * + */ + private static class BundleClassLoader extends ClassLoader { + + private HashSet bundles; + + BundleClassLoader(Bundle bundle, ClassLoader parent) { + super(parent); + this.bundles = new HashSet(); + bundles.add(bundle); + } + + private synchronized void addBundle(Bundle bundle) { + bundles.add(bundle); + } + + private synchronized void removeBundle(Bundle bundle) { + if (bundles.contains(bundle)) + bundles.remove(bundle); + } + + @Override protected Class findClass(String className) throws ClassNotFoundException { Class clazz = null; synchronized (this) { @@ -188,53 +185,50 @@ public class OSGiBundleActivator implements BundleActivator, BundleListener { } } - } + } if (clazz != null) { return clazz; } return super.findClass(className); } + @Override + @SuppressWarnings("unchecked") + public Enumeration getResources(String resName) throws IOException { + HashSet urlSet = new HashSet(); + Enumeration urls = null; + synchronized (this) { + for (Bundle bundle : bundles) { + urls = bundle.getResources(resName); + if (urls != null) { + while (urls.hasMoreElements()) { + urlSet.add(urls.nextElement()); + } + } + } + } + if (urlSet.size() > 0) + return Collections.enumeration(urlSet); + return super.getResources(resName); + } + + @Override + public URL getResource(String resName) { + URL url = null; + synchronized (this) { + for (Bundle bundle : bundles) { + url = bundle.getResource(resName); + if (url != null) + return url; + } + } + return super.getResource(resName); + } + + @Override + public String toString() { + return "Tuscany BundleClassLoader " + bundles.iterator().next(); + } - @Override - @SuppressWarnings("unchecked") - public Enumeration getResources(String resName) throws IOException { - HashSet urlSet = new HashSet(); - Enumeration urls = null; - synchronized (this) { - for (Bundle bundle : bundles) { - urls = bundle.getResources(resName); - if (urls != null) { - while (urls.hasMoreElements()) { - urlSet.add(urls.nextElement()); - } - } - } - } - if (urlSet.size() > 0) - return Collections.enumeration(urlSet); - return super.getResources(resName); - } - - @Override - public URL getResource(String resName) { - URL url = null; - synchronized (this) { - for (Bundle bundle : bundles) { - url = bundle.getResource(resName); - if (url != null) - return url; - } - } - return super.getResource(resName); - } - - @Override - public String toString() { - return "Tuscany BundleClassLoader " + bundles.iterator().next(); - } - - - - } + } } diff --git a/java/sca/modules/policy/src/main/java/org/apache/tuscany/sca/policy/util/PolicyHandlerDefinitionsLoader.java b/java/sca/modules/policy/src/main/java/org/apache/tuscany/sca/policy/util/PolicyHandlerDefinitionsLoader.java index 14736aa34f..3a37ed3c41 100644 --- a/java/sca/modules/policy/src/main/java/org/apache/tuscany/sca/policy/util/PolicyHandlerDefinitionsLoader.java +++ b/java/sca/modules/policy/src/main/java/org/apache/tuscany/sca/policy/util/PolicyHandlerDefinitionsLoader.java @@ -38,7 +38,7 @@ import org.apache.tuscany.sca.extensibility.ServiceDiscovery; */ public class PolicyHandlerDefinitionsLoader { - public static Map> loadPolicyHandlerClassnames() { + public static List loadPolicyHandlerClassnames() { // Get the processor service declarations Set sds; try { @@ -47,15 +47,10 @@ public class PolicyHandlerDefinitionsLoader { throw new IllegalStateException(e); } - Map> handlerTuples = new Hashtable>(); + List handlerTupleList = new ArrayList(); + + Map> handlerTuples = new Hashtable>(); for (ServiceDeclaration sd : sds) { - ClassLoader cl = sd.getClassLoader(); - - List handlerTupleList = handlerTuples.get(cl); - if ( handlerTupleList == null ) { - handlerTupleList = new ArrayList(); - handlerTuples.put(cl, handlerTupleList); - } Map attributes = sd.getAttributes(); String intentName = attributes.get("intent"); QName intentQName = getQName(intentName); @@ -64,10 +59,10 @@ public class PolicyHandlerDefinitionsLoader { if ( appliesTo != null && !appliesTo.startsWith("/") ) { appliesTo = "//" + appliesTo; } - handlerTupleList.add(new PolicyHandlerTuple(sd.getClassName(), intentQName, policyModelClassName, appliesTo)); + handlerTupleList.add(new PolicyHandlerTuple(sd, sd.getClassName(), intentQName, policyModelClassName, appliesTo)); } - return handlerTuples; + return handlerTupleList; } private static QName getQName(String qname) { diff --git a/java/sca/modules/policy/src/main/java/org/apache/tuscany/sca/policy/util/PolicyHandlerTuple.java b/java/sca/modules/policy/src/main/java/org/apache/tuscany/sca/policy/util/PolicyHandlerTuple.java index 10a67383bf..84ffe3ef29 100644 --- a/java/sca/modules/policy/src/main/java/org/apache/tuscany/sca/policy/util/PolicyHandlerTuple.java +++ b/java/sca/modules/policy/src/main/java/org/apache/tuscany/sca/policy/util/PolicyHandlerTuple.java @@ -21,34 +21,48 @@ package org.apache.tuscany.sca.policy.util; import javax.xml.namespace.QName; +import org.apache.tuscany.sca.extensibility.ServiceDeclaration; + /** * PolicyHanlder tuples stored in policy handler services files * * @version $Rev$ $Date$ */ public class PolicyHandlerTuple { + private ServiceDeclaration declaration; private String policyHandlerClassName; private QName providedIntentName; private String policyModelClassName; private String appliesTo; - - public String getAppliesTo() { - return appliesTo; - } - public void setAppliesTo(String appliesTo) { - this.appliesTo = appliesTo; - } - - public PolicyHandlerTuple(String handlerClassName, + public PolicyHandlerTuple(ServiceDeclaration declaration, + String handlerClassName, QName providedIntentName, String policyModelClassName, String appliesTo) { + this.declaration = declaration; this.policyHandlerClassName = handlerClassName; this.providedIntentName = providedIntentName; this.policyModelClassName = policyModelClassName; this.appliesTo = appliesTo; } + + public ServiceDeclaration getDeclaration() { + return declaration; + } + + public void setDeclaration(ServiceDeclaration declaration) { + this.declaration = declaration; + } + + public String getAppliesTo() { + return appliesTo; + } + + public void setAppliesTo(String appliesTo) { + this.appliesTo = appliesTo; + } + public String getPolicyHandlerClassName() { return policyHandlerClassName; diff --git a/java/sca/modules/policy/src/main/java/org/apache/tuscany/sca/policy/util/PolicyHandlerUtils.java b/java/sca/modules/policy/src/main/java/org/apache/tuscany/sca/policy/util/PolicyHandlerUtils.java index d399cce17f..f2977d63bf 100644 --- a/java/sca/modules/policy/src/main/java/org/apache/tuscany/sca/policy/util/PolicyHandlerUtils.java +++ b/java/sca/modules/policy/src/main/java/org/apache/tuscany/sca/policy/util/PolicyHandlerUtils.java @@ -20,7 +20,6 @@ package org.apache.tuscany.sca.policy.util; import java.util.List; -import java.util.Map; import org.apache.tuscany.sca.policy.Intent; import org.apache.tuscany.sca.policy.PolicySet; @@ -31,43 +30,34 @@ import org.apache.tuscany.sca.policy.PolicySet; * @version $Rev$ $Date$ */ public class PolicyHandlerUtils { - public static PolicyHandler findPolicyHandler(PolicySet policySet, - Map> policyHandlerClassNames) - throws IllegalAccessException, ClassNotFoundException, InstantiationException { - + public static PolicyHandler findPolicyHandler(PolicySet policySet, List policyHandlerClassNames) + throws IllegalAccessException, ClassNotFoundException, InstantiationException { + PolicyHandler handler = null; - - for (ClassLoader classLoader : policyHandlerClassNames.keySet()) { - for ( PolicyHandlerTuple handlerTuple : policyHandlerClassNames.get(classLoader) ) { - //System.out.println(handlerTuple); - for ( Intent intent : policySet.getProvidedIntents() ) { - if ( intent.getName().equals(handlerTuple.getProvidedIntentName())) { - for ( Object policy : policySet.getPolicies() ) { - if ( policy.getClass().getName().equals(handlerTuple.getPolicyModelClassName())) { - if ( handlerTuple.getAppliesTo() != null ) { - if ( handlerTuple.getAppliesTo().equals(policySet.getAppliesTo() )) { - handler = - (PolicyHandler)Class.forName(handlerTuple.getPolicyHandlerClassName(), - true, - classLoader).newInstance(); - handler.setApplicablePolicySet(policySet); - return handler; - } - } else { - handler = - (PolicyHandler)Class.forName(handlerTuple.getPolicyHandlerClassName(), - true, - classLoader).newInstance(); - handler.setApplicablePolicySet(policySet); - return handler; + + for (PolicyHandlerTuple handlerTuple : policyHandlerClassNames) { + //System.out.println(handlerTuple); + for (Intent intent : policySet.getProvidedIntents()) { + if (intent.getName().equals(handlerTuple.getProvidedIntentName())) { + for (Object policy : policySet.getPolicies()) { + if (policy.getClass().getName().equals(handlerTuple.getPolicyModelClassName())) { + if (handlerTuple.getAppliesTo() != null) { + if (handlerTuple.getAppliesTo().equals(policySet.getAppliesTo())) { + handler = (PolicyHandler)handlerTuple.getDeclaration().loadClass().newInstance(); + handler.setApplicablePolicySet(policySet); + return handler; } + } else { + handler = (PolicyHandler)handlerTuple.getDeclaration().loadClass().newInstance(); + handler.setApplicablePolicySet(policySet); + return handler; } } } } } } - + return handler; } diff --git a/java/sca/modules/pom.xml b/java/sca/modules/pom.xml index 028765a6c4..159e3a2481 100644 --- a/java/sca/modules/pom.xml +++ b/java/sca/modules/pom.xml @@ -103,6 +103,8 @@ domain-manager endpoint extensibility + extensibility-osgi + extensibility-eclipse extension-helper host-corba host-corba-jdk -- cgit v1.2.3