summaryrefslogtreecommitdiffstats
path: root/java/sca/modules/extensibility/src
diff options
context:
space:
mode:
authorrfeng <rfeng@13f79535-47bb-0310-9956-ffa450edef68>2009-10-29 06:48:59 +0000
committerrfeng <rfeng@13f79535-47bb-0310-9956-ffa450edef68>2009-10-29 06:48:59 +0000
commit4a473240fcfdecb8f7e0a03c3e252d87f1917632 (patch)
tree2e5fd75a7a9b3185415ffd5b0a03281a2403eae4 /java/sca/modules/extensibility/src
parent3a5430b346320015a8f97c9cc494223452df11d2 (diff)
Refactor the TCCL processing to ClassLoaderContext
Handle the OSGi service un-registration gracefully git-svn-id: http://svn.us.apache.org/repos/asf/tuscany@830852 13f79535-47bb-0310-9956-ffa450edef68
Diffstat (limited to 'java/sca/modules/extensibility/src')
-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
4 files changed, 299 insertions, 130 deletions
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);
+ }
+}