diff options
author | rfeng <rfeng@13f79535-47bb-0310-9956-ffa450edef68> | 2009-08-09 01:08:37 +0000 |
---|---|---|
committer | rfeng <rfeng@13f79535-47bb-0310-9956-ffa450edef68> | 2009-08-09 01:08:37 +0000 |
commit | d00035085d6089d942ff3179556e8893e2790b23 (patch) | |
tree | d64185218ef9f3a86f73ee471df99a4e564a2d8a /java/sca/modules/extensibility | |
parent | d927ce193627f96cac6b6d7dd83506b5fab1a585 (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.java | 122 |
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; + } + } } |