summaryrefslogtreecommitdiffstats
path: root/java/sca/modules/extensibility
diff options
context:
space:
mode:
authorrfeng <rfeng@13f79535-47bb-0310-9956-ffa450edef68>2009-08-09 01:08:37 +0000
committerrfeng <rfeng@13f79535-47bb-0310-9956-ffa450edef68>2009-08-09 01:08:37 +0000
commitd00035085d6089d942ff3179556e8893e2790b23 (patch)
treed64185218ef9f3a86f73ee471df99a4e564a2d8a /java/sca/modules/extensibility
parentd927ce193627f96cac6b6d7dd83506b5fab1a585 (diff)
Add a method to ServiceDiscovery to set context classloader for service providers in OSGi
git-svn-id: http://svn.us.apache.org/repos/asf/tuscany@802470 13f79535-47bb-0310-9956-ffa450edef68
Diffstat (limited to 'java/sca/modules/extensibility')
-rw-r--r--java/sca/modules/extensibility/src/main/java/org/apache/tuscany/sca/extensibility/ServiceDiscovery.java122
1 files changed, 122 insertions, 0 deletions
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 70274752e4..e92655146c 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,12 +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;
@@ -185,5 +189,123 @@ 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 parent : classLoaders) {
+ try {
+ return parent.loadClass(className);
+ } catch (ClassNotFoundException e) {
+ continue;
+ }
+ }
+ throw new ClassNotFoundException(className);
+ }
+
+ @Override
+ protected URL findResource(String resName) {
+ for (ClassLoader parent : classLoaders) {
+ URL url = parent.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 parent : classLoaders) {
+ Enumeration<URL> urls = parent.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;
+ }
+
+ 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;
+ }
+ }
}