sylvain 01/11/25 13:37:56 Modified: scratchpad/src/org/apache/cocoon/treeprocessor AbstractParentProcessingNode.java AbstractParentProcessingNodeBuilder.java AbstractProcessingNode.java AbstractProcessingNodeBuilder.java ListOfMapsResolver.java TreeBuilder.java TreeBuilderComponentManager.java TreeProcessor.java treeprocessor.xconf scratchpad/src/org/apache/cocoon/treeprocessor/sitemap ActNode.java ActNodeBuilder.java ComponentsNodeBuilder.java GenerateNode.java GenerateNodeBuilder.java MatchNode.java MatchNodeBuilder.java PipelineNode.java PipelineNodeBuilder.java PipelinesNodeBuilder.java PreparableMatchNode.java ReadNode.java ReadNodeBuilder.java RedirectToNodeBuilder.java SerializeNodeBuilder.java SitemapNodeBuilder.java TransformNode.java TransformNodeBuilder.java Added: scratchpad/src/org/apache/cocoon/treeprocessor ComponentUtil.java ParameterizableProcessingNode.java scratchpad/src/org/apache/cocoon/treeprocessor/sitemap HandleErrorsNode.java HandleErrorsNodeBuilder.java MountNode.java MountNodeBuilder.java Log: - polished the design (shouldn't change anymore), - more new features (some are still missing), - redirects are now ok, so the home page displays, - sitemap loading is also really fast. Revision Changes Path 1.4 +4 -2 xml-cocoon2/scratchpad/src/org/apache/cocoon/treeprocessor/AbstractParentProcessingNode.java Index: AbstractParentProcessingNode.java =================================================================== RCS file: /home/cvs/xml-cocoon2/scratchpad/src/org/apache/cocoon/treeprocessor/AbstractParentProcessingNode.java,v retrieving revision 1.3 retrieving revision 1.4 diff -u -r1.3 -r1.4 --- AbstractParentProcessingNode.java 2001/11/18 20:58:44 1.3 +++ AbstractParentProcessingNode.java 2001/11/25 21:37:55 1.4 @@ -20,7 +20,7 @@ /** * * @author <a href="mailto:[EMAIL PROTECTED]">Sylvain Wallez</a> - * @version CVS $Revision: 1.3 $ $Date: 2001/11/18 20:58:44 $ + * @version CVS $Revision: 1.4 $ $Date: 2001/11/25 21:37:55 $ */ public abstract class AbstractParentProcessingNode extends AbstractProcessingNode { @@ -65,9 +65,11 @@ List listOfMaps) throws Exception { + boolean debug = logger.isDebugEnabled(); for (int i = 0; i < nodes.length; i++) { - logger.debug("Invoking node " + nodes[i] + " at " + nodes[i].getLocation()); if (nodes[i].invoke(env, pipeline, eventPipeline, listOfMaps)) { + if (debug) + logger.debug("Node " + nodes[i] + " at " + nodes[i].getLocation() + " succeeded"); return true; } } 1.4 +6 -1 xml-cocoon2/scratchpad/src/org/apache/cocoon/treeprocessor/AbstractParentProcessingNodeBuilder.java Index: AbstractParentProcessingNodeBuilder.java =================================================================== RCS file: /home/cvs/xml-cocoon2/scratchpad/src/org/apache/cocoon/treeprocessor/AbstractParentProcessingNodeBuilder.java,v retrieving revision 1.3 retrieving revision 1.4 diff -u -r1.3 -r1.4 --- AbstractParentProcessingNodeBuilder.java 2001/11/18 20:58:44 1.3 +++ AbstractParentProcessingNodeBuilder.java 2001/11/25 21:37:55 1.4 @@ -22,7 +22,7 @@ * children nodes. * * @author <a href="mailto:[EMAIL PROTECTED]">Sylvain Wallez</a> - * @version CVS $Revision: 1.3 $ $Date: 2001/11/18 20:58:44 $ + * @version CVS $Revision: 1.4 $ $Date: 2001/11/25 21:37:55 $ */ @@ -58,6 +58,11 @@ String name = child.getName(); try { checkNamespace(child); + + // Is this a parameter of a ParameterizableProcessingNode ? + if (name.equals(this.treeBuilder.getParameterName()) && this.hasParameters()) { + continue; + } // Is this element to be ignored ? if (ignoredChildren != null && ignoredChildren.contains(name)) { 1.3 +1 -20 xml-cocoon2/scratchpad/src/org/apache/cocoon/treeprocessor/AbstractProcessingNode.java Index: AbstractProcessingNode.java =================================================================== RCS file: /home/cvs/xml-cocoon2/scratchpad/src/org/apache/cocoon/treeprocessor/AbstractProcessingNode.java,v retrieving revision 1.2 retrieving revision 1.3 diff -u -r1.2 -r1.3 --- AbstractProcessingNode.java 2001/11/12 18:07:43 1.2 +++ AbstractProcessingNode.java 2001/11/25 21:37:55 1.3 @@ -9,31 +9,19 @@ package org.apache.cocoon.treeprocessor; import org.apache.avalon.framework.logger.AbstractLoggable; -import org.apache.avalon.framework.parameters.Parameters; -import org.apache.avalon.framework.thread.ThreadSafe; -import org.apache.cocoon.environment.Environment; -import org.apache.cocoon.environment.Redirector; import org.apache.cocoon.environment.SourceResolver; -import org.apache.cocoon.components.pipeline.EventPipeline; -import org.apache.cocoon.components.pipeline.StreamPipeline; - -import java.util.Iterator; -import java.util.List; import java.util.Map; /** * * @author <a href="mailto:[EMAIL PROTECTED]">Sylvain Wallez</a> - * @version CVS $Revision: 1.2 $ $Date: 2001/11/12 18:07:43 $ + * @version CVS $Revision: 1.3 $ $Date: 2001/11/25 21:37:55 $ */ public abstract class AbstractProcessingNode extends AbstractLoggable implements ProcessingNode { - /** The node parameters, as a <code>Map</code> of <code>ListOfMapsResolver</code>s. */ - protected Map parameters; - protected String location = "unknown location"; /** @@ -41,13 +29,6 @@ */ protected static final SourceResolver getSourceResolver(Map objectModel) { return (SourceResolver)objectModel.get(OBJECT_SOURCE_RESOLVER); - } - - /** - * Set the parameters of this node as a <code>Map</code> of <code>ListOfMapsResolver</code>s - * that will be resolved at process-time. - */ - public void setParameters(Map parameters) { } /** 1.3 +10 -1 xml-cocoon2/scratchpad/src/org/apache/cocoon/treeprocessor/AbstractProcessingNodeBuilder.java Index: AbstractProcessingNodeBuilder.java =================================================================== RCS file: /home/cvs/xml-cocoon2/scratchpad/src/org/apache/cocoon/treeprocessor/AbstractProcessingNodeBuilder.java,v retrieving revision 1.2 retrieving revision 1.3 diff -u -r1.2 -r1.3 --- AbstractProcessingNodeBuilder.java 2001/11/12 18:07:43 1.2 +++ AbstractProcessingNodeBuilder.java 2001/11/25 21:37:55 1.3 @@ -24,7 +24,7 @@ /** * * @author <a href="mailto:[EMAIL PROTECTED]">Sylvain Wallez</a> - * @version CVS $Revision: 1.2 $ $Date: 2001/11/12 18:07:43 $ + * @version CVS $Revision: 1.3 $ $Date: 2001/11/25 21:37:55 $ */ @@ -35,6 +35,15 @@ public void setBuilder(TreeBuilder treeBuilder) { this.treeBuilder = treeBuilder; + } + + /** + * Does this node accept parameters ? Default is true : if a builder that doesn't + * have parameters doesn't override this method, erroneous parameters will be silently + * ignored. + */ + protected boolean hasParameters() { + return true; } /** 1.4 +2 -2 xml-cocoon2/scratchpad/src/org/apache/cocoon/treeprocessor/ListOfMapsResolver.java Index: ListOfMapsResolver.java =================================================================== RCS file: /home/cvs/xml-cocoon2/scratchpad/src/org/apache/cocoon/treeprocessor/ListOfMapsResolver.java,v retrieving revision 1.3 retrieving revision 1.4 diff -u -r1.3 -r1.4 --- ListOfMapsResolver.java 2001/11/18 20:58:44 1.3 +++ ListOfMapsResolver.java 2001/11/25 21:37:55 1.4 @@ -20,7 +20,7 @@ * Utility class for handling {...} pattern substitutions from a List of Maps. * * @author <a href="mailto:[EMAIL PROTECTED]">Sylvain Wallez</a> - * @version CVS $Revision: 1.3 $ $Date: 2001/11/18 20:58:44 $ + * @version CVS $Revision: 1.4 $ $Date: 2001/11/25 21:37:55 $ */ public abstract class ListOfMapsResolver { @@ -136,7 +136,7 @@ * No-op resolver for expressions that don't need to be resolved. */ private static class NullResolver extends ListOfMapsResolver { - private String originalExpr; + private String originalExpr = null; private String expression = null; public NullResolver(String expression) { 1.4 +104 -28 xml-cocoon2/scratchpad/src/org/apache/cocoon/treeprocessor/TreeBuilder.java Index: TreeBuilder.java =================================================================== RCS file: /home/cvs/xml-cocoon2/scratchpad/src/org/apache/cocoon/treeprocessor/TreeBuilder.java,v retrieving revision 1.3 retrieving revision 1.4 diff -u -r1.3 -r1.4 --- TreeBuilder.java 2001/11/18 20:58:44 1.3 +++ TreeBuilder.java 2001/11/25 21:37:55 1.4 @@ -10,6 +10,8 @@ import org.apache.avalon.excalibur.component.DefaultRoleManager; import org.apache.avalon.excalibur.component.ExcaliburComponentSelector; +import org.apache.avalon.excalibur.component.RoleManageable; +import org.apache.avalon.excalibur.component.RoleManager; import org.apache.avalon.excalibur.logger.LogKitManageable; import org.apache.avalon.excalibur.logger.LogKitManager; @@ -30,17 +32,15 @@ import org.apache.avalon.framework.logger.AbstractLoggable; +import org.apache.cocoon.sitemap.PatternException; import org.apache.cocoon.util.ClassUtils; -import java.util.HashMap; -import java.util.Map; -import org.apache.avalon.excalibur.component.RoleManageable; -import org.apache.avalon.excalibur.component.RoleManager; +import java.util.*; /** * * @author <a href="mailto:[EMAIL PROTECTED]">Sylvain Wallez</a> - * @version CVS $Revision: 1.3 $ $Date: 2001/11/18 20:58:44 $ + * @version CVS $Revision: 1.4 $ $Date: 2001/11/25 21:37:55 $ */ public class TreeBuilder extends AbstractLoggable implements @@ -70,8 +70,12 @@ private ExcaliburComponentSelector builderSelector; + private ComponentUtil compUtil; + private String namespace; + private String parameterElement; + private String languageName; private boolean canGetNode = false; @@ -86,15 +90,6 @@ public void compose(ComponentManager manager) throws ComponentException { this.parentManager = manager; - - // Create the new component manager - this.manager = new TreeBuilderComponentManager(this.parentManager); - this.manager.setLogger(getLogger()); - this.manager.contextualize(this.context); - this.manager.setRoleManager(this.roleManager); - this.manager.setLogKitManager(this.logKit); - // this.manager.configure( - no configuration - ); - // initialize() is called later. In the meanwhile, only parent components will be visible. } public void setRoleManager(RoleManager rm) { @@ -102,21 +97,44 @@ } public void configure(Configuration config) throws ConfigurationException { - - this.languageName = config.getAttribute("name"); - getLogger().debug("Configuring Builder for language : " + this.languageName); - - this.namespace = config.getChild("namespace").getAttribute("uri", ""); + // Create the new component manager + this.manager = new TreeBuilderComponentManager(this.parentManager); + try { + ComponentUtil.setupComponent(this.manager, + getLogger(), + this.context, + null, // component manager + this.roleManager, + this.logKit, + null // configuration + ); + } catch(Exception e) { + throw new ConfigurationException("Couldn't setup internal component manager", e); + } + + // makeVisible() is called later. In the meantime, only parent components will be visible. + try { + // Create a helper object to setup components + this.compUtil = new ComponentUtil(getLogger(), + this.context, + this.manager, + this.roleManager, + this.logKit, + null // configuration + ); + + this.languageName = config.getAttribute("name"); + getLogger().debug("Configuring Builder for language : " + this.languageName); + + this.namespace = config.getChild("namespace").getAttribute("uri", ""); + + this.parameterElement = config.getChild("parameter").getAttribute("element", "parameter"); + // Create the NodeBuilder selector. ExcaliburComponentSelector selector = new ExcaliburComponentSelector(); - selector.setLogger(getLogger()); - selector.contextualize(this.context); - selector.setRoleManager(this.roleManager); - selector.setLogKitManager(logKit); - selector.compose(this.manager); - //selector.configure(new DefaultConfiguration("node-builders","-")); + this.compUtil.setupComponent(selector, false); this.builderSelector = selector; @@ -151,8 +169,10 @@ selector.initialize(); - } catch(ComponentException ce) { - throw new ConfigurationException("Cannot setup selector for node builders", ce); + } catch(ConfigurationException ce) { + throw ce; + } catch(Exception ex) { + throw new ConfigurationException("Cannot setup selector for node builders", ex); } } @@ -172,6 +192,13 @@ } /** + * Returns the name of the parameter element. + */ + public String getParameterName() { + return this.parameterElement; + } + + /** * Register a named <code>ProcessingNode</code> in a given category. * For example, <code>ResourceNodeBuilder</code> stores here the <code>ProcessingNode</code> * it produces for use by sitemap pipelines. This allows to turn the tree into a graph. @@ -249,7 +276,7 @@ rootBuilder.buildNode(config, new HashMap()); // Expose newly added components - this.manager.initialize(); + this.manager.makeVisible(); // Calls to getNode() are now allowed this.canGetNode = true; @@ -257,5 +284,54 @@ // And get the tree return rootBuilder.getNode(); } + + /** + * 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>. + */ + public void setupNode(ProcessingNode node, Configuration config) + throws Exception { + if (node instanceof AbstractProcessingNode) { + ((AbstractProcessingNode)node).setLocation(config.getLocation()); + } + + this.compUtil.setupComponent(node); + + if (node instanceof ParameterizableProcessingNode) { + Map params = getParameters(config); + ((ParameterizableProcessingNode)node).setParameters(params); + } + } + /** + * 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) throws ConfigurationException { + // FIXME : hardcoded prefix + Configuration[] children = config.getChildren(this.parameterElement); + + if (children.length == 0) { + return null; + } + + Map params = new HashMap(); + for (int i = 0; i < children.length; i++) { + Configuration child = children[i]; + if (true) { // FIXME : check namespace + String value = child.getAttribute("value"); + try { + params.put(child.getAttribute("name"), ListOfMapsResolver.getResolver(value)); + } catch(PatternException pe) { + throw new ConfigurationException("Invalid pattern '" + value + + " at " + child.getLocation()); + } + } + } + + return params; + } } 1.3 +16 -8 xml-cocoon2/scratchpad/src/org/apache/cocoon/treeprocessor/TreeBuilderComponentManager.java Index: TreeBuilderComponentManager.java =================================================================== RCS file: /home/cvs/xml-cocoon2/scratchpad/src/org/apache/cocoon/treeprocessor/TreeBuilderComponentManager.java,v retrieving revision 1.2 retrieving revision 1.3 diff -u -r1.2 -r1.3 --- TreeBuilderComponentManager.java 2001/11/12 18:07:43 1.2 +++ TreeBuilderComponentManager.java 2001/11/25 21:37:55 1.3 @@ -15,15 +15,15 @@ /** * An <code>ExcaliburComponentManager</code> which directs all calls to - * <code>ComponentManager</code> methods to its parent while it isn't - * initialized. + * <code>ComponentManager</code> methods to its parent until + * {@link #makeVisible()) has been called. * <p> * This allows to give <code>ProcessingNodesBuilder</code>s a component manager * they can use to lookup parent-defined components while also allowing it to be * enriched through <code>Builder.addComponent()</code>. * * @author <a href="mailto:[EMAIL PROTECTED]">Sylvain Wallez</a> - * @version CVS $Revision: 1.2 $ $Date: 2001/11/12 18:07:43 $ + * @version CVS $Revision: 1.3 $ $Date: 2001/11/25 21:37:55 $ */ @@ -31,7 +31,7 @@ private ComponentManager parent; - private boolean initialized = false; + private boolean visible = false; public TreeBuilderComponentManager(ComponentManager parent) { super(parent); @@ -39,7 +39,7 @@ } public Component lookup(String role) throws ComponentException { - if (initialized) { + if (visible) { return super.lookup(role); } else { return parent.lookup(role); @@ -53,7 +53,7 @@ * @return True if the component exists, False if it does not. */ public boolean hasComponent(String role) { - if (initialized) { + if (visible) { return super.hasComponent(role); } else { return parent.hasComponent(role); @@ -70,7 +70,7 @@ * @param component The Component we are releasing. */ public void release(Component component) { - if (initialized) { + if (visible) { super.release(component); } else { parent.release(component); @@ -78,8 +78,16 @@ } public void initialize() { + // Trap it : will be called in makeVisible() + } + + /** + * Make the components managed by this manager visible (otherwhise, only parent + * manager components are visible). + */ + public void makeVisible() { super.initialize(); - initialized = true; + visible = true; } } 1.4 +70 -33 xml-cocoon2/scratchpad/src/org/apache/cocoon/treeprocessor/TreeProcessor.java Index: TreeProcessor.java =================================================================== RCS file: /home/cvs/xml-cocoon2/scratchpad/src/org/apache/cocoon/treeprocessor/TreeProcessor.java,v retrieving revision 1.3 retrieving revision 1.4 diff -u -r1.3 -r1.4 --- TreeProcessor.java 2001/11/18 20:58:44 1.3 +++ TreeProcessor.java 2001/11/25 21:37:55 1.4 @@ -13,6 +13,7 @@ import org.apache.avalon.excalibur.logger.LogKitManageable; import org.apache.avalon.excalibur.logger.LogKitManager; +import org.apache.avalon.framework.activity.Disposable; import org.apache.avalon.framework.activity.Initializable; import org.apache.avalon.framework.component.Component; import org.apache.avalon.framework.component.Composable; @@ -47,11 +48,11 @@ * Interpreted tree-traversal implementation of the a Processor language. * * @author <a href="mailto:[EMAIL PROTECTED]">Sylvain Wallez</a> - * @version CVS $Revision: 1.3 $ $Date: 2001/11/18 20:58:44 $ + * @version CVS $Revision: 1.4 $ $Date: 2001/11/25 21:37:55 $ */ public class TreeProcessor extends AbstractLoggable implements ThreadSafe, Processor, - Composable, Configurable, LogKitManageable, Initializable, Contextualizable { + Composable, Configurable, LogKitManageable, Initializable, Contextualizable, Disposable { private static final String XCONF_URL = "resource://org/apache/cocoon/treeprocessor/treeprocessor.xconf"; private static final String ROLES_URL = "resource://org/apache/cocoon/sitemap/sitemap.roles"; @@ -86,23 +87,46 @@ /** The current language configuration */ protected Configuration currentLanguage; - /** Build the root TreeProcessor */ + /** + * Create a TreeProcessor. + */ public TreeProcessor() { // Language can be overriden in the configuration. - this(null, "sitemap"); + this.language = "sitemap"; } - - /** Build a child processor for the same language as its parent */ - public TreeProcessor(TreeProcessor parent) { - this(parent, parent.language); - } - - /** Build a child processor for a given language */ - public TreeProcessor(TreeProcessor parent, String language) { + + /** + * Create a child processor for a given language + */ + protected TreeProcessor(TreeProcessor parent, ComponentManager manager, String language) { this.parent = parent; - this.language = language; + this.language = (language == null) ? parent.language : language; + + // Copy all that can be copied from the parent + this.context = parent.context; + this.logKit = parent.logKit; + this.languageConfigs = parent.languageConfigs; + + // We have our own CM + this.manager = manager; + + // Other fields are setup in initialize() } + /** + * Create a new child of this processor (used for mounting submaps). + * + * @param manager the component manager to be used by the child processor. + * @param language the language to be used by the child processor. + * @return a new child processor. + */ + public TreeProcessor createChildProcessor(ComponentManager manager, String language) throws Exception { + TreeProcessor child = new TreeProcessor(this, manager, language); + child.setLogger(getLogger()); + child.initialize(); + return child; + } + public void contextualize(Context context) throws ContextException { this.context = context; } @@ -124,12 +148,6 @@ */ public void configure(Configuration config) throws ConfigurationException { - if (this.parent != null) { - // Configuration is inherited from parent - getLogger().info("Child TreeProcessor ignores call to configure()"); - return; - } - AbstractParentProcessingNode.setStaticLogger(getLogger()); Configuration rootLangConfig = config.getChild("root-language", false); @@ -186,11 +204,7 @@ } public void initialize() throws Exception { - if (this.parent != null) { - // Copy parent configuration - this.languageConfigs = this.parent.languageConfigs; - } - + this.currentLanguage = (Configuration)this.languageConfigs.get(this.language); if (this.currentLanguage == null) { throw new ConfigurationException("No configuration defined for language '" + this.language + "'"); @@ -213,6 +227,9 @@ public boolean process(Environment environment, StreamPipeline pipeline, EventPipeline eventPipeline) throws Exception { SourceHandler oldSourceHandler = environment.getSourceHandler(); SourceHandler sourceHandler = (SourceHandler)this.manager.lookup(SourceHandler.ROLE); + String uri = org.apache.cocoon.environment.ObjectModelHelper.getRequest(environment.getObjectModel()).getSitemapURI(); + System.out.println("Sitemap URI = '" + uri + "'"); + try { environment.setSourceHandler(sourceHandler); setupRootNode(environment); @@ -230,6 +247,8 @@ return; } + long startTime = System.currentTimeMillis(); + // Read the tree definition file as a Configuration Configuration treeConfig; try { @@ -247,19 +266,32 @@ this.rootNode.dispose(); } + // Create a new builder to build the tree (it isn't stored since it is used + // only at build-time, which shouldn't occur often in a production server). TreeBuilder builder = new TreeBuilder(); - builder.setLogger(getLogger()); - builder.contextualize(this.context); - builder.setRoleManager(getRoleManager()); - builder.setLogKitManager(this.logKit); - builder.compose(this.manager); - builder.configure(this.currentLanguage); - //builder.initialize(); + ComponentUtil.setupComponent(builder, + getLogger(), + this.context, + this.manager, + getRoleManager(), + this.logKit, + this.currentLanguage); + + builder.setProcessor(this); + // Build the tree this.rootNode = builder.build(treeConfig); + + ComponentUtil.decommission(builder); + + this.lastModified = System.currentTimeMillis(); + + if (getLogger().isDebugEnabled()) { + double time = (this.lastModified - startTime) / 1000.0; + getLogger().debug("TreeProcessor built in " + time + " secs from " + source.getSystemId()); + } } - - + private RoleManager getRoleManager() throws Exception { Configuration rolesConfig; @@ -284,4 +316,9 @@ return sitemapRoleManager; } + public void dispose() { + if (this.rootNode != null) { + this.rootNode.dispose(); + } + } } 1.4 +6 -5 xml-cocoon2/scratchpad/src/org/apache/cocoon/treeprocessor/treeprocessor.xconf Index: treeprocessor.xconf =================================================================== RCS file: /home/cvs/xml-cocoon2/scratchpad/src/org/apache/cocoon/treeprocessor/treeprocessor.xconf,v retrieving revision 1.3 retrieving revision 1.4 diff -u -r1.3 -r1.4 --- treeprocessor.xconf 2001/11/18 20:58:44 1.3 +++ treeprocessor.xconf 2001/11/25 21:37:55 1.4 @@ -9,7 +9,7 @@ ***************************************************************************** @author <a href="mailto:[EMAIL PROTECTED]">Sylvain Wallez</a> - @version CVS $Revision: 1.3 $ $Date: 2001/11/18 20:58:44 $ + @version CVS $Revision: 1.4 $ $Date: 2001/11/25 21:37:55 $ --> <tree-processor> @@ -22,6 +22,9 @@ <!-- The file name for this language --> <file name="sitemap.xmap"/> + <!-- Description the parameter element --> + <parameter element="map:parameter"/> + <nodes> <!-- Note : for now, names are prefixed, but they'll be removed with the namespace-aware Configuration--> <!-- Sitemap root node --> @@ -63,19 +66,17 @@ <node name="map:match" builder="org.apache.cocoon.treeprocessor.sitemap.MatchNodeBuilder"> <forbidden-children>sitemap, components, pipeline, handle-errors</forbidden-children> - <ignored-children>map:parameter</ignored-children> </node> <node name="map:select" builder="org.apache.cocoon.treeprocessor.NullNodeBuilder"/> <node name="map:act" builder="org.apache.cocoon.treeprocessor.sitemap.ActNodeBuilder"> <forbidden-children>sitemap, components, pipeline, handle-errors</forbidden-children> - <ignored-children>map:parameter</ignored-children> </node> <node name="map:redirect-to" builder="org.apache.cocoon.treeprocessor.sitemap.RedirectToNodeBuilder"/> - <node name="map:mount" builder="org.apache.cocoon.treeprocessor.NullNodeBuilder"/> + <node name="map:mount" builder="org.apache.cocoon.treeprocessor.sitemap.MountNodeBuilder"/> <node name="map:read" builder="org.apache.cocoon.treeprocessor.sitemap.ReadNodeBuilder"> </node> @@ -89,7 +90,7 @@ <node name="map:serialize" builder="org.apache.cocoon.treeprocessor.sitemap.SerializeNodeBuilder"/> - <node name="map:handle-errors" builder="org.apache.cocoon.treeprocessor.NullNodeBuilder"/> + <node name="map:handle-errors" builder="org.apache.cocoon.treeprocessor.sitemap.HandleErrorsNodeBuilder"/> </nodes> 1.1 xml-cocoon2/scratchpad/src/org/apache/cocoon/treeprocessor/ComponentUtil.java Index: ComponentUtil.java =================================================================== /* * Copyright (C) The Apache Software Foundation. All rights reserved. * * This software is published under the terms of the Apache Software License * version 1.1, a copy of which has been included with this distribution in * the LICENSE file. */ package org.apache.cocoon.treeprocessor; import org.apache.avalon.framework.activity.Startable; import org.apache.avalon.framework.activity.Disposable; import org.apache.avalon.framework.activity.Initializable; import org.apache.avalon.framework.component.ComponentManager; import org.apache.avalon.framework.component.Composable; import org.apache.avalon.framework.configuration.Configurable; import org.apache.avalon.framework.configuration.Configuration; import org.apache.avalon.framework.parameters.Parameterizable; import org.apache.avalon.framework.parameters.Parameters; import org.apache.avalon.framework.context.Context; import org.apache.avalon.framework.context.Contextualizable; import org.apache.avalon.framework.logger.AbstractLoggable; import org.apache.avalon.framework.logger.Loggable; import org.apache.avalon.framework.thread.ThreadSafe; import org.apache.avalon.excalibur.component.RoleManageable; import org.apache.avalon.excalibur.component.RoleManager; import org.apache.avalon.excalibur.logger.LogKitManager; import org.apache.avalon.excalibur.logger.LogKitManageable; import org.apache.log.Logger; /** * Utility class for setting up Avalon components. Similar to Excalibur's * <code>DefaultComponentFactory</code>, but on existing objects. * <p> * Note : should be moved to Avalon. * * @author <a href="mailto:[EMAIL PROTECTED]">Sylvain Wallez</a> * @version CVS $Revision: 1.1 $ $Date: 2001/11/25 21:37:55 $ */ public class ComponentUtil { /** The Logger for the component */ private Logger m_logger; /** The Context for the component */ private Context m_context; /** The component manager for this component. */ private ComponentManager m_componentManager; /** The configuration for this component. */ private Configuration m_configuration; /** The RoleManager for child ComponentSelectors */ private RoleManager m_roles; /** The LogKitManager for child ComponentSelectors */ private LogKitManager m_logkit; /** * Construct a new <code>ComponentUtil</code> that can be used repeatedly to * setup several components. <b>Note</b> : if a parameter is <code>null</code>, * the corresponding method isn't called (e.g. if <code>configuration</code> is * <code>null</code>, <code>configure()</code> isn't called). * * @param logger the <code>Logger</code> to pass to <code>Loggable</code>s, unless there is * a <code>LogKitManager</code> and the configuration specifies a logger name. * @param context the <code>Context</code> to pass to <code>Contexutalizable</code>s. * @param componentManager the component manager to pass to <code>Composable</code>s. * @param roles the <code>RoleManager</code> to pass to <code>DefaultComponentSelector</code>s. * @param configuration the <code>Configuration</code> object to pass to new instances. */ public ComponentUtil( final Logger logger, final Context context, final ComponentManager componentManager, final RoleManager roles, final LogKitManager logkit, final Configuration configuration ) { m_logger = logger; m_context = context; m_componentManager = componentManager; m_roles = roles; m_logkit = logkit; m_configuration = configuration; } /** * Setup a component, including initialization and start. * * @param component the component to setup. * @return the component passed in, to allow function chaining. * @throws Exception if something went wrong. */ public Object setupComponent(Object component) throws Exception { return setupComponent(component, true); } /** * Setup a component, and optionnaly initializes (if it's <code>Initializable</code>) * and starts it (if it's <code>Startable</code>). * * @param component the component to setup. * @param initializeAndStart if true, <code>intialize()</code> and <code>start()</code> * will be called. * @return the component passed in, to allow function chaining. * @throws Exception if something went wrong. */ public Object setupComponent( Object component, boolean initializeAndStart ) throws Exception { return setupComponent( component, m_logger, m_context, m_componentManager, m_roles, m_logkit, m_configuration, initializeAndStart ); } /** * Static equivalent to {@link #setupComponent(Object)}, to be used when there's only one * component to setup. */ public static Object setupComponent( final Object component, final Logger logger, final Context context, final ComponentManager componentManager, final RoleManager roles, final LogKitManager logkit, final Configuration configuration ) throws Exception { return setupComponent( component, logger, context, componentManager, roles, logkit, configuration, true ); } /** * Static equivalent to {@link #setupComponent(Object, boolean)}, to be used when there's only one * component to setup. */ public static Object setupComponent( final Object component, final Logger logger, final Context context, final ComponentManager componentManager, final RoleManager roles, final LogKitManager logkit, final Configuration configuration, final boolean initializeAndStart ) throws Exception { if( component instanceof Loggable ) { Logger usedLogger; if( null == logkit ) { usedLogger = logger; } else if( configuration == null ) { usedLogger = logger; } else { final String loggerName = configuration.getAttribute( "logger", null ); if( null == loggerName ) { // No logger attribute available, using standard logger usedLogger = logger; } else { usedLogger = logkit.getLogger( loggerName ); } } ((Loggable)component).setLogger( usedLogger ); } if( null != context && component instanceof Contextualizable ) { ((Contextualizable)component).contextualize( context ); } if( null != componentManager && component instanceof Composable ) { ((Composable)component).compose( componentManager ); } if( null != roles && component instanceof RoleManageable ) { ((RoleManageable)component).setRoleManager( roles ); } if( null != logkit && component instanceof LogKitManageable ) { ((LogKitManageable)component).setLogKitManager( logkit ); } if( null != configuration && component instanceof Configurable ) { ((Configurable)component).configure( configuration ); } if( null != configuration && component instanceof Parameterizable ) { ((Parameterizable)component). parameterize( Parameters.fromConfiguration( configuration ) ); } if( initializeAndStart && component instanceof Initializable ) { ((Initializable)component).initialize(); } if( initializeAndStart && component instanceof Startable ) { ((Startable)component).start(); } return component; } /** * Decomission a component, by stopping (if it's <code>Startable</code>) and * disposing (if it's <code>Disposable</code>) a component. */ public static final void decommission( final Object component ) throws Exception { if( component instanceof Startable ) { ((Startable)component).stop(); } if( component instanceof Disposable ) { ((Disposable)component).dispose(); } } } 1.1 xml-cocoon2/scratchpad/src/org/apache/cocoon/treeprocessor/ParameterizableProcessingNode.java Index: ParameterizableProcessingNode.java =================================================================== /***************************************************************************** * Copyright (C) The Apache Software Foundation. All rights reserved. * * ------------------------------------------------------------------------- * * This software is published under the terms of the Apache Software License * * version 1.1, a copy of which has been included with this distribution in * * the LICENSE file. * *****************************************************************************/ package org.apache.cocoon.treeprocessor; import java.util.Map; /** * A <code>ProcessingNode</code> that has parameters. * * @author <a href="mailto:[EMAIL PROTECTED]">Sylvain Wallez</a> * @version CVS $Revision: 1.1 $ $Date: 2001/11/25 21:37:55 $ */ public interface ParameterizableProcessingNode extends ProcessingNode { /** * Set the parameters of this node as a <code>Map</code> of <code>ListOfMapsResolver</code>s * that will be resolved at process-time. */ void setParameters(Map parameterMap); } 1.2 +10 -2 xml-cocoon2/scratchpad/src/org/apache/cocoon/treeprocessor/sitemap/ActNode.java Index: ActNode.java =================================================================== RCS file: /home/cvs/xml-cocoon2/scratchpad/src/org/apache/cocoon/treeprocessor/sitemap/ActNode.java,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- ActNode.java 2001/11/18 20:58:45 1.1 +++ ActNode.java 2001/11/25 21:37:56 1.2 @@ -27,19 +27,23 @@ import org.apache.cocoon.treeprocessor.ProcessingNode; import org.apache.cocoon.treeprocessor.AbstractParentProcessingNode; import org.apache.cocoon.treeprocessor.ListOfMapsResolver; +import org.apache.cocoon.treeprocessor.ParameterizableProcessingNode; import java.util.List; import java.util.Map; /** * * @author <a href="mailto:[EMAIL PROTECTED]">Sylvain Wallez</a> - * @version CVS $Revision: 1.1 $ $Date: 2001/11/18 20:58:45 $ + * @version CVS $Revision: 1.2 $ $Date: 2001/11/25 21:37:56 $ */ -public class ActNode extends AbstractParentProcessingNode { +public class ActNode extends AbstractParentProcessingNode implements ParameterizableProcessingNode { /** The childrens of this action */ protected ProcessingNode[] children; + + /** The parameters of this node */ + private Map parameters; /** The action name */ protected String actionName; @@ -58,6 +62,10 @@ this.source = ListOfMapsResolver.getResolver(source); } + public void setParameters(Map parameterMap) { + this.parameters = parameterMap; + } + public void setChildren(ProcessingNode[] children) { this.children = children; } 1.2 +3 -5 xml-cocoon2/scratchpad/src/org/apache/cocoon/treeprocessor/sitemap/ActNodeBuilder.java Index: ActNodeBuilder.java =================================================================== RCS file: /home/cvs/xml-cocoon2/scratchpad/src/org/apache/cocoon/treeprocessor/sitemap/ActNodeBuilder.java,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- ActNodeBuilder.java 2001/11/18 20:58:45 1.1 +++ ActNodeBuilder.java 2001/11/25 21:37:56 1.2 @@ -26,7 +26,7 @@ /** * * @author <a href="mailto:[EMAIL PROTECTED]">Sylvain Wallez</a> - * @version CVS $Revision: 1.1 $ $Date: 2001/11/18 20:58:45 $ + * @version CVS $Revision: 1.2 $ $Date: 2001/11/25 21:37:56 $ */ public class ActNodeBuilder extends AbstractParentProcessingNodeBuilder implements Composable { @@ -39,7 +39,7 @@ public void compose(ComponentManager manager) { this.manager = manager; } - + public void buildNode(Configuration config, Map buildModel) throws Exception { String source = config.getAttribute("src", null); @@ -49,9 +49,7 @@ if (set == null) { String type = ComponentsNodeBuilder.getComponentType("action", config, this.treeBuilder); this.actNode = new ActNode(type, source); - this.actNode.setLogger(getLogger()); - this.actNode.setLocation(config.getLocation()); - this.actNode.setParameters(getParameters(config)); + this.treeBuilder.setupNode(this.actNode, config); // Selector is set in getNode() // Get all children 1.4 +113 -38 xml-cocoon2/scratchpad/src/org/apache/cocoon/treeprocessor/sitemap/ComponentsNodeBuilder.java Index: ComponentsNodeBuilder.java =================================================================== RCS file: /home/cvs/xml-cocoon2/scratchpad/src/org/apache/cocoon/treeprocessor/sitemap/ComponentsNodeBuilder.java,v retrieving revision 1.3 retrieving revision 1.4 diff -u -r1.3 -r1.4 --- ComponentsNodeBuilder.java 2001/11/18 20:58:45 1.3 +++ ComponentsNodeBuilder.java 2001/11/25 21:37:56 1.4 @@ -14,6 +14,8 @@ import org.apache.avalon.excalibur.logger.LogKitManager; import org.apache.avalon.excalibur.logger.LogKitManageable; +import org.apache.avalon.framework.component.Component; + import org.apache.avalon.framework.context.Context; import org.apache.avalon.framework.context.Contextualizable; @@ -27,23 +29,26 @@ import org.apache.avalon.framework.component.ComponentManager; import org.apache.avalon.framework.component.ComponentSelector; +import org.apache.cocoon.generation.Generator; +import org.apache.cocoon.transformation.Transformer; + import org.apache.cocoon.sitemap.SitemapComponentSelector; import org.apache.cocoon.treeprocessor.AbstractProcessingNodeBuilder; +import org.apache.cocoon.treeprocessor.ComponentUtil; import org.apache.cocoon.treeprocessor.ProcessingNode; import org.apache.cocoon.treeprocessor.TreeBuilder; import org.apache.cocoon.util.ClassUtils; -import java.util.Map; -import java.util.HashMap; +import java.util.*; /** * Handles <map:components>. It doesn't actually create a <code>ProcessingNode</code>, * but creates <code>ComponentSelectors</code> that are made available to other nodes. * * @author <a href="mailto:[EMAIL PROTECTED]">Sylvain Wallez</a> - * @version CVS $Revision: 1.3 $ $Date: 2001/11/18 20:58:45 $ + * @version CVS $Revision: 1.4 $ $Date: 2001/11/25 21:37:56 $ */ public class ComponentsNodeBuilder extends AbstractProcessingNodeBuilder implements @@ -64,6 +69,9 @@ protected ComponentManager manager; + /** Association of roles to selectors */ + private HashMap selectors = new HashMap(); + /** Association of element names to section names */ protected Map sectionElements = new HashMap(); @@ -102,6 +110,11 @@ } } + /** This builder has no parameters -- return <code>false</code> */ + protected boolean hasParameters() { + return true; + } + /** * Build a <code>ComponentSelector</code> for each component section and add it * each component contained in the section. @@ -145,26 +158,11 @@ // Create the selector for this section getLogger().debug("Creating component selector for " + sectionName); - // Prepare an empty role manager - DefaultRoleManager emptyRoleManager = new DefaultRoleManager(); - emptyRoleManager.setLogger(getLogger()); - try { - emptyRoleManager.configure(new DefaultConfiguration("role-list", "-")); - } catch(ConfigurationException ce) { - throw new ComponentException("Cannot configure role manager", ce); - } - String role = (String)this.sectionRoles.get(sectionName); - SitemapComponentSelector selector = new SitemapComponentSelector(); - selector.setLogger(getLogger()); - selector.contextualize(this.context); - selector.setRoleManager(emptyRoleManager); - selector.setLogKitManager(this.logKit); - selector.compose(this.manager); - DefaultConfiguration selectorConfig = new DefaultConfiguration("component", "-"); - selectorConfig.setAttribute("role", role); - selector.configure(selectorConfig); + SitemapComponentSelector selector = getSelector(role); + SitemapComponentSelector parentSelector = getParentSelector(role); + // Iterate on all components Configuration[] elements = section.getChildren(); for (int compIdx = 0; compIdx < elements.length; compIdx++) { @@ -208,30 +206,41 @@ } } // end for elements + if (defaultElement != null && parentSelector != null) { + // Default not found : does it exist in parent ? + try { + Component comp = parentSelector.select(defaultElement); + parentSelector.release(comp); + // Found in parent + defaultElement = null; + } catch(Exception e) { + // Not found in parent + } + } + if (defaultElement != null) { - // default not found + // Really not found throw new ConfigurationException("Default element '" + defaultElement + "' does not exist, at " + section.getLocation()); } - // Chain with parent processor selector, if any - try { - SitemapComponentSelector parentSelector = - (SitemapComponentSelector)this.manager.lookup(role); - - // Found. - selector.setParentSelector(parentSelector); - - } catch (ComponentException ce) { - // Ignore : means no parent - } - - selector.initialize(); + } // end for sections + + // Add any additional components + addAdditionalComponents(); + + // Initialize selectors and publish them in the builder's component manager + Iterator iter = this.selectors.entrySet().iterator(); + while(iter.hasNext()) { + Map.Entry entry = (Map.Entry)iter.next(); - // Publish the selector - this.treeBuilder.addComponentInstance(role , selector); + String role = (String)entry.getKey(); + SitemapComponentSelector selector = (SitemapComponentSelector)entry.getValue(); - } // end for sections + selector.initialize(); + + this.treeBuilder.addComponentInstance(role, selector); + } } /** @@ -257,5 +266,71 @@ } return type; + } + + protected SitemapComponentSelector getParentSelector(String role) { + try { + return (SitemapComponentSelector)this.manager.lookup(role); + } catch (ComponentException ce) { + return null; + } + } + + /** + * Get a selector for a role, and create one if none already exist. + */ + protected SitemapComponentSelector getSelector(String role) throws Exception { + + SitemapComponentSelector result = (SitemapComponentSelector)this.selectors.get(role); + + if (result == null) { + + // Prepare an empty role manager + DefaultRoleManager emptyRoleManager = new DefaultRoleManager(); + emptyRoleManager.setLogger(getLogger()); + emptyRoleManager.configure(new DefaultConfiguration("role-list", "-")); + + DefaultConfiguration selectorConfig = new DefaultConfiguration("component", "-"); + selectorConfig.setAttribute("role", role); + + result = new SitemapComponentSelector(); + ComponentUtil.setupComponent( + result, + getLogger(), + this.context, + this.manager, + emptyRoleManager, + this.logKit, + selectorConfig, + false // don't initialize + ); + + // Chain with parent processor selector, if any + SitemapComponentSelector parentSelector = getParentSelector(role); + if (parentSelector != null) { + result.setParentSelector(parentSelector); + } + + // Add in selector map + this.selectors.put(role, result); + } + + return result; + } + + /** + * Add additional components not described in the configuration file. + */ + protected void addAdditionalComponents() throws Exception { + + DefaultConfiguration emptyConfig = new DefaultConfiguration("", ""); + + SitemapComponentSelector generators = getSelector(Generator.ROLE + "Selector"); + + generators.addComponent("!error-notifier'", org.apache.cocoon.sitemap.ErrorNotifier.class, emptyConfig); + generators.addComponent("!content-aggregator!", org.apache.cocoon.sitemap.ContentAggregator.class, emptyConfig); + + SitemapComponentSelector transformers = getSelector(Transformer.ROLE + "Selector"); + transformers.addComponent("!link-translator!", org.apache.cocoon.sitemap.LinkTranslator.class, emptyConfig); } } 1.2 +10 -3 xml-cocoon2/scratchpad/src/org/apache/cocoon/treeprocessor/sitemap/GenerateNode.java Index: GenerateNode.java =================================================================== RCS file: /home/cvs/xml-cocoon2/scratchpad/src/org/apache/cocoon/treeprocessor/sitemap/GenerateNode.java,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- GenerateNode.java 2001/11/18 20:58:45 1.1 +++ GenerateNode.java 2001/11/25 21:37:56 1.2 @@ -16,23 +16,31 @@ import org.apache.cocoon.treeprocessor.ListOfMapsResolver; import java.util.List; +import org.apache.cocoon.treeprocessor.ParameterizableProcessingNode; +import java.util.Map; /** * * @author <a href="mailto:[EMAIL PROTECTED]">Sylvain Wallez</a> - * @version CVS $Revision: 1.1 $ $Date: 2001/11/18 20:58:45 $ + * @version CVS $Revision: 1.2 $ $Date: 2001/11/25 21:37:56 $ */ -public class GenerateNode extends AbstractProcessingNode { +public class GenerateNode extends AbstractProcessingNode implements ParameterizableProcessingNode { private String generatorName; private ListOfMapsResolver source; + private Map parameters; + public GenerateNode(String name, String source) throws PatternException { this.generatorName = name; this.source = ListOfMapsResolver.getResolver(source); } + public void setParameters(Map parameterMap) { + this.parameters = parameterMap; + } + public boolean invoke(Environment env, StreamPipeline pipeline, EventPipeline eventPipeline, List listOfMaps) throws Exception { @@ -45,5 +53,4 @@ // Return false to contine sitemap invocation return false; } - } 1.2 +2 -5 xml-cocoon2/scratchpad/src/org/apache/cocoon/treeprocessor/sitemap/GenerateNodeBuilder.java Index: GenerateNodeBuilder.java =================================================================== RCS file: /home/cvs/xml-cocoon2/scratchpad/src/org/apache/cocoon/treeprocessor/sitemap/GenerateNodeBuilder.java,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- GenerateNodeBuilder.java 2001/11/18 20:58:45 1.1 +++ GenerateNodeBuilder.java 2001/11/25 21:37:56 1.2 @@ -18,7 +18,7 @@ /** * * @author <a href="mailto:[EMAIL PROTECTED]">Sylvain Wallez</a> - * @version CVS $Revision: 1.1 $ $Date: 2001/11/18 20:58:45 $ + * @version CVS $Revision: 1.2 $ $Date: 2001/11/25 21:37:56 $ */ public class GenerateNodeBuilder extends AbstractProcessingNodeBuilder { @@ -30,10 +30,7 @@ String type = ComponentsNodeBuilder.getComponentType("generator", config, this.treeBuilder); this.node = new GenerateNode(type, config.getAttribute("src", null)); - this.node.setLogger(getLogger()); - this.node.setLocation(config.getLocation()); - - this.node.setParameters(getParameters(config)); + this.treeBuilder.setupNode(this.node, config); } 1.2 +11 -3 xml-cocoon2/scratchpad/src/org/apache/cocoon/treeprocessor/sitemap/MatchNode.java Index: MatchNode.java =================================================================== RCS file: /home/cvs/xml-cocoon2/scratchpad/src/org/apache/cocoon/treeprocessor/sitemap/MatchNode.java,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- MatchNode.java 2001/11/18 20:58:45 1.1 +++ MatchNode.java 2001/11/25 21:37:56 1.2 @@ -20,14 +20,16 @@ import org.apache.avalon.framework.parameters.Parameters; import java.util.*; +import org.apache.cocoon.treeprocessor.ParameterizableProcessingNode; +import java.util.Map; /** * * @author <a href="mailto:[EMAIL PROTECTED]">Sylvain Wallez</a> - * @version CVS $Revision: 1.1 $ $Date: 2001/11/18 20:58:45 $ + * @version CVS $Revision: 1.2 $ $Date: 2001/11/25 21:37:56 $ */ -public class MatchNode extends SimpleSelectorProcessingNode { +public class MatchNode extends SimpleSelectorProcessingNode implements ParameterizableProcessingNode { /** The 'pattern' attribute */ private ListOfMapsResolver pattern; @@ -35,11 +37,17 @@ /** The matcher, if it's ThreadSafe */ private Matcher threadSafeMatcher; + private Map parameters; + public MatchNode(String name, String pattern) throws PatternException { super(name); this.pattern = ListOfMapsResolver.getResolver(pattern); } - + + public void setParameters(Map parameterMap) { + this.parameters = parameterMap; + } + public void setSelector(ComponentSelector selector) throws Exception { super.setSelector(selector); this.threadSafeMatcher = (Matcher)this.getThreadSafeComponent(); 1.2 +2 -6 xml-cocoon2/scratchpad/src/org/apache/cocoon/treeprocessor/sitemap/MatchNodeBuilder.java Index: MatchNodeBuilder.java =================================================================== RCS file: /home/cvs/xml-cocoon2/scratchpad/src/org/apache/cocoon/treeprocessor/sitemap/MatchNodeBuilder.java,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- MatchNodeBuilder.java 2001/11/18 20:58:45 1.1 +++ MatchNodeBuilder.java 2001/11/25 21:37:56 1.2 @@ -26,7 +26,7 @@ /** * * @author <a href="mailto:[EMAIL PROTECTED]">Sylvain Wallez</a> - * @version CVS $Revision: 1.1 $ $Date: 2001/11/18 20:58:45 $ + * @version CVS $Revision: 1.2 $ $Date: 2001/11/25 21:37:56 $ */ public class MatchNodeBuilder extends AbstractParentProcessingNodeBuilder implements Composable { @@ -86,12 +86,8 @@ this.node = new MatchNode(type, pattern); } - this.node.setLogger(getLogger()); - this.node.setLocation(config.getLocation()); - + this.treeBuilder.setupNode(this.node, this.config); this.node.setSelector(selector); - this.node.setParameters(getParameters(config)); - this.node.setChildren(getNodes(this.builders)); } 1.4 +11 -14 xml-cocoon2/scratchpad/src/org/apache/cocoon/treeprocessor/sitemap/PipelineNode.java Index: PipelineNode.java =================================================================== RCS file: /home/cvs/xml-cocoon2/scratchpad/src/org/apache/cocoon/treeprocessor/sitemap/PipelineNode.java,v retrieving revision 1.3 retrieving revision 1.4 diff -u -r1.3 -r1.4 --- PipelineNode.java 2001/11/18 20:58:45 1.3 +++ PipelineNode.java 2001/11/25 21:37:56 1.4 @@ -29,10 +29,10 @@ * * * @author <a href="mailto:[EMAIL PROTECTED]">Sylvain Wallez</a> - * @version CVS $Revision: 1.3 $ $Date: 2001/11/18 20:58:45 $ + * @version CVS $Revision: 1.4 $ $Date: 2001/11/25 21:37:56 $ */ -public class PipelineNode extends AbstractParentProcessingNode { +public class PipelineNode extends AbstractParentProcessingNode implements Composable { // TODO : handle a 'fail-hard' environment attribute // can be useful to stop off-line generation when there's an error @@ -83,35 +83,32 @@ try { - if (invokeNodes(children, env, pipeline, eventPipeline, listOfMaps)) { - return true; - } else { - throw new ResourceNotFoundException("No pipeline matched request: " + - env.getURIPrefix()+'/'+env.getURI()); - } + return invokeNodes(children, env, pipeline, eventPipeline, listOfMaps); } catch(ResourceNotFoundException rnfe) { getLogger().debug("Resource not found in pipeline at " + getLocation(), rnfe); if (error404 != null) { - + // There's a handler invokeErrorHandler(error404, rnfe, env); - return false; + return true; } else { -return false; -// throw rnfe; + // No handler : propagate + throw rnfe; } + } catch(Exception e) { - getLogger().debug("Error while processing pipeline", e); + getLogger().debug("Error while processing pipeline at " + getLocation(), e); // Rethrow exception for internal requests if (error500 != null || !SitemapNode.isInternalRequest(env)) { invokeErrorHandler(error500, e, env); - return false; + return true; } else { + // No handler : propagate throw e; } } 1.3 +35 -33 xml-cocoon2/scratchpad/src/org/apache/cocoon/treeprocessor/sitemap/PipelineNodeBuilder.java Index: PipelineNodeBuilder.java =================================================================== RCS file: /home/cvs/xml-cocoon2/scratchpad/src/org/apache/cocoon/treeprocessor/sitemap/PipelineNodeBuilder.java,v retrieving revision 1.2 retrieving revision 1.3 diff -u -r1.2 -r1.3 --- PipelineNodeBuilder.java 2001/11/18 20:58:45 1.2 +++ PipelineNodeBuilder.java 2001/11/25 21:37:56 1.3 @@ -16,35 +16,30 @@ import org.apache.cocoon.treeprocessor.ProcessingNodeBuilder; import java.util.*; -import org.apache.avalon.framework.component.Composable; -import org.apache.avalon.framework.component.ComponentManager; -import org.apache.avalon.framework.component.ComponentException; /** * Builds a <map:pipeline> * @author <a href="mailto:[EMAIL PROTECTED]">Sylvain Wallez</a> - * @version CVS $Revision: 1.2 $ $Date: 2001/11/18 20:58:45 $ + * @version CVS $Revision: 1.3 $ $Date: 2001/11/25 21:37:56 $ */ -public class PipelineNodeBuilder extends AbstractParentProcessingNodeBuilder implements Composable { +public class PipelineNodeBuilder extends AbstractParentProcessingNodeBuilder { - private ComponentManager manager; private PipelineNode node; private List builders; private ProcessingNodeBuilder error404Builder; private ProcessingNodeBuilder error500Builder; - public void compose(ComponentManager manager) throws ComponentException { - this.manager = manager; + /** This builder has no parameters -- return <code>false</code> */ + protected boolean hasParameters() { + return true; } - + public void buildNode(Configuration config, Map buildModel) throws Exception { this.node = new PipelineNode(); - this.node.setLocation(config.getLocation()); - this.node.setLogger(getLogger()); - this.node.compose(this.manager); + this.treeBuilder.setupNode(this.node, config); this.node.setInternalOnly(config.getAttributeAsBoolean("internal-only", false)); @@ -52,36 +47,43 @@ if (this.ignoredChildren == null) this.ignoredChildren = new ArrayList(); - this.ignoredChildren.add("handle-errors"); + List allBuilders = createChildBuilders(config, buildModel); - this.builders = createChildBuilders(config, buildModel); + // Separate regular nodes and error handlers + this.builders = new ArrayList(); - Configuration[] handlersConfig = config.getChildren("handle-errors"); - for (int i = 0; i < handlersConfig.length; i++) { - Configuration handlerConfig = handlersConfig[i]; - - int type = handlerConfig.getAttributeAsInteger("type", 500); - - ProcessingNodeBuilder handlerBuilder = this.treeBuilder.createNodeBuilder(handlerConfig); - handlerBuilder.buildNode(handlerConfig, buildModel); + Iterator iter = allBuilders.iterator(); + while(iter.hasNext()) { + Object next = iter.next(); - if ( (type == 404 && this.error404Builder != null) || - (type == 500 && this.error500Builder != null) ) { - throw new ConfigurationException("Duplicate handle-errors at " + handlerConfig.getLocation()); - } - - if (type == 404) { - this.error404Builder = handlerBuilder; - } else if (type == 500) { - this.error500Builder = handlerBuilder; + if (next instanceof HandleErrorsNodeBuilder) { + // Error handler : check type + HandleErrorsNodeBuilder builder = (HandleErrorsNodeBuilder)next; + int type = builder.getStatusCode(); + + if ( (type == 404 && this.error404Builder != null) || + (type == 500 && this.error500Builder != null) ) { + throw new ConfigurationException("Duplicate handle-errors at " + builder.getLocation()); + } + + if (type == 404) { + this.error404Builder = builder; + } else if (type == 500) { + this.error500Builder = builder; + } else { + throw new ConfigurationException("Unkown handle-errors type (" + type + ") at " + + builder.getLocation()); + } + } else { - throw new ConfigurationException("Unkown handle-errors type (" + type + ") at " + - handlerConfig.getLocation()); + // Regular builder + this.builders.add(next); } } } public ProcessingNode getNode() throws Exception { + this.node.setChildren(this.getNodes(builders)); if (this.error404Builder != null) { 1.3 +7 -4 xml-cocoon2/scratchpad/src/org/apache/cocoon/treeprocessor/sitemap/PipelinesNodeBuilder.java Index: PipelinesNodeBuilder.java =================================================================== RCS file: /home/cvs/xml-cocoon2/scratchpad/src/org/apache/cocoon/treeprocessor/sitemap/PipelinesNodeBuilder.java,v retrieving revision 1.2 retrieving revision 1.3 diff -u -r1.2 -r1.3 --- PipelinesNodeBuilder.java 2001/11/18 20:58:45 1.2 +++ PipelinesNodeBuilder.java 2001/11/25 21:37:56 1.3 @@ -21,7 +21,7 @@ * Buildes a <map:pipelines> * * @author <a href="mailto:[EMAIL PROTECTED]">Sylvain Wallez</a> - * @version CVS $Revision: 1.2 $ $Date: 2001/11/18 20:58:45 $ + * @version CVS $Revision: 1.3 $ $Date: 2001/11/25 21:37:56 $ */ public class PipelinesNodeBuilder extends AbstractParentProcessingNodeBuilder { @@ -29,12 +29,15 @@ private PipelinesNode node; private List builders; + /** This builder has no parameters -- return <code>false</code> */ + protected boolean hasParameters() { + return false; + } + public void buildNode(Configuration config, Map buildModel) throws Exception { this.node = new PipelinesNode(); - this.node.setLocation(config.getLocation()); - this.node.setLogger(getLogger()); - + this.treeBuilder.setupNode(this.node, config); // Get all children this.builders = createChildBuilders(config, buildModel); 1.2 +12 -3 xml-cocoon2/scratchpad/src/org/apache/cocoon/treeprocessor/sitemap/PreparableMatchNode.java Index: PreparableMatchNode.java =================================================================== RCS file: /home/cvs/xml-cocoon2/scratchpad/src/org/apache/cocoon/treeprocessor/sitemap/PreparableMatchNode.java,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- PreparableMatchNode.java 2001/11/18 20:58:45 1.1 +++ PreparableMatchNode.java 2001/11/25 21:37:56 1.2 @@ -19,22 +19,26 @@ import org.apache.avalon.framework.component.ComponentException; import org.apache.avalon.framework.parameters.Parameters; import org.apache.avalon.framework.thread.ThreadSafe; +import org.apache.cocoon.treeprocessor.ParameterizableProcessingNode; import java.util.*; +import java.util.Map; /** * * @author <a href="mailto:[EMAIL PROTECTED]">Sylvain Wallez</a> - * @version CVS $Revision: 1.1 $ $Date: 2001/11/18 20:58:45 $ + * @version CVS $Revision: 1.2 $ $Date: 2001/11/25 21:37:56 $ */ -public class PreparableMatchNode extends SimpleSelectorProcessingNode { +public class PreparableMatchNode extends SimpleSelectorProcessingNode implements ParameterizableProcessingNode { /** The 'pattern' attribute */ private String pattern; private Object preparedPattern; + private Map parameters; + /** The matcher, if it's ThreadSafe */ private PreparableMatcher threadSafeMatcher; @@ -43,6 +47,10 @@ this.pattern = pattern; } + public void setParameters(Map parameterMap) { + this.parameters = parameterMap; + } + public void setSelector(ComponentSelector selector) throws Exception { super.setSelector(selector); @@ -88,7 +96,8 @@ if (result != null) { if (getLogger().isDebugEnabled()) { - getLogger().debug("Matcher '" + this.componentName + "' matched prepared pattern '" + this.pattern + "'"); + getLogger().debug("Matcher '" + this.componentName + "' matched prepared pattern '" + + this.pattern + "' at " + this.getLocation()); } // Invoke children with the matcher results 1.2 +10 -2 xml-cocoon2/scratchpad/src/org/apache/cocoon/treeprocessor/sitemap/ReadNode.java Index: ReadNode.java =================================================================== RCS file: /home/cvs/xml-cocoon2/scratchpad/src/org/apache/cocoon/treeprocessor/sitemap/ReadNode.java,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- ReadNode.java 2001/11/18 20:58:45 1.1 +++ ReadNode.java 2001/11/25 21:37:56 1.2 @@ -16,13 +16,15 @@ import org.apache.cocoon.treeprocessor.ListOfMapsResolver; import java.util.List; +import org.apache.cocoon.treeprocessor.ParameterizableProcessingNode; +import java.util.Map; /** * * @author <a href="mailto:[EMAIL PROTECTED]">Sylvain Wallez</a> - * @version CVS $Revision: 1.1 $ $Date: 2001/11/18 20:58:45 $ + * @version CVS $Revision: 1.2 $ $Date: 2001/11/25 21:37:56 $ */ -public class ReadNode extends AbstractProcessingNode { +public class ReadNode extends AbstractProcessingNode implements ParameterizableProcessingNode { private String readerName; @@ -32,6 +34,8 @@ private int statusCode; + private Map parameters; + /** * Build a <code>SerializerNode</code> having a name, a mime-type and a status code (HTTP codes). * @@ -46,6 +50,10 @@ this.statusCode = statusCode; } + public void setParameters(Map parameterMap) { + this.parameters = parameterMap; + } + public boolean invoke(Environment env, StreamPipeline pipeline, EventPipeline eventPipeline, List listOfMaps) throws Exception { 1.2 +2 -5 xml-cocoon2/scratchpad/src/org/apache/cocoon/treeprocessor/sitemap/ReadNodeBuilder.java Index: ReadNodeBuilder.java =================================================================== RCS file: /home/cvs/xml-cocoon2/scratchpad/src/org/apache/cocoon/treeprocessor/sitemap/ReadNodeBuilder.java,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- ReadNodeBuilder.java 2001/11/18 20:58:45 1.1 +++ ReadNodeBuilder.java 2001/11/25 21:37:56 1.2 @@ -18,7 +18,7 @@ /** * * @author <a href="mailto:[EMAIL PROTECTED]">Sylvain Wallez</a> - * @version CVS $Revision: 1.1 $ $Date: 2001/11/18 20:58:45 $ + * @version CVS $Revision: 1.2 $ $Date: 2001/11/25 21:37:56 $ */ public class ReadNodeBuilder extends AbstractProcessingNodeBuilder { @@ -36,10 +36,7 @@ config.getAttributeAsInteger("status-code", -1) ); - this.node.setLogger(getLogger()); - this.node.setLocation(config.getLocation()); - - // No parameters on a serializer + this.treeBuilder.setupNode(this.node, config); } public ProcessingNode getNode() { 1.2 +8 -8 xml-cocoon2/scratchpad/src/org/apache/cocoon/treeprocessor/sitemap/RedirectToNodeBuilder.java Index: RedirectToNodeBuilder.java =================================================================== RCS file: /home/cvs/xml-cocoon2/scratchpad/src/org/apache/cocoon/treeprocessor/sitemap/RedirectToNodeBuilder.java,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- RedirectToNodeBuilder.java 2001/11/18 20:58:45 1.1 +++ RedirectToNodeBuilder.java 2001/11/25 21:37:56 1.2 @@ -23,33 +23,33 @@ /** * * @author <a href="mailto:[EMAIL PROTECTED]">Sylvain Wallez</a> - * @version CVS $Revision: 1.1 $ $Date: 2001/11/18 20:58:45 $ + * @version CVS $Revision: 1.2 $ $Date: 2001/11/25 21:37:56 $ */ public class RedirectToNodeBuilder extends AbstractProcessingNodeBuilder { private AbstractProcessingNode node; + + /** This builder has no parameters -- return <code>false</code> */ + protected boolean hasParameters() { + return true; + } public void buildNode(Configuration config, Map buildModel) throws Exception { // Is it a redirect to resource ? String uri = config.getAttribute("uri", null); - if (uri == null) { + if (uri != null) { this.node = new RedirectToURINode(uri, config.getAttributeAsBoolean("session", false)); - this.node.setLogger(getLogger()); - this.node.setLocation(config.getLocation()); } else { getLogger().warn("redirect to resource not yet implemented"); this.node = new NullNode(); - this.node.setLogger(getLogger()); - this.node.setLocation(config.getLocation()); } + this.treeBuilder.setupNode(this.node, config); } public ProcessingNode getNode() throws Exception { - return this.node; - } } 1.2 +7 -6 xml-cocoon2/scratchpad/src/org/apache/cocoon/treeprocessor/sitemap/SerializeNodeBuilder.java Index: SerializeNodeBuilder.java =================================================================== RCS file: /home/cvs/xml-cocoon2/scratchpad/src/org/apache/cocoon/treeprocessor/sitemap/SerializeNodeBuilder.java,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- SerializeNodeBuilder.java 2001/11/18 20:58:45 1.1 +++ SerializeNodeBuilder.java 2001/11/25 21:37:56 1.2 @@ -18,12 +18,17 @@ /** * * @author <a href="mailto:[EMAIL PROTECTED]">Sylvain Wallez</a> - * @version CVS $Revision: 1.1 $ $Date: 2001/11/18 20:58:45 $ + * @version CVS $Revision: 1.2 $ $Date: 2001/11/25 21:37:56 $ */ public class SerializeNodeBuilder extends AbstractProcessingNodeBuilder { private SerializeNode node; + + /** This builder has no parameters -- return <code>false</code> */ + protected boolean hasParameters() { + return true; + } public void buildNode(Configuration config, Map buildModel) throws Exception { @@ -34,11 +39,7 @@ config.getAttribute("mime-type", null), config.getAttributeAsInteger("status-code", -1) ); - - this.node.setLogger(getLogger()); - this.node.setLocation(config.getLocation()); - - // No parameters on a serializer + this.treeBuilder.setupNode(this.node, config); } public ProcessingNode getNode() { 1.4 +4 -15 xml-cocoon2/scratchpad/src/org/apache/cocoon/treeprocessor/sitemap/SitemapNodeBuilder.java Index: SitemapNodeBuilder.java =================================================================== RCS file: /home/cvs/xml-cocoon2/scratchpad/src/org/apache/cocoon/treeprocessor/sitemap/SitemapNodeBuilder.java,v retrieving revision 1.3 retrieving revision 1.4 diff -u -r1.3 -r1.4 --- SitemapNodeBuilder.java 2001/11/18 20:58:45 1.3 +++ SitemapNodeBuilder.java 2001/11/25 21:37:56 1.4 @@ -8,9 +8,6 @@ package org.apache.cocoon.treeprocessor.sitemap; -import org.apache.avalon.framework.component.Composable; -import org.apache.avalon.framework.component.ComponentManager; -import org.apache.avalon.framework.component.ComponentException; import org.apache.avalon.framework.configuration.Configuration; import org.apache.avalon.framework.configuration.ConfigurationException; @@ -22,29 +19,21 @@ /** * * @author <a href="mailto:[EMAIL PROTECTED]">Sylvain Wallez</a> - * @version CVS $Revision: 1.3 $ $Date: 2001/11/18 20:58:45 $ + * @version CVS $Revision: 1.4 $ $Date: 2001/11/25 21:37:56 $ */ -public class SitemapNodeBuilder extends AbstractParentProcessingNodeBuilder implements Composable { +public class SitemapNodeBuilder extends AbstractParentProcessingNodeBuilder { - private ComponentManager manager; - private SitemapNode node; private List childBuilders; private String location; - public void compose(ComponentManager manager) throws ComponentException { - this.manager = manager; - } - public void buildNode(Configuration config, Map buildModel) throws Exception { this.location = config.getLocation(); - node = new SitemapNode(); - node.setLocation(this.location); - node.setLogger(getLogger()); - node.compose(this.manager); + this.node = new SitemapNode(); + this.treeBuilder.setupNode(this.node, config); // FIXME : should we make the assumption that map:components comes first in the sitemap ? // if not, default component types will not be set up properly for use by other NodeBuilder. 1.2 +12 -5 xml-cocoon2/scratchpad/src/org/apache/cocoon/treeprocessor/sitemap/TransformNode.java Index: TransformNode.java =================================================================== RCS file: /home/cvs/xml-cocoon2/scratchpad/src/org/apache/cocoon/treeprocessor/sitemap/TransformNode.java,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- TransformNode.java 2001/11/18 20:58:45 1.1 +++ TransformNode.java 2001/11/25 21:37:56 1.2 @@ -16,23 +16,31 @@ import org.apache.cocoon.treeprocessor.ListOfMapsResolver; import java.util.List; +import org.apache.cocoon.treeprocessor.ParameterizableProcessingNode; +import java.util.Map; /** * * @author <a href="mailto:[EMAIL PROTECTED]">Sylvain Wallez</a> - * @version CVS $Revision: 1.1 $ $Date: 2001/11/18 20:58:45 $ + * @version CVS $Revision: 1.2 $ $Date: 2001/11/25 21:37:56 $ */ -public class TransformNode extends AbstractProcessingNode { +public class TransformNode extends AbstractProcessingNode implements ParameterizableProcessingNode { private String transformerName; private ListOfMapsResolver source; + private Map parameters; + public TransformNode(String name, String source) throws PatternException { this.transformerName = name; this.source = ListOfMapsResolver.getResolver(source); } - + + public void setParameters(Map parameterMap) { + this.parameters = parameterMap; + } + public boolean invoke(Environment env, StreamPipeline pipeline, EventPipeline eventPipeline, List listOfMaps) throws Exception { @@ -44,6 +52,5 @@ // Return false to contine sitemap invocation return false; - } - + } } 1.2 +2 -6 xml-cocoon2/scratchpad/src/org/apache/cocoon/treeprocessor/sitemap/TransformNodeBuilder.java Index: TransformNodeBuilder.java =================================================================== RCS file: /home/cvs/xml-cocoon2/scratchpad/src/org/apache/cocoon/treeprocessor/sitemap/TransformNodeBuilder.java,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- TransformNodeBuilder.java 2001/11/18 20:58:45 1.1 +++ TransformNodeBuilder.java 2001/11/25 21:37:56 1.2 @@ -18,7 +18,7 @@ /** * * @author <a href="mailto:[EMAIL PROTECTED]">Sylvain Wallez</a> - * @version CVS $Revision: 1.1 $ $Date: 2001/11/18 20:58:45 $ + * @version CVS $Revision: 1.2 $ $Date: 2001/11/25 21:37:56 $ */ public class TransformNodeBuilder extends AbstractProcessingNodeBuilder { @@ -30,11 +30,7 @@ String type = ComponentsNodeBuilder.getComponentType("transformer", config, this.treeBuilder); this.node = new TransformNode(type, config.getAttribute("src", null)); - this.node.setLogger(getLogger()); - this.node.setLocation(config.getLocation()); - - this.node.setParameters(getParameters(config)); - + this.treeBuilder.setupNode(this.node, config); } public ProcessingNode getNode() { 1.1 xml-cocoon2/scratchpad/src/org/apache/cocoon/treeprocessor/sitemap/HandleErrorsNode.java Index: HandleErrorsNode.java =================================================================== /***************************************************************************** * Copyright (C) The Apache Software Foundation. All rights reserved. * * ------------------------------------------------------------------------- * * This software is published under the terms of the Apache Software License * * version 1.1, a copy of which has been included with this distribution in * * the LICENSE file. * *****************************************************************************/ package org.apache.cocoon.treeprocessor.sitemap; import org.apache.avalon.framework.component.ComponentManager; import org.apache.avalon.framework.component.Composable; import org.apache.avalon.framework.activity.Disposable; import org.apache.cocoon.ResourceNotFoundException; import org.apache.cocoon.environment.Environment; import org.apache.cocoon.components.pipeline.EventPipeline; import org.apache.cocoon.components.pipeline.StreamPipeline; import org.apache.cocoon.treeprocessor.AbstractParentProcessingNode; import org.apache.cocoon.treeprocessor.ProcessingNode; import java.util.*; /** * Handles <map:handle-errors> * * @author <a href="mailto:[EMAIL PROTECTED]">Sylvain Wallez</a> * @version CVS $Revision: 1.1 $ $Date: 2001/11/25 21:37:56 $ */ public final class HandleErrorsNode extends AbstractParentProcessingNode { private ProcessingNode[] children; public void setChildren(ProcessingNode[] nodes) { this.children = nodes; } public final boolean invoke(Environment env, StreamPipeline pipeline, EventPipeline eventPipeline, List listOfMaps) throws Exception { if (getLogger().isDebugEnabled()) { getLogger().debug("Processing handle-errors at " + getLocation()); } return invokeNodes(this.children, env, pipeline, eventPipeline, listOfMaps); } public final void dispose() { disposeNodes(this.children); } } 1.1 xml-cocoon2/scratchpad/src/org/apache/cocoon/treeprocessor/sitemap/HandleErrorsNodeBuilder.java Index: HandleErrorsNodeBuilder.java =================================================================== /***************************************************************************** * Copyright (C) The Apache Software Foundation. All rights reserved. * * ------------------------------------------------------------------------- * * This software is published under the terms of the Apache Software License * * version 1.1, a copy of which has been included with this distribution in * * the LICENSE file. * *****************************************************************************/ package org.apache.cocoon.treeprocessor.sitemap; import org.apache.avalon.framework.configuration.Configuration; import org.apache.cocoon.treeprocessor.AbstractParentProcessingNodeBuilder; import org.apache.cocoon.treeprocessor.ProcessingNode; import java.util.*; /** * Builds a <map:handle-errors> * * @author <a href="mailto:[EMAIL PROTECTED]">Sylvain Wallez</a> * @version CVS $Revision: 1.1 $ $Date: 2001/11/25 21:37:56 $ */ public class HandleErrorsNodeBuilder extends AbstractParentProcessingNodeBuilder { private HandleErrorsNode node; private List builders; private int statusCode; private String location; /** This builder has no parameters -- return <code>false</code> */ protected boolean hasParameters() { return false; } public void buildNode(Configuration config, Map buildModel) throws Exception { this.location = config.getLocation(); this.statusCode = config.getAttributeAsInteger("type", 500); this.node = new HandleErrorsNode(); this.treeBuilder.setupNode(this.node, config); // Get all children this.builders = createChildBuilders(config, buildModel); } public int getStatusCode() { return this.statusCode; } public String getLocation() { return this.location; } public ProcessingNode getNode() throws Exception { this.node.setChildren(getNodes(this.builders)); return this.node; } } 1.1 xml-cocoon2/scratchpad/src/org/apache/cocoon/treeprocessor/sitemap/MountNode.java Index: MountNode.java =================================================================== /***************************************************************************** * Copyright (C) The Apache Software Foundation. All rights reserved. * * ------------------------------------------------------------------------- * * This software is published under the terms of the Apache Software License * * version 1.1, a copy of which has been included with this distribution in * * the LICENSE file. * *****************************************************************************/ package org.apache.cocoon.treeprocessor.sitemap; import org.apache.avalon.framework.component.ComponentManager; import org.apache.cocoon.components.pipeline.EventPipeline; import org.apache.cocoon.components.pipeline.StreamPipeline; import org.apache.cocoon.environment.Environment; import org.apache.cocoon.sitemap.PatternException; import org.apache.cocoon.treeprocessor.ListOfMapsResolver; import org.apache.cocoon.treeprocessor.AbstractProcessingNode; import org.apache.cocoon.treeprocessor.TreeProcessor; import java.util.*; import org.apache.avalon.framework.component.Composable; import org.apache.avalon.framework.component.ComponentException; /** * * @author <a href="mailto:[EMAIL PROTECTED]">Sylvain Wallez</a> * @version CVS $Revision: 1.1 $ $Date: 2001/11/25 21:37:56 $ */ public class MountNode extends AbstractProcessingNode implements Composable { /** The 'uri-prefix' attribute */ private ListOfMapsResolver prefix; /** The 'src' attribute */ private ListOfMapsResolver source; /** Processors for sources */ private Map processors = new HashMap(); /** The processor for this node */ private TreeProcessor parentProcessor; /** The language for the mounted processor */ private String language; /** The component manager to be used by the mounted processor */ private ComponentManager manager; public MountNode(String prefix, String source, String language, TreeProcessor parentProcessor) throws PatternException { this.prefix = ListOfMapsResolver.getResolver(prefix); this.source = ListOfMapsResolver.getResolver(source); this.language = language; this.parentProcessor = parentProcessor; } public void compose(ComponentManager manager) throws ComponentException { this.manager = manager; } public boolean invoke(Environment env, StreamPipeline pipeline, EventPipeline eventPipeline, List listOfMaps) throws Exception { String resolvedSource = this.source.resolve(listOfMaps); TreeProcessor processor = (TreeProcessor)processors.get(resolvedSource); if (processor == null) { processor = getProcessor(resolvedSource); } String resolvedPrefix = this.prefix.resolve(listOfMaps); String oldPrefix = env.getURIPrefix(); String oldURI = env.getURI(); try { env.changeContext(resolvedPrefix, resolvedSource); if (SitemapNode.isInternalRequest(env)) { // Propagate pipelines return processor.process(env, pipeline, eventPipeline); } else { // Processor will create its own pipelines return processor.process(env); } } finally{ env.setContext(oldPrefix, oldURI); } } private synchronized TreeProcessor getProcessor(String source) throws Exception { TreeProcessor processor = (TreeProcessor)processors.get(source); if (processor == null) { processor = this.parentProcessor.createChildProcessor(this.manager, this.language); processors.put(source, processor); } return processor; } public void dispose() { super.dispose(); Iterator iter = this.processors.values().iterator(); while(iter.hasNext()) { ((TreeProcessor)iter.next()).dispose(); } } } 1.1 xml-cocoon2/scratchpad/src/org/apache/cocoon/treeprocessor/sitemap/MountNodeBuilder.java Index: MountNodeBuilder.java =================================================================== /***************************************************************************** * Copyright (C) The Apache Software Foundation. All rights reserved. * * ------------------------------------------------------------------------- * * This software is published under the terms of the Apache Software License * * version 1.1, a copy of which has been included with this distribution in * * the LICENSE file. * *****************************************************************************/ package org.apache.cocoon.treeprocessor.sitemap; import org.apache.avalon.framework.configuration.Configuration; import org.apache.cocoon.treeprocessor.AbstractProcessingNodeBuilder; import org.apache.cocoon.treeprocessor.ProcessingNode; import java.util.Map; /** * * @author <a href="mailto:[EMAIL PROTECTED]">Sylvain Wallez</a> * @version CVS $Revision: 1.1 $ $Date: 2001/11/25 21:37:56 $ */ public class MountNodeBuilder extends AbstractProcessingNodeBuilder { private MountNode node; /** This builder has no parameters -- return <code>false</code> */ protected boolean hasParameters() { return true; } public void buildNode(Configuration config, Map buildModel) throws Exception { this.node = new MountNode( config.getAttribute("uri-prefix"), config.getAttribute("src"), config.getAttribute("language", null), this.treeBuilder.getProcessor() ); this.treeBuilder.setupNode(this.node, config); } public ProcessingNode getNode() { return this.node; } }
---------------------------------------------------------------------- In case of troubles, e-mail: [EMAIL PROTECTED] To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]