You are viewing a plain text version of this content. The canonical link for it is here.
Posted to cvs@cocoon.apache.org by tc...@apache.org on 2005/09/24 15:25:25 UTC
svn commit: r291301 - in /cocoon:
blocks/javaflow/trunk/java/org/apache/cocoon/components/flow/java/
blocks/xsp/trunk/java/org/apache/cocoon/components/language/programming/java/
trunk/lib/ trunk/lib/core/ trunk/lib/optional/ trunk/src/java/org/apache/...
Author: tcurdt
Date: Sat Sep 24 06:22:13 2005
New Revision: 291301
URL: http://svn.apache.org/viewcvs?rev=291301&view=rev
Log:
upgraded and further integrated the latest jci and javaflow,
the introduced dependency of the core on javaflow is just temporary,
also upgraded the jdtcore
Added:
cocoon/trunk/lib/core/commons-javaflow-r291286.jar (with props)
cocoon/trunk/lib/core/commons-jci-r291284.jar (with props)
cocoon/trunk/lib/optional/jdtcore-3.1.0.jar (with props)
cocoon/trunk/src/java/org/apache/cocoon/components/classloader/ReloadingClassLoaderFactory.java
Removed:
cocoon/trunk/lib/core/commons-jci-r159148.jar
cocoon/trunk/lib/optional/commons-javaflow-0.1-dev.jar
cocoon/trunk/lib/optional/jdtcore-3.0.2.jar
Modified:
cocoon/blocks/javaflow/trunk/java/org/apache/cocoon/components/flow/java/CocoonContinuationContext.java
cocoon/blocks/javaflow/trunk/java/org/apache/cocoon/components/flow/java/JavaInterpreter.java
cocoon/blocks/xsp/trunk/java/org/apache/cocoon/components/language/programming/java/EclipseJavaCompiler.java
cocoon/trunk/lib/jars.xml
cocoon/trunk/src/java/org/apache/cocoon/components/fam/SitemapMonitor.java
cocoon/trunk/src/java/org/apache/cocoon/components/fam/SitemapMonitorImpl.java
cocoon/trunk/src/java/org/apache/cocoon/components/treeprocessor/ConcreteTreeProcessor.java
cocoon/trunk/src/java/org/apache/cocoon/components/treeprocessor/DefaultTreeBuilder.java
cocoon/trunk/src/java/org/apache/cocoon/components/treeprocessor/TreeProcessor.java
cocoon/trunk/src/java/org/apache/cocoon/components/treeprocessor/sitemap/SitemapLanguage.java
Modified: cocoon/blocks/javaflow/trunk/java/org/apache/cocoon/components/flow/java/CocoonContinuationContext.java
URL: http://svn.apache.org/viewcvs/cocoon/blocks/javaflow/trunk/java/org/apache/cocoon/components/flow/java/CocoonContinuationContext.java?rev=291301&r1=291300&r2=291301&view=diff
==============================================================================
--- cocoon/blocks/javaflow/trunk/java/org/apache/cocoon/components/flow/java/CocoonContinuationContext.java (original)
+++ cocoon/blocks/javaflow/trunk/java/org/apache/cocoon/components/flow/java/CocoonContinuationContext.java Sat Sep 24 06:22:13 2005
@@ -20,7 +20,6 @@
import org.apache.avalon.framework.parameters.Parameters;
import org.apache.avalon.framework.service.ServiceManager;
import org.apache.cocoon.environment.Redirector;
-import org.apache.commons.javaflow.ContinuationContext;
/**
* Helper class to associate cocoon flow informations to the continuation.
@@ -29,7 +28,7 @@
* @author <a href="mailto:stephan@apache.org">Stephan Michels</a>
* @version CVS $Id$
*/
-public class CocoonContinuationContext extends ContinuationContext {
+public class CocoonContinuationContext {
private Logger logger;
private Context avalonContext;
Modified: cocoon/blocks/javaflow/trunk/java/org/apache/cocoon/components/flow/java/JavaInterpreter.java
URL: http://svn.apache.org/viewcvs/cocoon/blocks/javaflow/trunk/java/org/apache/cocoon/components/flow/java/JavaInterpreter.java?rev=291301&r1=291300&r2=291301&view=diff
==============================================================================
--- cocoon/blocks/javaflow/trunk/java/org/apache/cocoon/components/flow/java/JavaInterpreter.java (original)
+++ cocoon/blocks/javaflow/trunk/java/org/apache/cocoon/components/flow/java/JavaInterpreter.java Sat Sep 24 06:22:13 2005
@@ -15,12 +15,12 @@
*/
package org.apache.cocoon.components.flow.java;
+import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
-
import org.apache.avalon.framework.parameters.Parameters;
import org.apache.cocoon.ProcessingException;
import org.apache.cocoon.components.ContextHelper;
@@ -30,7 +30,6 @@
import org.apache.cocoon.components.flow.WebContinuation;
import org.apache.cocoon.environment.Redirector;
import org.apache.commons.javaflow.Continuation;
-import org.apache.commons.javaflow.MethodLookup;
import org.apache.commons.javaflow.utils.ReflectionUtils;
import org.apache.commons.jxpath.JXPathIntrospector;
@@ -62,13 +61,26 @@
private Map methods = new HashMap();
- private MethodLookup lookup = new MethodLookup() {
- public Method getMethod(final String methodName) {
- final Method method = (Method) methods.get(methodName);
- return method;
+ private class Invoker implements Runnable {
+ private final Method method;
+ private final Object instance;
+
+ public Invoker(Method method) throws IllegalAccessException, InstantiationException {
+ this.method = method;
+ this.instance = method.getDeclaringClass().newInstance();
+ }
+
+ public void run() {
+ try {
+ method.invoke(instance, new Object[0]);
+ } catch (IllegalAccessException e) {
+ getLogger().error("", e);
+ } catch (InvocationTargetException e) {
+ getLogger().error("", e);
+ }
}
-
- };
+ }
+
private CocoonContinuationContext createContinuationContext( final List params, final Redirector redirector ) {
final CocoonContinuationContext context = new CocoonContinuationContext();
@@ -77,7 +89,6 @@
context.setLogger(getLogger());
context.setServiceManager(manager);
context.setRedirector(redirector);
- context.setMethodLookup(lookup);
final Parameters parameters = new Parameters();
for(final Iterator i = params.iterator(); i.hasNext();) {
@@ -146,7 +157,8 @@
// REVISIT: subscribe to jci events and only update accordingly
updateMethodIndex();
- if (lookup.getMethod(methodName) == null) {
+ final Method method = (Method) methods.get(methodName);
+ if (method == null) {
throw new ProcessingException("no method '" + methodName + "' found in " + methods);
}
@@ -160,7 +172,7 @@
FlowHelper.setWebContinuation(
ContextHelper.getObjectModel(avalonContext), wk);
- final Continuation newContinuation = Continuation.startWith(methodName, context);
+ final Continuation newContinuation = Continuation.startWith(new Invoker(method), context);
handler.setContinuation(newContinuation);
}
Modified: cocoon/blocks/xsp/trunk/java/org/apache/cocoon/components/language/programming/java/EclipseJavaCompiler.java
URL: http://svn.apache.org/viewcvs/cocoon/blocks/xsp/trunk/java/org/apache/cocoon/components/language/programming/java/EclipseJavaCompiler.java?rev=291301&r1=291300&r2=291301&view=diff
==============================================================================
--- cocoon/blocks/xsp/trunk/java/org/apache/cocoon/components/language/programming/java/EclipseJavaCompiler.java (original)
+++ cocoon/blocks/xsp/trunk/java/org/apache/cocoon/components/language/programming/java/EclipseJavaCompiler.java Sat Sep 24 06:22:13 2005
@@ -250,7 +250,7 @@
ICompilationUnit compilationUnit =
new CompilationUnit(sourceFile, className);
return
- new NameEnvironmentAnswer(compilationUnit);
+ new NameEnvironmentAnswer(compilationUnit, null);
}
String resourceName =
className.replace('.', '/') + ".class";
@@ -272,7 +272,7 @@
new ClassFileReader(classBytes, fileName,
true);
return
- new NameEnvironmentAnswer(classFileReader);
+ new NameEnvironmentAnswer(classFileReader, null);
}
} catch (IOException exc) {
handleError(className, -1, -1,
Added: cocoon/trunk/lib/core/commons-javaflow-r291286.jar
URL: http://svn.apache.org/viewcvs/cocoon/trunk/lib/core/commons-javaflow-r291286.jar?rev=291301&view=auto
==============================================================================
Binary file - no diff available.
Propchange: cocoon/trunk/lib/core/commons-javaflow-r291286.jar
------------------------------------------------------------------------------
svn:mime-type = application/octet-stream
Added: cocoon/trunk/lib/core/commons-jci-r291284.jar
URL: http://svn.apache.org/viewcvs/cocoon/trunk/lib/core/commons-jci-r291284.jar?rev=291301&view=auto
==============================================================================
Binary file - no diff available.
Propchange: cocoon/trunk/lib/core/commons-jci-r291284.jar
------------------------------------------------------------------------------
svn:mime-type = application/octet-stream
Modified: cocoon/trunk/lib/jars.xml
URL: http://svn.apache.org/viewcvs/cocoon/trunk/lib/jars.xml?rev=291301&r1=291300&r2=291301&view=diff
==============================================================================
--- cocoon/trunk/lib/jars.xml (original)
+++ cocoon/trunk/lib/jars.xml Sat Sep 24 06:22:13 2005
@@ -608,7 +608,7 @@
<title>Eclipse Java Development Tools Core</title>
<description>Eclipse Java Compiler</description>
<used-by>XSP</used-by>
- <lib>optional/jdtcore-3.0.2.jar</lib>
+ <lib>optional/jdtcore-3.1.0.jar</lib>
<homepage>http://www.eclipse.org/jdt/</homepage>
</file>
@@ -1149,7 +1149,7 @@
API for compiling java
</description>
<used-by>javaflow</used-by>
- <lib>core/commons-jci-r159148.jar</lib>
+ <lib>core/commons-jci-r291284.jar</lib>
<homepage></homepage>
</file>
@@ -1159,7 +1159,7 @@
API java continuations
</description>
<used-by>javaflow</used-by>
- <lib>optional/commons-javaflow-0.1-dev.jar</lib>
+ <lib>core/commons-javaflow-r291286.jar</lib>
<homepage></homepage>
</file>
Added: cocoon/trunk/lib/optional/jdtcore-3.1.0.jar
URL: http://svn.apache.org/viewcvs/cocoon/trunk/lib/optional/jdtcore-3.1.0.jar?rev=291301&view=auto
==============================================================================
Binary file - no diff available.
Propchange: cocoon/trunk/lib/optional/jdtcore-3.1.0.jar
------------------------------------------------------------------------------
svn:mime-type = application/octet-stream
Added: cocoon/trunk/src/java/org/apache/cocoon/components/classloader/ReloadingClassLoaderFactory.java
URL: http://svn.apache.org/viewcvs/cocoon/trunk/src/java/org/apache/cocoon/components/classloader/ReloadingClassLoaderFactory.java?rev=291301&view=auto
==============================================================================
--- cocoon/trunk/src/java/org/apache/cocoon/components/classloader/ReloadingClassLoaderFactory.java (added)
+++ cocoon/trunk/src/java/org/apache/cocoon/components/classloader/ReloadingClassLoaderFactory.java Sat Sep 24 06:22:13 2005
@@ -0,0 +1,306 @@
+/*
+ * Copyright 2002-2005 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 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>
+ */
+public class ReloadingClassLoaderFactory extends AbstractLogEnabled implements ClassLoaderFactory,
+ Serviceable, ThreadSafe, Disposable {
+
+ 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 = stores.length;
+ final ResourceStore[] newStores = new ResourceStore[n + 1];
+ System.arraycopy(stores, 0, newStores, 0, n);
+ newStores[n] = pStore;
+ 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);
+ }
+}
Modified: cocoon/trunk/src/java/org/apache/cocoon/components/fam/SitemapMonitor.java
URL: http://svn.apache.org/viewcvs/cocoon/trunk/src/java/org/apache/cocoon/components/fam/SitemapMonitor.java?rev=291301&r1=291300&r2=291301&view=diff
==============================================================================
--- cocoon/trunk/src/java/org/apache/cocoon/components/fam/SitemapMonitor.java (original)
+++ cocoon/trunk/src/java/org/apache/cocoon/components/fam/SitemapMonitor.java Sat Sep 24 06:22:13 2005
@@ -16,14 +16,11 @@
*/
package org.apache.cocoon.components.fam;
-import org.apache.avalon.framework.configuration.Configuration;
-import org.apache.avalon.framework.configuration.ConfigurationException;
import org.apache.commons.jci.monitor.FilesystemAlterationListener;
public interface SitemapMonitor {
String ROLE = SitemapMonitor.class.getName();
-
- void subscribeSitemap( FilesystemAlterationListener listener, Configuration sitemap ) throws ConfigurationException;
-
- void unsubscribeSitemap( FilesystemAlterationListener listener);
+
+ void subscribe(final FilesystemAlterationListener listener);
+ void unsubscribe(final FilesystemAlterationListener listener);
}
Modified: cocoon/trunk/src/java/org/apache/cocoon/components/fam/SitemapMonitorImpl.java
URL: http://svn.apache.org/viewcvs/cocoon/trunk/src/java/org/apache/cocoon/components/fam/SitemapMonitorImpl.java?rev=291301&r1=291300&r2=291301&view=diff
==============================================================================
--- cocoon/trunk/src/java/org/apache/cocoon/components/fam/SitemapMonitorImpl.java (original)
+++ cocoon/trunk/src/java/org/apache/cocoon/components/fam/SitemapMonitorImpl.java Sat Sep 24 06:22:13 2005
@@ -16,13 +16,8 @@
*/
package org.apache.cocoon.components.fam;
-import java.io.File;
-import java.util.ArrayList;
-import java.util.List;
import org.apache.avalon.framework.activity.Disposable;
import org.apache.avalon.framework.activity.Initializable;
-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;
@@ -30,77 +25,33 @@
import org.apache.avalon.framework.thread.ThreadSafe;
import org.apache.commons.jci.monitor.FilesystemAlterationListener;
import org.apache.commons.jci.monitor.FilesystemAlterationMonitor;
-import org.apache.excalibur.source.Source;
import org.apache.excalibur.source.SourceResolver;
public final class SitemapMonitorImpl extends AbstractLogEnabled implements SitemapMonitor, Serviceable, ThreadSafe, Initializable, Disposable {
private ServiceManager manager;
private SourceResolver resolver;
- private FilesystemAlterationMonitor monitor = new FilesystemAlterationMonitor();
-
+ private FilesystemAlterationMonitor monitor;
public void service( ServiceManager manager ) throws ServiceException {
this.manager = manager;
this.resolver = (SourceResolver) manager.lookup(SourceResolver.ROLE);
}
- private File[] parseConfiguration(Configuration config) throws ConfigurationException {
- List urlList = new ArrayList();
- Configuration[] children = config.getChild("components").getChild("classpath").getChildren();
- for (int i = 0; i < children.length; i++) {
- Configuration child = children[i];
- String name = child.getName();
- Source src = null;
- try {
- if ("class-dir".equals(name)) {
- src = resolver.resolveURI(child.getAttribute("src"));
- String dir = src.getURI();
- resolver.release(src);
- if (getLogger().isDebugEnabled()) {
- getLogger().debug("class-dir:" + dir);
- }
- urlList.add(new File(dir.substring(5)));
- } else if ("lib-dir".equals(name)) {
- src = resolver.resolveURI(child.getAttribute("src"));
- String dir = src.getURI();
- resolver.release(src);
- if (getLogger().isDebugEnabled()) {
- getLogger().debug("lib-dir:" + dir);
- }
- urlList.add(new File(dir.substring(5)));
- } else {
- // ignore for now include and exclude patterns
- }
- } catch(ConfigurationException ce) {
- resolver.release(src);
- throw ce;
- } catch(Exception e) {
- resolver.release(src);
- throw new ConfigurationException("Error loading " + name + " at " + child.getLocation(), e);
- }
- }
-
- return (File[])urlList.toArray(new File[urlList.size()]);
- }
-
- public void subscribeSitemap( FilesystemAlterationListener listener, Configuration sitemap ) throws ConfigurationException {
- File[] dirs = parseConfiguration(sitemap);
- for (int i = 0; i < dirs.length; i++) {
- monitor.addListener(listener, dirs[i]);
- }
+ public void initialize() throws Exception {
+ monitor = new FilesystemAlterationMonitor();
+ monitor.start();
}
- public void unsubscribeSitemap( FilesystemAlterationListener listener) {
- monitor.removeListener(listener);
+ public void dispose() {
+ monitor.stop();
}
- public void initialize() throws Exception {
- Thread myThread = new Thread(monitor);
- myThread.start();
+ public void subscribe(final FilesystemAlterationListener listener) {
+ monitor.addListener(listener);
}
-
-
- public void dispose() {
+
+ public void unsubscribe(final FilesystemAlterationListener listener) {
+ monitor.removeListener(listener);
}
}
Modified: cocoon/trunk/src/java/org/apache/cocoon/components/treeprocessor/ConcreteTreeProcessor.java
URL: http://svn.apache.org/viewcvs/cocoon/trunk/src/java/org/apache/cocoon/components/treeprocessor/ConcreteTreeProcessor.java?rev=291301&r1=291300&r2=291301&view=diff
==============================================================================
--- cocoon/trunk/src/java/org/apache/cocoon/components/treeprocessor/ConcreteTreeProcessor.java (original)
+++ cocoon/trunk/src/java/org/apache/cocoon/components/treeprocessor/ConcreteTreeProcessor.java Sat Sep 24 06:22:13 2005
@@ -15,14 +15,12 @@
*/
package org.apache.cocoon.components.treeprocessor;
-import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
-
import org.apache.avalon.framework.activity.Disposable;
import org.apache.avalon.framework.configuration.Configuration;
import org.apache.avalon.framework.container.ContainerUtil;
@@ -48,7 +46,7 @@
import org.apache.cocoon.sitemap.SitemapListener;
import org.apache.cocoon.util.location.Location;
import org.apache.cocoon.util.location.LocationImpl;
-import org.apache.commons.jci.monitor.FilesystemAlterationListener;
+import org.apache.commons.jci.listeners.NotificationListener;
/**
* The concrete implementation of {@link Processor}, containing the evaluation tree and associated
@@ -57,7 +55,7 @@
* @version $Id$
*/
public class ConcreteTreeProcessor extends AbstractLogEnabled
- implements Processor, Disposable, FilesystemAlterationListener, ExecutionContext {
+ implements Processor, Disposable, ExecutionContext, NotificationListener {
/** Our ServiceManager */
private ServiceManager manager;
@@ -93,82 +91,11 @@
/** Needs a reload? */
protected volatile boolean needsReload = false;
- protected boolean fresh = true;
/** Processor attributes */
protected Map processorAttributes = new HashMap();
- public void onChangeDirectory( final File changeDirectory ) {
- if (!fresh) {
- if (getLogger().isDebugEnabled()) {
- getLogger().debug("Sitemap reload required");
- }
- needsReload = true;
- }
- }
-
- public void onChangeFile( final File changedFile ) {
- if (!fresh) {
- if (getLogger().isDebugEnabled()) {
- getLogger().debug("Sitemap reload required");
- }
- needsReload = true;
- }
- }
-
- public void onCreateDirectory( final File createdDirectory ) {
- if (!fresh) {
- if (getLogger().isDebugEnabled()) {
- getLogger().debug("Sitemap reload required");
- }
- needsReload = true;
- }
- }
-
- public void onCreateFile( final File createdFile ) {
- if (!fresh) {
- if (getLogger().isDebugEnabled()) {
- getLogger().debug("Sitemap reload required");
- }
- needsReload = true;
- }
- }
-
- public void onDeleteDirectory( final File deletedDirectory ) {
- if (!fresh) {
- if (getLogger().isDebugEnabled()) {
- getLogger().debug("Sitemap reload required");
- }
- needsReload = true;
- }
- }
-
- public void onDeleteFile( final File deletedFile ) {
- if (!fresh) {
- if (getLogger().isDebugEnabled()) {
- getLogger().debug("Sitemap reload required");
- }
- needsReload = true;
- }
- }
-
- /**
- * @see org.apache.commons.jci.monitor.FilesystemAlterationListener#onStart()
- */
- public void onStart() {
- // nothing to do
- }
-
- /**
- * @see org.apache.commons.jci.monitor.FilesystemAlterationListener#onStop()
- */
- public void onStop() {
- if (getLogger().isDebugEnabled()) {
- getLogger().debug("Now tracking classpath changes");
- }
- fresh = false;
- }
-
+ private Map classpathListeners;
/**
* Builds a concrete processig, given the wrapping processor
@@ -179,17 +106,32 @@
this.wrappingProcessor = wrappingProcessor;
// Get the sitemap executor - we use the same executor for each sitemap
- this.sitemapExecutor = sitemapExecutor;
+ this.sitemapExecutor = sitemapExecutor;
}
+ public void handleNotification() {
+ if (getLogger().isDebugEnabled()) {
+ getLogger().debug(this + " got notified that a reload is required");
+ }
+ needsReload = true;
+ }
+
+ public void setClasspathListeners(Map classpathListeners) {
+ this.classpathListeners = classpathListeners;
+ }
+
+ public Map getClasspathListeners() {
+ return this.classpathListeners;
+ }
+
/** Set the processor data, result of the treebuilder job */
public void setProcessorData(ServiceManager manager,
ClassLoader classloader,
ProcessingNode rootNode,
List disposableNodes,
ComponentLocator componentLocator,
- List enterSitemapEventListeners,
- List leaveSitemapEventListeners) {
+ List enterSitemapEventListeners,
+ List leaveSitemapEventListeners) {
if (this.rootNode != null) {
throw new IllegalStateException("setProcessorData() can only be called once");
}
Modified: cocoon/trunk/src/java/org/apache/cocoon/components/treeprocessor/DefaultTreeBuilder.java
URL: http://svn.apache.org/viewcvs/cocoon/trunk/src/java/org/apache/cocoon/components/treeprocessor/DefaultTreeBuilder.java?rev=291301&r1=291300&r2=291301&view=diff
==============================================================================
--- cocoon/trunk/src/java/org/apache/cocoon/components/treeprocessor/DefaultTreeBuilder.java (original)
+++ cocoon/trunk/src/java/org/apache/cocoon/components/treeprocessor/DefaultTreeBuilder.java Sat Sep 24 06:22:13 2005
@@ -27,6 +27,7 @@
import org.apache.avalon.framework.configuration.AbstractConfiguration;
import org.apache.avalon.framework.configuration.Configuration;
import org.apache.avalon.framework.configuration.ConfigurationException;
+import org.apache.avalon.framework.configuration.DefaultConfiguration;
import org.apache.avalon.framework.configuration.SAXConfigurationHandler;
import org.apache.avalon.framework.context.Context;
import org.apache.avalon.framework.context.ContextException;
@@ -213,6 +214,12 @@
return this.context;
}
+ protected ClassLoader createClassLoader(Configuration tree) throws Exception {
+ // Useless method as it's redefined in SitemapLanguage
+ // which is the only used incarnation.
+ return Thread.currentThread().getContextClassLoader();
+ }
+
/**
* Create a service manager that will be used for all <code>Serviceable</code>
* <code>ProcessingNodeBuilder</code>s and <code>ProcessingNode</code>s.
@@ -226,11 +233,8 @@
*
* @return a component manager
*/
- protected ServiceManager createServiceManager(Context context, Configuration tree)
+ protected ServiceManager createServiceManager(ClassLoader classloader, Context context, Configuration tree)
throws Exception {
- // Useless method as it's redefined in SitemapLanguage
- // which is the only used incarnation.
- this.itsClassLoader = Thread.currentThread().getContextClassLoader();
return this.manager;
}
@@ -371,9 +375,25 @@
// The namespace used in the whole sitemap is the one of the root element
this.itsNamespace = tree.getNamespace();
- // Context and manager for the sitemap we build
+ Configuration componentConfig = tree.getChild("components", false);
+
+ if (componentConfig == null) {
+ if (getLogger().isDebugEnabled()) {
+ getLogger().debug("Sitemap has no components definition at " + tree.getLocation());
+ }
+ componentConfig = new DefaultConfiguration("", "");
+ }
+
+ // Context and manager and classloader for the sitemap we build
this.itsContext = createContext(tree);
- this.itsManager = createServiceManager(this.itsContext, tree);
+// this.itsClassLoader = createClassLoader(componentConfig);
+//
+// Thread currentThread = Thread.currentThread();
+ //ClassLoader oldClassLoader = currentThread.getContextClassLoader();
+// currentThread.setContextClassLoader(this.itsClassLoader);
+ this.itsClassLoader = Thread.currentThread().getContextClassLoader();
+
+ this.itsManager = createServiceManager(this.itsClassLoader, this.itsContext, componentConfig);
this.itsComponentInfo = (ProcessorComponentInfo)this.itsManager.lookup(ProcessorComponentInfo.ROLE);
// Create a helper object to setup components
Modified: cocoon/trunk/src/java/org/apache/cocoon/components/treeprocessor/TreeProcessor.java
URL: http://svn.apache.org/viewcvs/cocoon/trunk/src/java/org/apache/cocoon/components/treeprocessor/TreeProcessor.java?rev=291301&r1=291300&r2=291301&view=diff
==============================================================================
--- cocoon/trunk/src/java/org/apache/cocoon/components/treeprocessor/TreeProcessor.java (original)
+++ cocoon/trunk/src/java/org/apache/cocoon/components/treeprocessor/TreeProcessor.java Sat Sep 24 06:22:13 2005
@@ -15,8 +15,12 @@
*/
package org.apache.cocoon.components.treeprocessor;
+import java.io.File;
import java.net.URL;
-
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.Map;
import org.apache.avalon.framework.activity.Disposable;
import org.apache.avalon.framework.activity.Initializable;
import org.apache.avalon.framework.configuration.Configurable;
@@ -35,6 +39,8 @@
import org.apache.avalon.framework.thread.ThreadSafe;
import org.apache.cocoon.Processor;
import org.apache.cocoon.components.ContextHelper;
+import org.apache.cocoon.components.classloader.ClassLoaderFactory;
+import org.apache.cocoon.components.classloader.ReloadingClassLoaderFactory;
import org.apache.cocoon.components.fam.SitemapMonitor;
import org.apache.cocoon.components.flow.Interpreter;
import org.apache.cocoon.components.source.SourceUtil;
@@ -44,6 +50,16 @@
import org.apache.cocoon.environment.internal.EnvironmentHelper;
import org.apache.cocoon.sitemap.SitemapExecutor;
import org.apache.cocoon.sitemap.impl.DefaultExecutor;
+import org.apache.commons.jci.compilers.JavaCompiler;
+import org.apache.commons.jci.compilers.eclipse.EclipseJavaCompiler;
+import org.apache.commons.jci.listeners.CompilingListener;
+import org.apache.commons.jci.listeners.FileChangeListener;
+import org.apache.commons.jci.listeners.NotifyingListener;
+import org.apache.commons.jci.listeners.ReloadingListener;
+import org.apache.commons.jci.listeners.ResourceStoringListener;
+import org.apache.commons.jci.monitor.FilesystemAlterationListener;
+import org.apache.commons.jci.stores.ResourceStore;
+import org.apache.commons.jci.stores.TransactionalResourceStore;
import org.apache.excalibur.source.Source;
import org.apache.excalibur.source.SourceResolver;
import org.apache.regexp.RE;
@@ -86,7 +102,7 @@
/** Check for reload? */
protected boolean checkReload;
- protected SitemapMonitor fom;
+ protected SitemapMonitor fam;
/** The source resolver */
protected SourceResolver resolver;
@@ -135,7 +151,7 @@
this.manager = parent.concreteProcessor.getServiceManager();
this.resolver = (SourceResolver) this.manager.lookup(SourceResolver.ROLE);
- this.fom = (SitemapMonitor) this.manager.lookup(SitemapMonitor.ROLE);
+ this.fam = (SitemapMonitor) this.manager.lookup(SitemapMonitor.ROLE);
this.environmentHelper = new EnvironmentHelper(parent.environmentHelper);
// Setup environment helper
ContainerUtil.enableLogging(this.environmentHelper, this.getLogger());
@@ -171,7 +187,7 @@
public void service(ServiceManager manager) throws ServiceException {
this.manager = manager;
this.resolver = (SourceResolver) this.manager.lookup(SourceResolver.ROLE);
- this.fom = (SitemapMonitor) this.manager.lookup(SitemapMonitor.ROLE);
+ this.fam = (SitemapMonitor) this.manager.lookup(SitemapMonitor.ROLE);
}
/**
@@ -179,7 +195,7 @@
*/
public void initialize() throws Exception {
// setup the environment helper
- if (this.environmentHelper == null ) {
+ if (this.environmentHelper == null) {
this.environmentHelper = new EnvironmentHelper(
(URL) this.context.get(ContextHelper.CONTEXT_ROOT_URL));
}
@@ -188,7 +204,7 @@
// Create sitemap executor
if (this.parent == null) {
- if ( this.manager.hasService(SitemapExecutor.ROLE) ) {
+ if (this.manager.hasService(SitemapExecutor.ROLE)) {
this.sitemapExecutor = (SitemapExecutor) this.manager.lookup(SitemapExecutor.ROLE);
this.releaseSitemapExecutor = true;
} else {
@@ -368,7 +384,183 @@
buildConcreteProcessor(env);
}
}
+
+ private JavaCompiler createJavaCompiler(final Configuration config) {
+ // FIXME: extract compiler and compiler configuration from config
+ return new EclipseJavaCompiler();
+ }
+
+ private ResourceStore createResourceStore(final Configuration storeConfig) throws Exception {
+ final String className = storeConfig.getAttribute("class","org.apache.commons.jci.stores.MemoryResourceStore");
+ final ResourceStore store = (ResourceStore) Class.forName(className).newInstance();
+ if (getLogger().isDebugEnabled()) {
+ getLogger().debug("storing resources in " + store.getClass().getName());
+ }
+ return store;
+ }
+
+ private FilesystemAlterationListener createCompilingListener(
+ final Configuration dirConfig
+ ) throws Exception {
+ Source src = null;
+
+ try {
+ src = resolver.resolveURI(dirConfig.getAttribute("src"));
+ final File repository = new File(src.getURI().substring(5));
+
+ if (getLogger().isDebugEnabled()) {
+ getLogger().debug("monitoring src dir " + dirConfig.getAttribute("src"));
+ }
+
+ return new CompilingListener(
+ repository,
+ createJavaCompiler(dirConfig.getChild("compiler")),
+ new TransactionalResourceStore(createResourceStore(dirConfig.getChild("store")))
+ );
+ } finally {
+ resolver.release(src);
+ }
+ }
+
+ private FilesystemAlterationListener createReloadingListener(
+ final Configuration dirConfig
+ ) throws Exception {
+ Source src = null;
+
+ try {
+ src = resolver.resolveURI(dirConfig.getAttribute("src"));
+ final File repository = new File(src.getURI().substring(5));
+
+ if (getLogger().isDebugEnabled()) {
+ getLogger().debug("monitoring class dir " + dirConfig.getAttribute("src"));
+ }
+
+ return new ReloadingListener(
+ repository,
+ createResourceStore(dirConfig.getChild("store"))
+ );
+ } finally {
+ resolver.release(src);
+ }
+ }
+
+ private FilesystemAlterationListener createFileChangeListener(
+ final Configuration dirConfig
+ ) throws Exception {
+ Source src = null;
+
+ try {
+ src = resolver.resolveURI(dirConfig.getAttribute("src"));
+ final File repository = new File(src.getURI().substring(5));
+
+ if (getLogger().isDebugEnabled()) {
+ getLogger().debug("monitoring lib dir " + dirConfig.getAttribute("src"));
+ }
+
+ return new FileChangeListener(repository);
+ } finally {
+ resolver.release(src);
+ }
+ }
+
+
+ private boolean containsListener(Map map, String src, Class clazz) {
+ FilesystemAlterationListener listener = (FilesystemAlterationListener) map.get(src);
+ if (listener == null) {
+ if (getLogger().isDebugEnabled()) {
+ getLogger().debug("no previous listener for " + src);
+ }
+ return false;
+ }
+ if (!listener.getClass().equals(clazz)) {
+ if (getLogger().isDebugEnabled()) {
+ getLogger().debug("previous listener was of a different type");
+ }
+ return false;
+ }
+
+ return true;
+ }
+
+ private Map createClasspathListeners(Map oldListeners, Configuration classpathConfig) throws Exception {
+
+ final Configuration[] classDirConfigs = classpathConfig.getChildren("class-dir");
+ final Configuration[] srcDirConfigs = classpathConfig.getChildren("src-dir");
+ final Configuration[] libDirConfigs = classpathConfig.getChildren("lib-dir");
+
+ Map newListeners = new HashMap();
+ int r = 0;
+
+ for (int i = 0; i < classDirConfigs.length; i++) {
+ final Configuration dirConfig = classDirConfigs[i];
+ final String src = dirConfig.getAttribute("src");
+ if (containsListener(oldListeners,src, ReloadingListener.class)) {
+ if (getLogger().isDebugEnabled()) {
+ getLogger().debug("keeping ReloadingListener for " + src);
+ }
+ newListeners.put(src, oldListeners.get(src));
+ oldListeners.remove(src);
+ } else {
+ if (getLogger().isDebugEnabled()) {
+ getLogger().debug("new ReloadingListener for " + src);
+ }
+ newListeners.put(src, createReloadingListener(dirConfig));
+ }
+ }
+
+ for (int i = 0; i < srcDirConfigs.length; i++) {
+ final Configuration dirConfig = srcDirConfigs[i];
+ final String src = dirConfig.getAttribute("src");
+ if (containsListener(oldListeners, src, CompilingListener.class)) {
+ if (getLogger().isDebugEnabled()) {
+ getLogger().debug("keeping CompilingListener for " + src);
+ }
+ newListeners.put(src, oldListeners.get(src));
+ oldListeners.remove(src);
+ } else {
+ if (getLogger().isDebugEnabled()) {
+ getLogger().debug("new CompilingListener for " + src);
+ }
+ newListeners.put(src, createCompilingListener(dirConfig));
+ }
+ }
+
+ for (int i = 0; i < libDirConfigs.length; i++) {
+ final Configuration dirConfig = libDirConfigs[i];
+ final String src = dirConfig.getAttribute("src");
+ if (containsListener(oldListeners, src, FileChangeListener.class)) {
+ if (getLogger().isDebugEnabled()) {
+ getLogger().debug("keeping FileChangeListener for " + src);
+ }
+ newListeners.put(src, oldListeners.get(src));
+ oldListeners.remove(src);
+ } else {
+ if (getLogger().isDebugEnabled()) {
+ getLogger().debug("new FileChangeListener for " + src);
+ }
+ newListeners.put(src, createFileChangeListener(dirConfig));
+ }
+ }
+
+ return newListeners;
+ }
+
+ protected ClassLoader createClassLoader(Configuration classpathConfig)
+ throws Exception {
+ String factoryRole = classpathConfig.getAttribute("factory-role", ClassLoaderFactory.ROLE + "/ReloadingClassLoaderFactory");
+ // Create a new classloader
+ ClassLoaderFactory clFactory = (ClassLoaderFactory)this.manager.lookup(factoryRole);
+ try {
+ return clFactory.createClassLoader(
+ Thread.currentThread().getContextClassLoader(),
+ classpathConfig
+ );
+ } finally {
+ this.manager.release(clFactory);
+ }
+ }
+
/**
* Build the concrete processor (i.e. loads the sitemap). Should be called
* only by setupProcessor();
@@ -386,6 +578,20 @@
long newLastModified;
ConcreteTreeProcessor newProcessor;
ConcreteTreeProcessor oldProcessor = this.concreteProcessor;
+ Map oldListeners = Collections.EMPTY_MAP;
+ Map newListeners = Collections.EMPTY_MAP;
+
+ if (oldProcessor != null) {
+ if (getLogger().isDebugEnabled()) {
+ getLogger().debug("found a previous ConcreteTreeProcessor");
+ }
+ oldListeners = oldProcessor.getClasspathListeners();
+ } else {
+ if (getLogger().isDebugEnabled()) {
+ getLogger().debug("first version of the ConcreteTreeProcessor");
+ }
+ }
+
// We have to do a call to enterProcessor() here as during building
// of the tree, components (e.g. actions) are already instantiated
@@ -400,12 +606,69 @@
// Build a namespace-aware configuration object
NamespacedSAXConfigurationHandler handler = new NamespacedSAXConfigurationHandler();
AnnotationsFilter annotationsFilter = new AnnotationsFilter(handler);
- SourceUtil.toSAX(this.source, annotationsFilter );
+ SourceUtil.toSAX(this.source, annotationsFilter);
Configuration sitemapProgram = handler.getConfiguration();
newLastModified = this.source.getLastModified();
newProcessor = createConcreteTreeProcessor();
+ Configuration classpathConfig = sitemapProgram.getChild("components").getChild("classpath", false);
+ if (classpathConfig != null) {
+ if (getLogger().isDebugEnabled()) {
+ getLogger().debug("ConcreteTreeProcessor has a special classpath");
+ }
+
+ ClassLoader classloader = createClassLoader(classpathConfig);
+ Thread.currentThread().setContextClassLoader(classloader);
+
+ newListeners = createClasspathListeners(oldListeners, classpathConfig);
+ newProcessor.setClasspathListeners(newListeners);
+
+ if (getLogger().isDebugEnabled()) {
+ getLogger().debug("setting up listeners " + newListeners);
+ }
+ for (final Iterator it = newListeners.values().iterator(); it.hasNext();) {
+ final NotifyingListener newListener = (NotifyingListener) it.next();
+
+ newListener.setNotificationListener(newProcessor);
+
+ fam.subscribe(newListener);
+
+ if (newListener instanceof ResourceStoringListener) {
+ ResourceStoringListener l = (ResourceStoringListener)newListener;
+ if (classloader instanceof ReloadingClassLoaderFactory.DefaultClassLoader) {
+ if (getLogger().isDebugEnabled()) {
+ getLogger().debug("adding store " + l.getStore() + " to classloader");
+ }
+ ReloadingClassLoaderFactory.DefaultClassLoader cl = (ReloadingClassLoaderFactory.DefaultClassLoader) classloader;
+ cl.addResourceStore(l.getStore());
+ }
+ }
+ }
+ }
+
+ if (oldListeners.size() > 0) {
+ if (getLogger().isDebugEnabled()) {
+ getLogger().debug("unsubscribing " + oldListeners + " from fam");
+ }
+ for (final Iterator it = oldListeners.values().iterator(); it.hasNext();) {
+ final FilesystemAlterationListener oldListener = (FilesystemAlterationListener) it.next();
+ fam.unsubscribe(oldListener);
+ }
+ }
+
+
+ if (newListeners.size() > 0) {
+ // wait for the new ones to complete for the first time
+ for (final Iterator it = newListeners.values().iterator(); it.hasNext();) {
+ final NotifyingListener newListener = (NotifyingListener) it.next();
+ if (getLogger().isDebugEnabled()) {
+ getLogger().debug("waiting for initial compilation");
+ }
+ newListener.waitForFirstCheck();
+ }
+ }
+
// Get the treebuilder that can handle this version of the sitemap.
TreeBuilder treeBuilder = getTreeBuilder(sitemapProgram);
try {
@@ -416,21 +679,11 @@
newProcessor.setProcessorData(
treeBuilder.getBuiltProcessorManager(),
treeBuilder.getBuiltProcessorClassLoader(),
- root, treeBuilder.getDisposableNodes(),
+ root,
+ treeBuilder.getDisposableNodes(),
treeBuilder.getComponentLocator(),
treeBuilder.getEnterSitemapEventListeners(),
treeBuilder.getLeaveSitemapEventListeners());
-
- fom.unsubscribeSitemap(oldProcessor);
-
- Configuration classpath = sitemapProgram.getChild("components").getChild("classpath", false);
- if (classpath != null) {
- if (getLogger().isDebugEnabled()) {
- getLogger().debug("ConcreteTreeProcessor listening for changes");
- }
-
- fom.subscribeSitemap(newProcessor, sitemapProgram);
- }
if (getLogger().isDebugEnabled()) {
getLogger().debug("ConcreteTreeProcessor ready");
@@ -467,9 +720,9 @@
}
private ConcreteTreeProcessor createConcreteTreeProcessor() {
- ConcreteTreeProcessor processor = new ConcreteTreeProcessor(this, this.sitemapExecutor);
- setupLogger(processor);
- return processor;
+ ConcreteTreeProcessor newProcessor = new ConcreteTreeProcessor(this, this.sitemapExecutor);
+ setupLogger(newProcessor);
+ return newProcessor;
}
/* (non-Javadoc)
@@ -491,7 +744,7 @@
this.resolver.release(this.source.getSource());
this.source = null;
}
- this.manager.release(this.fom);
+ this.manager.release(this.fam);
this.manager.release(this.resolver);
this.resolver = null;
this.manager = null;
@@ -517,4 +770,5 @@
*/
public void setAttribute(String name, Object value) {
this.concreteProcessor.setAttribute(name, value);
- }}
+ }
+}
Modified: cocoon/trunk/src/java/org/apache/cocoon/components/treeprocessor/sitemap/SitemapLanguage.java
URL: http://svn.apache.org/viewcvs/cocoon/trunk/src/java/org/apache/cocoon/components/treeprocessor/sitemap/SitemapLanguage.java?rev=291301&r1=291300&r2=291301&view=diff
==============================================================================
--- cocoon/trunk/src/java/org/apache/cocoon/components/treeprocessor/sitemap/SitemapLanguage.java (original)
+++ cocoon/trunk/src/java/org/apache/cocoon/components/treeprocessor/sitemap/SitemapLanguage.java Sat Sep 24 06:22:13 2005
@@ -23,7 +23,6 @@
import java.util.Iterator;
import java.util.Map;
import java.util.Set;
-
import org.apache.avalon.framework.configuration.Configuration;
import org.apache.avalon.framework.configuration.ConfigurationException;
import org.apache.avalon.framework.configuration.DefaultConfiguration;
@@ -33,7 +32,6 @@
import org.apache.avalon.framework.service.ServiceManager;
import org.apache.cocoon.Constants;
import org.apache.cocoon.components.LifecycleHelper;
-import org.apache.cocoon.components.classloader.ClassLoaderFactory;
import org.apache.cocoon.components.container.CocoonServiceManager;
import org.apache.cocoon.components.treeprocessor.CategoryNode;
import org.apache.cocoon.components.treeprocessor.CategoryNodeBuilder;
@@ -65,105 +63,87 @@
private static final String COMMA_SPLIT_REGEXP = "[\\s]*,[\\s]*";
private static final String EQUALS_SPLIT_REGEXP = "[\\s]*=[\\s]*";
+// protected ClassLoader createClassLoader(Configuration config)
+// throws Exception {
+// ClassLoader newClassLoader;
+// Configuration classpathConfig = config.getChild("classpath", false);
+// if (classpathConfig == null) {
+// return Thread.currentThread().getContextClassLoader();
+// }
+//
+// String factoryRole = config.getAttribute("factory-role", ClassLoaderFactory.ROLE + "/ReloadingClassLoaderFactory");
+// // Create a new classloader
+// ClassLoaderFactory clFactory = (ClassLoaderFactory)this.parentProcessorManager.lookup(factoryRole);
+// try {
+// return clFactory.createClassLoader(
+// Thread.currentThread().getContextClassLoader(),
+// classpathConfig
+// );
+// } finally {
+// this.parentProcessorManager.release(clFactory);
+// }
+// }
+
/**
* Build a component manager with the contents of the <map:components> element of
* the tree.
*/
- protected ServiceManager createServiceManager(Context context, Configuration tree)
+ protected ServiceManager createServiceManager(ClassLoader classloader, Context context, Configuration config)
throws Exception {
- // Get the map:component node
- // Don't check namespace here : this will be done by node builders
- Configuration config = tree.getChild("components", false);
-
- if (config == null) {
- if (getLogger().isDebugEnabled()) {
- getLogger().debug("Sitemap has no components definition at " + tree.getLocation());
- }
- config = new DefaultConfiguration("", "");
- }
-
// Create the classloader, if needed.
- ClassLoader newClassLoader;
- Configuration classpathConfig = config.getChild("classpath", false);
- if (classpathConfig == null) {
- newClassLoader = Thread.currentThread().getContextClassLoader();
- } else {
- String factoryRole = config.getAttribute("factory-role", ClassLoaderFactory.ROLE);
- // Create a new classloader
- ClassLoaderFactory clFactory = (ClassLoaderFactory)this.parentProcessorManager.lookup(factoryRole);
- try {
- newClassLoader = clFactory.createClassLoader(
- Thread.currentThread().getContextClassLoader(),
- classpathConfig
- );
- } finally {
- this.parentProcessorManager.release(clFactory);
- }
- }
-
- this.itsClassLoader = newClassLoader;
-
- // Create the manager within its own classloader
- Thread currentThread = Thread.currentThread();
- ClassLoader oldClassLoader = currentThread.getContextClassLoader();
- currentThread.setContextClassLoader(newClassLoader);
ServiceManager newManager;
- try {
- newManager = new CocoonServiceManager(this.parentProcessorManager, newClassLoader);
-
+ newManager = new CocoonServiceManager(this.parentProcessorManager, classloader);
+
+ // Go through the component lifecycle
+ ContainerUtil.enableLogging(newManager, this.getLogger());
+ ContainerUtil.contextualize(newManager, context);
+ // before we pass the configuration we have to strip the
+ // additional configuration parts, like classpath etc. as these
+ // are not configurations for the service manager
+ final DefaultConfiguration c = new DefaultConfiguration(config.getName(),
+ config.getLocation(),
+ config.getNamespace(),
+ "");
+ c.addAll(config);
+ c.removeChild(config.getChild("application-container"));
+ c.removeChild(config.getChild("classpath"));
+ c.removeChild(config.getChild("listeners"));
+
+ ContainerUtil.configure(newManager, c);
+ ContainerUtil.initialize(newManager);
+
+ // check for an application specific container
+ final Configuration appContainer = config.getChild("application-container", false);
+ if ( appContainer != null ) {
+ final String clazzName = appContainer.getAttribute("class");
+
+ final ComponentLocator cl = (ComponentLocator)ClassUtils.newInstance(clazzName);
// Go through the component lifecycle
- ContainerUtil.enableLogging(newManager, this.getLogger());
- ContainerUtil.contextualize(newManager, context);
- // before we pass the configuration we have to strip the
- // additional configuration parts, like classpath etc. as these
- // are not configurations for the service manager
- final DefaultConfiguration c = new DefaultConfiguration(config.getName(),
- config.getLocation(),
- config.getNamespace(),
- "");
- c.addAll(config);
- c.removeChild(config.getChild("application-container"));
- c.removeChild(config.getChild("classpath"));
- c.removeChild(config.getChild("listeners"));
-
- ContainerUtil.configure(newManager, c);
- ContainerUtil.initialize(newManager);
-
- // check for an application specific container
- final Configuration appContainer = config.getChild("application-container", false);
- if ( appContainer != null ) {
- final String clazzName = appContainer.getAttribute("class");
-
- final ComponentLocator cl = (ComponentLocator)ClassUtils.newInstance(clazzName);
- // Go through the component lifecycle
- LifecycleHelper.setupComponent(cl, this.getLogger(), context, newManager, appContainer);
+ LifecycleHelper.setupComponent(cl, this.getLogger(), context, newManager, appContainer);
- this.applicationContainer = cl;
+ this.applicationContainer = cl;
- newManager = new ComponentManager(newManager, cl);
- }
+ newManager = new ComponentManager(newManager, cl);
+ }
- // and finally the listeners
- if ( this.applicationContainer instanceof SitemapListener ) {
- this.addListener(new TreeBuilder.EventComponent(this.applicationContainer, false));
- }
+ // and finally the listeners
+ if ( this.applicationContainer instanceof SitemapListener ) {
+ this.addListener(new TreeBuilder.EventComponent(this.applicationContainer, false));
+ }
- final Configuration listenersWrapper = config.getChild("listeners", false);
- if ( listenersWrapper != null ) {
- final Configuration[] listeners = listenersWrapper.getChildren("listener");
- for(int i = 0; i < listeners.length; i++) {
- final Configuration current = listeners[i];
- final TreeBuilder.EventComponent listener = this.createListener(newManager, context, current);
- if ( !(listener.component instanceof SitemapListener) ) {
- throw new ConfigurationException("Listener must implement the SitemapListener interface.");
- }
- this.addListener(listener);
+ final Configuration listenersWrapper = config.getChild("listeners", false);
+ if ( listenersWrapper != null ) {
+ final Configuration[] listeners = listenersWrapper.getChildren("listener");
+ for(int i = 0; i < listeners.length; i++) {
+ final Configuration current = listeners[i];
+ final TreeBuilder.EventComponent listener = this.createListener(newManager, context, current);
+ if ( !(listener.component instanceof SitemapListener) ) {
+ throw new ConfigurationException("Listener must implement the SitemapListener interface.");
}
+ this.addListener(listener);
}
- } finally {
- currentThread.setContextClassLoader(oldClassLoader);
}
return newManager;