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 &lt;xxx:parameter&gt; 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 &lt;map:components&gt;. 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 &lt;map:pipeline&gt;
    
    * @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 &lt;map:pipelines&gt;
    *
    * @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 &lt;map:handle-errors&gt;
   *
   * @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 &lt;map:handle-errors&gt;
   *
   * @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]

Reply via email to