You are viewing a plain text version of this content. The canonical link for it is here.
Posted to cvs@cocoon.apache.org by cz...@apache.org on 2006/05/19 11:57:42 UTC
svn commit: r407761 -
/cocoon/trunk/core/cocoon-core/src/main/java/org/apache/cocoon/components/classloader/
Author: cziegeler
Date: Fri May 19 02:57:42 2006
New Revision: 407761
URL: http://svn.apache.org/viewvc?rev=407761&view=rev
Log:
Refactor class loaders
Added:
cocoon/trunk/core/cocoon-core/src/main/java/org/apache/cocoon/components/classloader/AbstractClassLoaderFactory.java (with props)
cocoon/trunk/core/cocoon-core/src/main/java/org/apache/cocoon/components/classloader/DefaultClassLoader.java (with props)
cocoon/trunk/core/cocoon-core/src/main/java/org/apache/cocoon/components/classloader/ReloadingClassLoader.java (with props)
Modified:
cocoon/trunk/core/cocoon-core/src/main/java/org/apache/cocoon/components/classloader/ClassLoaderFactory.java
cocoon/trunk/core/cocoon-core/src/main/java/org/apache/cocoon/components/classloader/DefaultClassLoaderFactory.java
cocoon/trunk/core/cocoon-core/src/main/java/org/apache/cocoon/components/classloader/ReloadingClassLoaderFactory.java
Added: cocoon/trunk/core/cocoon-core/src/main/java/org/apache/cocoon/components/classloader/AbstractClassLoaderFactory.java
URL: http://svn.apache.org/viewvc/cocoon/trunk/core/cocoon-core/src/main/java/org/apache/cocoon/components/classloader/AbstractClassLoaderFactory.java?rev=407761&view=auto
==============================================================================
--- cocoon/trunk/core/cocoon-core/src/main/java/org/apache/cocoon/components/classloader/AbstractClassLoaderFactory.java (added)
+++ cocoon/trunk/core/cocoon-core/src/main/java/org/apache/cocoon/components/classloader/AbstractClassLoaderFactory.java Fri May 19 02:57:42 2006
@@ -0,0 +1,157 @@
+/*
+ * Copyright 2002-2006 The Apache Software Foundation
+ * Licensed 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.cocoon.components.classloader;
+
+import java.net.URL;
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+
+import org.apache.avalon.framework.activity.Disposable;
+import org.apache.avalon.framework.configuration.Configuration;
+import org.apache.avalon.framework.configuration.ConfigurationException;
+import org.apache.avalon.framework.logger.AbstractLogEnabled;
+import org.apache.avalon.framework.service.ServiceException;
+import org.apache.avalon.framework.service.ServiceManager;
+import org.apache.avalon.framework.service.Serviceable;
+import org.apache.avalon.framework.thread.ThreadSafe;
+import org.apache.cocoon.matching.helpers.WildcardHelper;
+import org.apache.excalibur.source.Source;
+import org.apache.excalibur.source.SourceResolver;
+import org.apache.excalibur.source.TraversableSource;
+
+/**
+ * Abstract implementation of {@link ClassLoaderFactory}. It accepts both class directory and jar
+ * directory configurations.
+ * <p>
+ * Wildcard patterns can also be specified to include or exclude some classes to be loaded in the
+ * classloader. In such case, the class is directly loaded from the parent classloader. The default
+ * is to include all classes.
+ * <p>
+ * Example:
+ * <pre>
+ * <classpath>
+ * <class-dir src="BLOCK-INF/classes"/>
+ * <lib-dir src="BLOCK-INF/lib"/>
+ * <include-classes pattern="org.apache.cocoon.**"/>
+ * <exclude-classes pattern="org.apache.cocoon.transformation.**"/>
+ * &/lt;classpath>
+ * </pre>
+ */
+public abstract class AbstractClassLoaderFactory
+ extends AbstractLogEnabled
+ implements ClassLoaderFactory,
+ Serviceable,
+ ThreadSafe,
+ Disposable {
+
+ protected ServiceManager manager;
+ protected SourceResolver resolver;
+
+ /**
+ * @see org.apache.avalon.framework.service.Serviceable#service(org.apache.avalon.framework.service.ServiceManager)
+ */
+ public void service(ServiceManager manager) throws ServiceException {
+ this.manager = manager;
+ this.resolver = (SourceResolver)manager.lookup(SourceResolver.ROLE);
+ }
+
+ private void ensureIsDirectory(Source src, String location) throws ConfigurationException {
+ if (!src.exists()) {
+ throw new ConfigurationException(src.getURI() + " doesn't exist, at " + location);
+ } else if (!(src instanceof TraversableSource) || !((TraversableSource)src).isCollection()) {
+ throw new ConfigurationException(src.getURI() + " is not a directory, at " + location);
+ }
+ }
+
+ /**
+ * @see org.apache.cocoon.components.classloader.ClassLoaderFactory#createClassLoader(java.lang.ClassLoader, org.apache.avalon.framework.configuration.Configuration)
+ */
+ public ClassLoader createClassLoader(ClassLoader parent, Configuration config) throws ConfigurationException {
+ final List urlList = new ArrayList();
+ Configuration[] children = config.getChildren();
+ for (int i = 0; i < children.length; i++) {
+ Configuration child = children[i];
+ String name = child.getName();
+ Source src = null;
+ try {
+ // A class dir: simply add its URL
+ if ("class-dir".equals(name)) {
+ src = resolver.resolveURI(child.getAttribute("src"));
+ ensureIsDirectory(src, child.getLocation());
+ urlList.add(new URL(src.getURI()));
+
+ // A lib dir: scan for all jar and zip it contains
+ } else if ("lib-dir".equals(name)) {
+ src = resolver.resolveURI(child.getAttribute("src"));
+ ensureIsDirectory(src, child.getLocation());
+ Iterator iter = ((TraversableSource)src).getChildren().iterator();
+ while (iter.hasNext()) {
+ Source childSrc = (Source)iter.next();
+ String childURI = childSrc.getURI();
+ resolver.release(childSrc);
+ if (childURI.endsWith(".jar") || childURI.endsWith(".zip")) {
+ urlList.add(new URL(childURI));
+ }
+ }
+ } else if (!"include-classes".equals(name) && !"exclude-classes".equals(name) ) {
+ throw new ConfigurationException("Unexpected element " + name + " at " + child.getLocation());
+ }
+ } catch(ConfigurationException ce) {
+ throw ce;
+ } catch(Exception e) {
+ throw new ConfigurationException("Error loading " + name + " at " + child.getLocation(), e);
+ } finally {
+ resolver.release(src);
+ src = null;
+ }
+ }
+
+ URL[] urls = (URL[])urlList.toArray(new URL[urlList.size()]);
+ int[][] includes = compilePatterns(config.getChildren("include-classes"));
+ int[][] excludes = compilePatterns(config.getChildren("exclude-classes"));
+
+ return this.createClassLoader(urls, includes, excludes, parent);
+ }
+
+ protected abstract ClassLoader createClassLoader(URL[] urls, int[][] includes, int[][] excludes, ClassLoader parent);
+
+ private int[][] compilePatterns(Configuration[] patternConfigs) throws ConfigurationException {
+ if (patternConfigs.length == 0) {
+ return null;
+ }
+
+ int[][] patterns = new int[patternConfigs.length][];
+
+ for (int i = 0; i < patternConfigs.length; i++) {
+ patterns[i] = WildcardHelper.compilePattern(patternConfigs[i].getAttribute("pattern"));
+ }
+
+ return patterns;
+ }
+
+ /**
+ * @see org.apache.avalon.framework.activity.Disposable#dispose()
+ */
+ public void dispose() {
+ if ( this.manager != null ) {
+ this.manager.release(this.resolver);
+ this.resolver = null;
+ this.manager = null;
+ }
+ }
+}
Propchange: cocoon/trunk/core/cocoon-core/src/main/java/org/apache/cocoon/components/classloader/AbstractClassLoaderFactory.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: cocoon/trunk/core/cocoon-core/src/main/java/org/apache/cocoon/components/classloader/AbstractClassLoaderFactory.java
------------------------------------------------------------------------------
svn:keywords = Id
Modified: cocoon/trunk/core/cocoon-core/src/main/java/org/apache/cocoon/components/classloader/ClassLoaderFactory.java
URL: http://svn.apache.org/viewvc/cocoon/trunk/core/cocoon-core/src/main/java/org/apache/cocoon/components/classloader/ClassLoaderFactory.java?rev=407761&r1=407760&r2=407761&view=diff
==============================================================================
--- cocoon/trunk/core/cocoon-core/src/main/java/org/apache/cocoon/components/classloader/ClassLoaderFactory.java (original)
+++ cocoon/trunk/core/cocoon-core/src/main/java/org/apache/cocoon/components/classloader/ClassLoaderFactory.java Fri May 19 02:57:42 2006
@@ -22,10 +22,11 @@
/**
* A <code>ClassLoader</code> factory, setting up the classpath given a
* <classpath> configuration.
- *
+ *
* @version $Id$
*/
public interface ClassLoaderFactory {
+
final static String ROLE = ClassLoaderFactory.class.getName();
ClassLoader createClassLoader(ClassLoader parent, Configuration config) throws ConfigurationException;
Added: cocoon/trunk/core/cocoon-core/src/main/java/org/apache/cocoon/components/classloader/DefaultClassLoader.java
URL: http://svn.apache.org/viewvc/cocoon/trunk/core/cocoon-core/src/main/java/org/apache/cocoon/components/classloader/DefaultClassLoader.java?rev=407761&view=auto
==============================================================================
--- cocoon/trunk/core/cocoon-core/src/main/java/org/apache/cocoon/components/classloader/DefaultClassLoader.java (added)
+++ cocoon/trunk/core/cocoon-core/src/main/java/org/apache/cocoon/components/classloader/DefaultClassLoader.java Fri May 19 02:57:42 2006
@@ -0,0 +1,154 @@
+/*
+ * Copyright 2002-2006 The Apache Software Foundation
+ * Licensed 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.cocoon.components.classloader;
+
+import java.net.URL;
+import java.net.URLClassLoader;
+import java.net.URLStreamHandlerFactory;
+
+import org.apache.cocoon.matching.helpers.WildcardHelper;
+
+/**
+ * @version $Id$
+ */
+public class DefaultClassLoader extends URLClassLoader {
+
+ protected final int[][] includes;
+ protected final int[][] excludes;
+
+ /**
+ * Alternate constructor to define a parent and initial <code>URL</code>
+ * s.
+ */
+ public DefaultClassLoader(URL[] urls, int[][] includes, int[][] excludes, final ClassLoader parent) {
+ this(urls, includes, excludes, parent, null);
+ }
+
+ /**
+ * Alternate constructor to define a parent, initial <code>URL</code>s,
+ * and a default <code>URLStreamHandlerFactory</code>.
+ */
+ public DefaultClassLoader(final URL[] urls, int[][] includes, int[][] excludes, ClassLoader parent, URLStreamHandlerFactory factory) {
+ super(urls, parent, factory);
+ this.includes = includes;
+ this.excludes = excludes;
+ }
+
+ protected boolean tryClassHere(String name) {
+ // Scan includes, then excludes
+ boolean tryHere;
+
+ // If no explicit includes, try here
+ if (this.includes == null) {
+ tryHere = true;
+ } else {
+ // See if it matches include patterns
+ tryHere = false;
+ for (int i = 0; i < this.includes.length; i++) {
+ if (WildcardHelper.match(null, name, includes[i])) {
+ tryHere = true;
+ break;
+ }
+ }
+ }
+
+ // Go through the exclusion list
+ if (tryHere && excludes != null) {
+ for (int i = 0; i < this.excludes.length; i++) {
+ if (WildcardHelper.match(null, name, excludes[i])) {
+ tryHere = false;
+ break;
+ }
+ }
+ }
+
+ return tryHere;
+ }
+
+ protected Class getClass(String name)
+ throws ClassNotFoundException {
+ return findClass(name);
+ }
+
+ /**
+ * Loads the class from this <code>ClassLoader</class>. If the
+ * class does not exist in this one, we check the parent. Please
+ * note that this is the exact opposite of the
+ * <code>ClassLoader</code> spec. We use it to work around
+ * inconsistent class loaders from third party vendors.
+ *
+ * @param name the name of the class
+ * @param resolve if <code>true</code> then resolve the class
+ * @return the resulting <code>Class</code> object
+ * @exception ClassNotFoundException if the class could not be found
+ */
+ public final Class loadClass(String name, boolean resolve) throws ClassNotFoundException {
+ // First check if it's already loaded
+ Class clazz = findLoadedClass(name);
+
+ if (clazz == null) {
+
+ ClassLoader parent = getParent();
+
+ if (tryClassHere(name)) {
+ try {
+ clazz = this.getClass(name);
+ } catch (ClassNotFoundException cnfe) {
+ if (parent == null) {
+ // Propagate exception
+ throw cnfe;
+ }
+ }
+ }
+
+ if (clazz == null) {
+ if (parent == null) {
+ throw new ClassNotFoundException(name);
+ } else {
+ // Will throw a CFNE if not found in parent
+ clazz = parent.loadClass(name);
+ }
+ }
+ }
+
+ if (resolve) {
+ resolveClass(clazz);
+ }
+
+ return clazz;
+ }
+
+ /**
+ * Gets a resource from this <code>ClassLoader</class>. If the
+ * resource does not exist in this one, we check the parent.
+ * Please note that this is the exact opposite of the
+ * <code>ClassLoader</code> spec. We use it to work around
+ * inconsistent class loaders from third party vendors.
+ *
+ * @param name of resource
+ */
+ public final URL getResource(final String name) {
+ URL resource = findResource(name);
+ ClassLoader parent = this.getParent();
+ if (resource == null && parent != null) {
+ resource = parent.getResource(name);
+ }
+
+ return resource;
+ }
+}
+
Propchange: cocoon/trunk/core/cocoon-core/src/main/java/org/apache/cocoon/components/classloader/DefaultClassLoader.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: cocoon/trunk/core/cocoon-core/src/main/java/org/apache/cocoon/components/classloader/DefaultClassLoader.java
------------------------------------------------------------------------------
svn:keywords = Id
Modified: cocoon/trunk/core/cocoon-core/src/main/java/org/apache/cocoon/components/classloader/DefaultClassLoaderFactory.java
URL: http://svn.apache.org/viewvc/cocoon/trunk/core/cocoon-core/src/main/java/org/apache/cocoon/components/classloader/DefaultClassLoaderFactory.java?rev=407761&r1=407760&r2=407761&view=diff
==============================================================================
--- cocoon/trunk/core/cocoon-core/src/main/java/org/apache/cocoon/components/classloader/DefaultClassLoaderFactory.java (original)
+++ cocoon/trunk/core/cocoon-core/src/main/java/org/apache/cocoon/components/classloader/DefaultClassLoaderFactory.java Fri May 19 02:57:42 2006
@@ -17,252 +17,15 @@
package org.apache.cocoon.components.classloader;
import java.net.URL;
-import java.net.URLClassLoader;
-import java.net.URLStreamHandlerFactory;
-import java.util.ArrayList;
-import java.util.Iterator;
-import java.util.List;
-
-import org.apache.avalon.framework.activity.Disposable;
-import org.apache.avalon.framework.configuration.Configuration;
-import org.apache.avalon.framework.configuration.ConfigurationException;
-import org.apache.avalon.framework.logger.AbstractLogEnabled;
-import org.apache.avalon.framework.service.ServiceException;
-import org.apache.avalon.framework.service.ServiceManager;
-import org.apache.avalon.framework.service.Serviceable;
-import org.apache.avalon.framework.thread.ThreadSafe;
-import org.apache.cocoon.matching.helpers.WildcardHelper;
-import org.apache.excalibur.source.Source;
-import org.apache.excalibur.source.SourceResolver;
-import org.apache.excalibur.source.TraversableSource;
/**
- * Default implementation of {@link ClassLoaderFactory}. It accepts both class directory and jar
- * directory configurations.
- * <p>
- * Wildcard patterns can also be specified to include or exclude some classes to be loaded in the
- * classloader. In such case, the class is directly loaded from the parent classloader. The default
- * is to include all classes.
- * <p>
- * Example:
- * <pre>
- * <classpath>
- * <class-dir src="BLOCK-INF/classes"/>
- * <lib-dir src="BLOCK-INF/lib"/>
- * <include-classes pattern="org.apache.cocoon.**"/>
- * <exclude-classes pattern="org.apache.cocoon.transformation.**"/>
- * &/lt;classpath>
- * </pre>
+ * @see AbstractClassLoaderFactory
+ * @version $Id$
*/
-public class DefaultClassLoaderFactory extends AbstractLogEnabled implements ClassLoaderFactory,
- Serviceable, ThreadSafe, Disposable {
+public class DefaultClassLoaderFactory
+ extends AbstractClassLoaderFactory {
- private ServiceManager manager;
- private SourceResolver resolver;
-
- /* (non-Javadoc)
- * @see org.apache.avalon.framework.service.Serviceable#service(org.apache.avalon.framework.service.ServiceManager)
- */
- public void service(ServiceManager manager) throws ServiceException {
- this.manager = manager;
- this.resolver = (SourceResolver)manager.lookup(SourceResolver.ROLE);
- }
-
- private void ensureIsDirectory(Source src, String location) throws ConfigurationException {
- if (!src.exists()) {
- throw new ConfigurationException(src.getURI() + " doesn't exist, at " + location);
- } else if (!(src instanceof TraversableSource) || !((TraversableSource)src).isCollection()) {
- throw new ConfigurationException(src.getURI() + " is not a directory, at " + location);
- }
- }
-
- /* (non-Javadoc)
- * @see org.apache.cocoon.core.ClassLoaderFactory#createClassLoader(java.lang.ClassLoader)
- */
- public ClassLoader createClassLoader(ClassLoader parent, Configuration config) throws ConfigurationException {
- List urlList = new ArrayList();
- List includeList = new ArrayList();
- List excludeList = new ArrayList();
- Configuration[] children = config.getChildren();
- for (int i = 0; i < children.length; i++) {
- Configuration child = children[i];
- String name = child.getName();
- Source src = null;
- try {
- // A class dir: simply add its URL
- if ("class-dir".equals(name)) {
- src = resolver.resolveURI(child.getAttribute("src"));
- ensureIsDirectory(src, child.getLocation());
- urlList.add(new URL(src.getURI()));
- resolver.release(src);
- src = null;
-
- // A lib dir: scan for all jar and zip it contains
- } else if ("lib-dir".equals(name)) {
- src = resolver.resolveURI(child.getAttribute("src"));
- ensureIsDirectory(src, child.getLocation());
- Iterator iter = ((TraversableSource)src).getChildren().iterator();
- while (iter.hasNext()) {
- Source childSrc = (Source)iter.next();
- String childURI = childSrc.getURI();
- resolver.release(childSrc);
- if (childURI.endsWith(".jar") || childURI.endsWith(".zip")) {
- urlList.add(new URL(childURI));
- }
- }
- resolver.release(src);
- src = null;
- } else if ("include-classes".equals(name)) {
- includeList.add(WildcardHelper.compilePattern(child.getAttribute("pattern")));
- } else if ("exclude-classes".equals(name)) {
- excludeList.add(WildcardHelper.compilePattern(child.getAttribute("pattern")));
- } else {
- throw new ConfigurationException("Unexpected element " + name + " at " + child.getLocation());
- }
- } catch(ConfigurationException ce) {
- resolver.release(src);
- throw ce;
- } catch(Exception e) {
- resolver.release(src);
- throw new ConfigurationException("Error loading " + name + " at " + child.getLocation(), e);
- }
- }
-
- URL[] urls = (URL[])urlList.toArray(new URL[urlList.size()]);
- int[][] includes = includeList.isEmpty() ? null : (int[][])includeList.toArray(new int[includeList.size()][]);
- int[][] excludes = excludeList.isEmpty() ? null : (int[][])excludeList.toArray(new int[excludeList.size()][]);
-
+ protected ClassLoader createClassLoader(URL[] urls, int[][] includes, int[][] excludes, ClassLoader parent) {
return new DefaultClassLoader(urls, includes, excludes, parent);
- }
-
- public static class DefaultClassLoader extends URLClassLoader {
-
- private final int[][] includes;
- private final int[][] excludes;
-
- /**
- * Alternate constructor to define a parent and initial <code>URL</code>
- * s.
- */
- public DefaultClassLoader(URL[] urls, int[][] includes, int[][] excludes, final ClassLoader parent) {
- this(urls, includes, excludes, parent, null);
- }
-
- /**
- * Alternate constructor to define a parent, initial <code>URL</code>s,
- * and a default <code>URLStreamHandlerFactory</code>.
- */
- public DefaultClassLoader(final URL[] urls, int[][] includes, int[][] excludes, ClassLoader parent, URLStreamHandlerFactory factory) {
- super(urls, parent, factory);
- this.includes = includes;
- this.excludes = excludes;
- }
-
- private boolean tryClassHere(String name) {
- // Scan includes, then excludes
- boolean tryHere;
-
- // If no explicit includes, try here
- if (this.includes == null) {
- tryHere = true;
- } else {
- // See if it matches include patterns
- tryHere = false;
- for (int i = 0; i < this.includes.length; i++) {
- if (WildcardHelper.match(null, name, includes[i])) {
- tryHere = true;
- break;
- }
- }
- }
-
- // Go through the exclusion list
- if (tryHere && excludes != null) {
- for (int i = 0; i < this.excludes.length; i++) {
- if (WildcardHelper.match(null, name, excludes[i])) {
- tryHere = false;
- break;
- }
- }
- }
-
- return tryHere;
- }
-
- /**
- * Loads the class from this <code>ClassLoader</class>. If the
- * class does not exist in this one, we check the parent. Please
- * note that this is the exact opposite of the
- * <code>ClassLoader</code> spec. We use it to work around
- * inconsistent class loaders from third party vendors.
- *
- * @param name the name of the class
- * @param resolve if <code>true</code> then resolve the class
- * @return the resulting <code>Class</code> object
- * @exception ClassNotFoundException if the class could not be found
- */
- public final Class loadClass(String name, boolean resolve) throws ClassNotFoundException {
- // First check if it's already loaded
- Class clazz = findLoadedClass(name);
-
- if (clazz == null) {
-
- ClassLoader parent = getParent();
-
- if (tryClassHere(name)) {
- try {
- clazz = findClass(name);
- //System.err.println("Paranoid load : " + name);
- } catch (ClassNotFoundException cnfe) {
- if (parent == null) {
- // Propagate exception
- throw cnfe;
- }
- }
- }
-
- if (clazz == null) {
- if (parent == null) {
- throw new ClassNotFoundException(name);
- } else {
- // Will throw a CFNE if not found in parent
- clazz = parent.loadClass(name);
- }
- }
- }
-
- if (resolve) {
- resolveClass(clazz);
- }
-
- return clazz;
- }
-
- /**
- * Gets a resource from this <code>ClassLoader</class>. If the
- * resource does not exist in this one, we check the parent.
- * Please note that this is the exact opposite of the
- * <code>ClassLoader</code> spec. We use it to work around
- * inconsistent class loaders from third party vendors.
- *
- * @param name of resource
- */
- public final URL getResource(final String name) {
-
- URL resource = findResource(name);
- ClassLoader parent = this.getParent();
- if (resource == null && parent != null) {
- resource = parent.getResource(name);
- }
-
- return resource;
- }
- }
-
- /* (non-Javadoc)
- * @see org.apache.avalon.framework.activity.Disposable#dispose()
- */
- public void dispose() {
- this.manager.release(this.resolver);
}
}
Added: cocoon/trunk/core/cocoon-core/src/main/java/org/apache/cocoon/components/classloader/ReloadingClassLoader.java
URL: http://svn.apache.org/viewvc/cocoon/trunk/core/cocoon-core/src/main/java/org/apache/cocoon/components/classloader/ReloadingClassLoader.java?rev=407761&view=auto
==============================================================================
--- cocoon/trunk/core/cocoon-core/src/main/java/org/apache/cocoon/components/classloader/ReloadingClassLoader.java (added)
+++ cocoon/trunk/core/cocoon-core/src/main/java/org/apache/cocoon/components/classloader/ReloadingClassLoader.java Fri May 19 02:57:42 2006
@@ -0,0 +1,79 @@
+/*
+ * Copyright 2002-2006 The Apache Software Foundation
+ * Licensed 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.cocoon.components.classloader;
+
+import java.net.URL;
+import java.net.URLStreamHandlerFactory;
+
+import org.apache.commons.jci.stores.ResourceStore;
+
+/**
+ * @version $Id$
+ */
+public class ReloadingClassLoader extends DefaultClassLoader {
+
+ private ResourceStore[] stores = new ResourceStore[0];
+
+ /**
+ * Alternate constructor to define a parent and initial <code>URL</code>
+ * s.
+ */
+ public ReloadingClassLoader(URL[] urls, int[][] includes, int[][] excludes, final ClassLoader parent) {
+ this(urls, includes, excludes, parent, null);
+ }
+
+ /**
+ * Alternate constructor to define a parent, initial <code>URL</code>s,
+ * and a default <code>URLStreamHandlerFactory</code>.
+ */
+ public ReloadingClassLoader(final URL[] urls, int[][] includes, int[][] excludes, ClassLoader parent, URLStreamHandlerFactory factory) {
+ super(urls, includes, excludes, parent, factory);
+ }
+
+ public void addResourceStore(final ResourceStore pStore) {
+ final int n = this.stores.length;
+ final ResourceStore[] newStores = new ResourceStore[n + 1];
+ System.arraycopy(this.stores, 0, newStores, 0, n);
+ newStores[n] = pStore;
+ this.stores = newStores;
+ }
+
+ private Class fastFindClass(final String name) {
+
+ if (stores != null) {
+ for (int i = 0; i < stores.length; i++) {
+ final ResourceStore store = stores[i];
+ final byte[] clazzBytes = store.read(name);
+ if (clazzBytes != null) {
+ return defineClass(name, clazzBytes, 0, clazzBytes.length);
+ }
+ }
+ }
+
+ return null;
+ }
+
+ protected Class getClass(String name) throws ClassNotFoundException {
+ Class clazz = fastFindClass(name);
+
+ if (clazz == null) {
+ return super.getClass(name);
+ }
+ return clazz;
+ }
+}
+
Propchange: cocoon/trunk/core/cocoon-core/src/main/java/org/apache/cocoon/components/classloader/ReloadingClassLoader.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: cocoon/trunk/core/cocoon-core/src/main/java/org/apache/cocoon/components/classloader/ReloadingClassLoader.java
------------------------------------------------------------------------------
svn:keywords = Id
Modified: cocoon/trunk/core/cocoon-core/src/main/java/org/apache/cocoon/components/classloader/ReloadingClassLoaderFactory.java
URL: http://svn.apache.org/viewvc/cocoon/trunk/core/cocoon-core/src/main/java/org/apache/cocoon/components/classloader/ReloadingClassLoaderFactory.java?rev=407761&r1=407760&r2=407761&view=diff
==============================================================================
--- cocoon/trunk/core/cocoon-core/src/main/java/org/apache/cocoon/components/classloader/ReloadingClassLoaderFactory.java (original)
+++ cocoon/trunk/core/cocoon-core/src/main/java/org/apache/cocoon/components/classloader/ReloadingClassLoaderFactory.java Fri May 19 02:57:42 2006
@@ -17,290 +17,14 @@
package org.apache.cocoon.components.classloader;
import java.net.URL;
-import java.net.URLClassLoader;
-import java.net.URLStreamHandlerFactory;
-import java.util.ArrayList;
-import java.util.Iterator;
-import java.util.List;
-import org.apache.avalon.framework.activity.Disposable;
-import org.apache.avalon.framework.configuration.Configuration;
-import org.apache.avalon.framework.configuration.ConfigurationException;
-import org.apache.avalon.framework.logger.AbstractLogEnabled;
-import org.apache.avalon.framework.service.ServiceException;
-import org.apache.avalon.framework.service.ServiceManager;
-import org.apache.avalon.framework.service.Serviceable;
-import org.apache.avalon.framework.thread.ThreadSafe;
-import org.apache.cocoon.matching.helpers.WildcardHelper;
-import org.apache.commons.jci.stores.ResourceStore;
-import org.apache.excalibur.source.Source;
-import org.apache.excalibur.source.SourceResolver;
-import org.apache.excalibur.source.TraversableSource;
/**
- * Default implementation of {@link ClassLoaderFactory}. It accepts both class directory and jar
- * directory configurations.
- * <p>
- * Wildcard patterns can also be specified to include or exclude some classes to be loaded in the
- * classloader. In such case, the class is directly loaded from the parent classloader. The default
- * is to include all classes.
- * <p>
- * Example:
- * <pre>
- * <classpath>
- * <class-dir src="BLOCK-INF/classes"/>
- * <lib-dir src="BLOCK-INF/lib"/>
- * <include-classes pattern="org.apache.cocoon.**"/>
- * <exclude-classes pattern="org.apache.cocoon.transformation.**"/>
- * &/lt;classpath>
- * </pre>
+ * @see AbstractClassLoaderFactory
+ * @version $Id$
*/
-public class ReloadingClassLoaderFactory extends AbstractLogEnabled implements ClassLoaderFactory,
- Serviceable, ThreadSafe, Disposable {
+public class ReloadingClassLoaderFactory extends AbstractClassLoaderFactory {
- private ServiceManager manager;
- private SourceResolver resolver;
-
- /* (non-Javadoc)
- * @see org.apache.avalon.framework.service.Serviceable#service(org.apache.avalon.framework.service.ServiceManager)
- */
- public void service(ServiceManager manager) throws ServiceException {
- this.manager = manager;
- this.resolver = (SourceResolver)manager.lookup(SourceResolver.ROLE);
- }
-
- private void ensureIsDirectory(Source src, String location) throws ConfigurationException {
- if (!src.exists()) {
- throw new ConfigurationException(src.getURI() + " doesn't exist, at " + location);
- } else if (!(src instanceof TraversableSource) || !((TraversableSource)src).isCollection()) {
- throw new ConfigurationException(src.getURI() + " is not a directory, at " + location);
- }
- }
-
- /* (non-Javadoc)
- * @see org.apache.cocoon.core.ClassLoaderFactory#createClassLoader(java.lang.ClassLoader)
- */
- public ClassLoader createClassLoader(ClassLoader parent, Configuration config) throws ConfigurationException {
- List urlList = new ArrayList();
-
- Configuration[] libDirConfig = config.getChildren("lib-dir");
- for (int i = 0; i < libDirConfig.length; i++) {
- Configuration child = libDirConfig[i];
-
- Source src = null;
- try {
- src = resolver.resolveURI(child.getAttribute("src"));
- ensureIsDirectory(src, child.getLocation());
- Iterator iter = ((TraversableSource)src).getChildren().iterator();
- while (iter.hasNext()) {
- Source childSrc = (Source)iter.next();
- String childURI = childSrc.getURI();
- resolver.release(childSrc);
- if (childURI.endsWith(".jar") || childURI.endsWith(".zip")) {
- urlList.add(new URL(childURI));
- }
- }
- } catch(ConfigurationException ce) {
- throw ce;
- } catch(Exception e) {
- throw new ConfigurationException("Error loading classpath at " + child.getLocation(), e);
- } finally {
- resolver.release(src);
- src = null;
- }
- }
-
- URL[] urls = (URL[])urlList.toArray(new URL[urlList.size()]);
-
- int[][] includes = compilePatterns(config.getChildren("include-classes"));
- int[][] excludes = compilePatterns(config.getChildren("exclude-classes"));
-
- return new DefaultClassLoader(urls, includes, excludes, parent);
- }
-
- private int[][] compilePatterns(Configuration[] patternConfigs) throws ConfigurationException {
- if (patternConfigs.length == 0) {
- return null;
- }
-
- int[][] patterns = new int[patternConfigs.length][];
-
- for (int i = 0; i < patternConfigs.length; i++) {
- patterns[i] = WildcardHelper.compilePattern(patternConfigs[i].getAttribute("pattern"));
- }
-
- return patterns;
- }
-
- public class DefaultClassLoader extends URLClassLoader {
-
- private ResourceStore[] stores = new ResourceStore[0];
- private final int[][] includes;
- private final int[][] excludes;
-
- /**
- * Alternate constructor to define a parent and initial <code>URL</code>
- * s.
- */
- public DefaultClassLoader(URL[] urls, int[][] includes, int[][] excludes, final ClassLoader parent) {
- this(urls, includes, excludes, parent, null);
- }
-
- /**
- * Alternate constructor to define a parent, initial <code>URL</code>s,
- * and a default <code>URLStreamHandlerFactory</code>.
- */
- public DefaultClassLoader(final URL[] urls, int[][] includes, int[][] excludes, ClassLoader parent, URLStreamHandlerFactory factory) {
- super(urls, parent, factory);
- this.includes = includes;
- this.excludes = excludes;
- }
-
-
- public void addResourceStore(final ResourceStore pStore) {
- final int n = this.stores.length;
- final ResourceStore[] newStores = new ResourceStore[n + 1];
- System.arraycopy(this.stores, 0, newStores, 0, n);
- newStores[n] = pStore;
- this.stores = newStores;
- if (getLogger().isDebugEnabled()) {
- getLogger().debug("added store " + stores);
- }
- }
-
- private Class fastFindClass(final String name) {
-
- if (stores != null) {
- for (int i = 0; i < stores.length; i++) {
- final ResourceStore store = stores[i];
- final byte[] clazzBytes = store.read(name);
- if (clazzBytes != null) {
-
- if (getLogger().isDebugEnabled()) {
- getLogger().debug("found class " + name + " in stores");
- }
-
- return defineClass(name, clazzBytes, 0, clazzBytes.length);
- }
- }
- }
-
- if (getLogger().isDebugEnabled()) {
- getLogger().debug("did not find class " + name + " in stores");
- }
-
- return null;
- }
-
- private boolean tryClassHere(String name) {
- // Scan includes, then excludes
- boolean tryHere;
-
- // If no explicit includes, try here
- if (this.includes == null) {
- tryHere = true;
- } else {
- // See if it matches include patterns
- tryHere = false;
- for (int i = 0; i < this.includes.length; i++) {
- if (WildcardHelper.match(null, name, includes[i])) {
- tryHere = true;
- break;
- }
- }
- }
-
- // Go through the exclusion list
- if (tryHere && excludes != null) {
- for (int i = 0; i < this.excludes.length; i++) {
- if (WildcardHelper.match(null, name, excludes[i])) {
- tryHere = false;
- break;
- }
- }
- }
-
- return tryHere;
- }
-
- /**
- * Loads the class from this <code>ClassLoader</class>. If the
- * class does not exist in this one, we check the parent. Please
- * note that this is the exact opposite of the
- * <code>ClassLoader</code> spec. We use it to work around
- * inconsistent class loaders from third party vendors.
- *
- * @param name the name of the class
- * @param resolve if <code>true</code> then resolve the class
- * @return the resulting <code>Class</code> object
- * @exception ClassNotFoundException if the class could not be found
- */
- public final Class loadClass(String name, boolean resolve) throws ClassNotFoundException {
- // First check if it's already loaded
- Class clazz = findLoadedClass(name);
-
- if (clazz == null) {
-
- ClassLoader parent = getParent();
-
- if (tryClassHere(name)) {
-
- clazz = fastFindClass(name);
-
- if (clazz == null) {
- try {
- clazz = findClass(name);
- //System.err.println("Paranoid load : " + name);
- } catch (ClassNotFoundException cnfe) {
- if (parent == null) {
- // Propagate exception
- throw cnfe;
- }
- }
- }
- }
-
- if (clazz == null) {
- if (parent == null) {
- throw new ClassNotFoundException(name);
- } else {
- // Will throw a CFNE if not found in parent
- clazz = parent.loadClass(name);
- }
- }
- }
-
- if (resolve) {
- resolveClass(clazz);
- }
-
- return clazz;
- }
-
- /**
- * Gets a resource from this <code>ClassLoader</class>. If the
- * resource does not exist in this one, we check the parent.
- * Please note that this is the exact opposite of the
- * <code>ClassLoader</code> spec. We use it to work around
- * inconsistent class loaders from third party vendors.
- *
- * @param name of resource
- */
- public final URL getResource(final String name) {
-
- URL resource = findResource(name);
- ClassLoader parent = this.getParent();
- if (resource == null && parent != null) {
- resource = parent.getResource(name);
- }
-
- return resource;
- }
- }
-
- /* (non-Javadoc)
- * @see org.apache.avalon.framework.activity.Disposable#dispose()
- */
- public void dispose() {
- this.manager.release(this.resolver);
+ protected ClassLoader createClassLoader(URL[] urls, int[][] includes, int[][] excludes, ClassLoader parent) {
+ return new ReloadingClassLoader(urls, includes, excludes, parent);
}
}