You are viewing a plain text version of this content. The canonical link for it is here.
Posted to cvs@cocoon.apache.org by sy...@apache.org on 2001/11/12 19:07:43 UTC
cvs commit: xml-cocoon2/scratchpad/src/org/apache/cocoon/treeprocessor/sitemap PipelineNodeBuilder.java PipelinesNode.java PipelinesNodeBuilder.java ActionNode.java ComponentsNodeBuilder.java GeneratorNode.java GeneratorNodeBuilder.java PipelineNode.java SitemapNode.java SitemapNodeBuilder.java
sylvain 01/11/12 10:07:43
Modified: scratchpad/src/org/apache/cocoon/treeprocessor
AbstractParentProcessingNode.java
AbstractParentProcessingNodeBuilder.java
AbstractProcessingNode.java
AbstractProcessingNodeBuilder.java
EnvironmentSourceResolver.java
ListOfMapsResolver.java ProcessingNode.java
ProcessingNodeBuilder.java TreeBuilder.java
TreeBuilderComponentManager.java TreeProcessor.java
treeprocessor.xconf
scratchpad/src/org/apache/cocoon/treeprocessor/sitemap
ActionNode.java ComponentsNodeBuilder.java
GeneratorNode.java GeneratorNodeBuilder.java
PipelineNode.java SitemapNode.java
SitemapNodeBuilder.java
Added: scratchpad/src/org/apache/cocoon/treeprocessor
ProcessingLanguageException.java
scratchpad/src/org/apache/cocoon/treeprocessor/sitemap
PipelineNodeBuilder.java PipelinesNode.java
PipelinesNodeBuilder.java
Log:
Update to scratchpad
Revision Changes Path
1.2 +31 -26 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.1
retrieving revision 1.2
diff -u -r1.1 -r1.2
--- AbstractParentProcessingNode.java 2001/11/08 14:39:23 1.1
+++ AbstractParentProcessingNode.java 2001/11/12 18:07:43 1.2
@@ -19,58 +19,63 @@
/**
*
* @author <a href="mailto:sylvain@apache.org">Sylvain Wallez</a>
- * @version CVS $Revision: 1.1 $ $Date: 2001/11/08 14:39:23 $
+ * @version CVS $Revision: 1.2 $ $Date: 2001/11/12 18:07:43 $
*/
public abstract class AbstractParentProcessingNode extends AbstractProcessingNode {
- protected ProcessingNode[] childNodes;
-
/**
- * Invoke in order all children, until one fails.
+ * Invoke all nodes of a node array in order, until one succeeds.
*
* @parameter currentMap the <code>Map<code> of parameters produced by this node,
- * which is added to <code>listOfMap</code> if not null.
+ * which is added to <code>listOfMap</code>.
*/
- protected boolean invokeChildren (
+ protected static final boolean invokeNodes (
+ ProcessingNode[] nodes,
Environment env,
StreamPipeline pipeline,
EventPipeline eventPipeline,
List listOfMaps, Map currentMap)
throws Exception {
- if (currentMap != null) {
- listOfMaps.add(currentMap);
- }
+ listOfMaps.add(currentMap);
- boolean success = true;
- for (int i = 0; i < childNodes.length; i++) {
- if (! childNodes[i].invoke(env, pipeline, eventPipeline, listOfMaps)) {
- success = false;
- break;
- }
- }
+ boolean success = invokeNodes(nodes, env, pipeline, eventPipeline, listOfMaps);
- if (currentMap != null) {
- listOfMaps.remove(listOfMaps.size() - 1);
- }
+ listOfMaps.remove(listOfMaps.size() - 1);
return success;
}
/**
- * Disposes all children of this node.
+ * Invoke all nodes of a node array in order, until one succeeds.
*/
- protected void disposeChildren() {
- for (int i = 0; i < childNodes.length; i++) {
- childNodes[i].dispose();
+ protected static final boolean invokeNodes (
+ ProcessingNode[] nodes,
+ Environment env,
+ StreamPipeline pipeline,
+ EventPipeline eventPipeline,
+ List listOfMaps)
+ throws Exception {
+
+ for (int i = 0; i < nodes.length; i++) {
+ if (nodes[i].invoke(env, pipeline, eventPipeline, listOfMaps)) {
+ return true;
+ }
}
+
+ return false;
}
-
+
/**
- * Dispose this node. At this level, simply call <code>disposeChildren()</code>.
+ * Dispose all nodes in an array.
*/
- public void dispose() {
- disposeChildren();
+ protected static final void disposeNodes(ProcessingNode[] nodes) {
+ if (nodes == null)
+ return;
+
+ for (int i = 0; i < nodes.length; i++) {
+ nodes[i].dispose();
+ }
}
}
1.2 +103 -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.1
retrieving revision 1.2
diff -u -r1.1 -r1.2
--- AbstractParentProcessingNodeBuilder.java 2001/11/08 14:39:23 1.1
+++ AbstractParentProcessingNodeBuilder.java 2001/11/12 18:07:43 1.2
@@ -10,12 +10,114 @@
import org.apache.avalon.framework.logger.AbstractLoggable;
+import java.util.*;
+import org.apache.avalon.framework.configuration.Configurable;
+import org.apache.avalon.framework.configuration.Configuration;
+import org.apache.avalon.framework.configuration.ConfigurationException;
+
+import org.apache.cocoon.util.StringUtils;
+
/**
+ * Base class for parent <code>ProcessingNodeBuilders</code>, providing services for parsing
+ * children nodes.
*
* @author <a href="mailto:sylvain@apache.org">Sylvain Wallez</a>
- * @version CVS $Revision: 1.1 $ $Date: 2001/11/08 14:39:23 $
+ * @version CVS $Revision: 1.2 $ $Date: 2001/11/12 18:07:43 $
*/
+
+public abstract class AbstractParentProcessingNodeBuilder extends AbstractProcessingNodeBuilder implements Configurable {
+
+ protected Collection allowedChildren;
+
+ protected Collection forbiddenChildren;
+
+ protected Collection ignoredChildren;
+
+ /**
+ * Configure the sets of allowed, forbidden and ignored children nodes.
+ */
+ public void configure(Configuration config) throws ConfigurationException {
+ this.allowedChildren = getStringCollection(config.getChild("allowed-children"));
+ this.forbiddenChildren = getStringCollection(config.getChild("forbidden-children"));
+ this.ignoredChildren = getStringCollection(config.getChild("ignored-children"));
+ }
+
+ /**
+ * Create the <code>ProcessingNodeBuilder</code>s for the children of a given node.
+ * Child nodes are controlled to be actually allowed in this node.
+ */
+ protected List createChildBuilders(Configuration config, Map buildModel) throws Exception {
+
+ Configuration[] children = config.getChildren();
+ List result = new ArrayList();
+
+ for (int i = 0; i < children.length; i++) {
+
+ Configuration child = children[i];
+ checkNamespace(child);
+ String name = child.getName();
+
+ // Is this element to be ignored ?
+ if (ignoredChildren != null && ignoredChildren.contains(name)) {
+ getLogger().debug("Element '" + name + "' is ignored for building children of element '" +
+ config.getName() + "'");
+
+ continue;
+ }
+
+ // Is it allowed ?
+ if ( (allowedChildren != null && !allowedChildren.contains(name)) ||
+ (forbiddenChildren != null && forbiddenChildren.contains(name)) ) {
+ throw new ConfigurationException("Element '" + name + "' is not allowed at " +
+ child.getLocation());
+ }
+
+ // OK : get a builder.
+ ProcessingNodeBuilder childBuilder = this.treeBuilder.createNodeBuilder(child);
+ childBuilder.buildNode(child, buildModel);
+ result.add(childBuilder);
+ }
+
+ return result;
+ }
+
+ /**
+ * Collect nodes from a list of builders, taking care of builders that may
+ * return null nodes.
+ */
+ protected ProcessingNode[] getNodes(List builderList) throws Exception {
+
+ List result = new ArrayList();
+
+ Iterator iter = builderList.iterator();
+ while(iter.hasNext()) {
+ ProcessingNode node = ((ProcessingNodeBuilder)iter.next()).getNode();
+ if (node != null) {
+ result.add(node);
+ }
+ }
+
+ return toNodeArray(result);
+ }
+
+ /**
+ * Convenience function that converts a <code>List</code> of <code>ProcessingNode</code>s
+ * to an array.
+ */
+ public static ProcessingNode[] toNodeArray(List list) {
+ return (ProcessingNode[])list.toArray(new ProcessingNode[list.size()]);
+ }
+
+ /**
+ * Splits the value of a Configuration in a Collection of Strings.
+ *
+ * @return a collection of Strings, or null if <code>config</code> has no value.
+ */
+ private Collection getStringCollection(Configuration config) {
+ String s = config.getValue(null);
+
+ return (s == null) ? null : Arrays.asList(StringUtils.split(s, ", "));
+ }
-public abstract class AbstractParentProcessingNodeBuilder extends AbstractProcessingNodeBuilder {
}
1.2 +26 -4 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.1
retrieving revision 1.2
diff -u -r1.1 -r1.2
--- AbstractProcessingNode.java 2001/11/08 14:39:23 1.1
+++ AbstractProcessingNode.java 2001/11/12 18:07:43 1.2
@@ -26,20 +26,42 @@
/**
*
* @author <a href="mailto:sylvain@apache.org">Sylvain Wallez</a>
- * @version CVS $Revision: 1.1 $ $Date: 2001/11/08 14:39:23 $
+ * @version CVS $Revision: 1.2 $ $Date: 2001/11/12 18:07:43 $
*/
public abstract class AbstractProcessingNode extends AbstractLoggable implements ProcessingNode {
- /** The node parameters, as a <code>Map</code> of <code>ListOfMapsResolver</code>. */
+ /** The node parameters, as a <code>Map</code> of <code>ListOfMapsResolver</code>s. */
protected Map parameters;
- protected SourceResolver getSourceResolver(Map objectModel) {
+ protected String location = "unknown location";
+
+ /**
+ * Get the <code>SourceResolver</code> in an object model.
+ */
+ 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) {
+ }
+
+ /**
+ * Get the location of this node.
+ */
+ public String getLocation() {
+ return this.location;
+ }
- protected Redirector getRedirector(Map objectModel) {
- return (Redirector)objectModel.get(OBJECT_REDIRECTOR);
+ /**
+ * Set the location of this node.
+ */
+ public void setLocation(String location) {
+ this.location = location;
}
/**
1.2 +5 -5 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.1
retrieving revision 1.2
diff -u -r1.1 -r1.2
--- AbstractProcessingNodeBuilder.java 2001/11/08 14:39:23 1.1
+++ AbstractProcessingNodeBuilder.java 2001/11/12 18:07:43 1.2
@@ -24,21 +24,21 @@
/**
*
* @author <a href="mailto:sylvain@apache.org">Sylvain Wallez</a>
- * @version CVS $Revision: 1.1 $ $Date: 2001/11/08 14:39:23 $
+ * @version CVS $Revision: 1.2 $ $Date: 2001/11/12 18:07:43 $
*/
public abstract class AbstractProcessingNodeBuilder extends AbstractLoggable
implements ProcessingNodeBuilder {
- protected TreeBuilder builder;
+ protected TreeBuilder treeBuilder;
- public void setBuilder(TreeBuilder builder) {
- this.builder = builder;
+ public void setBuilder(TreeBuilder treeBuilder) {
+ this.treeBuilder = treeBuilder;
}
/**
- * Get <xxx:parameter> elements as a <ocd>Map</code> of </code>ListOfMapResolver</code>s,
+ * Get <xxx:parameter> elements as a <code>Map</code> of </code>ListOfMapResolver</code>s,
* that can be turned into parameters using <code>ListOfMapResolver.buildParameters()</code>.
*
* @return the Map of ListOfMapResolver, or <code>null</code> if there are no parameters.
@@ -59,7 +59,7 @@
params.put(child.getAttribute("name"), ListOfMapsResolver.getResolver(value));
} catch(PatternException pe) {
throw new ConfigurationException("Invalid pattern '" + value +
- ", at " + child.getLocation());
+ " at " + child.getLocation());
}
}
}
1.2 +0 -0 xml-cocoon2/scratchpad/src/org/apache/cocoon/treeprocessor/EnvironmentSourceResolver.java
Index: EnvironmentSourceResolver.java
===================================================================
RCS file: /home/cvs/xml-cocoon2/scratchpad/src/org/apache/cocoon/treeprocessor/EnvironmentSourceResolver.java,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -r1.1 -r1.2
--- EnvironmentSourceResolver.java 2001/11/08 14:39:23 1.1
+++ EnvironmentSourceResolver.java 2001/11/12 18:07:43 1.2
@@ -26,7 +26,7 @@
* A <code>SourceResolver</code> that resolves URIs relative to an <code>Environment</code>.
*
* @author <a href="mailto:sylvain@apache.org">Sylvain Wallez</a>
- * @version CVS $Revision: 1.1 $ $Date: 2001/11/08 14:39:23 $
+ * @version CVS $Revision: 1.2 $ $Date: 2001/11/12 18:07:43 $
*/
public class EnvironmentSourceResolver implements SourceResolver, Disposable {
1.2 +4 -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.1
retrieving revision 1.2
diff -u -r1.1 -r1.2
--- ListOfMapsResolver.java 2001/11/08 14:39:23 1.1
+++ ListOfMapsResolver.java 2001/11/12 18:07:43 1.2
@@ -21,7 +21,7 @@
* Utility class for handling {...} pattern substitutions from a List of Maps.
*
* @author <a href="mailto:sylvain@apache.org">Sylvain Wallez</a>
- * @version CVS $Revision: 1.1 $ $Date: 2001/11/08 14:39:23 $
+ * @version CVS $Revision: 1.2 $ $Date: 2001/11/12 18:07:43 $
*/
public abstract class ListOfMapsResolver extends AbstractLoggable {
@@ -137,10 +137,12 @@
* No-op resolver for expressions that don't need to be resolved.
*/
private static class NullResolver extends ListOfMapsResolver {
- private String expression;
+ private String expression = null;
public NullResolver(String expression) {
- this.expression = this.unescape(expression);
+ if (expression != null) {
+ this.expression = this.unescape(expression);
+ }
}
public String resolve(List listOfMaps) {
1.2 +4 -0 xml-cocoon2/scratchpad/src/org/apache/cocoon/treeprocessor/ProcessingNode.java
Index: ProcessingNode.java
===================================================================
RCS file: /home/cvs/xml-cocoon2/scratchpad/src/org/apache/cocoon/treeprocessor/ProcessingNode.java,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -r1.1 -r1.2
--- ProcessingNode.java 2001/11/08 14:39:23 1.1
+++ ProcessingNode.java 2001/11/12 18:07:43 1.2
@@ -23,7 +23,7 @@
* on the root node.
*
* @author <a href="mailto:sylvain@apache.org">Sylvain Wallez</a>
- * @version CVS $Revision: 1.1 $ $Date: 2001/11/08 14:39:23 $
+ * @version CVS $Revision: 1.2 $ $Date: 2001/11/12 18:07:43 $
*/
public interface ProcessingNode extends ThreadSafe, Disposable {
@@ -48,4 +48,8 @@
*/
void dispose();
+ /**
+ * Get the location of this node.
+ */
+ String getLocation();
}
1.2 +0 -0 xml-cocoon2/scratchpad/src/org/apache/cocoon/treeprocessor/ProcessingNodeBuilder.java
Index: ProcessingNodeBuilder.java
===================================================================
RCS file: /home/cvs/xml-cocoon2/scratchpad/src/org/apache/cocoon/treeprocessor/ProcessingNodeBuilder.java,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -r1.1 -r1.2
--- ProcessingNodeBuilder.java 2001/11/08 14:39:23 1.1
+++ ProcessingNodeBuilder.java 2001/11/12 18:07:43 1.2
@@ -34,7 +34,7 @@
* implementations.
*
* @author <a href="mailto:sylvain@apache.org">Sylvain Wallez</a>
- * @version CVS $Revision: 1.1 $ $Date: 2001/11/08 14:39:23 $
+ * @version CVS $Revision: 1.2 $ $Date: 2001/11/12 18:07:43 $
*/
import java.util.Map;
1.2 +14 -11 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.1
retrieving revision 1.2
diff -u -r1.1 -r1.2
--- TreeBuilder.java 2001/11/08 14:39:23 1.1
+++ TreeBuilder.java 2001/11/12 18:07:43 1.2
@@ -38,23 +38,19 @@
/**
*
* @author <a href="mailto:sylvain@apache.org">Sylvain Wallez</a>
- * @version CVS $Revision: 1.1 $ $Date: 2001/11/08 14:39:23 $
+ * @version CVS $Revision: 1.2 $ $Date: 2001/11/12 18:07:43 $
*/
public class TreeBuilder extends AbstractLoggable implements
Composable, Configurable, Contextualizable, LogKitManageable {
/**
- * The role name to be used by composable <code>ProcessingNodeBuilder</code>s to get
- * the <code>Builder</code> for which they operate.
- */
- public static final String ROLE = "org.apache.cocoon.components.treeprocessor.Builder";
-
- /**
* The categories of node Maps.
*/
private Map categories = new HashMap();
+ private Map attributes = new HashMap();
+
/**
* The tree processor that we're building.
*/
@@ -114,7 +110,7 @@
this.languageName = config.getAttribute("name");
getLogger().debug("Configuring Builder for language : " + this.languageName);
- this.namespace = config.getAttribute("namespace");
+ this.namespace = config.getChild("namespace").getAttribute("uri", "");
try {
// Create the NodeBuilder selector.
@@ -184,7 +180,7 @@
* 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.
*/
- public void addNode(ProcessingNode node, String category, String name) {
+ public void addNode(String category, String name,ProcessingNode node) {
Map nodes = (Map)categories.get(category);
if (nodes == null) {
nodes = new HashMap();
@@ -207,6 +203,14 @@
}
}
+ public void setAttribute(String name, Object value) {
+ this.attributes.put(name, value);
+ }
+
+ public Object getAttribute(String name) {
+ return this.attributes.get(name);
+ }
+
/**
* Some NodeBuilders create components to be used by others
*/
@@ -222,9 +226,8 @@
public ProcessingNodeBuilder createNodeBuilder(Configuration config) throws Exception {
//FIXME : check namespace
String nodeName = config.getName();
- int pos;
- if ((pos = nodeName.indexOf(':')) != -1)
- nodeName = nodeName.substring(pos+1);
+
+ getLogger().debug("Creating node builder for " + nodeName);
ProcessingNodeBuilder builder = (ProcessingNodeBuilder)this.builderSelector.select(nodeName);
builder.setBuilder(this);
1.2 +0 -0 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.1
retrieving revision 1.2
diff -u -r1.1 -r1.2
--- TreeBuilderComponentManager.java 2001/11/08 14:39:23 1.1
+++ TreeBuilderComponentManager.java 2001/11/12 18:07:43 1.2
@@ -23,7 +23,7 @@
* enriched through <code>Builder.addComponent()</code>.
*
* @author <a href="mailto:sylvain@apache.org">Sylvain Wallez</a>
- * @version CVS $Revision: 1.1 $ $Date: 2001/11/08 14:39:23 $
+ * @version CVS $Revision: 1.2 $ $Date: 2001/11/12 18:07:43 $
*/
1.2 +0 -0 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.1
retrieving revision 1.2
diff -u -r1.1 -r1.2
--- TreeProcessor.java 2001/11/08 14:39:23 1.1
+++ TreeProcessor.java 2001/11/12 18:07:43 1.2
@@ -45,7 +45,7 @@
* Interpreted tree-traversal implementation of the a Processor language.
*
* @author <a href="mailto:sylvain@apache.org">Sylvain Wallez</a>
- * @version CVS $Revision: 1.1 $ $Date: 2001/11/08 14:39:23 $
+ * @version CVS $Revision: 1.2 $ $Date: 2001/11/12 18:07:43 $
*/
public class TreeProcessor extends AbstractLoggable implements ThreadSafe, Processor,
1.2 +27 -16 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.1
retrieving revision 1.2
diff -u -r1.1 -r1.2
--- treeprocessor.xconf 2001/11/08 14:39:23 1.1
+++ treeprocessor.xconf 2001/11/12 18:07:43 1.2
@@ -9,48 +9,59 @@
*****************************************************************************
@author <a href="mailto:sylvain@apache.org">Sylvain Wallez</a>
- @version CVS $Revision: 1.1 $ $Date: 2001/11/08 14:39:23 $
+ @version CVS $Revision: 1.2 $ $Date: 2001/11/12 18:07:43 $
-->
<tree-processor>
<!-- The sitemap language -->
- <language name="sitemap" namespace="http://apache.org/cocoon/sitemap/1.0">
+ <language name="sitemap">
- <!-- Should we allow to specify the builder class ? -->
- <!-- builder class="org.apache.cocoon.treeprocessor.Builder"/ -->
-
+ <!-- The namespace for this language -->
+ <namespace uri="http://apache.org/cocoon/sitemap/1.0"/>
+
<!-- The file name for this language -->
<file name="sitemap.xmap"/>
<nodes>
+ <!-- Note : for now, names are prefixed, but they'll be removed with the namespace-aware Configuration-->
<!-- Sitemap root node -->
- <node name="sitemap" builder="org.apache.cocoon.treeprocessor.sitemap.SitemapNodeBuilder">
- <allowed-children>components, pipeline, views, resources, action-sets</allowed-children>
+ <node name="map:sitemap" builder="org.apache.cocoon.treeprocessor.sitemap.SitemapNodeBuilder">
+ <allowed-children>map:pipelines, map:components</allowed-children>
+ <!-- the children below will be allowed when implemented :) -->
+ <ignored-children>map:views, map:resources, map:action-sets</ignored-children>
</node>
<!-- Components definition : fills selectors on the TreeProcessor -->
- <node name="components" builder="org.apache.cocoon.treeprocessor.sitemap.ComponentsNodeBuilder">
- <selector section="matchers" elements="matcher"
+ <node name="map:components" builder="org.apache.cocoon.treeprocessor.sitemap.ComponentsNodeBuilder">
+ <selector section="map:matchers" elements="map:matcher"
role="org.apache.cocoon.matching.MatcherSelector"/>
- <selector section="selectors" elements="selector"
+ <selector section="map:selectors" elements="map:selector"
role="org.apache.cocoon.selection.SelectorSelector"/>
- <selector section="actions" elements="action"
+ <selector section="map:actions" elements="map:action"
role="org.apache.cocoon.acting.ActionSelector"/>
- <selector section="generators" elements="generator"
+ <selector section="map:generators" elements="map:generator"
role="org.apache.cocoon.generation.GeneratorSelector"/>
- <selector section="transformers" elements="transformer"
+ <selector section="map:transformers" elements="map:transformer"
role="org.apache.cocoon.transformation.TransformerSelector"/>
- <selector section="serializers" elements="serializer"
+ <selector section="map:serializers" elements="map:serializer"
role="org.apache.cocoon.serialization.SerializerSelector"/>
- <selector section="readers" elements="reader"
+ <selector section="map:readers" elements="map:reader"
role="org.apache.cocoon.reading.ReaderSelector"/>
</node>
+
+ <node name="map:pipelines" builder="org.apache.cocoon.treeprocessor.sitemap.PipelinesNodeBuilder">
+ <allowed-children>map:pipeline</allowed-children>
+ </node>
+
+ <node name="map:pipeline" builder="org.apache.cocoon.treeprocessor.sitemap.PipelineNodeBuilder">
+ <forbidden-children>map:sitemap, map:components, map:pipelines</forbidden-children>
+ </node>
- <!--node name="action" builder="org.apache.cocoon.treeprocessor.sitemap.ActionNodeBuilder">
+ <!--node name="map:action" builder="org.apache.cocoon.treeprocessor.sitemap.ActionNodeBuilder">
<forbidden-children>sitemap, components, pipeline, error-handler</forbidden-children>
</node-->
- <node name="generator" builder="org.apache.cocoon.treeprocessor.sitemap.GeneratorNodeBuilder"/>
+ <node name="map:generate" builder="org.apache.cocoon.treeprocessor.sitemap.GeneratorNodeBuilder"/>
</nodes>
</language>
1.1 xml-cocoon2/scratchpad/src/org/apache/cocoon/treeprocessor/ProcessingLanguageException.java
Index: ProcessingLanguageException.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.CascadingException;
import java.io.PrintStream;
import java.io.PrintWriter;
/**
* Exception thrown when there's something wrong in the syntax of a
* processing language (i.e. sitemap).
*
* @author <a href="mailto:sylvain@apache.org">Sylvain Wallez</a>
* @version CVS $Revision: 1.1 $ $Date: 2001/11/12 18:07:43 $
*/
public class ProcessingLanguageException extends CascadingException {
/**
* Create a new <code>ProcessingLanguageException</code> instance.
*/
public ProcessingLanguageException(String message) {
super(message, null);
}
/**
* Create a new <code>ProcessingLanguageException</code> instance.
*
* @param ex the originating <code>Exception</code>
*/
public ProcessingLanguageException(Exception ex) {
super(ex.getMessage(), ex);
}
/**
* Construct a new <code>ProcessingLanguageException</code> that references
* a parent Exception.
*/
public ProcessingLanguageException(String message, Throwable t) {
super(message, t);
}
public String toString() {
StringBuffer s = new StringBuffer();
s.append(super.toString());
if(getCause()!=null) {
s.append(": ");
s.append(getCause().toString());
}
return s.toString();
}
public void printStackTrace() {
super.printStackTrace();
if(getCause()!=null)
getCause().printStackTrace();
}
public void printStackTrace( PrintStream s ) {
super.printStackTrace(s);
if(getCause()!=null)
getCause().printStackTrace(s);
}
public void printStackTrace( PrintWriter s ) {
super.printStackTrace(s);
if(getCause()!=null)
getCause().printStackTrace(s);
}
}
1.2 +40 -18 xml-cocoon2/scratchpad/src/org/apache/cocoon/treeprocessor/sitemap/ActionNode.java
Index: ActionNode.java
===================================================================
RCS file: /home/cvs/xml-cocoon2/scratchpad/src/org/apache/cocoon/treeprocessor/sitemap/ActionNode.java,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -r1.1 -r1.2
--- ActionNode.java 2001/11/08 14:39:24 1.1
+++ ActionNode.java 2001/11/12 18:07:43 1.2
@@ -21,7 +21,9 @@
import org.apache.cocoon.components.pipeline.StreamPipeline;
import org.apache.cocoon.sitemap.PatternException;
+import org.apache.cocoon.sitemap.SitemapRedirector;
+import org.apache.cocoon.treeprocessor.ProcessingNode;
import org.apache.cocoon.treeprocessor.AbstractParentProcessingNode;
import org.apache.cocoon.treeprocessor.ListOfMapsResolver;
@@ -30,13 +32,16 @@
/**
*
* @author <a href="mailto:sylvain@apache.org">Sylvain Wallez</a>
- * @version CVS $Revision: 1.1 $ $Date: 2001/11/08 14:39:24 $
+ * @version CVS $Revision: 1.2 $ $Date: 2001/11/12 18:07:43 $
*/
public class ActionNode extends AbstractParentProcessingNode {
+ /** The childrens of this action */
+ protected ProcessingNode[] children;
+
/** The action name */
- protected String name;
+ protected String actionName;
/** The 'src' attribute */
protected ListOfMapsResolver source;
@@ -48,16 +53,20 @@
protected Action threadSafeAction;
public ActionNode(String name, String source) throws PatternException {
- this.name = name;
+ this.actionName = name;
this.source = ListOfMapsResolver.getResolver(source);
}
+ public void setChildren(ProcessingNode[] children) {
+ this.children = children;
+ }
+
public void setSelector(ComponentSelector selector) throws ComponentException {
this.selector = selector;
// Is it a ThreadSafe action ?
- Action action = (Action)selector.select(name);
+ Action action = (Action)selector.select(actionName);
if (action instanceof ThreadSafe) {
// Yes : keep it.
this.threadSafeAction = action;
@@ -72,39 +81,52 @@
// Extract required data from the object model
Map objectModel = env.getObjectModel();
-
- // Execute the action
- Action action = this.threadSafeAction;
- if (action == null) {
- action = (Action)this.selector.select(this.name);
- }
-
+ SitemapRedirector redirector = SitemapNode.getRedirector(env);
Map actionResult;
- try {
- actionResult = action.act(
- getRedirector(objectModel),
+
+ if (this.threadSafeAction != null) {
+ actionResult = this.threadSafeAction.act(
+ redirector,
getSourceResolver(objectModel),
objectModel,
source.resolve(listOfMaps),
ListOfMapsResolver.buildParameters(this.parameters, listOfMaps)
);
- } finally {
- if (this.threadSafeAction == null) {
+
+ } else {
+ Action action = (Action)this.selector.select(this.actionName);
+ try {
+ actionResult = action.act(
+ redirector,
+ getSourceResolver(objectModel),
+ objectModel,
+ source.resolve(listOfMaps),
+ ListOfMapsResolver.buildParameters(this.parameters, listOfMaps)
+ );
+ } finally {
this.selector.release(action);
}
}
+ if (redirector.hasRedirected()) {
+ return true;
+ }
+
if (actionResult == null) {
// Action failed
return false;
} else {
- // Action succeeded : process children
- return this.invokeChildren(env, pipeline, eventPipeline, listOfMaps, actionResult);
+ // Action succeeded : process children if there are some.
+ if (this.children != null) {
+ return this.invokeNodes(this.children, env, pipeline, eventPipeline, listOfMaps, actionResult);
+ } else {
+ return true;
+ }
}
}
public void dispose() {
- super.dispose();
+ disposeNodes(children);
if (this.threadSafeAction != null) {
this.selector.release(this.threadSafeAction);
}
1.2 +43 -17 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.1
retrieving revision 1.2
diff -u -r1.1 -r1.2
--- ComponentsNodeBuilder.java 2001/11/08 14:39:24 1.1
+++ ComponentsNodeBuilder.java 2001/11/12 18:07:43 1.2
@@ -27,6 +27,8 @@
import org.apache.avalon.framework.component.ComponentManager;
import org.apache.avalon.framework.component.ComponentSelector;
+import org.apache.cocoon.sitemap.SitemapComponentSelector;
+
import org.apache.cocoon.treeprocessor.AbstractProcessingNodeBuilder;
import org.apache.cocoon.treeprocessor.ProcessingNode;
@@ -40,14 +42,18 @@
* but creates <code>ComponentSelectors</code> that are made available to other nodes.
*
* @author <a href="mailto:sylvain@apache.org">Sylvain Wallez</a>
- * @version CVS $Revision: 1.1 $ $Date: 2001/11/08 14:39:24 $
+ * @version CVS $Revision: 1.2 $ $Date: 2001/11/12 18:07:43 $
*/
public class ComponentsNodeBuilder extends AbstractProcessingNodeBuilder implements
Composable, Configurable, Contextualizable, LogKitManageable {
- /** The hint name to use to select the default component in a selector */
- public static final String DEFAULT_HINT = "!default!";
+ /**
+ * The prefix used to store default components as <code>TreeBuilder</code> attributes.
+ * For example, the default generator (if any) can be obtained using
+ * <code>builder.getAttribute(ComponentsNodeBuilder.DEFAULT_PREFIX + "generator")</code>.
+ */
+ public static final String DEFAULT_PREFIX = "components:default-";
private Context context;
@@ -97,16 +103,21 @@
/**
* Build a <code>ComponentSelector</code> for each component section and add it
- * each component contained in the section. Selectors are also published on the
- * <code>TreeBuilder</code> for use by other nodes.
+ * each component contained in the section.
+ * <p>
+ * Selectors are added to the component manager using <code>TreeBuilder.addComponent()</code>
+ * for use by other nodes.
+ * <p>
+ * For each section for which a default is provided (e.g. <code><generators default="file"></code>),
+ * this default is registred as an attribute on the builder
*/
public void buildNode(Configuration config, Map buildModel) throws Exception {
// Iterate on all sections
Configuration[] sections = config.getChildren();
- for (int i = 0; i < sections.length; i++) {
+ for (int sectIdx = 0; sectIdx < sections.length; sectIdx++) {
- Configuration section = sections[i];
+ Configuration section = sections[sectIdx];
checkNamespace(section);
String sectionName = section.getName();
@@ -122,8 +133,10 @@
String defaultElement = section.getAttribute("default", null);
if (defaultElement == null) {
getLogger().debug("Component section '" + sectionName + "' has no default");
+ } else {
+ this.treeBuilder.setAttribute(DEFAULT_PREFIX + elementName, defaultElement);
}
-
+
// Create the selector for this section
getLogger().debug("Creating component selector for " + sectionName);
@@ -136,20 +149,19 @@
throw new ComponentException("Cannot configure role manager", ce);
}
- ExcaliburComponentSelector selector = new ExcaliburComponentSelector();
+ SitemapComponentSelector selector = new SitemapComponentSelector();
selector.setLogger(getLogger());
selector.contextualize(this.context);
selector.setRoleManager(emptyRoleManager);
selector.setLogKitManager(this.logKit);
selector.compose(this.manager);
// selector.configure( - no configuration - );
-
-
+
// Iterate on all components
Configuration[] elements = section.getChildren();
- for (int j = 0; i < elements.length; j++) {
+ for (int compIdx = 0; compIdx < elements.length; compIdx++) {
- Configuration element = elements[i];
+ Configuration element = elements[compIdx];
checkNamespace(element);
// Is it the right name ?
@@ -161,7 +173,7 @@
// Get the element name
String name = element.getAttribute("name");
- // Register the class
+ // Get the class
String className = element.getAttribute("src");
Class clazz;
try {
@@ -171,12 +183,13 @@
"' for " + elementName + " '" + name + "', at " + element.getLocation(), e);
}
+ // Get the mime-type, if any
+ String mimeType = element.getAttribute("mime-type", null);
+
// Register the component
selector.addComponent(name, clazz, element);
+
if (name.equals(defaultElement)) {
- // Also register as default component
- selector.addComponent(DEFAULT_HINT, clazz, element);
-
// Clear default to mark it as found
defaultElement = null;
}
@@ -188,10 +201,23 @@
"' does not exist, at " + section.getLocation());
}
+ // Chain with parent processor selector, if any
+ String role = (String)this.sectionRoles.get(sectionName);
+ try {
+ SitemapComponentSelector parentSelector =
+ (SitemapComponentSelector)this.manager.lookup(role);
+
+ // Found.
+ selector.setParentSelector(parentSelector);
+
+ } catch (ComponentException ce) {
+ // Ignore : means no parent
+ }
+
selector.initialize();
// Publish the selector
- this.builder.addComponentInstance((String)this.sectionRoles.get(sectionName), selector);
+ this.treeBuilder.addComponentInstance(role , selector);
} // end for sections
}
1.2 +11 -4 xml-cocoon2/scratchpad/src/org/apache/cocoon/treeprocessor/sitemap/GeneratorNode.java
Index: GeneratorNode.java
===================================================================
RCS file: /home/cvs/xml-cocoon2/scratchpad/src/org/apache/cocoon/treeprocessor/sitemap/GeneratorNode.java,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -r1.1 -r1.2
--- GeneratorNode.java 2001/11/08 14:39:24 1.1
+++ GeneratorNode.java 2001/11/12 18:07:43 1.2
@@ -11,6 +11,7 @@
import org.apache.cocoon.environment.Environment;
import org.apache.cocoon.components.pipeline.EventPipeline;
import org.apache.cocoon.components.pipeline.StreamPipeline;
+import org.apache.cocoon.sitemap.PatternException;
import org.apache.cocoon.treeprocessor.AbstractProcessingNode;
import org.apache.cocoon.treeprocessor.ListOfMapsResolver;
@@ -18,15 +19,20 @@
/**
*
* @author <a href="mailto:sylvain@apache.org">Sylvain Wallez</a>
- * @version CVS $Revision: 1.1 $ $Date: 2001/11/08 14:39:24 $
+ * @version CVS $Revision: 1.2 $ $Date: 2001/11/12 18:07:43 $
*/
public class GeneratorNode extends AbstractProcessingNode {
- protected String generatorName;
+ private String generatorName;
- protected ListOfMapsResolver source;
-
+ private ListOfMapsResolver source;
+
+ public GeneratorNode(String name, String source) throws PatternException {
+ this.generatorName = name;
+ this.source = ListOfMapsResolver.getResolver(source);
+ }
+
public boolean invoke(Environment env, StreamPipeline pipeline, EventPipeline eventPipeline, List listOfMaps)
throws Exception {
@@ -36,7 +42,8 @@
ListOfMapsResolver.buildParameters(this.parameters, listOfMaps)
);
- return true;
+ // Return false to contine sitemap invocation
+ return false;
}
}
1.2 +24 -2 xml-cocoon2/scratchpad/src/org/apache/cocoon/treeprocessor/sitemap/GeneratorNodeBuilder.java
Index: GeneratorNodeBuilder.java
===================================================================
RCS file: /home/cvs/xml-cocoon2/scratchpad/src/org/apache/cocoon/treeprocessor/sitemap/GeneratorNodeBuilder.java,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -r1.1 -r1.2
--- GeneratorNodeBuilder.java 2001/11/08 14:39:24 1.1
+++ GeneratorNodeBuilder.java 2001/11/12 18:07:43 1.2
@@ -9,6 +9,7 @@
package org.apache.cocoon.treeprocessor.sitemap;
import org.apache.avalon.framework.configuration.Configuration;
+import org.apache.avalon.framework.configuration.ConfigurationException;
import org.apache.cocoon.treeprocessor.AbstractProcessingNodeBuilder;
import org.apache.cocoon.treeprocessor.ProcessingNode;
@@ -17,14 +18,35 @@
/**
*
* @author <a href="mailto:sylvain@apache.org">Sylvain Wallez</a>
- * @version CVS $Revision: 1.1 $ $Date: 2001/11/08 14:39:24 $
+ * @version CVS $Revision: 1.2 $ $Date: 2001/11/12 18:07:43 $
*/
public class GeneratorNodeBuilder extends AbstractProcessingNodeBuilder {
- public void buildNode(Configuration config, Map buildModel) {
+ private GeneratorNode node;
+
+ public void buildNode(Configuration config, Map buildModel) throws Exception {
+
+ String type = config.getAttribute("type", null);
+ if (type == null) {
+ type = (String)this.treeBuilder.getAttribute(ComponentsNodeBuilder.DEFAULT_PREFIX + "generator");
+ }
+
+ if (type == null) {
+ throw new ConfigurationException(
+ "There is no default generator defined. Cannot create generator at " +
+ config.getLocation());
+ }
+
+ this.node = new GeneratorNode(type, config.getAttribute("src", null));
+ this.node.setLogger(getLogger());
+ this.node.setLocation(config.getLocation());
+
+ this.node.setParameters(getParameters(config));
+
}
+
public ProcessingNode getNode() {
- return null;
+ return this.node;
}
}
1.2 +145 -13 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.1
retrieving revision 1.2
diff -u -r1.1 -r1.2
--- PipelineNode.java 2001/11/08 14:39:24 1.1
+++ PipelineNode.java 2001/11/12 18:07:43 1.2
@@ -9,45 +9,177 @@
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.environment.ObjectModelHelper;
+import org.apache.cocoon.environment.http.HttpResponse;
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.ListOfMapsResolver;
+import org.apache.cocoon.treeprocessor.ProcessingNode;
-import java.util.List;
-import java.util.Map;
+import java.util.*;
/**
*
*
* @author <a href="mailto:sylvain@apache.org">Sylvain Wallez</a>
- * @version CVS $Revision: 1.1 $ $Date: 2001/11/08 14:39:24 $
+ * @version CVS $Revision: 1.2 $ $Date: 2001/11/12 18:07:43 $
*/
public class PipelineNode extends AbstractParentProcessingNode {
+ // TODO : handle a 'fail-hard' environment attribute
+ // can be useful to stop off-line generation when there's an error
+
+ private ProcessingNode[] children;
+
+ private ProcessingNode error404;
+
+ private ProcessingNode error500;
+
+ private ComponentManager manager;
+
+ private boolean internalOnly = false;
+
+ /**
+ * The component manager is used to create error pipelines
+ */
+ public void compose(ComponentManager manager) {
+ this.manager = manager;
+ }
+
+ public void setChildren(ProcessingNode[] node)
+ {
+ this.children = children;
+ }
+
+ public void set404Handler(ProcessingNode node)
+ {
+ this.error404 = node;
+ }
+
+ public void set500Handler(ProcessingNode node)
+ {
+ this.error500 = node;
+ }
+
+ public void setInternalOnly(boolean internalOnly) {
+ this.internalOnly = internalOnly;
+ }
+
public boolean invoke(Environment env, StreamPipeline pipeline, EventPipeline eventPipeline, List listOfMaps)
throws Exception {
- boolean success = false;
+ // Always fail on external resquests if internal only.
+ if (this.internalOnly && !SitemapNode.isInternalRequest(env)) {
+ return false;
+ }
- // Try each of the children until one is successfull.
try {
- for (int i = 0; i < childNodes.length; i++) {
- if (childNodes[i].invoke(env, pipeline, eventPipeline, listOfMaps)) {
- success = true;
- break;
- }
- }
+ if (invokeNodes(children, env, pipeline, eventPipeline, listOfMaps)) {
+ return true;
+ } else {
+ throw new ResourceNotFoundException("No pipeline matched request: " +
+ env.getURIPrefix()+'/'+env.getURI());
+ }
+
+ } catch(ResourceNotFoundException rnfe) {
+ getLogger().debug("Not found while processing pipeline", rnfe);
+
+ if (error404 != null) {
+
+ invokeErrorHandler(error404, rnfe, env);
+ return false;
+
+ } else {
+ throw rnfe;
+ }
} catch(Exception e) {
- // FIXME Error pipelines.
getLogger().debug("Error while processing pipeline", e);
- throw e;
+
+ // Rethrow exception for internal requests
+ if (error500 != null || !SitemapNode.isInternalRequest(env)) {
+
+ invokeErrorHandler(error500, e, env);
+ return false;
+
+ } else {
+ throw e;
+ }
}
+ }
+
+ private boolean invokeErrorHandler(ProcessingNode node, Exception ex, Environment env)
+ throws Exception {
+ EventPipeline eventPipeline = null;
+ StreamPipeline pipeline = null;
+ try {
+ tryResetResponse(env);
+ eventPipeline = (EventPipeline) this.manager.lookup(EventPipeline.ROLE);
+ pipeline = (StreamPipeline) this.manager.lookup(StreamPipeline.ROLE);
+ pipeline.setEventPipeline(eventPipeline);
+ List listOfMaps = new ArrayList();
+
+ eventPipeline.setGenerator ("!error-notifier!", ex.getMessage(),
+ ListOfMapsResolver.EMPTY_PARAMETERS, ex);
+
+ return node.invoke(env, pipeline, eventPipeline, listOfMaps);
+
+ } catch (Exception subEx) {
+ getLogger().error("error notifier barfs", subEx);
+ throw ex;
+
+ } finally {
+ this.manager.release(eventPipeline);
+ this.manager.release(pipeline);
+ }
+ }
+
+ /**
+ * Reset the response if possible. This allows error handlers to have
+ * a higher chance to produce clean output if the pipeline that raised
+ * the error has already output some data.
+ *
+ * @param objectModel the object model
+ * @return true if the response was successfully reset
+ */
+ private void tryResetResponse(Environment env)
+ {
+ try {
+ Object responseObj = ObjectModelHelper.getRequest(env.getObjectModel());
+ if (responseObj instanceof HttpResponse) {
+ HttpResponse response = (HttpResponse)responseObj;
+ if (! response.isCommitted()) {
+ response.reset();
+ getLogger().debug("Response successfully reset");
+ }
+ }
+ } catch(Exception e) {
+ // Log the error, but don't transmit it
+ getLogger().warn("Problem resetting response", e);
+ }
+
+ getLogger().debug("Response wasn't reset");
+ }
+
+
+ public void dispose() {
+
+ disposeNodes(children);
- return success;
+ if (this.error404 != null) {
+ this.error404.dispose();
+ }
+
+ if (this.error500 != null) {
+ this.error500.dispose();
+ }
}
}
1.2 +30 -16 xml-cocoon2/scratchpad/src/org/apache/cocoon/treeprocessor/sitemap/SitemapNode.java
Index: SitemapNode.java
===================================================================
RCS file: /home/cvs/xml-cocoon2/scratchpad/src/org/apache/cocoon/treeprocessor/sitemap/SitemapNode.java,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -r1.1 -r1.2
--- SitemapNode.java 2001/11/08 14:39:24 1.1
+++ SitemapNode.java 2001/11/12 18:07:43 1.2
@@ -22,15 +22,15 @@
import org.apache.cocoon.treeprocessor.AbstractParentProcessingNode;
import org.apache.cocoon.treeprocessor.EnvironmentSourceResolver;
+import org.apache.cocoon.treeprocessor.ProcessingNode;
-import java.util.List;
-import java.util.Map;
+import java.util.*;
/**
* The root node of a sitemap.
*
* @author <a href="mailto:sylvain@apache.org">Sylvain Wallez</a>
- * @version CVS $Revision: 1.1 $ $Date: 2001/11/08 14:39:24 $
+ * @version CVS $Revision: 1.2 $ $Date: 2001/11/12 18:07:43 $
*/
public class SitemapNode extends AbstractParentProcessingNode implements Composable {
@@ -41,12 +41,16 @@
protected ComponentManager manager;
+ protected PipelinesNode pipelines;
+
+ protected ProcessingNode[] otherNodes;
+
public static boolean isInternalRequest(Environment env) {
return env.getAttribute(INTERNAL_ATTR) != null;
}
- public static Redirector getRedirector(Environment env) {
- return (Redirector)env.getAttribute(REDIRECTOR_ATTR);
+ public static SitemapRedirector getRedirector(Environment env) {
+ return (SitemapRedirector)env.getAttribute(REDIRECTOR_ATTR);
}
/**
@@ -58,6 +62,21 @@
}
/**
+ * Set the pipeline nodes that will process the environment.
+ */
+ public void setPipelines(PipelinesNode pipelines) {
+ this.pipelines = pipelines;
+ }
+
+ /**
+ * Set the non-pipeline nodes (views & resources), which are held to properly
+ * <code>dispose()</code> them.
+ */
+ public void setOtherNodes(ProcessingNode[] otherNodes) {
+ this.otherNodes = otherNodes;
+ }
+
+ /**
* Process the environment. Also adds an <code>EnvironmentSourceResolver</code>
* and a <code>Redirector</code> in the object model. The previous resolver and
* redirector, if any, are restored before return.
@@ -106,6 +125,7 @@
// component manager used by all other nodes, which may redefine the
// SourceHandler to use.
EnvironmentSourceResolver resolver = new EnvironmentSourceResolver(this.manager, env);
+ SitemapRedirector redirector = new SitemapRedirector(env);
Map objectModel = env.getObjectModel();
@@ -113,23 +133,14 @@
Object oldRedirector = env.getAttribute(REDIRECTOR_ATTR);
objectModel.put(OBJECT_SOURCE_RESOLVER, resolver);
- env.setAttribute(REDIRECTOR_ATTR, new SitemapRedirector(env));
+ env.setAttribute(REDIRECTOR_ATTR, redirector);
- boolean success = true;
try {
// FIXME : is there any useful information that can be passed as top-level parameters,
// such as the URI of the mount point ?
- for (int i = 0; i < childNodes.length; i++) {
- if (! childNodes[i].invoke(env, pipeline, eventPipeline, listOfMaps)) {
- success = false;
- break;
- }
- }
- //TODO : check redirector
+ return this.pipelines.invoke(env, pipeline, eventPipeline, listOfMaps);
- return success;
-
} finally {
// Restore old redirector and resolver
@@ -145,7 +156,10 @@
* Dispose all children and the component manager.
*/
public void dispose() {
- this.disposeChildren();
+
+ this.pipelines.dispose();
+ disposeNodes(this.otherNodes);
+
if (this.manager instanceof Disposable) {
((Disposable)this.manager).dispose();
}
1.2 +42 -4 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.1
retrieving revision 1.2
diff -u -r1.1 -r1.2
--- SitemapNodeBuilder.java 2001/11/08 14:39:24 1.1
+++ SitemapNodeBuilder.java 2001/11/12 18:07:43 1.2
@@ -12,35 +12,73 @@
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;
import org.apache.cocoon.treeprocessor.ProcessingNode;
import org.apache.cocoon.treeprocessor.AbstractParentProcessingNodeBuilder;
-import java.util.Map;
+import java.util.*;
/**
*
* @author <a href="mailto:sylvain@apache.org">Sylvain Wallez</a>
- * @version CVS $Revision: 1.1 $ $Date: 2001/11/08 14:39:24 $
+ * @version CVS $Revision: 1.2 $ $Date: 2001/11/12 18:07:43 $
*/
public class SitemapNodeBuilder extends AbstractParentProcessingNodeBuilder implements Composable {
- protected ComponentManager manager;
+ private ComponentManager manager;
- protected SitemapNode node;
+ 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.childBuilders = createChildBuilders(config, buildModel);
+
}
public ProcessingNode getNode() throws Exception {
+
+ ProcessingNode[] childNodes = getNodes(childBuilders);
+
+ // Children contain resources, view and pipelines : separate pipelines
+ PipelinesNode pipelines = null;
+ List otherNodes = new ArrayList();
+
+ for (int i = 0; i < childNodes.length; i++) {
+
+ if (childNodes[i] instanceof PipelinesNode) {
+ if (pipelines != null) {
+ throw new ConfigurationException("There can only be one 'map:pipelines' at " +
+ this.location);
+ } else {
+ pipelines = (PipelinesNode) childNodes[i];
+ }
+ } else {
+ otherNodes.add(childNodes[i]);
+ }
+ }
+
+ if (pipelines == null) {
+ throw new ConfigurationException("There is no 'map:pipelines' in sitemap at " + this.location);
+ }
+
+ node.setPipelines(pipelines);
+ node.setOtherNodes(toNodeArray(otherNodes));
+
return this.node;
}
-
}
1.1 xml-cocoon2/scratchpad/src/org/apache/cocoon/treeprocessor/sitemap/PipelineNodeBuilder.java
Index: PipelineNodeBuilder.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.avalon.framework.configuration.ConfigurationException;
import org.apache.cocoon.treeprocessor.AbstractParentProcessingNodeBuilder;
import org.apache.cocoon.treeprocessor.ProcessingNode;
import org.apache.cocoon.treeprocessor.ProcessingNodeBuilder;
import java.util.*;
/**
* Builds a <map:pipeline>
* @author <a href="mailto:sylvain@apache.org">Sylvain Wallez</a>
* @version CVS $Revision: 1.1 $ $Date: 2001/11/12 18:07:43 $
*/
public class PipelineNodeBuilder extends AbstractParentProcessingNodeBuilder {
private PipelineNode node;
private List builders;
private ProcessingNodeBuilder error404Builder;
private ProcessingNodeBuilder error500Builder;
public void buildNode(Configuration config, Map buildModel) throws Exception {
this.node = new PipelineNode();
this.node.setLocation(config.getLocation());
this.node.setLogger(getLogger());
this.node.setInternalOnly(config.getAttributeAsBoolean("internal-only", false));
// Get all children but the error handlers
if (this.ignoredChildren == null)
this.ignoredChildren = new ArrayList();
this.ignoredChildren.add("handle-errors");
this.builders = createChildBuilders(config, buildModel);
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);
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;
} else {
throw new ConfigurationException("Unkown handle-errors type (" + type + ") at " +
handlerConfig.getLocation());
}
}
}
public ProcessingNode getNode() throws Exception {
this.node.setChildren(this.getNodes(builders));
if (this.error404Builder != null) {
this.node.set404Handler(this.error404Builder.getNode());
}
if (this.error500Builder != null) {
this.node.set500Handler(this.error500Builder.getNode());
}
return this.node;
}
}
1.1 xml-cocoon2/scratchpad/src/org/apache/cocoon/treeprocessor/sitemap/PipelinesNode.java
Index: PipelinesNode.java
===================================================================
/*****************************************************************************
* Copyright (C) The Apache Software Foundation. All rights reserved. *
* ------------------------------------------------------------------------- *
* This software is published under the terms of the Apache Software License *
* version 1.1, a copy of which has been included with this distribution in *
* the LICENSE file. *
*****************************************************************************/
package org.apache.cocoon.treeprocessor.sitemap;
import org.apache.avalon.framework.component.ComponentManager;
import org.apache.avalon.framework.component.Composable;
import org.apache.avalon.framework.activity.Disposable;
import org.apache.cocoon.ResourceNotFoundException;
import org.apache.cocoon.environment.Environment;
import org.apache.cocoon.components.pipeline.EventPipeline;
import org.apache.cocoon.components.pipeline.StreamPipeline;
import org.apache.cocoon.treeprocessor.AbstractParentProcessingNode;
import org.apache.cocoon.treeprocessor.ProcessingNode;
import java.util.*;
/**
* Handles <map:pipelines>
*
* @author <a href="mailto:sylvain@apache.org">Sylvain Wallez</a>
* @version CVS $Revision: 1.1 $ $Date: 2001/11/12 18:07:43 $
*/
public final class PipelinesNode extends AbstractParentProcessingNode {
private ProcessingNode[] children;
public void setChildren(ProcessingNode[] node)
{
this.children = children;
}
public final boolean invoke(Environment env, StreamPipeline pipeline, EventPipeline eventPipeline, List listOfMaps)
throws Exception {
return invokeNodes(children, env, pipeline, eventPipeline, listOfMaps);
}
public final void dispose() {
disposeNodes(children);
}
}
1.1 xml-cocoon2/scratchpad/src/org/apache/cocoon/treeprocessor/sitemap/PipelinesNodeBuilder.java
Index: PipelinesNodeBuilder.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.avalon.framework.configuration.ConfigurationException;
import org.apache.cocoon.treeprocessor.AbstractParentProcessingNodeBuilder;
import org.apache.cocoon.treeprocessor.ProcessingNode;
import org.apache.cocoon.treeprocessor.ProcessingNodeBuilder;
import java.util.*;
/**
* Buildes a <map:pipelines>
*
* @author <a href="mailto:sylvain@apache.org">Sylvain Wallez</a>
* @version CVS $Revision: 1.1 $ $Date: 2001/11/12 18:07:43 $
*/
public class PipelinesNodeBuilder extends AbstractParentProcessingNodeBuilder {
private PipelinesNode node;
private List builders;
public void buildNode(Configuration config, Map buildModel) throws Exception {
this.node = new PipelinesNode();
this.node.setLocation(config.getLocation());
this.node.setLogger(getLogger());
// Get all children but the error handlers
this.builders = createChildBuilders(config, buildModel);
if (this.builders.size() == 0) {
throw new ConfigurationException("There must be at least one pipeline at " +
config.getLocation());
}
}
public ProcessingNode getNode() throws Exception {
this.node.setChildren(this.getNodes(builders));
return this.node;
}
}
----------------------------------------------------------------------
In case of troubles, e-mail: webmaster@xml.apache.org
To unsubscribe, e-mail: cocoon-cvs-unsubscribe@xml.apache.org
For additional commands, e-mail: cocoon-cvs-help@xml.apache.org