summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--java/sca/modules/binding-ws-axis2/src/main/java/org/apache/tuscany/sca/binding/ws/axis2/Axis2ConfiguratorHelper.java4
-rw-r--r--java/sca/modules/databinding-jaxb/src/main/java/org/apache/tuscany/sca/databinding/jaxb/JAXBContextCache.java8
-rw-r--r--java/sca/modules/extensibility-equinox/src/main/java/org/apache/tuscany/sca/extensibility/equinox/OSGiExtensionPointRegistry.java65
-rw-r--r--java/sca/modules/extensibility/src/main/java/org/apache/tuscany/sca/core/DefaultExtensionPointRegistry.java2
-rw-r--r--java/sca/modules/extensibility/src/main/java/org/apache/tuscany/sca/extensibility/ClassLoaderContext.java208
-rw-r--r--java/sca/modules/extensibility/src/main/java/org/apache/tuscany/sca/extensibility/ServiceDiscovery.java130
-rw-r--r--java/sca/modules/extensibility/src/main/java/org/apache/tuscany/sca/extensibility/impl/ClassLoaderDelegate.java89
-rw-r--r--java/sca/modules/node-api/src/main/java/org/apache/tuscany/sca/node/NodeFactory.java6
8 files changed, 324 insertions, 188 deletions
diff --git a/java/sca/modules/binding-ws-axis2/src/main/java/org/apache/tuscany/sca/binding/ws/axis2/Axis2ConfiguratorHelper.java b/java/sca/modules/binding-ws-axis2/src/main/java/org/apache/tuscany/sca/binding/ws/axis2/Axis2ConfiguratorHelper.java
index 782cfd6066..a7dc09ea6d 100644
--- a/java/sca/modules/binding-ws-axis2/src/main/java/org/apache/tuscany/sca/binding/ws/axis2/Axis2ConfiguratorHelper.java
+++ b/java/sca/modules/binding-ws-axis2/src/main/java/org/apache/tuscany/sca/binding/ws/axis2/Axis2ConfiguratorHelper.java
@@ -26,7 +26,7 @@ import java.security.PrivilegedExceptionAction;
import org.apache.axis2.AxisFault;
import org.apache.axis2.context.ConfigurationContext;
import org.apache.axis2.deployment.URLBasedAxisConfigurator;
-import org.apache.tuscany.sca.extensibility.ServiceDiscovery;
+import org.apache.tuscany.sca.extensibility.ClassLoaderContext;
import org.oasisopen.sca.ServiceRuntimeException;
/**
@@ -56,7 +56,7 @@ public class Axis2ConfiguratorHelper {
// The axis2 class loader
ClassLoader cl1 = URLBasedAxisConfigurator.class.getClassLoader();
- ClassLoader tccl = ServiceDiscovery.getInstance().setContextClassLoader(cl0, cl1);
+ ClassLoader tccl = ClassLoaderContext.setContextClassLoader(cl0, cl1);
try {
return new TuscanyAxisConfigurator(isRampartRequired).getConfigurationContext();
diff --git a/java/sca/modules/databinding-jaxb/src/main/java/org/apache/tuscany/sca/databinding/jaxb/JAXBContextCache.java b/java/sca/modules/databinding-jaxb/src/main/java/org/apache/tuscany/sca/databinding/jaxb/JAXBContextCache.java
index 6b32f0844b..9e08bbbbec 100644
--- a/java/sca/modules/databinding-jaxb/src/main/java/org/apache/tuscany/sca/databinding/jaxb/JAXBContextCache.java
+++ b/java/sca/modules/databinding-jaxb/src/main/java/org/apache/tuscany/sca/databinding/jaxb/JAXBContextCache.java
@@ -56,6 +56,7 @@ import javax.xml.datatype.DatatypeFactory;
import javax.xml.transform.Source;
import org.apache.tuscany.sca.databinding.util.LRUCache;
+import org.apache.tuscany.sca.extensibility.ClassLoaderContext;
import org.apache.tuscany.sca.extensibility.ServiceDiscovery;
/**
@@ -125,9 +126,10 @@ public class JAXBContextCache {
public JAXBContext run() throws JAXBException {
// Try to set up TCCL so that JAXBContext service discovery works in OSGi
ClassLoader tccl =
- ServiceDiscovery.getInstance().setContextClassLoader(JAXBContextCache.class.getClassLoader(),
- JAXBContext.class.getName(),
- DatatypeFactory.class.getName());
+ ClassLoaderContext.setContextClassLoader(JAXBContextCache.class.getClassLoader(),
+ ServiceDiscovery.getInstance(),
+ JAXBContext.class,
+ DatatypeFactory.class);
try {
JAXBContext context = JAXBContext.newInstance(classesToBeBound);
return context;
diff --git a/java/sca/modules/extensibility-equinox/src/main/java/org/apache/tuscany/sca/extensibility/equinox/OSGiExtensionPointRegistry.java b/java/sca/modules/extensibility-equinox/src/main/java/org/apache/tuscany/sca/extensibility/equinox/OSGiExtensionPointRegistry.java
index 470d681555..bd92312235 100644
--- a/java/sca/modules/extensibility-equinox/src/main/java/org/apache/tuscany/sca/extensibility/equinox/OSGiExtensionPointRegistry.java
+++ b/java/sca/modules/extensibility-equinox/src/main/java/org/apache/tuscany/sca/extensibility/equinox/OSGiExtensionPointRegistry.java
@@ -21,14 +21,10 @@ package org.apache.tuscany.sca.extensibility.equinox;
import java.util.Dictionary;
import java.util.Hashtable;
-import java.util.IdentityHashMap;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
-import java.util.logging.Level;
-import java.util.logging.Logger;
import org.apache.tuscany.sca.core.DefaultExtensionPointRegistry;
-import org.apache.tuscany.sca.core.LifeCycleListener;
import org.apache.tuscany.sca.extensibility.ServiceDeclaration;
import org.apache.tuscany.sca.extensibility.ServiceDiscovery;
import org.osgi.framework.Bundle;
@@ -38,11 +34,10 @@ import org.osgi.framework.ServiceReference;
import org.osgi.framework.ServiceRegistration;
/**
- *
+ * OSGi ServiceRegistry based extension point registry
*/
public class OSGiExtensionPointRegistry extends DefaultExtensionPointRegistry {
- private static final Logger logger = Logger.getLogger(OSGiExtensionPointRegistry.class.getName());
- private Map<Class<?>, ServiceRegistration> services = new ConcurrentHashMap<Class<?>, ServiceRegistration>();
+ private Map<Class<?>, ServiceRegistration> registrations = new ConcurrentHashMap<Class<?>, ServiceRegistration>();
private BundleContext bundleContext;
public OSGiExtensionPointRegistry(BundleContext bundleContext) {
@@ -51,27 +46,9 @@ public class OSGiExtensionPointRegistry extends DefaultExtensionPointRegistry {
}
@Override
- protected <T> Object findExtensionPoint(Class<T> extensionPointType) {
- ServiceRegistration registration = services.get(extensionPointType);
- if (registration != null) {
- ServiceReference ref = registration.getReference();
- if (ref != null) {
- return ref.getBundle().getBundleContext().getService(ref);
- }
- }
- /*
- else {
- ServiceReference ref = bundleContext.getServiceReference(extensionPointType.getName());
- if (ref != null) {
- return bundleContext.getService(ref);
- }
- }
- */
- return null;
- }
-
- @Override
- protected void registerExtensionPoint(Class<?> i, Object extensionPoint, ServiceDeclaration declaration) {
+ protected void registerExtensionPoint(Class<?> extensionPointType,
+ Object extensionPoint,
+ ServiceDeclaration declaration) {
BundleContext context = bundleContext;
if (declaration instanceof EquinoxServiceDiscoverer.ServiceDeclarationImpl) {
EquinoxServiceDiscoverer.ServiceDeclarationImpl declarationImpl =
@@ -92,46 +69,34 @@ public class OSGiExtensionPointRegistry extends DefaultExtensionPointRegistry {
context = bundle.getBundleContext();
}
Dictionary<Object, Object> props = new Hashtable<Object, Object>();
- ServiceRegistration registration = context.registerService(i.getName(), extensionPoint, props);
- services.put(i, registration);
+ ServiceRegistration registration = context.registerService(extensionPointType.getName(), extensionPoint, props);
+ registrations.put(extensionPointType, registration);
+ super.registerExtensionPoint(extensionPointType, extensionPoint, declaration);
}
@Override
protected void unregisterExtensionPoint(Class<?> i) {
- ServiceRegistration registration = services.get(i);
+ ServiceRegistration registration = registrations.remove(i);
if (registration != null) {
registration.unregister();
}
- services.remove(i);
+ super.unregisterExtensionPoint(i);
}
@Override
public synchronized void stop() {
- // Get a unique map as an extension point may exist in the map by different keys
- Map<LifeCycleListener, LifeCycleListener> map = new IdentityHashMap<LifeCycleListener, LifeCycleListener>();
- for (ServiceRegistration reg : services.values()) {
+ for (ServiceRegistration reg : registrations.values()) {
try {
ServiceReference ref = reg.getReference();
if (ref != null) {
- Object service = bundleContext.getService(ref);
- if (service instanceof LifeCycleListener) {
- LifeCycleListener activator = (LifeCycleListener)service;
- map.put(activator, activator);
- }
reg.unregister();
}
- } catch (Throwable e) {
- logger.log(Level.WARNING, e.getMessage(), e);
- }
- }
- for (LifeCycleListener activator : map.values()) {
- try {
- activator.stop();
- } catch (Throwable e) {
- logger.log(Level.WARNING, e.getMessage(), e);
+ } catch (IllegalStateException e) {
+ // Ignore it, the service has been unregistered when the owning bundle stops
}
}
- services.clear();
+ registrations.clear();
+ super.stop();
}
}
diff --git a/java/sca/modules/extensibility/src/main/java/org/apache/tuscany/sca/core/DefaultExtensionPointRegistry.java b/java/sca/modules/extensibility/src/main/java/org/apache/tuscany/sca/core/DefaultExtensionPointRegistry.java
index 66df61996b..2317fbd475 100644
--- a/java/sca/modules/extensibility/src/main/java/org/apache/tuscany/sca/core/DefaultExtensionPointRegistry.java
+++ b/java/sca/modules/extensibility/src/main/java/org/apache/tuscany/sca/core/DefaultExtensionPointRegistry.java
@@ -41,7 +41,7 @@ import org.apache.tuscany.sca.extensibility.ServiceHelper;
* @version $Rev$ $Date$
*/
public class DefaultExtensionPointRegistry implements ExtensionPointRegistry {
- private Map<Class<?>, Object> extensionPoints = new HashMap<Class<?>, Object>();
+ protected Map<Class<?>, Object> extensionPoints = new HashMap<Class<?>, Object>();
private ServiceDiscovery discovery;
/**
* Constructs a new registry.
diff --git a/java/sca/modules/extensibility/src/main/java/org/apache/tuscany/sca/extensibility/ClassLoaderContext.java b/java/sca/modules/extensibility/src/main/java/org/apache/tuscany/sca/extensibility/ClassLoaderContext.java
new file mode 100644
index 0000000000..e6ccb22ed5
--- /dev/null
+++ b/java/sca/modules/extensibility/src/main/java/org/apache/tuscany/sca/extensibility/ClassLoaderContext.java
@@ -0,0 +1,208 @@
+/*
+ * 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.security.PrivilegedAction;
+import java.security.PrivilegedActionException;
+import java.security.PrivilegedExceptionAction;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+
+import org.apache.tuscany.sca.extensibility.impl.ClassLoaderDelegate;
+
+/**
+ * A utility that controls context class loaders
+ */
+public class ClassLoaderContext {
+ private ClassLoader classLoader;
+
+ /**
+ * Create a context with the parent classloader and a list of service types that can be discovered
+ * by the {@link ServiceDiscovery}
+ * @param parent
+ * @param discovery
+ * @param serviceTypes
+ */
+ public ClassLoaderContext(ClassLoader parent, ServiceDiscovery discovery, Class<?>... serviceTypes) {
+ this(parent, getClassLoaders(discovery, serviceTypes));
+ }
+
+ private ClassLoaderContext(ClassLoader parent, List<ClassLoader> delegates) {
+ List<ClassLoader> loaders = new ArrayList<ClassLoader>(delegates);
+ loaders.remove(parent);
+ if (delegates.isEmpty()) {
+ classLoader = parent;
+ } else {
+ classLoader = new ClassLoaderDelegate(parent, loaders);
+ }
+ }
+
+ /**
+ * Create a context that is visible to the parent classloader as well as the list of classloaders
+ * @param parent
+ * @param delegates
+ */
+ public ClassLoaderContext(ClassLoader parent, ClassLoader... delegates) {
+ this(parent, Arrays.asList(delegates));
+ }
+
+ /**
+ * Create a context with the parent classloader and a list of service types that can be discovered
+ * by the {@link ServiceDiscovery}
+ * @param parent
+ * @param discovery
+ * @param serviceTypes
+ */
+ public ClassLoaderContext(ClassLoader parent, ServiceDiscovery discovery, String... serviceTypes) {
+ this(parent, getClassLoaders(discovery, serviceTypes));
+ }
+
+ public <T> T doPrivileged(PrivilegedAction<T> action) {
+ ClassLoader tccl = Thread.currentThread().getContextClassLoader();
+ if (tccl != classLoader) {
+ Thread.currentThread().setContextClassLoader(classLoader);
+ }
+ try {
+ return action.run();
+ } finally {
+ if (tccl != classLoader) {
+ Thread.currentThread().setContextClassLoader(tccl);
+ }
+ }
+ }
+
+ public <T> T doPrivileged(PrivilegedExceptionAction<T> action) throws PrivilegedActionException {
+ ClassLoader tccl = Thread.currentThread().getContextClassLoader();
+ if (tccl != classLoader) {
+ Thread.currentThread().setContextClassLoader(classLoader);
+ }
+ try {
+ return action.run();
+ } catch (Exception e) {
+ throw new PrivilegedActionException(e);
+ } finally {
+ if (tccl != classLoader) {
+ Thread.currentThread().setContextClassLoader(tccl);
+ }
+ }
+ }
+
+ /**
+ * Set the thread context classloader (TCCL) to a classloader that delegates to a collection
+ * of classloaders
+ * @param parent The parent classloader
+ * @param delegates A list of classloaders to try
+ * @return The existing TCCL
+ */
+ public static ClassLoader setContextClassLoader(ClassLoader parent, ClassLoader... delegates) {
+ ClassLoaderContext context = new ClassLoaderContext(parent, delegates);
+ return context.setContextClassLoader();
+ }
+
+ /**
+ * Set the context classloader so that it can access the list of service providers
+ * @param parent The parent classloader
+ * @param serviceNames A list of service provider names
+ * @return The old TCCL if a new one is set, otherwise null
+ */
+ public static ClassLoader setContextClassLoader(ClassLoader parent, ServiceDiscovery discovery, String... serviceNames) {
+ ClassLoaderContext context = new ClassLoaderContext(parent, discovery, serviceNames);
+ return context.setContextClassLoader();
+ }
+
+ /**
+ * Set the context classloader so that it can access the list of service providers
+ * @param parent The parent classloader
+ * @param serviceNames A list of service provider names
+ * @return The old TCCL if a new one is set, otherwise null
+ */
+ public static ClassLoader setContextClassLoader(ClassLoader parent, ServiceDiscovery discovery, Class<?>... serviceTypes) {
+ ClassLoaderContext context = new ClassLoaderContext(parent, discovery, serviceTypes);
+ return context.setContextClassLoader();
+ }
+
+ public ClassLoader setContextClassLoader() {
+ ClassLoader tccl = Thread.currentThread().getContextClassLoader();
+ if (tccl != classLoader) {
+ Thread.currentThread().setContextClassLoader(classLoader);
+ return tccl;
+ } else {
+ return null;
+ }
+ }
+
+ private static ClassLoader getClassLoader(ServiceDiscovery discovery, String serviceProvider) {
+ try {
+ ServiceDeclaration sd = discovery.getServiceDeclaration(serviceProvider);
+ if (sd != null) {
+ return sd.loadClass().getClassLoader();
+ }
+ } catch (Exception e) {
+ // Ignore
+ }
+ return null;
+ }
+
+ private static List<ClassLoader> getClassLoaders(ServiceDiscovery discovery, String... serviceNames) {
+ List<ClassLoader> loaders = new ArrayList<ClassLoader>();
+ for (String sp : serviceNames) {
+ ClassLoader loader = getClassLoader(discovery, sp);
+ if (loader != null) {
+ if (!loaders.contains(loader)) {
+ loaders.add(loader);
+ }
+ }
+ }
+ ClassLoader tccl = discovery.getContextClassLoader();
+ if (!loaders.contains(tccl)) {
+ loaders.add(tccl);
+ }
+ return loaders;
+ }
+
+ private static ClassLoader getClassLoader(ServiceDiscovery discovery, Class<?> serviceType) {
+ try {
+ ServiceDeclaration sd = discovery.getServiceDeclaration(serviceType);
+ if (sd != null) {
+ return sd.loadClass().getClassLoader();
+ }
+ } catch (Exception e) {
+ // Ignore
+ }
+ return null;
+ }
+
+ private static List<ClassLoader> getClassLoaders(ServiceDiscovery discovery, Class<?>... serviceTypes) {
+ List<ClassLoader> loaders = new ArrayList<ClassLoader>();
+ for (Class<?> serviceType : serviceTypes) {
+ ClassLoader classLoader = getClassLoader(discovery, serviceType);
+ if (classLoader != null && loaders.contains(classLoader)) {
+ loaders.add(classLoader);
+ }
+ }
+ ClassLoader tccl = discovery.getContextClassLoader();
+ if (!loaders.contains(tccl)) {
+ loaders.add(tccl);
+ }
+ return loaders;
+ }
+
+}
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 1c03166eeb..b5f26c7a34 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
@@ -20,19 +20,16 @@
package org.apache.tuscany.sca.extensibility;
import java.io.IOException;
-import java.net.URL;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.Comparator;
-import java.util.Enumeration;
-import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
-import java.util.Set;
import java.util.logging.Level;
import java.util.logging.Logger;
+import org.apache.tuscany.sca.extensibility.impl.ClassLoaderDelegate;
import org.apache.tuscany.sca.extensibility.impl.LDAPFilter;
/**
@@ -243,130 +240,5 @@ public final class ServiceDiscovery implements ServiceDiscoverer {
public ClassLoader getContextClassLoader() {
return discoverer.getContextClassLoader();
}
-
- private static class ClassLoaderDelegate extends ClassLoader {
- private final List<ClassLoader> classLoaders = new ArrayList<ClassLoader>();
-
- /**
- * @param parent The parent classloaders
- * @param loaders A list of classloaders to be used to load classes or resources
- */
- public ClassLoaderDelegate(ClassLoader parent, Collection<ClassLoader> loaders) {
- super(parent);
- if (loaders != null) {
- for (ClassLoader cl : loaders) {
- if (cl != null && cl != parent && !classLoaders.contains(cl)) {
- this.classLoaders.add(cl);
- }
- }
- }
- }
-
- @Override
- protected Class<?> findClass(String className) throws ClassNotFoundException {
- for (ClassLoader delegate : classLoaders) {
- try {
- return delegate.loadClass(className);
- } catch (ClassNotFoundException e) {
- continue;
- }
- }
- throw new ClassNotFoundException(className);
- }
-
- @Override
- protected URL findResource(String resName) {
- for (ClassLoader delegate : classLoaders) {
- URL url = delegate.getResource(resName);
- if (url != null) {
- return url;
- }
- }
- return null;
- }
-
- @Override
- protected Enumeration<URL> findResources(String resName) throws IOException {
- Set<URL> urlSet = new HashSet<URL>();
- for (ClassLoader delegate : classLoaders) {
- Enumeration<URL> urls = delegate.getResources(resName);
- if (urls != null) {
- while (urls.hasMoreElements()) {
- urlSet.add(urls.nextElement());
- }
- }
- }
- return Collections.enumeration(urlSet);
- }
- }
-
- private ClassLoader getClassLoader(String serviceProvider) {
- try {
- ServiceDeclaration sd = getServiceDeclaration(serviceProvider);
- if (sd != null) {
- return sd.loadClass().getClassLoader();
- }
- } catch (Exception e) {
- // Ignore
- }
- return null;
- }
-
- /**
- * Set the context classloader so that it can access the list of service providers
- * @param parent The parent classloader
- * @param serviceProviders A list of service provider names
- * @return The old TCCL if a new one is set, otherwise null
- */
- public ClassLoader setContextClassLoader(ClassLoader parent, String... serviceProviders) {
- List<ClassLoader> loaders = getClassLoaders(serviceProviders);
- return setContextClassLoader(parent, loaders.toArray(new ClassLoader[loaders.size()]));
- }
-
- private List<ClassLoader> getClassLoaders(String... serviceProviders) {
- List<ClassLoader> loaders = new ArrayList<ClassLoader>();
- for (String sp : serviceProviders) {
- ClassLoader loader = getClassLoader(sp);
- if (loader != null) {
- if (!loaders.contains(loader)) {
- loaders.add(loader);
- }
- }
- }
- return loaders;
- }
-
- /**
- * Set the thread context classloader (TCCL) to a classloader that delegates to a collection
- * of classloaders
- * @param parent The parent classloader
- * @param delegates A list of classloaders to try
- * @return The existing TCCL
- */
- public ClassLoader setContextClassLoader(ClassLoader parent, ClassLoader... delegates) {
- ClassLoader tccl = Thread.currentThread().getContextClassLoader();
- List<ClassLoader> loaders = new ArrayList<ClassLoader>();
- for (ClassLoader loader : delegates) {
- if (loader != null && loader != tccl && loader != parent) {
- if (!loaders.contains(loader)) {
- loaders.add(loader);
- }
- }
- }
- if (!loaders.isEmpty()) {
- ClassLoader cl = getContextClassLoader();
- if (cl != parent) {
- loaders.add(cl);
- }
- if (tccl != parent) {
- loaders.add(tccl);
- }
- ClassLoader newTccl = new ClassLoaderDelegate(parent, loaders);
- Thread.currentThread().setContextClassLoader(newTccl);
- return tccl;
- } else {
- return null;
- }
- }
}
diff --git a/java/sca/modules/extensibility/src/main/java/org/apache/tuscany/sca/extensibility/impl/ClassLoaderDelegate.java b/java/sca/modules/extensibility/src/main/java/org/apache/tuscany/sca/extensibility/impl/ClassLoaderDelegate.java
new file mode 100644
index 0000000000..d052d6b10f
--- /dev/null
+++ b/java/sca/modules/extensibility/src/main/java/org/apache/tuscany/sca/extensibility/impl/ClassLoaderDelegate.java
@@ -0,0 +1,89 @@
+/*
+ * 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.impl;
+
+import java.io.IOException;
+import java.net.URL;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.Enumeration;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+
+/**
+ * A classloader that can delegate to a list of other classloaders
+ */
+public class ClassLoaderDelegate extends ClassLoader {
+ private final List<ClassLoader> classLoaders = new ArrayList<ClassLoader>();
+
+ /**
+ * @param parent The parent classloaders
+ * @param loaders A list of classloaders to be used to load classes or resources
+ */
+ public ClassLoaderDelegate(ClassLoader parent, Collection<ClassLoader> loaders) {
+ super(parent);
+ if (loaders != null) {
+ for (ClassLoader cl : loaders) {
+ if (cl != null && cl != parent && !classLoaders.contains(cl)) {
+ this.classLoaders.add(cl);
+ }
+ }
+ }
+ }
+
+ @Override
+ protected Class<?> findClass(String className) throws ClassNotFoundException {
+ for (ClassLoader delegate : classLoaders) {
+ try {
+ return delegate.loadClass(className);
+ } catch (ClassNotFoundException e) {
+ continue;
+ }
+ }
+ throw new ClassNotFoundException(className);
+ }
+
+ @Override
+ protected URL findResource(String resName) {
+ for (ClassLoader delegate : classLoaders) {
+ URL url = delegate.getResource(resName);
+ if (url != null) {
+ return url;
+ }
+ }
+ return null;
+ }
+
+ @Override
+ protected Enumeration<URL> findResources(String resName) throws IOException {
+ Set<URL> urlSet = new HashSet<URL>();
+ for (ClassLoader delegate : classLoaders) {
+ Enumeration<URL> urls = delegate.getResources(resName);
+ if (urls != null) {
+ while (urls.hasMoreElements()) {
+ urlSet.add(urls.nextElement());
+ }
+ }
+ }
+ return Collections.enumeration(urlSet);
+ }
+}
diff --git a/java/sca/modules/node-api/src/main/java/org/apache/tuscany/sca/node/NodeFactory.java b/java/sca/modules/node-api/src/main/java/org/apache/tuscany/sca/node/NodeFactory.java
index a4daa2177d..a351b7b074 100644
--- a/java/sca/modules/node-api/src/main/java/org/apache/tuscany/sca/node/NodeFactory.java
+++ b/java/sca/modules/node-api/src/main/java/org/apache/tuscany/sca/node/NodeFactory.java
@@ -62,9 +62,9 @@ public abstract class NodeFactory extends DefaultNodeConfigurationFactory {
protected static Map<String, NodeFactory> nodeFactories = new HashMap<String, NodeFactory>();
protected static void setNodeFactory(NodeFactory factory) {
- if (nodeFactories.get(Node.DEFAULT_DOMAIN_URI) != null) {
- throw new IllegalStateException();
- }
+// if (nodeFactories.get(Node.DEFAULT_DOMAIN_URI) != null) {
+// throw new IllegalStateException();
+// }
nodeFactories.put(Node.DEFAULT_DOMAIN_URI, factory);
}