tcurdt 2002/10/11 22:11:40 Modified: . changes.xml src/java/org/apache/cocoon/components/treeprocessor AbstractParentProcessingNode.java InvokeContext.java src/java/org/apache/cocoon/components/treeprocessor/sitemap ActNodeBuilder.java ActSetNode.java ActTypeNode.java ActionSetNode.java AggregateNode.java CallFunctionNode.java CallNode.java ContinueNode.java GenerateNode.java MatchNode.java MatchNodeBuilder.java MountNode.java PreparableMatchNode.java ReadNode.java RedirectToURINode.java SelectNode.java SerializeNode.java SwitchSelectNode.java TransformNode.java src/java/org/apache/cocoon/components/treeprocessor/variables NOPVariableResolver.java PreparedVariableResolver.java VariableResolver.java Log: fixed a bug for the {/1} syntax, implemented the {#name:variable} syntax for sitemap variable anchors. Revision Changes Path 1.264 +8 -1 xml-cocoon2/changes.xml Index: changes.xml =================================================================== RCS file: /home/cvs/xml-cocoon2/changes.xml,v retrieving revision 1.263 retrieving revision 1.264 diff -u -r1.263 -r1.264 --- changes.xml 29 Sep 2002 20:24:22 -0000 1.263 +++ changes.xml 12 Oct 2002 05:11:39 -0000 1.264 @@ -40,6 +40,13 @@ </devs> <release version="@version@" date="@date@"> + <action dev="TC" type="add"> + Added support for sitemap variable anchors {#name:variable}. + This introduces a new "name" attribute for matchers and actions + </action> + <action dev="TC" type="add"> + added support for direct access of root level sitemap variables {/1} + </action> <action dev="SW" type="add" fixes-bug="12780" due-to="Michael Melhem" due-to-email="[EMAIL PROTECTED]"> New pipeline hint attribute to allow pipeline components (i.e. map:generate, map:transform and map:serialize) to hold some pipeline-specific parameters. The first usage of this feature 1.5 +4 -2 xml-cocoon2/src/java/org/apache/cocoon/components/treeprocessor/AbstractParentProcessingNode.java Index: AbstractParentProcessingNode.java =================================================================== RCS file: /home/cvs/xml-cocoon2/src/java/org/apache/cocoon/components/treeprocessor/AbstractParentProcessingNode.java,v retrieving revision 1.4 retrieving revision 1.5 diff -u -r1.4 -r1.5 --- AbstractParentProcessingNode.java 6 Jun 2002 14:28:14 -0000 1.4 +++ AbstractParentProcessingNode.java 12 Oct 2002 05:11:39 -0000 1.5 @@ -69,14 +69,16 @@ * @param currentMap the <code>Map<code> of parameters produced by this node, * which is added to <code>listOfMap</code>. */ + protected final boolean invokeNodes( ProcessingNode[] nodes, Environment env, InvokeContext context, + String currentName, Map currentMap) throws Exception { - context.pushMap(currentMap); + context.pushMap(currentName,currentMap); try { for (int i = 0; i < nodes.length; i++) { 1.14 +43 -12 xml-cocoon2/src/java/org/apache/cocoon/components/treeprocessor/InvokeContext.java Index: InvokeContext.java =================================================================== RCS file: /home/cvs/xml-cocoon2/src/java/org/apache/cocoon/components/treeprocessor/InvokeContext.java,v retrieving revision 1.13 retrieving revision 1.14 diff -u -r1.13 -r1.14 --- InvokeContext.java 9 Aug 2002 07:47:16 -0000 1.13 +++ InvokeContext.java 12 Oct 2002 05:11:39 -0000 1.14 @@ -78,12 +78,15 @@ * * @author <a href="mailto:[EMAIL PROTECTED]">Sylvain Wallez</a> * @author <a href="mailto:[EMAIL PROTECTED]">Carsten Ziegeler</a> + * @author <a href="mailto:[EMAIL PROTECTED]">Torsten Curdt</a> * @version CVS $Id$ */ public class InvokeContext implements Recomposable, Disposable, LogEnabled { private List mapStack = new ArrayList(); + private HashMap nameToMap = new HashMap(); + private HashMap mapToName = new HashMap(); private boolean isInternalRequest; @@ -188,7 +191,7 @@ this.processingPipeline.recompose( this.pipelinesManager ); this.processingPipeline.setup( VariableResolver.buildParameters(this.processingPipelineParameters, - this.getMapStack(), this.processingPipelineObjectModel) + this, this.processingPipelineObjectModel) ); if (this.isInternalRequest) { CocoonComponentManager.addComponentForAutomaticRelease(this.pipelineSelector, @@ -221,35 +224,59 @@ } /** + * Get the result Map by anchor name + */ + public final Map getMapByAnchor(String anchor) { + return((Map) this.nameToMap.get(anchor)); + } + + /** * Push a Map on top of the current Map stack. */ - public final void pushMap(Map map) { + public final void pushMap(String anchorName, Map map) { mapStack.add(map); if (this.logger.isDebugEnabled()) { - dumpParameters(getMapStack()); + dumpParameters(); + } + + if (anchorName != null) { + if (!nameToMap.containsKey(anchorName)) { + nameToMap.put(anchorName,map); + mapToName.put(map,anchorName); + } + else { + if (this.logger.isErrorEnabled()) { + this.logger.error("name [" + anchorName + "] clashes"); + } + } } } /** * Dumps all sitemap parameters to log */ - protected void dumpParameters(List list) + protected void dumpParameters() { - if (!list.isEmpty()) { + if (!mapStack.isEmpty()) { StringBuffer sb = new StringBuffer(); sb.append("\nCurrent Sitemap Parameters:\n"); String path = ""; - for (int i = list.size() - 1; i >= 0; i--) { - Map map = (Map) list.get(i); - Iterator keys = map.keySet().iterator(); + for (int i = mapStack.size() - 1; i >= 0; i--) { + Map map = (Map) mapStack.get(i); + sb.append("LEVEL ").append(i+1); + if (mapToName.containsKey(map)) { + sb.append(" is named '").append(String.valueOf(mapToName.get(map))).append("'"); + } + sb.append("\n"); + Iterator keys = map.keySet().iterator(); while (keys.hasNext()) { Object key = keys.next(); - sb.append("PARAM: '").append(path).append(key); - sb.append("' VALUE: '").append(map.get(key)).append("'\n"); + sb.append("PARAM: '").append(path).append(key).append("' "); + sb.append("VALUE: '").append(map.get(key)).append("'\n"); } path = "../" + path; @@ -257,6 +284,7 @@ this.logger.debug(sb.toString()); } + } @@ -264,7 +292,10 @@ * Pop the topmost element of the current Map stack. */ public final void popMap() { - mapStack.remove(mapStack.size() - 1); + Object map = mapStack.remove(mapStack.size() - 1); + Object name = mapToName.get(map); + mapToName.remove(map); + nameToMap.remove(name); } /** 1.3 +4 -2 xml-cocoon2/src/java/org/apache/cocoon/components/treeprocessor/sitemap/ActNodeBuilder.java Index: ActNodeBuilder.java =================================================================== RCS file: /home/cvs/xml-cocoon2/src/java/org/apache/cocoon/components/treeprocessor/sitemap/ActNodeBuilder.java,v retrieving revision 1.2 retrieving revision 1.3 diff -u -r1.2 -r1.3 --- ActNodeBuilder.java 24 Jun 2002 20:32:19 -0000 1.2 +++ ActNodeBuilder.java 12 Oct 2002 05:11:39 -0000 1.3 @@ -83,12 +83,14 @@ this.actSetName = config.getAttribute("set", null); if (actSetName == null) { + String name = config.getAttribute("name", null); String source = config.getAttribute("src", null); String type = this.treeBuilder.getTypeForStatement(config, Action.ROLE + "Selector"); ActTypeNode actTypeNode = new ActTypeNode( type, - VariableResolverFactory.getResolver(source, this.manager) + VariableResolverFactory.getResolver(source, this.manager), + name ); this.treeBuilder.setupNode(actTypeNode, config); 1.6 +3 -3 xml-cocoon2/src/java/org/apache/cocoon/components/treeprocessor/sitemap/ActSetNode.java Index: ActSetNode.java =================================================================== RCS file: /home/cvs/xml-cocoon2/src/java/org/apache/cocoon/components/treeprocessor/sitemap/ActSetNode.java,v retrieving revision 1.5 retrieving revision 1.6 diff -u -r1.5 -r1.6 --- ActSetNode.java 9 Aug 2002 07:47:17 -0000 1.5 +++ ActSetNode.java 12 Oct 2002 05:11:39 -0000 1.6 @@ -104,7 +104,7 @@ Parameters resolvedParams = VariableResolver.buildParameters( this.parameters, - context.getMapStack(), + context, env.getObjectModel() ); @@ -120,7 +120,7 @@ return true; } else { - return this.invokeNodes(this.children, env, context, result); + return this.invokeNodes(this.children, env, context, null, result); } } } 1.6 +10 -7 xml-cocoon2/src/java/org/apache/cocoon/components/treeprocessor/sitemap/ActTypeNode.java Index: ActTypeNode.java =================================================================== RCS file: /home/cvs/xml-cocoon2/src/java/org/apache/cocoon/components/treeprocessor/sitemap/ActTypeNode.java,v retrieving revision 1.5 retrieving revision 1.6 diff -u -r1.5 -r1.6 --- ActTypeNode.java 9 Aug 2002 07:47:17 -0000 1.5 +++ ActTypeNode.java 12 Oct 2002 05:11:39 -0000 1.6 @@ -87,14 +87,18 @@ /** The 'src' attribute */ protected VariableResolver source; + /** The 'name' for the variable anchor */ + protected String name; + /** Pre-selected action, if it's ThreadSafe */ protected Action threadSafeAction; protected ComponentManager manager; - public ActTypeNode(String name, VariableResolver source) throws PatternException { - super(name); + public ActTypeNode(String type, VariableResolver source, String name) throws PatternException { + super(type); this.source = source; + this.name = name; } public void setParameters(Map parameterMap) { @@ -119,9 +123,8 @@ Map objectModel = env.getObjectModel(); Redirector redirector = PipelinesNode.getRedirector(env); SourceResolver resolver = getSourceResolver(objectModel); - List mapStack = context.getMapStack(); - String resolvedSource = source.resolve(mapStack, objectModel); - Parameters resolvedParams = VariableResolver.buildParameters(this.parameters, mapStack, objectModel); + String resolvedSource = source.resolve(context, objectModel); + Parameters resolvedParams = VariableResolver.buildParameters(this.parameters, context, objectModel); Map actionResult; @@ -152,7 +155,7 @@ } else { // Action succeeded : process children if there are some, with the action result if (this.children != null) { - return this.invokeNodes(this.children, env, context, actionResult); + return this.invokeNodes(this.children, env, context, name, actionResult); } else { // Return false to continue sitemap invocation 1.7 +3 -4 xml-cocoon2/src/java/org/apache/cocoon/components/treeprocessor/sitemap/ActionSetNode.java Index: ActionSetNode.java =================================================================== RCS file: /home/cvs/xml-cocoon2/src/java/org/apache/cocoon/components/treeprocessor/sitemap/ActionSetNode.java,v retrieving revision 1.6 retrieving revision 1.7 diff -u -r1.6 -r1.7 --- ActionSetNode.java 11 Sep 2002 10:08:35 -0000 1.6 +++ ActionSetNode.java 12 Oct 2002 05:11:39 -0000 1.7 @@ -139,7 +139,6 @@ Map objectModel = env.getObjectModel(); Redirector redirector = PipelinesNode.getRedirector(env); SourceResolver resolver = getSourceResolver(objectModel); - List mapStack = context.getMapStack(); String cocoonAction = env.getAction(); @@ -154,10 +153,10 @@ Action action; String actionName = actionNames[i]; - String source = sources[i].resolve(mapStack, objectModel); + String source = sources[i].resolve(context, objectModel); if (actionName == null || actionName.equals(cocoonAction)) { - Parameters actionParams = VariableResolver.buildParameters(parameters[i], mapStack, objectModel); + Parameters actionParams = VariableResolver.buildParameters(parameters[i], context, objectModel); if (actionParams == Parameters.EMPTY_PARAMETERS) { actionParams = params; } else { 1.8 +9 -10 xml-cocoon2/src/java/org/apache/cocoon/components/treeprocessor/sitemap/AggregateNode.java Index: AggregateNode.java =================================================================== RCS file: /home/cvs/xml-cocoon2/src/java/org/apache/cocoon/components/treeprocessor/sitemap/AggregateNode.java,v retrieving revision 1.7 retrieving revision 1.8 diff -u -r1.7 -r1.8 --- AggregateNode.java 9 Sep 2002 12:00:42 -0000 1.7 +++ AggregateNode.java 12 Oct 2002 05:11:39 -0000 1.8 @@ -120,7 +120,6 @@ boolean infoEnabled = getLogger().isInfoEnabled(); - List mapStack = context.getMapStack(); Map objectModel = env.getObjectModel(); // Setup aggregator @@ -130,9 +129,9 @@ ContentAggregator aggregator = (ContentAggregator)processingPipeline.getGenerator(); aggregator.setRootElement( - this.element.resolve(mapStack, objectModel), - this.nsURI.resolve(mapStack, objectModel), - this.nsPrefix.resolve(mapStack, objectModel) + this.element.resolve(context, objectModel), + this.nsURI.resolve(context, objectModel), + this.nsPrefix.resolve(context, objectModel) ); // Get actual parts, potentially filtered by the view @@ -158,11 +157,11 @@ Part part = actualParts[i]; if (part != null) { aggregator.addPart( - part.source.resolve(mapStack, objectModel), - part.element.resolve(mapStack, objectModel), - part.nsURI.resolve(mapStack, objectModel), - part.stripRoot.resolve(mapStack, objectModel), - part.nsPrefix.resolve(mapStack, objectModel) + part.source.resolve(context, objectModel), + part.element.resolve(context, objectModel), + part.nsURI.resolve(context, objectModel), + part.stripRoot.resolve(context, objectModel), + part.nsPrefix.resolve(context, objectModel) ); } } 1.7 +6 -6 xml-cocoon2/src/java/org/apache/cocoon/components/treeprocessor/sitemap/CallFunctionNode.java Index: CallFunctionNode.java =================================================================== RCS file: /home/cvs/xml-cocoon2/src/java/org/apache/cocoon/components/treeprocessor/sitemap/CallFunctionNode.java,v retrieving revision 1.6 retrieving revision 1.7 diff -u -r1.6 -r1.7 --- CallFunctionNode.java 1 Oct 2002 09:08:04 -0000 1.6 +++ CallFunctionNode.java 12 Oct 2002 05:11:39 -0000 1.7 @@ -80,8 +80,8 @@ protected ComponentManager manager; protected Interpreter interpreter; - public static List resolveList(List expressions, ComponentManager manager, List mapStack, Map objectModel) - throws PatternException + public static List resolveList(List expressions, ComponentManager manager, InvokeContext context, Map objectModel) + throws PatternException { int size; if (expressions == null || (size = expressions.size()) == 0) @@ -91,7 +91,7 @@ for (int i = 0; i < size; i++) { Interpreter.Argument arg = (Interpreter.Argument)expressions.get(i); - String value = VariableResolverFactory.getResolver(arg.value, manager).resolve(mapStack, objectModel); + String value = VariableResolverFactory.getResolver(arg.value, manager).resolve(context, objectModel); result.add (new Interpreter.Argument(arg.name, value)); } @@ -162,13 +162,13 @@ // Resolve parameters if (parameters != null) - params = resolveList(parameters, manager, context.getMapStack(), + params = resolveList(parameters, manager, context, env.getObjectModel()); String continuation; if (continuationResolver != null) { // Need to resolve the function name at runtime - continuation = continuationResolver.resolve(context.getMapStack(), + continuation = continuationResolver.resolve(context, env.getObjectModel()); } else @@ -187,7 +187,7 @@ String name; if (functionNameResolver != null) { // Need to resolve the function name at runtime - name = functionNameResolver.resolve(context.getMapStack(), + name = functionNameResolver.resolve(context, env.getObjectModel()); } else 1.6 +5 -6 xml-cocoon2/src/java/org/apache/cocoon/components/treeprocessor/sitemap/CallNode.java Index: CallNode.java =================================================================== RCS file: /home/cvs/xml-cocoon2/src/java/org/apache/cocoon/components/treeprocessor/sitemap/CallNode.java,v retrieving revision 1.5 retrieving revision 1.6 diff -u -r1.5 -r1.6 --- CallNode.java 11 Sep 2002 10:08:35 -0000 1.5 +++ CallNode.java 12 Oct 2002 05:11:39 -0000 1.6 @@ -120,15 +120,14 @@ public final boolean invoke(Environment env, InvokeContext context) throws Exception { - List mapStack = context.getMapStack(); Map objectModel = env.getObjectModel(); // Resolve parameters, but push them only once the resource name has been // resolved, otherwise it adds an unwanted nesting level - Map params = VariableResolver.buildMap(this.parameters, mapStack, objectModel); + Map params = VariableResolver.buildMap(this.parameters, context, objectModel); if (this.resourceNode != null) { // Static resource name - context.pushMap(params); + context.pushMap(null,params); try { return this.resourceNode.invoke(env, context); @@ -138,13 +137,13 @@ } else { // Resolved resource name - String name = this.resourceResolver.resolve(mapStack, objectModel); + String name = this.resourceResolver.resolve(context, objectModel); if (getLogger().isDebugEnabled()) { getLogger().debug("Calling resource " + name); } // and only now push the parameters - context.pushMap(params); + context.pushMap(null,params); try { return this.resources.invokeByName(name, env, context); 1.5 +2 -2 xml-cocoon2/src/java/org/apache/cocoon/components/treeprocessor/sitemap/ContinueNode.java Index: ContinueNode.java =================================================================== RCS file: /home/cvs/xml-cocoon2/src/java/org/apache/cocoon/components/treeprocessor/sitemap/ContinueNode.java,v retrieving revision 1.4 retrieving revision 1.5 diff -u -r1.4 -r1.5 --- ContinueNode.java 8 Sep 2002 00:29:20 -0000 1.4 +++ ContinueNode.java 12 Oct 2002 05:11:39 -0000 1.5 @@ -125,12 +125,12 @@ // Resolve parameters if (this.parameters != null) params = CallFunctionNode.resolveList(this.parameters, this.manager, - context.getMapStack(), env.getObjectModel()); + context, env.getObjectModel()); String contId = continuationId; if (continuationIdResolver != null) { - contId = continuationIdResolver.resolve(context.getMapStack(), env.getObjectModel()); + contId = continuationIdResolver.resolve(context, env.getObjectModel()); } InterpreterSelector selector 1.9 +4 -5 xml-cocoon2/src/java/org/apache/cocoon/components/treeprocessor/sitemap/GenerateNode.java Index: GenerateNode.java =================================================================== RCS file: /home/cvs/xml-cocoon2/src/java/org/apache/cocoon/components/treeprocessor/sitemap/GenerateNode.java,v retrieving revision 1.8 retrieving revision 1.9 diff -u -r1.8 -r1.9 --- GenerateNode.java 13 Sep 2002 17:47:54 -0000 1.8 +++ GenerateNode.java 12 Oct 2002 05:11:39 -0000 1.9 @@ -95,16 +95,15 @@ public final boolean invoke(Environment env, InvokeContext context) throws Exception { - List mapStack = context.getMapStack(); Map objectModel = env.getObjectModel(); context.getProcessingPipeline().setGenerator( this.generatorName, - source.resolve(mapStack, objectModel), - VariableResolver.buildParameters(this.parameters, mapStack, objectModel), + source.resolve(context, objectModel), + VariableResolver.buildParameters(this.parameters, context, objectModel), this.pipelineHints == null ? Parameters.EMPTY_PARAMETERS - : VariableResolver.buildParameters(this.pipelineHints, mapStack, objectModel) + : VariableResolver.buildParameters(this.pipelineHints, context, objectModel) ); 1.6 +10 -6 xml-cocoon2/src/java/org/apache/cocoon/components/treeprocessor/sitemap/MatchNode.java Index: MatchNode.java =================================================================== RCS file: /home/cvs/xml-cocoon2/src/java/org/apache/cocoon/components/treeprocessor/sitemap/MatchNode.java,v retrieving revision 1.5 retrieving revision 1.6 diff -u -r1.5 -r1.6 --- MatchNode.java 9 Aug 2002 07:47:17 -0000 1.5 +++ MatchNode.java 12 Oct 2002 05:11:39 -0000 1.6 @@ -79,6 +79,9 @@ /** The 'pattern' attribute */ private VariableResolver pattern; + /** The 'name' for the variable anchor */ + private String name; + /** The matcher, if it's ThreadSafe */ private Matcher threadSafeMatcher; @@ -86,9 +89,10 @@ private ComponentManager manager; - public MatchNode(String name, VariableResolver pattern) throws PatternException { - super(name); + public MatchNode(String type, VariableResolver pattern, String name) throws PatternException { + super(type); this.pattern = pattern; + this.name = name; } public void setParameters(Map parameterMap) { @@ -112,8 +116,8 @@ List mapStack = context.getMapStack(); Map objectModel = env.getObjectModel(); - String resolvedPattern = pattern.resolve(mapStack, objectModel); - Parameters resolvedParams = VariableResolver.buildParameters(this.parameters, mapStack, objectModel); + String resolvedPattern = pattern.resolve(context, objectModel); + Parameters resolvedParams = VariableResolver.buildParameters(this.parameters, context, objectModel); Map result = null; @@ -139,7 +143,7 @@ } // Invoke children with the matcher results - return this.invokeNodes(children, env, context, result); + return this.invokeNodes(children, env, context, name, result); } else { // Matcher failed 1.7 +4 -3 xml-cocoon2/src/java/org/apache/cocoon/components/treeprocessor/sitemap/MatchNodeBuilder.java Index: MatchNodeBuilder.java =================================================================== RCS file: /home/cvs/xml-cocoon2/src/java/org/apache/cocoon/components/treeprocessor/sitemap/MatchNodeBuilder.java,v retrieving revision 1.6 retrieving revision 1.7 diff -u -r1.6 -r1.7 --- MatchNodeBuilder.java 25 Jun 2002 07:55:13 -0000 1.6 +++ MatchNodeBuilder.java 12 Oct 2002 05:11:39 -0000 1.7 @@ -79,6 +79,7 @@ public ProcessingNode buildNode(Configuration config) throws Exception { String pattern = config.getAttribute("pattern", null); + String name = config.getAttribute("name", null); String type = this.treeBuilder.getTypeForStatement(config, SELECTOR_ROLE); @@ -105,9 +106,9 @@ VariableResolver patternResolver = VariableResolverFactory.getResolver(pattern, this.manager); if (preparable) { - node = new PreparableMatchNode(type, VariableResolverFactory.unescape(pattern)); + node = new PreparableMatchNode(type, VariableResolverFactory.unescape(pattern),name); } else { - node = new MatchNode(type, patternResolver); + node = new MatchNode(type, patternResolver,name); } this.treeBuilder.setupNode(node, config); 1.8 +3 -3 xml-cocoon2/src/java/org/apache/cocoon/components/treeprocessor/sitemap/MountNode.java Index: MountNode.java =================================================================== RCS file: /home/cvs/xml-cocoon2/src/java/org/apache/cocoon/components/treeprocessor/sitemap/MountNode.java,v retrieving revision 1.7 retrieving revision 1.8 diff -u -r1.7 -r1.8 --- MountNode.java 24 Jun 2002 20:32:19 -0000 1.7 +++ MountNode.java 12 Oct 2002 05:11:39 -0000 1.8 @@ -104,13 +104,13 @@ List mapStack = context.getMapStack(); Map objectModel = env.getObjectModel(); - String resolvedSource = this.source.resolve(mapStack, objectModel); + String resolvedSource = this.source.resolve(context, objectModel); TreeProcessor processor = (TreeProcessor)processors.get(resolvedSource); if (processor == null) { processor = getProcessor(env, resolvedSource); } - String resolvedPrefix = this.prefix.resolve(mapStack, objectModel); + String resolvedPrefix = this.prefix.resolve(context, objectModel); String oldPrefix = env.getURIPrefix(); String oldURI = env.getURI(); 1.7 +9 -5 xml-cocoon2/src/java/org/apache/cocoon/components/treeprocessor/sitemap/PreparableMatchNode.java Index: PreparableMatchNode.java =================================================================== RCS file: /home/cvs/xml-cocoon2/src/java/org/apache/cocoon/components/treeprocessor/sitemap/PreparableMatchNode.java,v retrieving revision 1.6 retrieving revision 1.7 diff -u -r1.6 -r1.7 --- PreparableMatchNode.java 11 Sep 2002 10:08:35 -0000 1.6 +++ PreparableMatchNode.java 12 Oct 2002 05:11:39 -0000 1.7 @@ -80,6 +80,9 @@ /** The 'pattern' attribute */ private String pattern; + /** The 'name' for the variable anchor */ + private String name; + private Object preparedPattern; private Map parameters; @@ -89,9 +92,10 @@ protected ComponentManager manager; - public PreparableMatchNode(String name, String pattern) throws PatternException { - super(name); + public PreparableMatchNode(String type, String pattern, String name) throws PatternException { + super(type); this.pattern = pattern; + this.name = name; } public void setParameters(Map parameterMap) { @@ -132,7 +136,7 @@ Map objectModel = env.getObjectModel(); Parameters resolvedParams = VariableResolver.buildParameters( - this.parameters, context.getMapStack(), objectModel + this.parameters, context, objectModel ); Map result = null; @@ -159,7 +163,7 @@ } // Invoke children with the matcher results - return this.invokeNodes(children, env, context, result); + return this.invokeNodes(children, env, context, name, result); } else { // Matcher failed 1.4 +3 -4 xml-cocoon2/src/java/org/apache/cocoon/components/treeprocessor/sitemap/ReadNode.java Index: ReadNode.java =================================================================== RCS file: /home/cvs/xml-cocoon2/src/java/org/apache/cocoon/components/treeprocessor/sitemap/ReadNode.java,v retrieving revision 1.3 retrieving revision 1.4 diff -u -r1.3 -r1.4 --- ReadNode.java 24 Jun 2002 20:32:19 -0000 1.3 +++ ReadNode.java 12 Oct 2002 05:11:39 -0000 1.4 @@ -100,15 +100,14 @@ public final boolean invoke(Environment env, InvokeContext context) throws Exception { - List mapStack = context.getMapStack(); Map objectModel = env.getObjectModel(); ProcessingPipeline pipeline = context.getProcessingPipeline(); pipeline.setReader( this.readerName, - source.resolve(mapStack, objectModel), - VariableResolver.buildParameters(this.parameters, mapStack, objectModel), + source.resolve(context, objectModel), + VariableResolver.buildParameters(this.parameters, context, objectModel), this.mimeType ); 1.6 +2 -2 xml-cocoon2/src/java/org/apache/cocoon/components/treeprocessor/sitemap/RedirectToURINode.java Index: RedirectToURINode.java =================================================================== RCS file: /home/cvs/xml-cocoon2/src/java/org/apache/cocoon/components/treeprocessor/sitemap/RedirectToURINode.java,v retrieving revision 1.5 retrieving revision 1.6 diff -u -r1.5 -r1.6 --- RedirectToURINode.java 13 Aug 2002 14:05:18 -0000 1.5 +++ RedirectToURINode.java 12 Oct 2002 05:11:39 -0000 1.6 @@ -83,7 +83,7 @@ public final boolean invoke(Environment env, InvokeContext context) throws Exception { - String resolvedURI = uri.resolve(context.getMapStack(), env.getObjectModel()); + String resolvedURI = uri.resolve(context, env.getObjectModel()); if (getLogger().isInfoEnabled()) { getLogger().info("Redirecting to '" + resolvedURI + "' at " + this.getLocation()); 1.6 +4 -5 xml-cocoon2/src/java/org/apache/cocoon/components/treeprocessor/sitemap/SelectNode.java Index: SelectNode.java =================================================================== RCS file: /home/cvs/xml-cocoon2/src/java/org/apache/cocoon/components/treeprocessor/sitemap/SelectNode.java,v retrieving revision 1.5 retrieving revision 1.6 diff -u -r1.5 -r1.6 --- SelectNode.java 9 Aug 2002 07:47:17 -0000 1.5 +++ SelectNode.java 12 Oct 2002 05:11:39 -0000 1.6 @@ -127,15 +127,14 @@ // Prepare data needed by the action Map objectModel = env.getObjectModel(); - List mapStack = context.getMapStack(); - Parameters resolvedParams = VariableResolver.buildParameters(this.parameters, mapStack, objectModel); + Parameters resolvedParams = VariableResolver.buildParameters(this.parameters, context, objectModel); // If selector is ThreadSafe, avoid select() and try/catch block (faster !) if (this.threadSafeSelector != null) { for (int i = 0; i < this.whenTests.length; i++) { if (this.threadSafeSelector.select( - whenTests[i].resolve(mapStack, objectModel), + whenTests[i].resolve(context, objectModel), objectModel, resolvedParams)) { return invokeNodes(this.whenNodes[i], env, context); @@ -154,7 +153,7 @@ for (int i = 0; i < this.whenTests.length; i++) { if (selector.select( - whenTests[i].resolve(mapStack, objectModel), + whenTests[i].resolve(context, objectModel), objectModel, resolvedParams)) { return invokeNodes(this.whenNodes[i], env, context); 1.8 +2 -2 xml-cocoon2/src/java/org/apache/cocoon/components/treeprocessor/sitemap/SerializeNode.java Index: SerializeNode.java =================================================================== RCS file: /home/cvs/xml-cocoon2/src/java/org/apache/cocoon/components/treeprocessor/sitemap/SerializeNode.java,v retrieving revision 1.7 retrieving revision 1.8 diff -u -r1.7 -r1.8 --- SerializeNode.java 13 Sep 2002 17:47:54 -0000 1.7 +++ SerializeNode.java 12 Oct 2002 05:11:39 -0000 1.8 @@ -135,7 +135,7 @@ Parameters.EMPTY_PARAMETERS, // No parameters on serializers this.pipelineHints == null ? Parameters.EMPTY_PARAMETERS - : VariableResolver.buildParameters(this.pipelineHints, mapStack, objectModel), + : VariableResolver.buildParameters(this.pipelineHints, context, objectModel), this.mimeType ); 1.5 +4 -5 xml-cocoon2/src/java/org/apache/cocoon/components/treeprocessor/sitemap/SwitchSelectNode.java Index: SwitchSelectNode.java =================================================================== RCS file: /home/cvs/xml-cocoon2/src/java/org/apache/cocoon/components/treeprocessor/sitemap/SwitchSelectNode.java,v retrieving revision 1.4 retrieving revision 1.5 diff -u -r1.4 -r1.5 --- SwitchSelectNode.java 9 Aug 2002 07:47:17 -0000 1.4 +++ SwitchSelectNode.java 12 Oct 2002 05:11:39 -0000 1.5 @@ -129,8 +129,7 @@ // Prepare data needed by the action Map objectModel = env.getObjectModel(); - List mapStack = context.getMapStack(); - Parameters resolvedParams = VariableResolver.buildParameters(this.parameters, mapStack, objectModel); + Parameters resolvedParams = VariableResolver.buildParameters(this.parameters, context, objectModel); // If selector is ThreadSafe, avoid select() and try/catch block (faster !) if (this.threadSafeSelector != null) { @@ -138,7 +137,7 @@ Object ctx = this.threadSafeSelector.getSelectorContext(objectModel, resolvedParams); for (int i = 0; i < this.whenTests.length; i++) { - if (this.threadSafeSelector.select(whenTests[i].resolve(mapStack, objectModel), ctx)) { + if (this.threadSafeSelector.select(whenTests[i].resolve(context, objectModel), ctx)) { return invokeNodes(this.whenNodes[i], env, context); } } @@ -157,7 +156,7 @@ try { for (int i = 0; i < this.whenTests.length; i++) { - if (selector.select(whenTests[i].resolve(mapStack, objectModel), ctx)) { + if (selector.select(whenTests[i].resolve(context, objectModel), ctx)) { return invokeNodes(this.whenNodes[i], env, context); } } 1.8 +4 -5 xml-cocoon2/src/java/org/apache/cocoon/components/treeprocessor/sitemap/TransformNode.java Index: TransformNode.java =================================================================== RCS file: /home/cvs/xml-cocoon2/src/java/org/apache/cocoon/components/treeprocessor/sitemap/TransformNode.java,v retrieving revision 1.7 retrieving revision 1.8 diff -u -r1.7 -r1.8 --- TransformNode.java 13 Sep 2002 17:47:54 -0000 1.7 +++ TransformNode.java 12 Oct 2002 05:11:39 -0000 1.8 @@ -92,16 +92,15 @@ public final boolean invoke(Environment env, InvokeContext context) throws Exception { - List mapStack = context.getMapStack(); Map objectModel = env.getObjectModel(); context.getProcessingPipeline().addTransformer( this.transformerName, - source.resolve(mapStack, objectModel), - VariableResolver.buildParameters(this.parameters, mapStack, objectModel), + source.resolve(context, objectModel), + VariableResolver.buildParameters(this.parameters, context, objectModel), this.pipelineHints == null ? Parameters.EMPTY_PARAMETERS - : VariableResolver.buildParameters(this.pipelineHints, mapStack, objectModel) + : VariableResolver.buildParameters(this.pipelineHints, context, objectModel) ); // Check view 1.3 +3 -1 xml-cocoon2/src/java/org/apache/cocoon/components/treeprocessor/variables/NOPVariableResolver.java Index: NOPVariableResolver.java =================================================================== RCS file: /home/cvs/xml-cocoon2/src/java/org/apache/cocoon/components/treeprocessor/variables/NOPVariableResolver.java,v retrieving revision 1.2 retrieving revision 1.3 diff -u -r1.2 -r1.3 --- NOPVariableResolver.java 29 Sep 2002 20:24:22 -0000 1.2 +++ NOPVariableResolver.java 12 Oct 2002 05:11:40 -0000 1.3 @@ -50,6 +50,8 @@ */ package org.apache.cocoon.components.treeprocessor.variables; +import org.apache.cocoon.components.treeprocessor.InvokeContext; + import java.util.List; import java.util.Map; @@ -73,7 +75,7 @@ return this.originalExpr; } - public final String resolve(List mapStack, Map objectModel) { + public final String resolve(InvokeContext context, Map objectModel) { return this.expression; } 1.5 +81 -42 xml-cocoon2/src/java/org/apache/cocoon/components/treeprocessor/variables/PreparedVariableResolver.java Index: PreparedVariableResolver.java =================================================================== RCS file: /home/cvs/xml-cocoon2/src/java/org/apache/cocoon/components/treeprocessor/variables/PreparedVariableResolver.java,v retrieving revision 1.4 retrieving revision 1.5 diff -u -r1.4 -r1.5 --- PreparedVariableResolver.java 8 Oct 2002 17:21:59 -0000 1.4 +++ PreparedVariableResolver.java 12 Oct 2002 05:11:40 -0000 1.5 @@ -58,6 +58,7 @@ import org.apache.avalon.framework.thread.ThreadSafe; import org.apache.cocoon.components.modules.input.InputModule; +import org.apache.cocoon.components.treeprocessor.InvokeContext; import org.apache.cocoon.sitemap.PatternException; import java.util.ArrayList; @@ -66,21 +67,26 @@ /** * Prepared implementation of {@link VariableResolver} for fast evaluation. + * + * @author <a href="mailto:[EMAIL PROTECTED]">Sylvain Wallez</a> + * @author <a href="mailto:[EMAIL PROTECTED]">Torsten Curdt</a> */ -public class PreparedVariableResolver extends VariableResolver implements Disposable { +final public class PreparedVariableResolver extends VariableResolver implements Disposable { private ComponentManager manager; private ComponentSelector selector; - private List items = new ArrayList(); - + final private List items = new ArrayList(); + final private String originalExpr; + // Special constants used for levels static final int ROOT = 0; static final int LITERAL = -1; static final int THREADSAFE_MODULE = -2; static final int STATEFUL_MODULE = -3; - + static final int ANCHOR = -4; + public PreparedVariableResolver(String expr, ComponentManager manager) throws PatternException { this.originalExpr = expr; @@ -128,10 +134,17 @@ addSitemapVariable(variable); } else { - // Module used String module = expr.substring(pos, colon); String variable = expr.substring(colon + 1, end); - addModuleVariable(module, variable); + + if (module.startsWith("#")) { + // anchor syntax refering to a name result level + addAnchorVariable(module.substring(1), variable); + } + else { + // Module used + addModuleVariable(module, variable); + } } } else { // Unprefixed name : sitemap variable @@ -164,7 +177,13 @@ this.items.add(variable.substring(pos)); } } - + + private void addAnchorVariable(String anchor, String variable) throws PatternException { + this.items.add(new Integer(ANCHOR)); + this.items.add(anchor); + this.items.add(variable); + } + private void addModuleVariable(String moduleName, String variable) throws PatternException { if (this.selector == null) { try { @@ -198,7 +217,9 @@ } } - public final String resolve(List mapStack, Map objectModel) throws PatternException { + public final String resolve(InvokeContext context, Map objectModel) throws PatternException { + List mapStack = context.getMapStack(); + StringBuffer result = new StringBuffer(); int stackSize = mapStack.size(); @@ -236,6 +257,24 @@ } break; + case ANCHOR: + { + String name = (String) this.items.get(++i); + Object variable = this.items.get(++i); + Map levelResult = context.getMapByAnchor(name); + + if (levelResult == null) { + throw new PatternException("Error while evaluating '" + this.originalExpr + + "' : no anchor '" + String.valueOf(name) + "' found in context"); + } + + Object value = levelResult.get(variable); + if (value != null) { + result.append(value); + } + } + break; + case THREADSAFE_MODULE : { InputModule module = (InputModule)items.get(++i); @@ -291,41 +330,41 @@ } public final void dispose() { - if (this.selector == null) { - // No module in this expression, or already released - return; - } - - for (int i = 0; i < this.items.size(); i++) { - int type = ((Integer)this.items.get(i)).intValue(); - - switch(type) { - case ROOT : - i++; // variable - break; - - case LITERAL : - i++; // literal string - break; - - case THREADSAFE_MODULE : - i++; // module - this.selector.release((InputModule)this.items.get(i)); - i++; // variable - break; - - case STATEFUL_MODULE : - i += 2; // module name, variable - break; - - default: - // relative sitemap variable - i++; // variable + if (this.selector != null) { + for (int i = 0; i < this.items.size(); i++) { + int type = ((Integer) this.items.get(i)).intValue(); + + switch (type) { + case ROOT: + i++; // variable + break; + + case LITERAL: + i++; // literal string + break; + + case ANCHOR: + i += 2; // anchor name, variable + break; + + case THREADSAFE_MODULE: + i++; // module + this.selector.release((InputModule) this.items.get(i)); + i++; // variable + break; + + case STATEFUL_MODULE: + i += 2; // module name, variable + break; + + default: + // relative sitemap variable + i++; // variable + } } + this.manager.release(this.selector); + this.selector = null; + this.manager = null; } - - this.manager.release(this.selector); - this.selector = null; - this.manager = null; } } 1.3 +10 -9 xml-cocoon2/src/java/org/apache/cocoon/components/treeprocessor/variables/VariableResolver.java Index: VariableResolver.java =================================================================== RCS file: /home/cvs/xml-cocoon2/src/java/org/apache/cocoon/components/treeprocessor/variables/VariableResolver.java,v retrieving revision 1.2 retrieving revision 1.3 diff -u -r1.2 -r1.3 --- VariableResolver.java 29 Sep 2002 20:24:22 -0000 1.2 +++ VariableResolver.java 12 Oct 2002 05:11:40 -0000 1.3 @@ -53,6 +53,7 @@ import org.apache.avalon.framework.parameters.Parameters; import org.apache.cocoon.sitemap.PatternException; import org.apache.cocoon.util.HashUtil; +import org.apache.cocoon.components.treeprocessor.InvokeContext; import java.util.Collections; import java.util.Iterator; @@ -68,7 +69,7 @@ */ public abstract class VariableResolver { - + public static final Map EMPTY_MAP = Collections.unmodifiableMap(new java.util.HashMap(0)); protected String originalExpr = null; @@ -100,7 +101,7 @@ /** * Resolve all {...} patterns using the values given in the list of maps and the object model. */ - public abstract String resolve(List mapStack, Map objectModel) throws PatternException; + public abstract String resolve(InvokeContext context, Map objectModel) throws PatternException; /** * Build a <code>Parameters</code> object from a Map of named <code>VariableResolver</code>s and @@ -108,7 +109,7 @@ * * @return a fully resolved <code>Parameters</code>. */ - public static Parameters buildParameters(Map expressions, List mapStack, Map objectModel) throws PatternException { + public static Parameters buildParameters(Map expressions, InvokeContext context, Map objectModel) throws PatternException { if (expressions == null || expressions.size() == 0) { return Parameters.EMPTY_PARAMETERS; } @@ -119,8 +120,8 @@ while (iter.hasNext()) { Map.Entry entry = (Map.Entry)iter.next(); result.setParameter( - ((VariableResolver)entry.getKey()).resolve(mapStack, objectModel), - ((VariableResolver)entry.getValue()).resolve(mapStack, objectModel) + ((VariableResolver)entry.getKey()).resolve(context, objectModel), + ((VariableResolver)entry.getValue()).resolve(context, objectModel) ); } @@ -133,7 +134,7 @@ * * @return a fully resolved <code>Map</code>. */ - public static Map buildMap(Map expressions, List mapStack, Map objectModel) throws PatternException { + public static Map buildMap(Map expressions, InvokeContext context, Map objectModel) throws PatternException { int size; if (expressions == null || (size = expressions.size()) == 0) { return EMPTY_MAP; @@ -145,8 +146,8 @@ while (iter.hasNext()) { Map.Entry entry = (Map.Entry)iter.next(); result.put( - ((VariableResolver)entry.getKey()).resolve(mapStack, objectModel), - ((VariableResolver)entry.getValue()).resolve(mapStack, objectModel) + ((VariableResolver)entry.getKey()).resolve(context, objectModel), + ((VariableResolver)entry.getValue()).resolve(context, objectModel) ); }
---------------------------------------------------------------------- In case of troubles, e-mail: [EMAIL PROTECTED] To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]