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/03/04 21:12:37 UTC
svn commit: r383193 - in /cocoon/trunk/cocoon-core/src:
main/java/org/apache/cocoon/components/treeprocessor/
main/java/org/apache/cocoon/components/treeprocessor/sitemap/
main/java/org/apache/cocoon/reading/
test/java/org/apache/cocoon/core/container/
Author: cziegeler
Date: Sat Mar 4 12:12:35 2006
New Revision: 383193
URL: http://svn.apache.org/viewcvs?rev=383193&view=rev
Log:
Combine DefaultTreeBuilder and SitemapLanguage
Remove per sitemap class loading
Removed:
cocoon/trunk/cocoon-core/src/main/java/org/apache/cocoon/components/treeprocessor/DefaultTreeBuilder.java
Modified:
cocoon/trunk/cocoon-core/src/main/java/org/apache/cocoon/components/treeprocessor/ConcreteTreeProcessor.java
cocoon/trunk/cocoon-core/src/main/java/org/apache/cocoon/components/treeprocessor/TreeBuilder.java
cocoon/trunk/cocoon-core/src/main/java/org/apache/cocoon/components/treeprocessor/TreeProcessor.java
cocoon/trunk/cocoon-core/src/main/java/org/apache/cocoon/components/treeprocessor/sitemap/SitemapLanguage.java
cocoon/trunk/cocoon-core/src/main/java/org/apache/cocoon/reading/ImageReader.java
cocoon/trunk/cocoon-core/src/test/java/org/apache/cocoon/core/container/ContainerTestCase.java
Modified: cocoon/trunk/cocoon-core/src/main/java/org/apache/cocoon/components/treeprocessor/ConcreteTreeProcessor.java
URL: http://svn.apache.org/viewcvs/cocoon/trunk/cocoon-core/src/main/java/org/apache/cocoon/components/treeprocessor/ConcreteTreeProcessor.java?rev=383193&r1=383192&r2=383193&view=diff
==============================================================================
--- cocoon/trunk/cocoon-core/src/main/java/org/apache/cocoon/components/treeprocessor/ConcreteTreeProcessor.java (original)
+++ cocoon/trunk/cocoon-core/src/main/java/org/apache/cocoon/components/treeprocessor/ConcreteTreeProcessor.java Sat Mar 4 12:12:35 2006
@@ -69,9 +69,6 @@
/** Our ServiceManager */
private ServiceManager manager;
- /** Our class loader */
- private ClassLoader classloader;
-
/** The processor that wraps us */
private TreeProcessor wrappingProcessor;
@@ -104,9 +101,6 @@
/** Processor attributes */
protected Map processorAttributes = new HashMap();
- /** no listeners by default */
- private Map classpathListeners = Collections.EMPTY_MAP;
-
/** Bean Factory for this sitemap. */
protected ConfigurableBeanFactory beanFactory;
@@ -129,19 +123,10 @@
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(ConfigurableBeanFactory beanFactory,
ServiceManager manager,
- ClassLoader classloader,
- ProcessingNode rootNode,
+ ProcessingNode rootNode,
List disposableNodes,
List enterSitemapEventListeners,
List leaveSitemapEventListeners) {
@@ -151,7 +136,6 @@
this.beanFactory = beanFactory;
this.manager = manager;
- this.classloader = classloader;
this.rootNode = rootNode;
this.disposableNodes = disposableNodes;
this.enterSitemapEventListeners = enterSitemapEventListeners;
@@ -333,10 +317,6 @@
requestCount++;
}
- Thread currentThread = Thread.currentThread();
- ClassLoader oldClassLoader = currentThread.getContextClassLoader();
- currentThread.setContextClassLoader(this.classloader);
-
try {
// invoke listeners
// only invoke if pipeline is not internally
@@ -384,9 +364,6 @@
((LeaveSitemapEventListener)current.component).leftSitemap(leaveEvent);
}
}
-
- // Restore classloader
- currentThread.setContextClassLoader(oldClassLoader);
// Decrement the concurrent request count
synchronized (this) {
Modified: cocoon/trunk/cocoon-core/src/main/java/org/apache/cocoon/components/treeprocessor/TreeBuilder.java
URL: http://svn.apache.org/viewcvs/cocoon/trunk/cocoon-core/src/main/java/org/apache/cocoon/components/treeprocessor/TreeBuilder.java?rev=383193&r1=383192&r2=383193&view=diff
==============================================================================
--- cocoon/trunk/cocoon-core/src/main/java/org/apache/cocoon/components/treeprocessor/TreeBuilder.java (original)
+++ cocoon/trunk/cocoon-core/src/main/java/org/apache/cocoon/components/treeprocessor/TreeBuilder.java Sat Mar 4 12:12:35 2006
@@ -45,8 +45,6 @@
ServiceManager getServiceManager();
- ClassLoader getBuiltProcessorClassLoader();
-
ConcreteTreeProcessor getProcessor();
void setProcessor(ConcreteTreeProcessor processor);
Modified: cocoon/trunk/cocoon-core/src/main/java/org/apache/cocoon/components/treeprocessor/TreeProcessor.java
URL: http://svn.apache.org/viewcvs/cocoon/trunk/cocoon-core/src/main/java/org/apache/cocoon/components/treeprocessor/TreeProcessor.java?rev=383193&r1=383192&r2=383193&view=diff
==============================================================================
--- cocoon/trunk/cocoon-core/src/main/java/org/apache/cocoon/components/treeprocessor/TreeProcessor.java (original)
+++ cocoon/trunk/cocoon-core/src/main/java/org/apache/cocoon/components/treeprocessor/TreeProcessor.java Sat Mar 4 12:12:35 2006
@@ -15,13 +15,10 @@
*/
package org.apache.cocoon.components.treeprocessor;
-import java.io.File;
import java.io.IOException;
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;
@@ -40,9 +37,6 @@
import org.apache.cocoon.ProcessingException;
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;
import org.apache.cocoon.components.source.impl.DelayedRefreshSourceWrapper;
@@ -52,16 +46,6 @@
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;
@@ -104,8 +88,6 @@
/** Check for reload? */
protected boolean checkReload;
- protected SitemapMonitor fam;
-
/** The source resolver */
protected SourceResolver resolver;
@@ -149,7 +131,6 @@
this.manager = parent.concreteProcessor.getServiceManager();
this.resolver = (SourceResolver) this.manager.lookup(SourceResolver.ROLE);
- this.fam = (SitemapMonitor) this.manager.lookup(SitemapMonitor.ROLE);
this.settings = (Settings) this.manager.lookup(Settings.ROLE);
this.environmentHelper = new EnvironmentHelper(parent.environmentHelper);
// Setup environment helper
@@ -186,7 +167,6 @@
public void service(ServiceManager manager) throws ServiceException {
this.manager = manager;
this.resolver = (SourceResolver) this.manager.lookup(SourceResolver.ROLE);
- this.fam = (SitemapMonitor) this.manager.lookup(SitemapMonitor.ROLE);
this.settings = (Settings) this.manager.lookup(Settings.ROLE);
}
@@ -274,7 +254,7 @@
return this.concreteProcessor.buildPipeline(environment);
}
- /* (non-Javadoc)
+ /**
* @see org.apache.cocoon.Processor#getRootProcessor()
*/
public Processor getRootProcessor() {
@@ -360,181 +340,6 @@
}
}
- 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();
-
- 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);
- }
- }
-
-
private Configuration createSitemapProgram(Source source) throws ProcessingException, SAXException, IOException {
NamespacedSAXConfigurationHandler handler = new NamespacedSAXConfigurationHandler();
AnnotationsFilter annotationsFilter = new AnnotationsFilter(handler);
@@ -542,62 +347,6 @@
return handler.getConfiguration();
}
- private void subscribeListeners(Map listerens, ConcreteTreeProcessor processor) {
- if (getLogger().isDebugEnabled()) {
- getLogger().debug("setting up listeners " + listerens);
- }
- for (final Iterator it = listerens.values().iterator(); it.hasNext();) {
- final NotifyingListener newListener = (NotifyingListener) it.next();
-
- newListener.setNotificationListener(processor);
-
- fam.subscribe(newListener);
- }
- }
-
- private void unsubscribeListeners(Map listerens) {
- if (listerens != null && listerens.size() > 0) {
- if (getLogger().isDebugEnabled()) {
- getLogger().debug("unsubscribing " + listerens + " from fam");
- }
- for (final Iterator it = listerens.values().iterator(); it.hasNext();) {
- final FilesystemAlterationListener oldListener = (FilesystemAlterationListener) it.next();
- fam.unsubscribe(oldListener);
- }
- }
- }
-
- private void waitForInitialCompilation(Map listeners) throws Exception {
- if (listeners.size() > 0) {
- // wait for the new ones to complete for the first time
- for (final Iterator it = listeners.values().iterator(); it.hasNext();) {
- final NotifyingListener newListener = (NotifyingListener) it.next();
- if (getLogger().isDebugEnabled()) {
- getLogger().debug("waiting for initial compilation");
- }
- newListener.waitForFirstCheck();
- }
- }
- }
-
- private void provideClasses(Map listeners, ClassLoader classloader) {
- for (final Iterator it = listeners.values().iterator(); it.hasNext();) {
- final NotifyingListener newListener = (NotifyingListener) it.next();
-
- 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());
- }
- }
- }
- }
-
-
/**
* Build the concrete processor (i.e. loads the sitemap). Should be called
* only by setupProcessor();
@@ -615,14 +364,11 @@
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");
@@ -650,37 +396,6 @@
newProcessor = createConcreteTreeProcessor();
- // setup sitemap specific classloader
- // (RP) Should we really support sitemap specific classloader when the global
- // BlocksClassloader is in place?
- Configuration classpathConfig = sitemapProgram.getChild("components").getChild("classpath", false);
- if (classpathConfig != null) {
- if (getLogger().isDebugEnabled()) {
- getLogger().debug("ConcreteTreeProcessor has a special classpath");
- }
-
- // create a reloading classloader and make it the context classloader
- ClassLoader classloader = createClassLoader(classpathConfig);
- Thread.currentThread().setContextClassLoader(classloader);
-
- // create the listeners for all classpath entries (lib, classes, src)
- newListeners = createClasspathListeners(oldListeners, classpathConfig);
-
- // store the listeners in the the concreteTreeProcessor instance
- newProcessor.setClasspathListeners(newListeners);
-
- // subscribe all listeners to filesystem altering monitor (FAM)
- subscribeListeners(newListeners, newProcessor);
-
- // use the information about the listeners to create the classpath
- provideClasses(newListeners, classloader);
- }
-
- unsubscribeListeners(oldListeners);
-
- waitForInitialCompilation(newListeners);
-
-
// Get the treebuilder that can handle this version of the sitemap.
TreeBuilder treeBuilder = getTreeBuilder(sitemapProgram);
try {
@@ -690,7 +405,6 @@
newProcessor.setProcessorData(
treeBuilder.getBeanFactory(),
treeBuilder.getServiceManager(),
- treeBuilder.getBuiltProcessorClassLoader(),
root,
treeBuilder.getDisposableNodes(),
treeBuilder.getEnterSitemapEventListeners(),
@@ -749,7 +463,6 @@
this.resolver.release(this.source.getSource());
this.source = null;
}
- this.manager.release(this.fam);
this.manager.release(this.resolver);
this.manager.release(this.settings);
this.resolver = null;
Modified: cocoon/trunk/cocoon-core/src/main/java/org/apache/cocoon/components/treeprocessor/sitemap/SitemapLanguage.java
URL: http://svn.apache.org/viewcvs/cocoon/trunk/cocoon-core/src/main/java/org/apache/cocoon/components/treeprocessor/sitemap/SitemapLanguage.java?rev=383193&r1=383192&r2=383193&view=diff
==============================================================================
--- cocoon/trunk/cocoon-core/src/main/java/org/apache/cocoon/components/treeprocessor/sitemap/SitemapLanguage.java (original)
+++ cocoon/trunk/cocoon-core/src/main/java/org/apache/cocoon/components/treeprocessor/sitemap/SitemapLanguage.java Sat Mar 4 12:12:35 2006
@@ -15,31 +15,54 @@
*/
package org.apache.cocoon.components.treeprocessor.sitemap;
+import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
+import java.util.List;
import java.util.Map;
import java.util.Set;
import javax.servlet.ServletConfig;
+import org.apache.avalon.excalibur.pool.Recyclable;
+import org.apache.avalon.framework.activity.Disposable;
+import org.apache.avalon.framework.activity.Initializable;
+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;
+import org.apache.avalon.framework.context.Contextualizable;
import org.apache.avalon.framework.context.DefaultContext;
+import org.apache.avalon.framework.logger.AbstractLogEnabled;
import org.apache.avalon.framework.logger.Logger;
+import org.apache.avalon.framework.service.ServiceException;
import org.apache.avalon.framework.service.ServiceManager;
+import org.apache.avalon.framework.service.ServiceSelector;
+import org.apache.avalon.framework.service.Serviceable;
import org.apache.cocoon.Constants;
import org.apache.cocoon.components.ContextHelper;
import org.apache.cocoon.components.LifecycleHelper;
+import org.apache.cocoon.components.source.SourceUtil;
+import org.apache.cocoon.components.treeprocessor.AbstractProcessingNode;
import org.apache.cocoon.components.treeprocessor.CategoryNode;
import org.apache.cocoon.components.treeprocessor.CategoryNodeBuilder;
-import org.apache.cocoon.components.treeprocessor.DefaultTreeBuilder;
+import org.apache.cocoon.components.treeprocessor.ConcreteTreeProcessor;
+import org.apache.cocoon.components.treeprocessor.LinkedProcessingNodeBuilder;
+import org.apache.cocoon.components.treeprocessor.ParameterizableProcessingNode;
+import org.apache.cocoon.components.treeprocessor.ProcessingNode;
+import org.apache.cocoon.components.treeprocessor.ProcessingNodeBuilder;
+import org.apache.cocoon.components.treeprocessor.ProcessorComponentInfo;
+import org.apache.cocoon.components.treeprocessor.StandaloneServiceSelector;
import org.apache.cocoon.components.treeprocessor.TreeBuilder;
+import org.apache.cocoon.components.treeprocessor.variables.VariableResolver;
+import org.apache.cocoon.components.treeprocessor.variables.VariableResolverFactory;
import org.apache.cocoon.core.Settings;
import org.apache.cocoon.core.container.spring.BeanFactoryUtil;
import org.apache.cocoon.core.container.spring.AvalonEnvironment;
@@ -56,8 +79,14 @@
import org.apache.cocoon.sitemap.LeaveSitemapEventListener;
import org.apache.cocoon.sitemap.PatternException;
import org.apache.cocoon.sitemap.SitemapListener;
+import org.apache.cocoon.sitemap.SitemapParameters;
import org.apache.cocoon.util.ClassUtils;
import org.apache.cocoon.util.StringUtils;
+import org.apache.cocoon.util.location.Location;
+import org.apache.cocoon.util.location.LocationImpl;
+import org.apache.cocoon.util.location.LocationUtils;
+import org.apache.excalibur.source.Source;
+import org.apache.excalibur.source.SourceResolver;
import org.apache.regexp.RE;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.BeanCreationException;
@@ -67,94 +96,613 @@
/**
* The tree builder for the sitemap language.
- *
+ *
* @version $Id$
*/
public class SitemapLanguage
- extends DefaultTreeBuilder
- implements BeanFactoryAware {
-
- /** Spring application context. */
- protected ConfigurableBeanFactory beanFactory;
+ extends AbstractLogEnabled
+ implements TreeBuilder, Contextualizable, Serviceable, Recyclable, BeanFactoryAware {
// Regexp's for splitting expressions
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);
-// }
-// }
-
+ protected Map attributes = new HashMap();
+
+ /** Spring application context. */
+ protected ConfigurableBeanFactory beanFactory;
+
+
+ // ----- lifecycle-related objects ------
+
+ /**
+ * This component's avalon context
+ */
+ private Context context;
+
+ /**
+ * This component's service manager
+ */
+ private ServiceManager manager;
+
+ // -------------------------------------
+
+ /**
+ * The tree processor that we are building.
+ */
+ protected ConcreteTreeProcessor processor;
+
+ /**
+ * The namespace of configuration for the processor that we are building.
+ */
+ protected String itsNamespace;
+
+ /**
+ * The context for the processor that we are building It is created by
+ * {@link #createContext(Configuration)}.
+ */
+ private Context itsContext;
+
+ /**
+ * The service manager for the processor that we are building. It is created
+ * by {@link #createServiceManager(ClassLoader, Context, Configuration)}.
+ */
+ private ServiceManager itsManager;
+
+ private ConfigurableBeanFactory itsBeanFactory;
+
+ /**
+ * Helper object which sets up components in the context of the processor
+ * that we are building.
+ */
+ private LifecycleHelper itsLifecycle;
+
+ /**
+ * Selector for ProcessingNodeBuilders which is set up in the context of the
+ * processor that we are building.
+ */
+ private ServiceSelector itsBuilders;
+
+ /**
+ * The sitemap component information grabbed while building itsMaanger
+ */
+ protected ProcessorComponentInfo itsComponentInfo;
+
+ /** Optional event listeners for the enter sitemap event */
+ protected List enterSitemapEventListeners = new ArrayList();
+
+ /** Optional event listeners for the leave sitemap event */
+ protected List leaveSitemapEventListeners = new ArrayList();
+
+ // -------------------------------------
+
+ /** Nodes gone through setupNode() that implement Initializable */
+ private List initializableNodes = new ArrayList();
+
+ /** Nodes gone through setupNode() that implement Disposable */
+ private List disposableNodes = new ArrayList();
+
+ /**
+ * NodeBuilders created by createNodeBuilder() that implement
+ * LinkedProcessingNodeBuilder
+ */
+ private List linkedBuilders = new ArrayList();
+
+ /** Are we in a state that allows to get registered nodes ? */
+ private boolean canGetNode = false;
+
+ /** Nodes registered using registerNode() */
+ private Map registeredNodes = new HashMap();
+
+ /**
+ * @see org.apache.avalon.framework.context.Contextualizable#contextualize(org.apache.avalon.framework.context.Context)
+ */
+ public void contextualize(Context context) throws ContextException {
+ this.context = context;
+ }
+
+ /**
+ * @see org.apache.avalon.framework.service.Serviceable#service(org.apache.avalon.framework.service.ServiceManager)
+ */
+ public void service(ServiceManager manager) throws ServiceException {
+ this.manager = manager;
+ }
+
+ /**
+ * Get the location of the treebuilder config file. Can be overridden for
+ * other versions.
+ *
+ * @return The location of the treebuilder config file
+ */
+ protected String getBuilderConfigURL() {
+ return "resource://org/apache/cocoon/components/treeprocessor/sitemap-language.xml";
+ }
+
+ /**
+ * @see org.apache.cocoon.components.treeprocessor.TreeBuilder#setAttribute(java.lang.String,
+ * java.lang.Object)
+ */
+ public void setAttribute(String name, Object value) {
+ this.attributes.put(name, value);
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.apache.cocoon.components.treeprocessor.TreeBuilder#getAttribute(java.lang.String)
+ */
+ public Object getAttribute(String name) {
+ return this.attributes.get(name);
+ }
+
+ /**
+ * @see org.apache.cocoon.components.treeprocessor.TreeBuilder#setProcessor(ConcreteTreeProcessor)
+ */
+ public void setProcessor(ConcreteTreeProcessor processor) {
+ this.processor = processor;
+ }
+
+ /**
+ * @see org.apache.cocoon.components.treeprocessor.TreeBuilder#getProcessor()
+ */
+ public ConcreteTreeProcessor getProcessor() {
+ return this.processor;
+ }
+
+ /**
+ * @see org.apache.cocoon.components.treeprocessor.TreeBuilder#getBeanFactory()
+ */
+ public ConfigurableBeanFactory getBeanFactory() {
+ return this.itsBeanFactory;
+ }
+
+ public ServiceManager getServiceManager() {
+ return this.itsManager;
+ }
+
+ /**
+ * @see org.apache.cocoon.components.treeprocessor.TreeBuilder#getEnterSitemapEventListeners()
+ */
+ public List getEnterSitemapEventListeners() {
+ // we make a copy here, so we can clear(recylce) the list after the
+ // sitemap is build
+ return (List) ((ArrayList) this.enterSitemapEventListeners).clone();
+ }
+
+ /**
+ * @see org.apache.cocoon.components.treeprocessor.TreeBuilder#getLeaveSitemapEventListeners()
+ */
+ public List getLeaveSitemapEventListeners() {
+ // we make a copy here, so we can clear(recylce) the list after the
+ // sitemap is build
+ return (List) ((ArrayList) this.leaveSitemapEventListeners).clone();
+ }
+
+ /**
+ * @see org.apache.cocoon.components.treeprocessor.TreeBuilder#registerNode(java.lang.String,
+ * org.apache.cocoon.components.treeprocessor.ProcessingNode)
+ */
+ public boolean registerNode(String name, ProcessingNode node) {
+ if (this.registeredNodes.containsKey(name)) {
+ return false;
+ }
+ this.registeredNodes.put(name, node);
+ return true;
+ }
+
+ public ProcessingNode getRegisteredNode(String name) {
+ if (this.canGetNode) {
+ return (ProcessingNode) this.registeredNodes.get(name);
+ }
+ throw new IllegalArgumentException("Categories are only available during buildNode()");
+ }
+
+ public ProcessingNodeBuilder createNodeBuilder(Configuration config) throws Exception {
+ // FIXME : check namespace
+ String nodeName = config.getName();
+
+ if (getLogger().isDebugEnabled()) {
+ getLogger().debug("Creating node builder for " + nodeName);
+ }
+
+ ProcessingNodeBuilder builder;
+ try {
+ builder = (ProcessingNodeBuilder) this.itsBuilders.select(nodeName);
+ } catch (ServiceException ce) {
+ // Is it because this element is unknown ?
+ if (this.itsBuilders.isSelectable(nodeName)) {
+ // No : rethrow
+ throw ce;
+ }
+ // Throw a more meaningful exception
+ String msg = "Unknown element '" + nodeName + "' at " + config.getLocation();
+ throw new ConfigurationException(msg);
+ }
+
+ builder.setBuilder(this);
+
+ if (builder instanceof LinkedProcessingNodeBuilder) {
+ this.linkedBuilders.add(builder);
+ }
+
+ return builder;
+ }
+
+ /**
+ * Create the tree once component manager and node builders have been set
+ * up. Can be overriden by subclasses to perform pre/post tree creation
+ * operations.
+ */
+ protected ProcessingNode createTree(Configuration tree) throws Exception {
+ // Create a node builder from the top-level element
+ ProcessingNodeBuilder rootBuilder = createNodeBuilder(tree);
+
+ // Build the whole tree (with an empty buildModel)
+ return rootBuilder.buildNode(tree);
+ }
+
+ /**
+ * Resolve links : call <code>linkNode()</code> on all
+ * <code>LinkedProcessingNodeBuilder</code>s. Can be overriden by
+ * subclasses to perform pre/post resolution operations.
+ *
+ * Before linking nodes, lookup the view category node used in
+ * {@link #getViewNodes(Collection)}.
+ */
+ protected void linkNodes() throws Exception {
+ // Get the views category node
+ this.viewsNode = CategoryNodeBuilder.getCategoryNode(this, "views");
+
+ // Resolve links
+ Iterator iter = this.linkedBuilders.iterator();
+ while (iter.hasNext()) {
+ ((LinkedProcessingNodeBuilder) iter.next()).linkNode();
+ }
+ }
+
/**
- * Build a component manager with the contents of the <map:components> element
- * of the tree.
+ * Get the namespace URI that builders should use to find their nodes.
*/
- protected ConfigurableBeanFactory createBeanFactory(ClassLoader classloader,
- Context context,
+ public String getNamespace() {
+ return this.itsNamespace;
+ }
+
+ /**
+ * Build a processing tree from a <code>Configuration</code>.
+ */
+ public ProcessingNode build(Configuration tree) throws Exception {
+ // The namespace used in the whole sitemap is the one of the root
+ // element
+ this.itsNamespace = tree.getNamespace();
+
+ 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);
+
+ // Only create an sitemap internal component manager if there really is
+ // a configuration
+ // FIXME: Internal configurations doesn't work in a non bean factory
+ // environment
+ if (componentConfig != null) {
+ this.itsBeanFactory = this.createBeanFactory(this.itsContext, componentConfig);
+ this.itsManager = (ServiceManager) this.itsBeanFactory.getBean(ServiceManager.class
+ .getName());
+ } else {
+ this.itsManager = manager;
+ }
+ this.itsComponentInfo = (ProcessorComponentInfo) this.itsManager
+ .lookup(ProcessorComponentInfo.ROLE);
+ // Create a helper object to setup components
+ this.itsLifecycle = new LifecycleHelper(getLogger(), this.itsContext, this.itsManager, null /* configuration */);
+
+ // Create & initialize the NodeBuilder selector.
+ {
+ StandaloneServiceSelector selector = new StandaloneServiceSelector();
+
+ // Load the builder config file
+ SourceResolver resolver = (SourceResolver) this.manager.lookup(SourceResolver.ROLE);
+ String url = getBuilderConfigURL();
+ Configuration config;
+ try {
+ Source src = resolver.resolveURI(url);
+ try {
+ SAXConfigurationHandler handler = new SAXConfigurationHandler();
+ SourceUtil.toSAX(this.manager, src, null, handler);
+ config = handler.getConfiguration();
+ } finally {
+ resolver.release(src);
+ }
+ } catch (Exception e) {
+ throw new ConfigurationException("Could not load TreeBuilder configuration from "
+ + url, e);
+ } finally {
+ this.manager.release(resolver);
+ }
+ LifecycleHelper.setupComponent(selector, getLogger(), this.itsContext, this.itsManager,
+ config.getChild("nodes", false), true);
+ this.itsBuilders = selector;
+ }
+
+ // Calls to getRegisteredNode() are forbidden
+ this.canGetNode = false;
+
+ // Collect all disposable variable resolvers
+ VariableResolverFactory.setDisposableCollector(this.disposableNodes);
+
+ ProcessingNode result = createTree(tree);
+
+ // Calls to getRegisteredNode() are now allowed
+ this.canGetNode = true;
+
+ linkNodes();
+
+ // Initialize all Initializable nodes
+ Iterator iter = this.initializableNodes.iterator();
+ while (iter.hasNext()) {
+ ((Initializable) iter.next()).initialize();
+ }
+
+ // And that's all !
+ return result;
+ }
+
+ /**
+ * Return the list of <code>ProcessingNodes</code> part of this tree that
+ * are <code>Disposable</code>. Care should be taken to properly dispose
+ * them before trashing the processing tree.
+ */
+ public List getDisposableNodes() {
+ return this.disposableNodes;
+ }
+
+ /**
+ * Setup a <code>ProcessingNode</code> by setting its location, calling
+ * all the lifecycle interfaces it implements and giving it the parameter
+ * map if it's a <code>ParameterizableNode</code>.
+ * <p>
+ * As a convenience, the node is returned by this method to allow constructs
+ * like <code>return treeBuilder.setupNode(new MyNode(), config)</code>.
+ */
+ public ProcessingNode setupNode(ProcessingNode node, Configuration config) throws Exception {
+ Location location = getLocation(config);
+ if (node instanceof AbstractProcessingNode) {
+ ((AbstractProcessingNode) node).setLocation(location);
+ ((AbstractProcessingNode) node).setSitemapExecutor(this.processor.getSitemapExecutor());
+ }
+
+ this.itsLifecycle.setupComponent(node, false);
+
+ if (node instanceof ParameterizableProcessingNode) {
+ Map params = getParameters(config, location);
+ ((ParameterizableProcessingNode) node).setParameters(params);
+ }
+
+ if (node instanceof Initializable) {
+ this.initializableNodes.add(node);
+ }
+
+ if (node instanceof Disposable) {
+ this.disposableNodes.add(node);
+ }
+
+ return node;
+ }
+
+ protected LocationImpl getLocation(Configuration config) {
+ String prefix = "";
+
+ if (config instanceof AbstractConfiguration) {
+ // FIXME: AbstractConfiguration has a _protected_ getPrefix()
+ // method.
+ // So make some reasonable guess on the prefix until it becomes
+ // public
+ String namespace = null;
+ try {
+ namespace = ((AbstractConfiguration) config).getNamespace();
+ } catch (ConfigurationException e) {
+ // ignore
+ }
+ if ("http://apache.org/cocoon/sitemap/1.0".equals(namespace)) {
+ prefix = "map";
+ }
+ }
+
+ StringBuffer desc = new StringBuffer().append('<');
+ if (prefix.length() > 0) {
+ desc.append(prefix).append(':').append(config.getName());
+ } else {
+ desc.append(config.getName());
+ }
+ String type = config.getAttribute("type", null);
+ if (type != null) {
+ desc.append(" type=\"").append(type).append('"');
+ }
+ desc.append('>');
+
+ Location rawLoc = LocationUtils.getLocation(config);
+ return new LocationImpl(desc.toString(), rawLoc.getURI(), rawLoc.getLineNumber(), rawLoc
+ .getColumnNumber());
+ }
+
+ /**
+ * Get <xxx:parameter> elements as a <code>Map</code> of </code>ListOfMapResolver</code>s,
+ * that can be turned into parameters using <code>ListOfMapResolver.buildParameters()</code>.
+ *
+ * @return the Map of ListOfMapResolver, or <code>null</code> if there are
+ * no parameters.
+ */
+ protected Map getParameters(Configuration config, Location location)
+ throws ConfigurationException {
+
+ Configuration[] children = config.getChildren("parameter");
+
+ if (children.length == 0) {
+ // Parameters are only the component's location
+ // TODO Optimize this
+ return new SitemapParameters.LocatedHashMap(location, 0);
+ }
+
+ Map params = new SitemapParameters.LocatedHashMap(location, children.length + 1);
+ for (int i = 0; i < children.length; i++) {
+ Configuration child = children[i];
+ if (true) { // FIXME : check namespace
+ String name = child.getAttribute("name");
+ String value = child.getAttribute("value");
+ try {
+ params.put(resolve(name), resolve(value));
+ } catch (PatternException pe) {
+ String msg = "Invalid pattern '" + value + "' at " + child.getLocation();
+ throw new ConfigurationException(msg, pe);
+ }
+ }
+ }
+
+ return params;
+ }
+
+ /**
+ * Get the type for a statement : it returns the 'type' attribute if
+ * present, and otherwhise the default type defined for this role in the
+ * components declarations.
+ *
+ * @throws ConfigurationException
+ * if the type could not be found.
+ */
+ public String getTypeForStatement(Configuration statement, String role)
+ throws ConfigurationException {
+
+ // Get the component type for the statement
+ String type = statement.getAttribute("type", null);
+ if (type == null) {
+ type = this.itsComponentInfo.getDefaultType(role);
+ }
+
+ if (type == null) {
+ throw new ConfigurationException("No default type exists for 'map:"
+ + statement.getName() + "' at " + statement.getLocation());
+ }
+
+ // Check that this type actually exists
+ ServiceSelector selector = null;
+ try {
+ selector = (ServiceSelector) this.itsManager.lookup(role + "Selector");
+ } catch (ServiceException e) {
+ throw new ConfigurationException("Cannot get service selector for 'map:"
+ + statement.getName() + "' at " + statement.getLocation(), e);
+ }
+
+ if (!selector.isSelectable(type)) {
+ throw new ConfigurationException("Type '" + type + "' does not exist for 'map:"
+ + statement.getName() + "' at " + statement.getLocation());
+ }
+
+ this.itsManager.release(selector);
+
+ return type;
+ }
+
+ /**
+ * Resolve expression using its manager
+ */
+ protected VariableResolver resolve(String expression) throws PatternException {
+ return VariableResolverFactory.getResolver(expression, this.itsManager);
+ }
+
+ public void recycle() {
+ // Reset all data created during the build
+ this.attributes.clear();
+ this.canGetNode = false;
+ this.disposableNodes = new ArrayList(); // Must not be cleared as it's
+ // used for processor disposal
+ this.initializableNodes.clear();
+ this.linkedBuilders.clear();
+ this.processor = null; // Set in setProcessor()
+
+ this.itsNamespace = null; // Set in build()
+ LifecycleHelper.dispose(this.itsBuilders);
+ this.itsBuilders = null; // Set in build()
+ this.itsLifecycle = null; // Set in build()
+ this.itsManager = null; // Set in build()
+ this.itsContext = null; // Set in build()
+
+ this.registeredNodes.clear();
+ this.initializableNodes.clear();
+ this.linkedBuilders.clear();
+ this.canGetNode = false;
+ this.registeredNodes.clear();
+
+ VariableResolverFactory.setDisposableCollector(null);
+ this.enterSitemapEventListeners.clear();
+ this.leaveSitemapEventListeners.clear();
+
+ // Go back to initial state
+ this.labelViews.clear();
+ this.viewsNode = null;
+ this.isBuildingView = false;
+ this.isBuildingErrorHandler = false;
+ }
+
+ /**
+ * Build a component manager with the contents of the <map:components>
+ * element of the tree.
+ */
+ protected ConfigurableBeanFactory createBeanFactory(Context context,
Configuration config)
throws Exception {
-
- // Create the classloader, if needed.
ServiceManager newManager;
-
+
// before we pass the configuration we have to strip the
- // additional configuration parts, like classpath etc. as these
+ // additional configuration parts, like listeners etc. as these
// are not configurations for the service manager
- final DefaultConfiguration c = new DefaultConfiguration(config.getName(),
- config.getLocation(),
- config.getNamespace(),
- "");
+ final DefaultConfiguration c = new DefaultConfiguration(config.getName(), config
+ .getLocation(), config.getNamespace(), "");
c.addAll(config);
- c.removeChild(config.getChild("classpath"));
c.removeChild(config.getChild("listeners"));
// setup spring container
// first, get the correct parent
ConfigurableBeanFactory parentContext = this.beanFactory;
final Request request = ContextHelper.getRequest(context);
- if ( request.getAttribute(CocoonBeanFactory.BEAN_FACTORY_REQUEST_ATTRIBUTE) != null ) {
- parentContext = (ConfigurableBeanFactory)request.getAttribute(CocoonBeanFactory.BEAN_FACTORY_REQUEST_ATTRIBUTE);
+ if (request.getAttribute(CocoonBeanFactory.BEAN_FACTORY_REQUEST_ATTRIBUTE) != null) {
+ parentContext = (ConfigurableBeanFactory) request
+ .getAttribute(CocoonBeanFactory.BEAN_FACTORY_REQUEST_ATTRIBUTE);
}
final AvalonEnvironment ae = new AvalonEnvironment();
ae.context = context;
ae.logger = this.getLogger();
- ae.servletContext = ((ServletConfig)context.get(CocoonServlet.CONTEXT_SERVLET_CONFIG)).getServletContext();
- ae.settings = (Settings)this.beanFactory.getBean(Settings.ROLE);
- final ConfigurationInfo parentConfigInfo = (ConfigurationInfo)parentContext.getBean(ConfigurationInfo.class.getName());
+ ae.servletContext = ((ServletConfig) context.get(CocoonServlet.CONTEXT_SERVLET_CONFIG))
+ .getServletContext();
+ ae.settings = (Settings) this.beanFactory.getBean(Settings.ROLE);
+ final ConfigurationInfo parentConfigInfo = (ConfigurationInfo) parentContext
+ .getBean(ConfigurationInfo.class.getName());
final ConfigurationInfo ci = ConfigReader.readConfiguration(c, parentConfigInfo, ae);
- final ConfigurableBeanFactory sitemapContext =
- BeanFactoryUtil.createBeanFactory(ae, ci, parentContext, false);
+ final ConfigurableBeanFactory sitemapContext = BeanFactoryUtil.createBeanFactory(ae, ci,
+ parentContext, false);
newManager = (ServiceManager) sitemapContext.getBean(ServiceManager.class.getName());
- Logger sitemapLogger = (Logger)sitemapContext.getBean(Logger.class.getName());
+ Logger sitemapLogger = (Logger) sitemapContext.getBean(Logger.class.getName());
// and finally the listeners
final Configuration listenersWrapper = config.getChild("listeners", false);
- if ( listenersWrapper != null ) {
- final Configuration[] listeners = listenersWrapper.getChildren("listener");
- for(int i = 0; i < listeners.length; i++) {
+ 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, sitemapLogger, context, current);
- if ( !(listener.component instanceof SitemapListener) ) {
- throw new ConfigurationException("Listener must implement the SitemapListener interface.");
+ final TreeBuilder.EventComponent listener = this.createListener(newManager,
+ sitemapLogger, context, current);
+ if (!(listener.component instanceof SitemapListener)) {
+ throw new ConfigurationException(
+ "Listener must implement the SitemapListener interface.");
}
this.addListener(listener);
}
@@ -167,13 +715,10 @@
* Create a listener
*/
protected TreeBuilder.EventComponent createListener(ServiceManager manager,
- Logger sitemapLogger,
- Context context,
- Configuration config)
- throws Exception {
+ Logger sitemapLogger, Context context, Configuration config) throws Exception {
// role or class?
final String role = config.getAttribute("role", null);
- if ( role != null ) {
+ if (role != null) {
return new TreeBuilder.EventComponent(manager.lookup(role), true);
}
final String className = config.getAttribute("class");
@@ -188,9 +733,9 @@
* Add a listener
*/
protected void addListener(TreeBuilder.EventComponent listener) {
- if ( listener.component instanceof EnterSitemapEventListener ) {
+ if (listener.component instanceof EnterSitemapEventListener) {
this.enterSitemapEventListeners.add(listener);
- } else if ( listener.component instanceof LeaveSitemapEventListener ) {
+ } else if (listener.component instanceof LeaveSitemapEventListener) {
this.leaveSitemapEventListeners.add(listener);
}
}
@@ -200,17 +745,18 @@
*/
protected Context createContext(Configuration tree) throws Exception {
// Create sub-context for this sitemap
- DefaultContext newContext = new DefaultContext(super.createContext(tree));
+ DefaultContext newContext = new DefaultContext(this.context);
Environment env = EnvironmentHelper.getCurrentEnvironment();
newContext.put(Constants.CONTEXT_ENV_URI, env.getURI());
newContext.put(Constants.CONTEXT_ENV_PREFIX, env.getURIPrefix());
// FIXME How to get rid of EnvironmentHelper?
- newContext.put(Constants.CONTEXT_ENV_HELPER, getProcessor().getWrappingProcessor().getEnvironmentHelper());
+ newContext.put(Constants.CONTEXT_ENV_HELPER, getProcessor().getWrappingProcessor()
+ .getEnvironmentHelper());
return newContext;
}
- //---- Views management
+ // ---- Views management
/** Collection of view names for each label */
private Map labelViews = new HashMap();
@@ -225,30 +771,20 @@
private boolean isBuildingErrorHandler = false;
/**
- * Pseudo-label for views <code>from-position="first"</code> (i.e. generator).
+ * Pseudo-label for views <code>from-position="first"</code> (i.e.
+ * generator).
*/
public static final String FIRST_POS_LABEL = "!first!";
/**
- * Pseudo-label for views <code>from-position="last"</code> (i.e. serializer).
+ * Pseudo-label for views <code>from-position="last"</code> (i.e.
+ * serializer).
*/
public static final String LAST_POS_LABEL = "!last!";
- /* (non-Javadoc)
- * @see org.apache.avalon.excalibur.pool.Recyclable#recycle()
- */
- public void recycle() {
- super.recycle();
-
- // Go back to initial state
- this.labelViews.clear();
- this.viewsNode = null;
- this.isBuildingView = false;
- this.isBuildingErrorHandler = false;
- }
-
/**
- * Set to <code>true</code> while building the internals of a <map:view>
+ * Set to <code>true</code> while building the internals of a
+ * <map:view>
*/
public void setBuildingView(boolean building) {
this.isBuildingView = building;
@@ -262,7 +798,8 @@
}
/**
- * Set to <code>true</code> while building the internals of a <map:handle-errors>
+ * Set to <code>true</code> while building the internals of a
+ * <map:handle-errors>
*/
public void setBuildingErrorHandler(boolean building) {
this.isBuildingErrorHandler = building;
@@ -276,17 +813,19 @@
}
/**
- * Add a view for a label. This is used to register all views that start from
- * a given label.
- *
- * @param label the label (or pseudo-label) for the view
- * @param view the view name
+ * Add a view for a label. This is used to register all views that start
+ * from a given label.
+ *
+ * @param label
+ * the label (or pseudo-label) for the view
+ * @param view
+ * the view name
*/
public void addViewForLabel(String label, String view) {
if (getLogger().isDebugEnabled()) {
getLogger().debug("views:addViewForLabel(" + label + ", " + view + ")");
}
- Set views = (Set)this.labelViews.get(label);
+ Set views = (Set) this.labelViews.get(label);
if (views == null) {
views = new HashSet();
this.labelViews.put(label, views);
@@ -296,22 +835,28 @@
}
/**
- * Get the names of views for a given statement. If the cocoon view exists in the returned
- * collection, the statement can directly branch to the view-handling node.
- *
- * @param role the component role (e.g. <code>Generator.ROLE</code>)
- * @param hint the component hint, i.e. the 'type' attribute
- * @param statement the sitemap statement
+ * Get the names of views for a given statement. If the cocoon view exists
+ * in the returned collection, the statement can directly branch to the
+ * view-handling node.
+ *
+ * @param role
+ * the component role (e.g. <code>Generator.ROLE</code>)
+ * @param hint
+ * the component hint, i.e. the 'type' attribute
+ * @param statement
+ * the sitemap statement
* @return the view names for this statement
*/
- public Collection getViewsForStatement(String role, String hint, Configuration statement) throws Exception {
+ public Collection getViewsForStatement(String role, String hint, Configuration statement)
+ throws Exception {
String statementLabels = statement.getAttribute("label", null);
if (this.isBuildingView) {
// Labels are forbidden inside view definition
if (statementLabels != null) {
- String msg = "Cannot put a 'label' attribute inside view definition at " + statement.getLocation();
+ String msg = "Cannot put a 'label' attribute inside view definition at "
+ + statement.getLocation();
throw new ConfigurationException(msg);
}
@@ -352,14 +897,14 @@
// Iterate on all labels for this statement
Iterator labelIter = labels.iterator();
- while(labelIter.hasNext()) {
+ while (labelIter.hasNext()) {
// Iterate on all views for this labek
- Collection coll = (Collection)this.labelViews.get(labelIter.next());
+ Collection coll = (Collection) this.labelViews.get(labelIter.next());
if (coll != null) {
Iterator viewIter = coll.iterator();
- while(viewIter.hasNext()) {
- String viewName = (String)viewIter.next();
+ while (viewIter.hasNext()) {
+ String viewName = (String) viewIter.next();
views.add(viewName);
}
@@ -371,14 +916,15 @@
views = null;
if (getLogger().isDebugEnabled()) {
- getLogger().debug(statement.getName() + " has no views at " + statement.getLocation());
+ getLogger().debug(
+ statement.getName() + " has no views at " + statement.getLocation());
}
} else {
if (getLogger().isDebugEnabled()) {
// Dump matching views
StringBuffer buf = new StringBuffer(statement.getName() + " will match views [");
Iterator iter = views.iterator();
- while(iter.hasNext()) {
+ while (iter.hasNext()) {
buf.append(iter.next()).append(" ");
}
buf.append("] at ").append(statement.getLocation());
@@ -391,20 +937,11 @@
}
/**
- * Before linking nodes, lookup the view category node used in {@link #getViewNodes(Collection)}.
- */
- protected void linkNodes() throws Exception {
- // Get the views category node
- this.viewsNode = CategoryNodeBuilder.getCategoryNode(this, "views");
-
- super.linkNodes();
- }
-
- /**
- * Get the {view name, view node} map for a collection of view names.
- * This allows to resolve view nodes at build time, thus avoiding runtime lookup.
- *
- * @param viewNames the view names
+ * Get the {view name, view node} map for a collection of view names. This
+ * allows to resolve view nodes at build time, thus avoiding runtime lookup.
+ *
+ * @param viewNames
+ * the view names
* @return association of names to views
*/
public Map getViewNodes(Collection viewNames) throws Exception {
@@ -419,8 +956,8 @@
Map result = new HashMap();
Iterator iter = viewNames.iterator();
- while(iter.hasNext()) {
- String viewName = (String)iter.next();
+ while (iter.hasNext()) {
+ String viewName = (String) iter.next();
result.put(viewName, viewsNode.getNodeByName(viewName));
}
@@ -429,31 +966,38 @@
/**
* Extract pipeline-hints from the given statement (if any exist)
- *
- * @param role the component role (e.g. <code>Generator.ROLE</code>)
- * @param hint the component hint, i.e. the 'type' attribute
- * @param statement the sitemap statement
- * @return the hint params <code>Map</code> for this statement, or null
- * if none exist
+ *
+ * @param role
+ * the component role (e.g. <code>Generator.ROLE</code>)
+ * @param hint
+ * the component hint, i.e. the 'type' attribute
+ * @param statement
+ * the sitemap statement
+ * @return the hint params <code>Map</code> for this statement, or null if
+ * none exist
*/
- public Map getHintsForStatement(String role, String hint, Configuration statement) throws Exception {
+ public Map getHintsForStatement(String role, String hint, Configuration statement)
+ throws Exception {
// This method implemets the hintParam Syntax as follows:
- // A hints attribute has one or more comma separated hints
- // hints-attr :: hint [ ',' hint ]*
- // A hint is a name and an optional (string) value
- // If there is no value, it is considered as boolean string "true"
- // hint :: literal [ '=' litteral ]
- // literal :: <a character string where the chars ',' and '=' are not permitted>
+ // A hints attribute has one or more comma separated hints
+ // hints-attr :: hint [ ',' hint ]*
+ // A hint is a name and an optional (string) value
+ // If there is no value, it is considered as boolean string "true"
+ // hint :: literal [ '=' litteral ]
+ // literal :: <a character string where the chars ',' and '=' are not
+ // permitted>
//
- // A ConfigurationException is thrown if there is a problem "parsing"
- // the hint.
+ // A ConfigurationException is thrown if there is a problem "parsing"
+ // the hint.
String statementHintParams = statement.getAttribute("pipeline-hints", null);
String componentHintParams = null;
String hintParams = null;
- // firstly, determine if any pipeline-hints are defined at the component level
- // if so, inherit these pipeline-hints (these hints can be overriden by local pipeline-hints)
+ // firstly, determine if any pipeline-hints are defined at the component
+ // level
+ // if so, inherit these pipeline-hints (these hints can be overriden by
+ // local pipeline-hints)
componentHintParams = this.itsComponentInfo.getPipelineHint(role, hint);
if (componentHintParams != null) {
@@ -477,32 +1021,34 @@
RE commaSplit = new RE(COMMA_SPLIT_REGEXP);
RE equalsSplit = new RE(EQUALS_SPLIT_REGEXP);
- String[] expressions = commaSplit.split(hintParams.trim());
+ String[] expressions = commaSplit.split(hintParams.trim());
if (getLogger().isDebugEnabled()) {
getLogger().debug("pipeline-hints: (aggregate-hint) " + hintParams);
}
- for (int i=0; i<expressions.length;i++) {
- String [] nameValuePair = equalsSplit.split(expressions[i]);
+ for (int i = 0; i < expressions.length; i++) {
+ String[] nameValuePair = equalsSplit.split(expressions[i]);
try {
if (nameValuePair.length < 2) {
if (getLogger().isDebugEnabled()) {
- getLogger().debug("pipeline-hints: (name) " + nameValuePair[0]
- + "\npipeline-hints: (value) [implicit] true");
+ getLogger().debug(
+ "pipeline-hints: (name) " + nameValuePair[0]
+ + "\npipeline-hints: (value) [implicit] true");
}
params.put(resolve(nameValuePair[0]), resolve("true"));
} else {
if (getLogger().isDebugEnabled()) {
- getLogger().debug("pipeline-hints: (name) " + nameValuePair[0]
- + "\npipeline-hints: (value) " + nameValuePair[1]);
+ getLogger().debug(
+ "pipeline-hints: (name) " + nameValuePair[0]
+ + "\npipeline-hints: (value) " + nameValuePair[1]);
}
params.put(resolve(nameValuePair[0]), resolve(nameValuePair[1]));
}
- } catch(PatternException pe) {
+ } catch (PatternException pe) {
String msg = "Invalid pattern '" + hintParams + "' at " + statement.getLocation();
getLogger().error(msg, pe);
throw new ConfigurationException(msg, pe);
@@ -511,7 +1057,7 @@
return params;
}
-
+
/**
* Get the mime-type for a component (either a serializer or a reader)
*
@@ -539,9 +1085,11 @@
* @see org.springframework.beans.factory.BeanFactoryAware#setBeanFactory(org.springframework.beans.factory.BeanFactory)
*/
public void setBeanFactory(BeanFactory beanFactory) throws BeansException {
- if ( ! (beanFactory instanceof ConfigurableBeanFactory) ) {
- throw new BeanCreationException("Bean factory for tree processor must be an instance of " + ConfigurableBeanFactory.class.getName());
+ if (!(beanFactory instanceof ConfigurableBeanFactory)) {
+ throw new BeanCreationException(
+ "Bean factory for tree processor must be an instance of "
+ + ConfigurableBeanFactory.class.getName());
}
- this.beanFactory = (ConfigurableBeanFactory)beanFactory;
+ this.beanFactory = (ConfigurableBeanFactory) beanFactory;
}
}
Modified: cocoon/trunk/cocoon-core/src/main/java/org/apache/cocoon/reading/ImageReader.java
URL: http://svn.apache.org/viewcvs/cocoon/trunk/cocoon-core/src/main/java/org/apache/cocoon/reading/ImageReader.java?rev=383193&r1=383192&r2=383193&view=diff
==============================================================================
--- cocoon/trunk/cocoon-core/src/main/java/org/apache/cocoon/reading/ImageReader.java (original)
+++ cocoon/trunk/cocoon-core/src/main/java/org/apache/cocoon/reading/ImageReader.java Sat Mar 4 12:12:35 2006
@@ -37,9 +37,7 @@
import com.sun.image.codec.jpeg.ImageFormatException;
import com.sun.image.codec.jpeg.JPEGCodec;
-import com.sun.image.codec.jpeg.JPEGDecodeParam;
import com.sun.image.codec.jpeg.JPEGEncodeParam;
-import com.sun.image.codec.jpeg.JPEGImageDecoder;
import com.sun.image.codec.jpeg.JPEGImageEncoder;
/**
Modified: cocoon/trunk/cocoon-core/src/test/java/org/apache/cocoon/core/container/ContainerTestCase.java
URL: http://svn.apache.org/viewcvs/cocoon/trunk/cocoon-core/src/test/java/org/apache/cocoon/core/container/ContainerTestCase.java?rev=383193&r1=383192&r2=383193&view=diff
==============================================================================
--- cocoon/trunk/cocoon-core/src/test/java/org/apache/cocoon/core/container/ContainerTestCase.java (original)
+++ cocoon/trunk/cocoon-core/src/test/java/org/apache/cocoon/core/container/ContainerTestCase.java Sat Mar 4 12:12:35 2006
@@ -34,7 +34,6 @@
import org.apache.avalon.framework.parameters.Parameters;
import org.apache.avalon.framework.service.ServiceException;
import org.apache.avalon.framework.service.ServiceManager;
-import org.apache.cocoon.core.Core;
import org.apache.cocoon.core.MutableSettings;
import org.apache.cocoon.core.container.spring.BeanFactoryUtil;
import org.apache.cocoon.core.container.spring.AvalonEnvironment;
@@ -287,18 +286,17 @@
avalonEnv.logger = this.logger;
avalonEnv.context = this.context;
avalonEnv.settings = new MutableSettings();
- avalonEnv.core = new Core(avalonEnv.context);
avalonEnv.servletContext = new MockContext();
this.rootContext = BeanFactoryUtil.createRootApplicationContext(avalonEnv);
// read roles
ConfigurationInfo rolesInfo = ConfigReader.readConfiguration(confRM, null, avalonEnv);
- ConfigurableBeanFactory rolesContext = BeanFactoryUtil.createApplicationContext(avalonEnv, rolesInfo, rootContext, true);
+ ConfigurableBeanFactory rolesContext = BeanFactoryUtil.createBeanFactory(avalonEnv, rolesInfo, rootContext, true);
// read components
ConfigurationInfo componentsInfo = ConfigReader.readConfiguration(confCM, rolesInfo, avalonEnv);
this.addComponents( componentsInfo );
- ConfigurableBeanFactory componentsContext = BeanFactoryUtil.createApplicationContext(avalonEnv, componentsInfo, rolesContext, false);
+ ConfigurableBeanFactory componentsContext = BeanFactoryUtil.createBeanFactory(avalonEnv, componentsInfo, rolesContext, false);
this.manager = (ServiceManager)componentsContext.getBean(ServiceManager.class.getName());
}