How does this relate to the existing CompositeClassLoader?
--
Jeremy

On Feb 6, 2007, at 4:48 PM, [EMAIL PROTECTED] wrote:

Author: rfeng
Date: Tue Feb  6 16:48:21 2007
New Revision: 504392

URL: http://svn.apache.org/viewvc?view=rev&rev=504392
Log:
Copy the MultiParentClassLoader from Axis2

Added:
incubator/tuscany/java/sca/kernel/spi/src/main/java/org/apache/ tuscany/spi/util/MultiParentClassLoader.java (with props)

Added: incubator/tuscany/java/sca/kernel/spi/src/main/java/org/ apache/tuscany/spi/util/MultiParentClassLoader.java URL: http://svn.apache.org/viewvc/incubator/tuscany/java/sca/kernel/ spi/src/main/java/org/apache/tuscany/spi/util/ MultiParentClassLoader.java?view=auto&rev=504392 ====================================================================== ======== --- incubator/tuscany/java/sca/kernel/spi/src/main/java/org/apache/ tuscany/spi/util/MultiParentClassLoader.java (added) +++ incubator/tuscany/java/sca/kernel/spi/src/main/java/org/apache/ tuscany/spi/util/MultiParentClassLoader.java Tue Feb 6 16:48:21 2007
@@ -0,0 +1,402 @@
+/*
+ * 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.spi.util;
+
+import java.beans.Introspector;
+import java.io.IOException;
+import java.net.URL;
+import java.net.URLClassLoader;
+import java.net.URLStreamHandlerFactory;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.Enumeration;
+import java.util.List;
+import java.util.Set;
+
+/**
+ * A MultiParentClassLoader is a simple extension of the URLClassLoader that + * simply changes the single parent class loader model to support a list of + * parent class loaders. Each operation that accesses a parent, has been + * replaced with a operation that checks each parent in order. This getParent + * method of this class will always return null, which may be interpreted by the + * calling code to mean that this class loader is a direct child of the system
+ * class loader.
+ *
+ * @version $Rev$ $Date$
+ */
+public class MultiParentClassLoader extends URLClassLoader {
+    private boolean destroyed;
+    private final String[] hiddenClasses;
+    private final String[] hiddenResources;
+    private final boolean inverseClassLoading;
+    private final String[] nonOverridableClasses;
+    private final String[] nonOverridableResources;
+
+    private final ClassLoader[] parents;
+
+    /**
+     * Creates a named class loader with no parents.
+     *
+ * @param urls the urls from which this class loader will classes and
+     *            resources
+     */
+    public MultiParentClassLoader(URL[] urls) {
+        super(urls);
+ parents = new ClassLoader[] {ClassLoader.getSystemClassLoader()};
+        inverseClassLoading = false;
+        hiddenClasses = new String[0];
+        nonOverridableClasses = new String[0];
+        hiddenResources = new String[0];
+        nonOverridableResources = new String[0];
+    }
+
+    /**
+ * Creates a named class loader as a child of the specified parent.
+     *
+ * @param urls the urls from which this class loader will classes and
+     *            resources
+     * @param parent the parent of this class loader
+     */
+    public MultiParentClassLoader(URL[] urls, ClassLoader parent) {
+        this(urls, new ClassLoader[] {parent});
+    }
+
+    public MultiParentClassLoader(URL[] urls,
+                                  ClassLoader parent,
+                                  boolean inverseClassLoading,
+                                  String[] hiddenClasses,
+                                  String[] nonOverridableClasses) {
+ this(urls, new ClassLoader[] {parent}, inverseClassLoading, hiddenClasses, nonOverridableClasses);
+    }
+
+    /**
+ * Creates a named class loader as a child of the specified parent and using
+     * the specified URLStreamHandlerFactory for accessing the urls..
+     *
+ * @param urls the urls from which this class loader will classes and
+     *            resources
+     * @param parent the parent of this class loader
+ * @param factory the URLStreamHandlerFactory used to access the urls
+     */
+ public MultiParentClassLoader(URL[] urls, ClassLoader parent, URLStreamHandlerFactory factory) {
+        this(urls, new ClassLoader[] {parent}, factory);
+    }
+
+    /**
+ * Creates a named class loader as a child of the specified parents.
+     *
+ * @param urls the urls from which this class loader will classes and
+     *            resources
+     * @param parents the parents of this class loader
+     */
+ public MultiParentClassLoader(URL[] urls, ClassLoader[] parents) {
+        super(urls);
+        this.parents = copyParents(parents);
+        inverseClassLoading = false;
+        hiddenClasses = new String[0];
+        nonOverridableClasses = new String[0];
+        hiddenResources = new String[0];
+        nonOverridableResources = new String[0];
+    }
+
+    public MultiParentClassLoader(URL[] urls,
+                                  ClassLoader[] parents,
+                                  boolean inverseClassLoading,
+                                  Collection<String> hiddenClasses,
+ Collection<String> nonOverridableClasses) { + this(urls, parents, inverseClassLoading, (String[]) hiddenClasses.toArray(new String[hiddenClasses.size()]), + (String[])nonOverridableClasses.toArray(new String [nonOverridableClasses.size()]));
+    }
+
+    public MultiParentClassLoader(URL[] urls,
+                                  ClassLoader[] parents,
+                                  boolean inverseClassLoading,
+                                  String[] hiddenClasses,
+                                  String[] nonOverridableClasses) {
+        super(urls);
+        this.parents = copyParents(parents);
+        this.inverseClassLoading = inverseClassLoading;
+        this.hiddenClasses = hiddenClasses;
+        this.nonOverridableClasses = nonOverridableClasses;
+        hiddenResources = toResources(hiddenClasses);
+        nonOverridableResources = toResources(nonOverridableClasses);
+    }
+
+    /**
+ * Creates a named class loader as a child of the specified parents and + * using the specified URLStreamHandlerFactory for accessing the urls..
+     *
+ * @param urls the urls from which this class loader will classes and
+     *            resources
+     * @param parents the parents of this class loader
+ * @param factory the URLStreamHandlerFactory used to access the urls
+     */
+ public MultiParentClassLoader(URL[] urls, ClassLoader[] parents, URLStreamHandlerFactory factory) {
+        super(urls, null, factory);
+        this.parents = copyParents(parents);
+        inverseClassLoading = false;
+        hiddenClasses = new String[0];
+        nonOverridableClasses = new String[0];
+        hiddenResources = new String[0];
+        nonOverridableResources = new String[0];
+    }
+
+    private static ClassLoader[] copyParents(ClassLoader[] parents) {
+ ClassLoader[] newParentsArray = new ClassLoader [parents.length];
+        for (int i = 0; i < parents.length; i++) {
+            ClassLoader parent = parents[i];
+            if (parent == null) {
+ throw new RuntimeException("parent[" + i + "] is null");
+            }
+            newParentsArray[i] = parent;
+        }
+        return newParentsArray;
+    }
+
+    public void addURL(URL url) {
+        // todo this needs a security check
+        super.addURL(url);
+    }
+
+    public void destroy() {
+        synchronized (this) {
+            if (destroyed) {
+                return;
+            }
+            destroyed = true;
+        }
+
+        // clearSoftCache(ObjectInputStream.class, "subclassAudits");
+ // clearSoftCache(ObjectOutputStream.class, "subclassAudits");
+        // clearSoftCache(ObjectStreamClass.class, "localDescs");
+        // clearSoftCache(ObjectStreamClass.class, "reflectors");
+
+ // The beanInfoCache in java.beans.Introspector will hold on to Classes
+        // which
+ // it has introspected. If we don't flush the cache, we may run out of
+        // Permanent Generation space.
+        Introspector.flushCaches();
+    }
+
+ public Enumeration<URL> findResources(String name) throws IOException {
+        if (isDestroyed()) {
+            Set<URL> emptySet = Collections.emptySet();
+            return Collections.enumeration(emptySet);
+        }
+
+        List<URL> resources = new ArrayList<URL>();
+
+        //
+ // if we are using inverse class loading, add the resources from local
+        // urls first
+        //
+        if (inverseClassLoading && !isDestroyed()) {
+ List<URL> myResources = Collections.list (super.findResources(name));
+            resources.addAll(myResources);
+        }
+
+        //
+        // Add parent resources
+        //
+        for (int i = 0; i < parents.length; i++) {
+            ClassLoader parent = parents[i];
+ List<URL> parentResources = Collections.list (parent.getResources(name));
+            resources.addAll(parentResources);
+        }
+
+        //
+ // if we are not using inverse class loading, add the resources from
+        // local urls now
+        //
+        if (!inverseClassLoading && !isDestroyed()) {
+ List<URL> myResources = Collections.list (super.findResources(name));
+            resources.addAll(myResources);
+        }
+
+        return Collections.enumeration(resources);
+    }
+
+    /**
+     * Gets the parents of this class loader.
+     *
+     * @return the parents of this class loader
+     */
+    public ClassLoader[] getParents() {
+        return parents;
+    }
+
+    public URL getResource(String name) {
+        if (isDestroyed()) {
+            return null;
+        }
+
+        //
+ // if we are using inverse class loading, check local urls first
+        //
+ if (inverseClassLoading && !isDestroyed() && ! isNonOverridableResource(name)) {
+            URL url = findResource(name);
+            if (url != null) {
+                return url;
+            }
+        }
+
+        //
+        // Check parent class loaders
+        //
+        if (!isHiddenResource(name)) {
+            for (int i = 0; i < parents.length; i++) {
+                ClassLoader parent = parents[i];
+                URL url = parent.getResource(name);
+                if (url != null) {
+                    return url;
+                }
+            }
+        }
+
+        //
+ // if we are not using inverse class loading, check local urls now
+        //
+ // don't worry about excluding non-overridable resources here... we + // have alredy checked he parent and the parent didn't have the
+        // resource, so we can override now
+        if (!isDestroyed()) {
+ // parents didn't have the resource; attempt to load it from my urls
+            return findResource(name);
+        }
+
+        return null;
+    }
+
+    public synchronized boolean isDestroyed() {
+        return destroyed;
+    }
+
+    private boolean isHiddenClass(String name) {
+        for (int i = 0; i < hiddenClasses.length; i++) {
+            if (name.startsWith(hiddenClasses[i])) {
+                return true;
+            }
+        }
+        return false;
+    }
+
+    private boolean isHiddenResource(String name) {
+        for (int i = 0; i < hiddenResources.length; i++) {
+            if (name.startsWith(hiddenResources[i])) {
+                return true;
+            }
+        }
+        return false;
+    }
+
+    private boolean isNonOverridableClass(String name) {
+        for (int i = 0; i < nonOverridableClasses.length; i++) {
+            if (name.startsWith(nonOverridableClasses[i])) {
+                return true;
+            }
+        }
+        return false;
+    }
+
+    private boolean isNonOverridableResource(String name) {
+        for (int i = 0; i < nonOverridableResources.length; i++) {
+            if (name.startsWith(nonOverridableResources[i])) {
+                return true;
+            }
+        }
+        return false;
+    }
+
+    @SuppressWarnings("unchecked")
+ protected synchronized Class loadClass(String name, boolean resolve) throws ClassNotFoundException {
+        //
+        // Check if class is in the loaded classes cache
+        //
+        Class cachedClass = findLoadedClass(name);
+        if (cachedClass != null) {
+            return resolveClass(cachedClass, resolve);
+        }
+
+        //
+ // if we are using inverse class loading, check local urls first
+        //
+ if (inverseClassLoading && !isDestroyed() && ! isNonOverridableClass(name)) {
+            try {
+                Class clazz = findClass(name);
+                return resolveClass(clazz, resolve);
+            } catch (ClassNotFoundException ignored) {
+                // Ignore it
+            }
+        }
+
+        //
+        // Check parent class loaders
+        //
+        if (!isHiddenClass(name)) {
+            for (int i = 0; i < parents.length; i++) {
+                ClassLoader parent = parents[i];
+                try {
+                    Class clazz = parent.loadClass(name);
+                    return resolveClass(clazz, resolve);
+                } catch (ClassNotFoundException ignored) {
+ // this parent didn't have the class; try the next one
+                }
+            }
+        }
+
+        //
+ // if we are not using inverse class loading, check local urls now
+        //
+ // don't worry about excluding non-overridable classes here... we + // have alredy checked he parent and the parent didn't have the
+        // class, so we can override now
+        if (!isDestroyed()) {
+            try {
+                Class clazz = findClass(name);
+                return resolveClass(clazz, resolve);
+            } catch (ClassNotFoundException ignored) {
+                // Ignore it
+            }
+        }
+
+        throw new ClassNotFoundException(name);
+    }
+
+    private Class resolveClass(Class clazz, boolean resolve) {
+        if (resolve) {
+            resolveClass(clazz);
+        }
+        return clazz;
+    }
+
+    private String[] toResources(String[] classes) {
+        String[] resources = new String[classes.length];
+        for (int i = 0; i < classes.length; i++) {
+            String className = classes[i];
+            resources[i] = className.replace('.', '/');
+        }
+        return resources;
+    }
+
+    public String toString() {
+        return "[" + getClass().getName() + "]";
+    }
+
+}

Propchange: incubator/tuscany/java/sca/kernel/spi/src/main/java/org/ apache/tuscany/spi/util/MultiParentClassLoader.java ---------------------------------------------------------------------- --------
    svn:eol-style = native

Propchange: incubator/tuscany/java/sca/kernel/spi/src/main/java/org/ apache/tuscany/spi/util/MultiParentClassLoader.java ---------------------------------------------------------------------- --------
    svn:keywords = Rev Date



---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]



---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]

Reply via email to