You are viewing a plain text version of this content. The canonical link for it is here.
Posted to cvs@cocoon.apache.org by vg...@apache.org on 2004/11/18 01:15:59 UTC
svn commit: rev 76197 - in cocoon/trunk/src/java/org/apache/cocoon: . components/treeprocessor components/treeprocessor/sitemap
Author: vgritsenko
Date: Wed Nov 17 16:15:58 2004
New Revision: 76197
Modified:
cocoon/trunk/src/java/org/apache/cocoon/Constants.java
cocoon/trunk/src/java/org/apache/cocoon/components/treeprocessor/DefaultTreeBuilder.java
cocoon/trunk/src/java/org/apache/cocoon/components/treeprocessor/sitemap/SitemapLanguage.java
Log:
Refactor DefaultTreeBuilder. Make stuff private.
Implement separate context object for each pipeline
(required for VPCs)
Modified: cocoon/trunk/src/java/org/apache/cocoon/Constants.java
==============================================================================
--- cocoon/trunk/src/java/org/apache/cocoon/Constants.java (original)
+++ cocoon/trunk/src/java/org/apache/cocoon/Constants.java Wed Nov 17 16:15:58 2004
@@ -24,7 +24,7 @@
*
* @author <a href="mailto:stefano@apache.org">Stefano Mazzocchi</a>
* @author <a href="mailto:proyal@managingpartners.com">Peter Royal</a>
- * @version CVS $Id: Constants.java,v 1.15 2004/06/11 21:37:04 vgritsenko Exp $
+ * @version CVS $Id$
*/
public final class Constants {
@@ -255,6 +255,19 @@
/** Application <code>Context</code> Key for the current classpath */
public static final String CONTEXT_CLASSPATH = "classpath";
+
+
+ /** Application <code>Context</code> key for the current environment URI */
+ public static final String CONTEXT_ENV_URI = "env-uri";
+
+ /** Application <code>Context</code> key for the current environment prefix */
+ public static final String CONTEXT_ENV_PREFIX = "env-prefix";
+
+ /** Application <code>Context</code> key for the current environment helper */
+ public static final String CONTEXT_ENV_HELPER = "env-helper";
+
+ /** Application <code>Context</code> key prefix for the current sitemap virtual components */
+ public static final String CONTEXT_VPC_PREFIX = "vpc-";
/**
* Application <code>Context</code> Key for the URL to the configuration file
Modified: cocoon/trunk/src/java/org/apache/cocoon/components/treeprocessor/DefaultTreeBuilder.java
==============================================================================
--- cocoon/trunk/src/java/org/apache/cocoon/components/treeprocessor/DefaultTreeBuilder.java (original)
+++ cocoon/trunk/src/java/org/apache/cocoon/components/treeprocessor/DefaultTreeBuilder.java Wed Nov 17 16:15:58 2004
@@ -39,6 +39,7 @@
import org.apache.cocoon.components.LifecycleHelper;
import org.apache.cocoon.components.source.SourceUtil;
import org.apache.cocoon.components.treeprocessor.variables.VariableResolverFactory;
+import org.apache.cocoon.components.treeprocessor.variables.VariableResolver;
import org.apache.cocoon.sitemap.PatternException;
import org.apache.cocoon.sitemap.SitemapParameters;
import org.apache.excalibur.source.Source;
@@ -56,38 +57,62 @@
protected Map attributes = new HashMap();
+ //----- lifecycle-related objects ------
+
+ /**
+ * This component's avalon context
+ */
+ private Context context;
+
+ /**
+ * This component's service manager
+ */
+ private ServiceManager manager;
+
+ // -------------------------------------
+
/**
- * The tree processor that we're building.
+ * The tree processor that we are building.
*/
protected ConcreteTreeProcessor processor;
- //----- lifecycle-related objects ------
- protected Context context;
+ /**
+ * The namespace of configuration for the processor that we are building.
+ */
+ protected String itsNamespace;
/**
- * The parent component manager. Either the one of the parent processor, or that provided
- * by Cocoon in service()
+ * The context for the processor that we are building
+ * It is created by {@link #createContext(Configuration)}.
*/
- protected ServiceManager ownManager;
+ private Context itsContext;
- // -------------------------------------
+ /**
+ * The service manager for the processor that we are building.
+ * It is created by {@link #createServiceManager(Context, Configuration)}.
+ */
+ private ServiceManager itsManager;
/**
- * Component processor of the parent manager (can be null for the root sitemap)
+ * Helper object which sets up components in the context
+ * of the processor that we are building.
*/
- protected ServiceManager parentProcessorManager;
+ private LifecycleHelper itsLifecycle;
/**
- * Component manager created by {@link #createServiceManager(Configuration)}.
+ * Selector for ProcessingNodeBuilders which is set up
+ * in the context of the processor that we are building.
*/
- protected ServiceManager processorManager;
+ private ServiceSelector itsBuilders;
- /** Selector for ProcessingNodeBuilders */
- protected ServiceSelector builderSelector;
+ // -------------------------------------
- protected LifecycleHelper lifecycle;
+ /**
+ * Component processor of the parent manager
+ * (can be null for the root sitemap)
+ */
+ protected ServiceManager parentProcessorManager;
- protected String namespace;
/** Nodes gone through setupNode() that implement Initializable */
private List initializableNodes = new ArrayList();
@@ -116,9 +141,13 @@
* @see org.apache.avalon.framework.service.Serviceable#service(org.apache.avalon.framework.service.ServiceManager)
*/
public void service(ServiceManager manager) throws ServiceException {
- this.ownManager = manager;
+ this.manager = manager;
}
+ public void initialize() throws Exception {
+ }
+
+
/**
* Get the location of the treebuilder config file. Can be overridden for other versions.
* @return
@@ -127,51 +156,6 @@
return "resource://org/apache/cocoon/components/treeprocessor/sitemap-language.xml";
}
- public void initialize() throws Exception {
- // Load the builder config file
- SourceResolver resolver = (SourceResolver) this.ownManager.lookup(SourceResolver.ROLE);
- String url = getBuilderConfigURL();
- Configuration config;
- try {
- Source src = resolver.resolveURI(url);
- try {
- SAXConfigurationHandler handler = new SAXConfigurationHandler();
- SourceUtil.toSAX(this.ownManager, 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.ownManager.release(resolver);
- }
-
- // Create the NodeBuilder selector.
- CocoonServiceSelector selector = new CocoonServiceSelector() {
- protected String getComponentInstanceName() {
- return "node";
- }
-
- protected String getClassAttributeName() {
- return "builder";
- }
- };
-
- // Automagically initialize the selector
- LifecycleHelper.setupComponent(selector,
- getLogger(),
- this.context,
- this.ownManager,
- config.getChild("nodes", false),
- true
- );
-
- this.builderSelector = selector;
-
- }
-
-
public void setParentProcessorManager(ServiceManager manager) {
this.parentProcessorManager = manager;
}
@@ -191,23 +175,44 @@
}
/**
+ * Create a context that will be used for all <code>Contextualizable</code>
+ * <code>ProcessingNodeBuilder</code>s and <code>ProcessingNode</code>s.
+ *
+ * <p>The default here is to simply return the context set in
+ * <code>contextualize()</code>, i.e. the context set by the calling
+ * <code>TreeProcessor</code>.
+ *
+ * <p>Subclasses can redefine this method to create a context local to
+ * a tree, such as for sitemap's <map:components>.
+ *
+ * @return a context
+ */
+ protected Context createContext(Configuration tree)
+ throws Exception {
+ return this.context;
+ }
+
+ /**
* Create a service manager that will be used for all <code>Serviceable</code>
* <code>ProcessingNodeBuilder</code>s and <code>ProcessingNode</code>s.
- * <p>
- * The default here is to simply return the manager set by <code>compose()</code>,
- * i.e. the component manager set by the calling <code>TreeProcessor</code>.
- * <p>
- * Subclasses can redefine this method to create a component manager local to a tree,
- * such as for sitemap's <map:components>.
+ *
+ * <p>The default here is to simply return the manager set in
+ * <code>compose()</code>, i.e. the component manager set by the calling
+ * <code>TreeProcessor</code>.
+ *
+ * <p>Subclasses can redefine this method to create a service manager local to
+ * a tree, such as for sitemap's <map:components>.
*
* @return a component manager
*/
- protected ServiceManager createServiceManager(Configuration tree) throws Exception {
- return this.ownManager;
+ protected ServiceManager createServiceManager(Context context, Configuration tree)
+ throws Exception {
+ return this.manager;
}
+
/* (non-Javadoc)
- * @see org.apache.cocoon.components.treeprocessor.TreeBuilder#setProcessor(org.apache.cocoon.components.treeprocessor.ConcreteTreeProcessor)
+ * @see org.apache.cocoon.components.treeprocessor.TreeBuilder#setProcessor(ConcreteTreeProcessor)
*/
public void setProcessor(ConcreteTreeProcessor processor) {
this.processor = processor;
@@ -220,6 +225,7 @@
return this.processor;
}
+
/**
* Register a <code>ProcessingNode</code> under a given name.
* For example, <code>ResourceNodeBuilder</code> stores here the <code>ProcessingNode</code>s
@@ -241,17 +247,16 @@
// FIXME : check namespace
String nodeName = config.getName();
- if (this.getLogger().isDebugEnabled()) {
+ if (getLogger().isDebugEnabled()) {
getLogger().debug("Creating node builder for " + nodeName);
}
ProcessingNodeBuilder builder;
try {
- builder = (ProcessingNodeBuilder)this.builderSelector.select(nodeName);
-
- } catch(ServiceException ce) {
+ builder = (ProcessingNodeBuilder) this.itsBuilders.select(nodeName);
+ } catch (ServiceException ce) {
// Is it because this element is unknown ?
- if (this.builderSelector.isSelectable(nodeName)) {
+ if (this.itsBuilders.isSelectable(nodeName)) {
// No : rethrow
throw ce;
} else {
@@ -299,25 +304,63 @@
* Get the namespace URI that builders should use to find their nodes.
*/
public String getNamespace() {
- return this.namespace;
+ 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();
- // The namespace use in the whole sitemap is the one of the root element
- this.namespace = tree.getNamespace();
-
- this.processorManager = createServiceManager(tree);
+ // Context and manager for the sitemap we build
+ this.itsContext = createContext(tree);
+ this.itsManager = createServiceManager(this.itsContext, tree);
// Create a helper object to setup components
- this.lifecycle = new LifecycleHelper(getLogger(),
- this.context,
- this.processorManager,
- null // configuration
- );
+ this.itsLifecycle = new LifecycleHelper(getLogger(),
+ this.itsContext,
+ this.itsManager,
+ null /* configuration */);
+
+ // Create & initialize the NodeBuilder selector.
+ {
+ CocoonServiceSelector selector = new CocoonServiceSelector() {
+ protected String getComponentInstanceName() {
+ return "node";
+ }
+
+ protected String getClassAttributeName() {
+ return "builder";
+ }
+ };
+ // 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;
@@ -366,7 +409,7 @@
((AbstractProcessingNode)node).setSitemapExecutor(this.processor.getSitemapExecutor());
}
- this.lifecycle.setupComponent(node, false);
+ this.itsLifecycle.setupComponent(node, false);
if (node instanceof ParameterizableProcessingNode) {
Map params = getParameters(config);
@@ -407,9 +450,7 @@
String name = child.getAttribute("name");
String value = child.getAttribute("value");
try {
- params.put(
- VariableResolverFactory.getResolver(name, this.processorManager),
- VariableResolverFactory.getResolver(value, this.processorManager));
+ params.put(resolve(name), resolve(value));
} catch(PatternException pe) {
String msg = "Invalid pattern '" + value + "' at " + child.getLocation();
throw new ConfigurationException(msg, pe);
@@ -442,42 +483,50 @@
// Check that this type actually exists
ServiceSelector selector = null;
-
try {
- selector = (ServiceSelector)this.processorManager.lookup(role + "Selector");
- } catch(ServiceException ce) {
+ selector = (ServiceSelector) this.itsManager.lookup(role + "Selector");
+ } catch (ServiceException e) {
throw new ConfigurationException("Cannot get service selector for 'map:" +
- statement.getName() + "' at " + statement.getLocation(),
- ce
- );
+ statement.getName() + "' at " + statement.getLocation(),
+ e);
}
- this.processorManager.release(selector);
+ this.itsManager.release(selector);
if (!selector.isSelectable(type)) {
throw new ConfigurationException("Type '" + type + "' does not exist for 'map:" +
- statement.getName() + "' at " + statement.getLocation()
- );
+ statement.getName() + "' at " + statement.getLocation());
}
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.lifecycle = null; // Created in build()
this.linkedBuilders.clear();
- this.namespace = null; // Set in build()
this.parentProcessorManager = null; // Set in setParentProcessorManager()
- this.processor = null; // Set in setProcessor()
- this.processorManager = null; // Set in build()
- this.registeredNodes.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.lifecycle = null; // Created in build()
+ this.registeredNodes.clear();
this.initializableNodes.clear();
this.linkedBuilders.clear();
this.canGetNode = false;
@@ -487,8 +536,6 @@
}
public void dispose() {
- LifecycleHelper.dispose(this.builderSelector);
-
// Don't dispose manager or roles: they are used by the built tree
// and thus must live longer than the builder.
}
Modified: cocoon/trunk/src/java/org/apache/cocoon/components/treeprocessor/sitemap/SitemapLanguage.java
==============================================================================
--- 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 Wed Nov 17 16:15:58 2004
@@ -15,20 +15,14 @@
*/
package org.apache.cocoon.components.treeprocessor.sitemap;
-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.Map;
-import java.util.Set;
-import java.util.StringTokenizer;
-
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.context.Context;
+import org.apache.avalon.framework.context.DefaultContext;
import org.apache.avalon.framework.service.ServiceManager;
+
+import org.apache.cocoon.Constants;
import org.apache.cocoon.acting.Action;
import org.apache.cocoon.components.container.CocoonServiceManager;
import org.apache.cocoon.components.pipeline.ProcessingPipeline;
@@ -36,7 +30,8 @@
import org.apache.cocoon.components.treeprocessor.CategoryNodeBuilder;
import org.apache.cocoon.components.treeprocessor.DefaultTreeBuilder;
import org.apache.cocoon.components.treeprocessor.ProcessorComponentInfo;
-import org.apache.cocoon.components.treeprocessor.variables.VariableResolverFactory;
+import org.apache.cocoon.environment.Environment;
+import org.apache.cocoon.environment.internal.EnvironmentHelper;
import org.apache.cocoon.generation.Generator;
import org.apache.cocoon.matching.Matcher;
import org.apache.cocoon.reading.Reader;
@@ -45,8 +40,19 @@
import org.apache.cocoon.sitemap.PatternException;
import org.apache.cocoon.transformation.Transformer;
import org.apache.cocoon.util.StringUtils;
+
import org.apache.regexp.RE;
+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.Map;
+import java.util.Set;
+import java.util.StringTokenizer;
+
/**
* The tree builder for the sitemap language.
*
@@ -63,7 +69,7 @@
* Build a component manager with the contents of the <map:components> element of
* the tree.
*/
- protected ServiceManager createServiceManager(Configuration tree) throws Exception {
+ protected ServiceManager createServiceManager(Context context, Configuration tree) throws Exception {
// Get the map:component node
// Don't check namespace here : this will be done by node builders
@@ -80,7 +86,7 @@
// Go through the component lifecycle
newManager.enableLogging(getLogger());
- newManager.contextualize(this.context);
+ newManager.contextualize(context);
newManager.configure(config);
newManager.initialize();
@@ -111,6 +117,17 @@
return newManager;
}
+ protected Context createContext(Configuration tree) throws Exception {
+ // Create sub-context for this sitemap
+ DefaultContext newContext = new DefaultContext(super.createContext(tree));
+ Environment env = EnvironmentHelper.getCurrentEnvironment();
+ newContext.put(Constants.CONTEXT_ENV_URI, env.getURI());
+ newContext.put(Constants.CONTEXT_ENV_PREFIX, env.getURIPrefix());
+ // FIXME How to get rif of EnvironmentHelper?
+ newContext.put(Constants.CONTEXT_ENV_HELPER, getProcessor().getWrappingProcessor().getEnvironmentHelper());
+ return newContext;
+ }
+
/**
* Setup the default compnent type for a given role.
*
@@ -461,16 +478,14 @@
+ "\npipeline-hints: (value) [implicit] true");
}
- params.put( VariableResolverFactory.getResolver(nameValuePair[0], this.processorManager),
- VariableResolverFactory.getResolver("true", this.processorManager));
+ params.put(resolve(nameValuePair[0]), resolve("true"));
} else {
if (getLogger().isDebugEnabled()) {
getLogger().debug("pipeline-hints: (name) " + nameValuePair[0]
+ "\npipeline-hints: (value) " + nameValuePair[1]);
}
- params.put( VariableResolverFactory.getResolver(nameValuePair[0], this.processorManager),
- VariableResolverFactory.getResolver(nameValuePair[1], this.processorManager));
+ params.put(resolve(nameValuePair[0]), resolve(nameValuePair[1]));
}
} catch(PatternException pe) {
String msg = "Invalid pattern '" + hintParams + "' at " + statement.getLocation();