On 29/10/2011 18:37, Thorsten Scherler wrote:
On Sat, 2011-10-29 at 16:39 +0200, Francesco Chicchiriccò wrote:
On 28/10/2011 12:58, Thorsten Scherler wrote:
[...]
Finally, I've also made a fix for passing non-String parameters to ST,
so $if$ is actually doing its job (take a look at cocoon-stringtemplate
unit tests): unfortunately, this does not seem to work for sitemap, so I
preferred not to update StringTemplate samples in cocoon-sample.

Can anyone confirm (and possibly point out where to look, in case) that
sitemap parameters are always cast to String?
/cocoon-sitemap/src/main/java/org/apache/cocoon/sitemap/InvocationImpl.java

resolveParameter(String){
...
  return result.toString();
}

I am not sure if we can change
org.apache.cocoon.sitemap.node.SitemapNode but in that interface we
define:
  void setParameters(Map<String, String>  parameters);
I reckon Map<String, Object>  would the one we are looking for.

Hi,
see attached a patch letting sitemap parameters be actual Objects: check updated StringTemplate samples in cocoon-sample in order to see effective $if$ (finally!) in place.

For the moment I preferred not to commit the attached patch, because it is a quite intrusive change (talking about interfaces, not only implementations). Besides all unit and integration tests defined, I've also made some others by-hand testing, and it *should* work.

Please let me know if you run into any problem and if you think this patch to be committed.

Regards.

--
Francesco Chicchiriccò

Apache Cocoon Committer and PMC Member
http://people.apache.org/~ilgrosso/

Index: cocoon-sitemap/src/main/java/org/apache/cocoon/sitemap/node/GenerateNode.java
===================================================================
--- cocoon-sitemap/src/main/java/org/apache/cocoon/sitemap/node/GenerateNode.java	(revisione 1195412)
+++ cocoon-sitemap/src/main/java/org/apache/cocoon/sitemap/node/GenerateNode.java	(copia locale)
@@ -41,11 +41,18 @@
      * @see org.apache.cocoon.sitemap.node.AbstractSitemapNode#invoke(org.apache.cocoon.sitemap.Invocation)
      */
     @Override
-    public InvocationResult invoke(Invocation invocation) {
-        Map<String, Object> parameters = new HashMap<String, Object>(this.getParameters());
+    public InvocationResult invoke(final Invocation invocation) {
+        final Map<String, Object> parameters =
+                new HashMap<String, Object>(this.getParameters());
         if (this.src != null) {
-            String resolvedSource = invocation.resolveParameter(this.src);
-            parameters.put("source", invocation.resolve(resolvedSource));
+            final Object resolvedSource = invocation.resolveParameter(this.src);
+            if (!(resolvedSource instanceof String)) {
+                throw new IllegalArgumentException(
+                        "Only strings can be resolved as URLs");
+            }
+
+            parameters.put("source",
+                    invocation.resolve((String) resolvedSource));
         }
 
         // set the baseUrl
Index: cocoon-sitemap/src/main/java/org/apache/cocoon/sitemap/node/MatchNode.java
===================================================================
--- cocoon-sitemap/src/main/java/org/apache/cocoon/sitemap/node/MatchNode.java	(revisione 1195412)
+++ cocoon-sitemap/src/main/java/org/apache/cocoon/sitemap/node/MatchNode.java	(copia locale)
@@ -40,7 +40,7 @@
      */
     private static final Logger LOG =
             LoggerFactory.getLogger(MatchNode.class);
-    
+
     @Parameter
     private String name;
 
@@ -78,21 +78,31 @@
      * @see org.apache.cocoon.sitemap.node.AbstractSitemapNode#invoke(org.apache.cocoon.sitemap.Invocation)
      */
     @Override
-    public InvocationResult invoke(Invocation invocation) {
+    public InvocationResult invoke(final Invocation invocation) {
+        final Object resolvedValue = invocation.resolveParameter(this.value);
+//        if (resolvedValue != null && !(resolvedValue instanceof String)) {
+//            throw new IllegalArgumentException(
+//                    "Only strings can be resolved as matches");
+//        }
+
         // try to resolve the test value in the case that it is an expression
-        String testValue = invocation.resolveParameter(this.value);
+        String testValue = resolvedValue == null
+                ? null : resolvedValue.toString();
         if (testValue == null) {
             testValue = invocation.getRequestURI();
-            if (testValue.startsWith("/")) {
+            if (testValue.charAt(0) == '/') {
                 testValue = testValue.substring(1);
             }
         }
 
-        // create the matching context based on the used matching attributes (regexp, equals, etc.)
+        // create the matching context based on the used matching attributes 
+        // (regexp, equals, etc.)
         this.matcherContext = this.lookupMatcherContext();
         if (this.matcherContext == null) {
-            throw new MatchingAttributeException("Use on of the matching attributes: "
-                    + "wildcard, equals, regexp, starts-with, ends-with, contains");
+            throw new MatchingAttributeException(
+                    "Use on of the matching attributes: "
+                    + "wildcard, equals, regexp, starts-with, "
+                    + "ends-with, contains");
         }
 
         this.matches = this.matcherContext.match(testValue);
@@ -103,7 +113,7 @@
 
         // invoke the child nodes
         invocation.pushSitemapParameters(this.name, this.matches);
-        InvocationResult invocationResult = super.invoke(invocation);
+        final InvocationResult invocationResult = super.invoke(invocation);
         invocation.popSitemapParameters();
 
         // check if there has been some processing in the child nodes
@@ -117,7 +127,8 @@
             return InvocationResult.CONTINUE;
         }
 
-        // although this match node has matched, there was no processing in the child nodes
+        // although this match node has matched, there was no processing 
+        // in the child nodes
         return InvocationResult.NONE;
     }
 
@@ -126,43 +137,54 @@
     }
 
     /**
-     * Find out what matching attribute (pattern, wildcard, equals, etc.) is used, check that it's not more than one
+     * Find out what matching attribute (pattern, wildcard, equals, etc.) is 
+     * used, check that it's not more than one
      * that is used and throw an exception otherwise.
      */
     protected MatcherContext lookupMatcherContext() {
-        // determine the matching type and check if there are conflicting match attributes
-        LinkedList<MatcherContext> matcherContextList = new LinkedList<MatcherContext>();
+        // determine the matching type and check if there are conflicting
+        // match attributes
+        final LinkedList<MatcherContext> matcherContextList =
+                new LinkedList<MatcherContext>();
         if (this.pattern != null) {
-            matcherContextList.add(new MatcherContext(new WildcardMatcher(), this.pattern));
+            matcherContextList.add(new MatcherContext(new WildcardMatcher(),
+                    this.pattern));
         }
         if (this.regexp != null) {
-            matcherContextList.add(new MatcherContext(new RegexpMatcher(), this.regexp));
+            matcherContextList.add(new MatcherContext(new RegexpMatcher(),
+                    this.regexp));
         }
         if (this.equals != null) {
-            matcherContextList.add(new MatcherContext(new EqualsMatcher(), this.equals));
+            matcherContextList.add(new MatcherContext(new EqualsMatcher(),
+                    this.equals));
         }
         if (this.contains != null) {
-            matcherContextList.add(new MatcherContext(new ContainsMatcher(), this.contains));
+            matcherContextList.add(new MatcherContext(new ContainsMatcher(),
+                    this.contains));
         }
         if (this.wildcard != null) {
-            matcherContextList.add(new MatcherContext(new WildcardMatcher(), this.wildcard));
+            matcherContextList.add(new MatcherContext(new WildcardMatcher(),
+                    this.wildcard));
         }
         if (this.startsWith != null) {
-            matcherContextList.add(new MatcherContext(new StartsWithMatcher(), this.startsWith));
+            matcherContextList.add(new MatcherContext(new StartsWithMatcher(),
+                    this.startsWith));
         }
         if (this.endsWith != null) {
-            matcherContextList.add(new MatcherContext(new EndsWithMatcher(), this.endsWith));
+            matcherContextList.add(new MatcherContext(new EndsWithMatcher(),
+                    this.endsWith));
         }
         if (matcherContextList.size() > 1) {
-            String message = "Only one matching attribute (regexp, equals, contains, wildcard, pattern) can be set: "
+            String message = "Only one matching attribute (regexp, equals, "
+                    + "contains, wildcard, pattern) can be set: "
                     + matcherContextList;
             LOG.error(message);
             throw new MatchingAttributeException(message);
         }
-        return matcherContextList.isEmpty() ? null : matcherContextList.getFirst();
+        return matcherContextList.isEmpty() ? null
+                : matcherContextList.getFirst();
     }
 
-
     /**
      * {@inheritDoc}
      *
@@ -189,6 +211,7 @@
                 LoggerFactory.getLogger(MatcherContext.class);
 
         private Matcher matcher;
+
         private String expression;
 
         public MatcherContext(Matcher matcher, String expression) {
@@ -198,10 +221,12 @@
         }
 
         public Map<String, String> match(String testValue) {
-            Map<String, String> result = this.matcher.match(this.expression, testValue);
+            Map<String, String> result = this.matcher.match(this.expression,
+                    testValue);
 
             if (LOG.isDebugEnabled()) {
-                String message = "Matching: expression=" + this.expression + ", testValue=" + testValue + ", result="
+                String message = "Matching: expression=" + this.expression
+                        + ", testValue=" + testValue + ", result="
                         + result;
                 LOG.debug(message);
             }
@@ -219,7 +244,7 @@
 
         private static final long serialVersionUID = 1L;
 
-        public MatchingAttributeException(String message) {
+        public MatchingAttributeException(final String message) {
             super(message);
         }
     }
Index: cocoon-sitemap/src/main/java/org/apache/cocoon/sitemap/node/ReadNode.java
===================================================================
--- cocoon-sitemap/src/main/java/org/apache/cocoon/sitemap/node/ReadNode.java	(revisione 1195412)
+++ cocoon-sitemap/src/main/java/org/apache/cocoon/sitemap/node/ReadNode.java	(copia locale)
@@ -50,11 +50,18 @@
      * @see org.apache.cocoon.sitemap.node.AbstractSitemapNode#invoke(org.apache.cocoon.sitemap.Invocation)
      */
     @Override
-    public InvocationResult invoke(Invocation invocation) {
-        Map<String, Object> parameters = new HashMap<String, Object>(this.getParameters());
+    public InvocationResult invoke(final Invocation invocation) {
+        final Map<String, Object> parameters =
+                new HashMap<String, Object>(this.getParameters());
         if (this.src != null) {
-            String resolvedSource = invocation.resolveParameter(this.src);
-            parameters.put("source", invocation.resolve(resolvedSource));
+            final Object resolvedSource = invocation.resolveParameter(this.src);
+            if (!(resolvedSource instanceof String)) {
+                throw new IllegalArgumentException(
+                        "Only strings can be resolved as URLs");
+            }
+
+            parameters.put("source",
+                    invocation.resolve((String) resolvedSource));
         }
 
         // set the baseUrl
Index: cocoon-sitemap/src/main/java/org/apache/cocoon/sitemap/node/TransformNode.java
===================================================================
--- cocoon-sitemap/src/main/java/org/apache/cocoon/sitemap/node/TransformNode.java	(revisione 1195412)
+++ cocoon-sitemap/src/main/java/org/apache/cocoon/sitemap/node/TransformNode.java	(copia locale)
@@ -51,10 +51,18 @@
      */
     @Override
     public InvocationResult invoke(final Invocation invocation) {
-        final Map<String, Object> parameters = new HashMap<String, Object>(this.getParameters());
+        final Map<String, Object> parameters =
+                new HashMap<String, Object>(this.getParameters());
         if (this.src != null) {
-            String resolvedSource = invocation.resolveParameter(this.src);
-            parameters.put("source", invocation.resolve(resolvedSource));
+            final Object resolvedSource = invocation.resolveParameter(this.src);
+            if (!(resolvedSource instanceof String)) {
+                throw new IllegalArgumentException(
+                        "Only strings can be resolved as URLs");
+            }
+
+
+            parameters.put("source",
+                    invocation.resolve((String) resolvedSource));
         }
 
         // set the baseUrl
@@ -74,6 +82,7 @@
      */
     @Override
     public String toString() {
-        return "TransformNode(src=" + this.getParameters().get("src") + ", type=" + this.type + ")";
+        return "TransformNode(src=" + this.getParameters().get("src")
+                + ", type=" + this.type + ")";
     }
 }
Index: cocoon-sitemap/src/main/java/org/apache/cocoon/sitemap/Invocation.java
===================================================================
--- cocoon-sitemap/src/main/java/org/apache/cocoon/sitemap/Invocation.java	(revisione 1195412)
+++ cocoon-sitemap/src/main/java/org/apache/cocoon/sitemap/Invocation.java	(copia locale)
@@ -60,5 +60,5 @@
 
     void popSitemapParameters();
 
-    String resolveParameter(final String parameter);
+    Object resolveParameter(final String parameter);
 }
Index: cocoon-sitemap/src/main/java/org/apache/cocoon/sitemap/SitemapParametersStack.java
===================================================================
--- cocoon-sitemap/src/main/java/org/apache/cocoon/sitemap/SitemapParametersStack.java	(revisione 1195412)
+++ cocoon-sitemap/src/main/java/org/apache/cocoon/sitemap/SitemapParametersStack.java	(copia locale)
@@ -25,88 +25,95 @@
 
 public class SitemapParametersStack {
 
-    private static final Pattern ABSOLUTE_PARAMETER_PATTERN = Pattern.compile("([a-zA-z0-9]+)/(.+)");
+    private static final Pattern ABSOLUTE_PARAMETER_PATTERN =
+            Pattern.compile("([a-zA-z0-9]+)/(.+)");
+
     private static final String RELATIVE_LOCATION_PREFIX = "../";
-    private static final Pattern RELATIVE_PARAMETER_PATTERN = Pattern.compile("(("
-            + Pattern.quote(RELATIVE_LOCATION_PREFIX) + ")*)(.+)");
 
+    private static final Pattern RELATIVE_PARAMETER_PATTERN =
+            Pattern.compile("((" + Pattern.quote(RELATIVE_LOCATION_PREFIX)
+            + ")*)(.+)");
+
     private Stack<Entry> entries = new Stack<Entry>();
 
-    public String getParameter(String parameterName) {
+    public Object getParameter(final String parameterName) {
 
-        Matcher absoluteParameterMatcher = ABSOLUTE_PARAMETER_PATTERN.matcher(parameterName);
+        final Matcher absoluteParameterMatcher =
+                ABSOLUTE_PARAMETER_PATTERN.matcher(parameterName);
         if (absoluteParameterMatcher.matches()) {
-            return this.resolveAbsoluteParameter(parameterName, absoluteParameterMatcher);
+            return this.resolveAbsoluteParameter(parameterName,
+                    absoluteParameterMatcher);
         }
 
-        Matcher relativeParameterMatcher = RELATIVE_PARAMETER_PATTERN.matcher(parameterName);
+        final Matcher relativeParameterMatcher =
+                RELATIVE_PARAMETER_PATTERN.matcher(parameterName);
         if (relativeParameterMatcher.matches()) {
             return this.resolveRelativeParameter(relativeParameterMatcher);
         }
 
-        throw new IllegalArgumentException("Sitemap parameter '" + parameterName + "' is invalid. Valid formats are: '"
-                + ABSOLUTE_PARAMETER_PATTERN.pattern() + "' or '" + RELATIVE_PARAMETER_PATTERN.pattern() + "'");
+        throw new IllegalArgumentException("Sitemap parameter '" + parameterName
+                + "' is invalid. Valid formats are: '"
+                + ABSOLUTE_PARAMETER_PATTERN.pattern() + "' or '"
+                + RELATIVE_PARAMETER_PATTERN.pattern() + "'");
     }
 
     public void popParameters() {
         this.entries.pop();
     }
 
-    public void pushParameters(String name, Map<String, ? extends Object> parameters) {
+    public void pushParameters(final String name,
+            final Map<String, ? extends Object> parameters) {
+
         this.entries.push(new Entry(name, parameters));
     }
 
-    private String resolveAbsoluteParameter(String parameterName, Matcher absoluteParameterMatcher) {
+    private Object resolveAbsoluteParameter(final String parameterName,
+            final Matcher absoluteParameterMatcher) {
+
         final String entryName = absoluteParameterMatcher.group(1);
         final String name = absoluteParameterMatcher.group(2);
 
         for (Entry entry : this.entries) {
             if (entryName.equals(entry.getName())) {
-                Object result = entry.getParameter(name);
-                if (result == null) {
-                    return null;
-                }
-
-                return result.toString();
+                return entry.getParameter(name);
             }
         }
 
         throw new IllegalArgumentException("Sitemap parameter '" + parameterName
-                + "' could not be resolved. There was no entry for the name '" + entryName + "'");
+                + "' could not be resolved. There was no entry for the name '"
+                + entryName + "'");
     }
 
-    private String resolveRelativeParameter(Matcher relativeParameterMatcher) {
+    private Object resolveRelativeParameter(
+            final Matcher relativeParameterMatcher) {
+
         final String levelPrefix = relativeParameterMatcher.group(2);
-        final String name = relativeParameterMatcher.group(3);
-        final int level;
-        if (levelPrefix == null) {
-            level = 0;
-        } else {
-            level = levelPrefix.length() / RELATIVE_LOCATION_PREFIX.length();
-        }
+        final int level = levelPrefix == null
+                ? 0 : levelPrefix.length() / RELATIVE_LOCATION_PREFIX.length();
 
         final int index = this.entries.size() - level - 1;
         if (index < 0) {
-            throw new IllegalArgumentException("Sitemap parameter '" + relativeParameterMatcher.group()
-                    + "' could not be resolved. There are only " + this.entries.size() + " entries available, but "
+            throw new IllegalArgumentException("Sitemap parameter '"
+                    + relativeParameterMatcher.group()
+                    + "' could not be resolved. There are only " + this.entries.
+                    size() + " entries available, but "
                     + level + " entries were requested.");
         }
 
-        Entry entry = this.entries.get(index);
-        Object result = entry.getParameter(name);
-        if (result == null) {
-            return null;
-        }
-
-        return result.toString();
+        final Entry entry = this.entries.get(index);
+        final String name = relativeParameterMatcher.group(3);
+        return entry.getParameter(name);
     }
 
-    private class Entry {
+    private static class Entry {
 
         private String name;
+
         private Map<String, ? extends Object> parameters;
 
-        public Entry(String name, Map<String, ? extends Object> parameters) {
+        public Entry(final String name,
+                final Map<String, ? extends Object> parameters) {
+
             super();
             this.name = name;
             this.parameters = parameters;
@@ -116,7 +123,7 @@
             return this.name;
         }
 
-        public Object getParameter(String parameterName) {
+        public Object getParameter(final String parameterName) {
             return this.parameters.get(parameterName);
         }
     }
Index: cocoon-sitemap/src/main/java/org/apache/cocoon/sitemap/expression/SettingsInterpreter.java
===================================================================
--- cocoon-sitemap/src/main/java/org/apache/cocoon/sitemap/expression/SettingsInterpreter.java	(revisione 1195412)
+++ cocoon-sitemap/src/main/java/org/apache/cocoon/sitemap/expression/SettingsInterpreter.java	(copia locale)
@@ -31,16 +31,17 @@
     @Autowired
     private Settings settings;
 
-    public String resolve(String expression, ObjectModel objectModel) {
-        Object result = null;
+    public Object resolve(final String expression,
+            final ObjectModel objectModel) {
 
+        String result = null;
+
         try {
             result = this.settings.getProperty(expression);
         } catch (Exception e) {
             e.printStackTrace();
         }
 
-        return result != null ? result.toString() : "";
+        return result != null ? result : "";
     }
-
 }
Index: cocoon-sitemap/src/main/java/org/apache/cocoon/sitemap/expression/LanguageInterpreter.java
===================================================================
--- cocoon-sitemap/src/main/java/org/apache/cocoon/sitemap/expression/LanguageInterpreter.java	(revisione 1195412)
+++ cocoon-sitemap/src/main/java/org/apache/cocoon/sitemap/expression/LanguageInterpreter.java	(copia locale)
@@ -20,5 +20,5 @@
 
 public interface LanguageInterpreter {
 
-    String resolve(String expression, ObjectModel objectModel);
+    Object resolve(String expression, ObjectModel objectModel);
 }
Index: cocoon-sitemap/src/main/java/org/apache/cocoon/sitemap/expression/JexlLanguageInterpreter.java
===================================================================
--- cocoon-sitemap/src/main/java/org/apache/cocoon/sitemap/expression/JexlLanguageInterpreter.java	(revisione 1195412)
+++ cocoon-sitemap/src/main/java/org/apache/cocoon/sitemap/expression/JexlLanguageInterpreter.java	(copia locale)
@@ -35,7 +35,7 @@
             LoggerFactory.getLogger(JexlLanguageInterpreter.class);
 
     @Override
-    public String resolve(final String expression,
+    public Object resolve(final String expression,
             final ObjectModel objectModel) {
 
         final JexlEngine jexlEngine = new JexlEngine();
@@ -51,6 +51,6 @@
             LOG.error("While evaluating '" + expression + "'", e);
         }
 
-        return result == null ? "" : result.toString();
+        return result == null ? "" : result;
     }
 }
Index: cocoon-sitemap/src/main/java/org/apache/cocoon/sitemap/expression/SitemapLanguageInterpreter.java
===================================================================
--- cocoon-sitemap/src/main/java/org/apache/cocoon/sitemap/expression/SitemapLanguageInterpreter.java	(revisione 1195412)
+++ cocoon-sitemap/src/main/java/org/apache/cocoon/sitemap/expression/SitemapLanguageInterpreter.java	(copia locale)
@@ -22,7 +22,9 @@
 
 public class SitemapLanguageInterpreter implements LanguageInterpreter {
 
-    public String resolve(String variable, ObjectModel objectModel) {
+    public Object resolve(final String variable,
+            final ObjectModel objectModel) {
+
         return objectModel.getSitemapParameters().getParameter(variable);
     }
 }
Index: cocoon-sitemap/src/main/java/org/apache/cocoon/sitemap/InvocationImpl.java
===================================================================
--- cocoon-sitemap/src/main/java/org/apache/cocoon/sitemap/InvocationImpl.java	(revisione 1195412)
+++ cocoon-sitemap/src/main/java/org/apache/cocoon/sitemap/InvocationImpl.java	(copia locale)
@@ -47,10 +47,11 @@
      * Logger.
      */
     private static final Logger ERROR_LOG =
-            LoggerFactory.getLogger(InvocationImpl.class.getName() 
+            LoggerFactory.getLogger(InvocationImpl.class.getName()
             + "/handle-errors");
 
-    private static final Pattern PARAMETER_PATTERN = Pattern.compile("\\{([a-zA-Z\\-]+):([^\\{]*)\\}");
+    private static final Pattern PARAMETER_PATTERN =
+            Pattern.compile("\\{([a-zA-Z\\-]+):([^\\{]*)\\}");
 
     private List<Action> actions = new LinkedList<Action>();
 
@@ -69,7 +70,7 @@
     private ObjectModel objectModel;
 
     private boolean hasFinisher;
-    
+
     @Autowired
     private Settings settings;
 
@@ -82,7 +83,7 @@
      * @param outputStream The {@link OutputStream} where the result is written
      *            to.
      */
-    public InvocationImpl(OutputStream outputStream) {
+    public InvocationImpl(final OutputStream outputStream) {
         super();
         this.outputStream = outputStream;
     }
@@ -95,7 +96,9 @@
      *            to.
      * @param requestURI The requested path.
      */
-    public InvocationImpl(OutputStream outputStream, String requestURI) {
+    public InvocationImpl(final OutputStream outputStream,
+            final String requestURI) {
+
         super();
         this.outputStream = outputStream;
         this.requestURI = requestURI;
@@ -111,7 +114,9 @@
      * @param parameters A {@link Map} of parameters that are used when the
      *            pipeline is being executed.
      */
-    public InvocationImpl(OutputStream outputStream, String requestURI, Map<String, Object> parameters) {
+    public InvocationImpl(final OutputStream outputStream,
+            final String requestURI, final Map<String, Object> parameters) {
+
         super();
         this.outputStream = outputStream;
         this.requestURI = requestURI;
@@ -133,9 +138,12 @@
      *
      * @see org.apache.cocoon.sitemap.Invocation#execute()
      */
-    public void execute() throws Exception {
+    public void execute()
+            throws Exception {
+
         if (this.pipeline == null) {
-            throw new IllegalStateException("InvocationImpl has been executed without having a pipeline.");
+            throw new IllegalStateException("InvocationImpl has been executed "
+                    + "without having a pipeline.");
         }
 
         // first setup everything
@@ -215,7 +223,8 @@
      */
     public void installAction(String type) {
         if (this.pipeline == null) {
-            throw new IllegalStateException("Action cannot be installed without having a pipeline.");
+            throw new IllegalStateException("Action cannot be installed without"
+                    + " having a pipeline.");
         }
 
         Action action = this.componentProvider.createAction(type);
@@ -228,13 +237,18 @@
      * @see org.apache.cocoon.sitemap.Invocation#installComponent(java.lang.String,
      *      java.util.Map)
      */
-    public void installComponent(String type, Map<String, ? extends Object> componentParameters) {
+    public void installComponent(final String type,
+            final Map<String, ? extends Object> componentParameters) {
+
         if (this.pipeline == null) {
-            throw new IllegalStateException("Pipeline component cannot be installed without having a pipeline.");
+            throw new IllegalStateException("Pipeline component cannot be "
+                    + "installed without having a pipeline.");
         }
 
-        PipelineComponent component = this.componentProvider.createComponent(type);
-        Map<String, ? extends Object> resolvedParameters = this.resolveParameters(componentParameters);
+        final PipelineComponent component =
+                this.componentProvider.createComponent(type);
+        final Map<String, ? extends Object> resolvedParameters =
+                this.resolveParameters(componentParameters);
         component.setConfiguration(resolvedParameters);
         this.pipeline.addComponent(component);
 
@@ -249,9 +263,12 @@
      * @see org.apache.cocoon.sitemap.Invocation#installPipeline(java.lang.String,
      *      java.util.Map)
      */
-    public void installPipeline(String type, Map<String, ? extends Object> componentParameters) {
+    public void installPipeline(final String type,
+            final Map<String, ? extends Object> componentParameters) {
+
         this.pipeline = this.componentProvider.createPipeline(type);
-        Map<String, ? extends Object> resolvedParameters = this.resolveParameters(componentParameters);
+        final Map<String, ? extends Object> resolvedParameters =
+                this.resolveParameters(componentParameters);
         this.pipeline.setConfiguration(resolvedParameters);
     }
 
@@ -279,8 +296,11 @@
      * @see org.apache.cocoon.sitemap.Invocation#pushSitemapParameters(java.lang.String,
      *      java.util.Map)
      */
-    public void pushSitemapParameters(String nodeName, Map<String, ? extends Object> sitemapParameters) {
-        this.objectModel.getSitemapParameters().pushParameters(nodeName, sitemapParameters);
+    public void pushSitemapParameters(final String nodeName,
+            final Map<String, ? extends Object> sitemapParameters) {
+
+        this.objectModel.getSitemapParameters().
+                pushParameters(nodeName, sitemapParameters);
     }
 
     /**
@@ -288,7 +308,7 @@
      *
      * @see org.apache.cocoon.sitemap.Invocation#resolve(java.lang.String)
      */
-    public URL resolve(String resource) {
+    public URL resolve(final String resource) {
         try {
             return new URL(this.baseURL, resource);
         } catch (MalformedURLException e) {
@@ -296,7 +316,9 @@
         }
     }
 
-    public void setComponentProvider(ComponentProvider componentProvider) {
+    public void setComponentProvider(
+            final ComponentProvider componentProvider) {
+
         this.componentProvider = componentProvider;
     }
 
@@ -305,7 +327,7 @@
      *
      * @see org.apache.cocoon.sitemap.Invocation#setOutputStream(java.io.OutputStream)
      */
-    public void setOutputStream(OutputStream outputStream) {
+    public void setOutputStream(final OutputStream outputStream) {
         this.outputStream = outputStream;
     }
 
@@ -314,11 +336,11 @@
      *
      * @see org.apache.cocoon.sitemap.Invocation#setParameters(java.util.Map)
      */
-    public void setParameters(Map<String, Object> parameters) {
+    public void setParameters(final Map<String, Object> parameters) {
         this.parameters = parameters;
     }
 
-    public void setRequestURI(String requestURI) {
+    public void setRequestURI(final String requestURI) {
         this.requestURI = requestURI;
     }
 
@@ -340,11 +362,12 @@
                 }
             }
         }
-        
+
         this.objectModel.getCocoonObject().put("exception", cause);
         ParameterHelper.setThrowable(this.parameters, cause);
 
-        String message = "Error while executing the sitemap. [request-uri=" + this.getRequestURI() + "]";
+        final String message = "Error while executing the sitemap. "
+                + "[request-uri=" + this.getRequestURI() + "]";
         ERROR_LOG.error(message, throwable);
     }
 
@@ -357,51 +380,63 @@
      *
      * @see org.apache.cocoon.sitemap.Invocation#resolveParameter(java.lang.String)
      */
-    public String resolveParameter(final String parameter) {
+    public Object resolveParameter(final String parameter) {
         if (parameter == null) {
             return null;
         }
 
-        final StringBuilder result = new StringBuilder(parameter);
-        final Matcher matcher = PARAMETER_PATTERN.matcher(result);
+        Object result = parameter;
+        final StringBuilder sbResult = new StringBuilder(parameter);
 
+        final Matcher matcher = PARAMETER_PATTERN.matcher(sbResult);
+        final boolean wholeMatch = matcher.matches();
+        matcher.reset();
+
+        String language;
+        LanguageInterpreter interpreter;
+        String variable;
         while (matcher.find()) {
-            final String language = matcher.group(1);
-            final LanguageInterpreter languageInterpreter = this.getLanguageInterpreter(language);
-            if (languageInterpreter == null) {
-                throw new UnsupportedExpressionLanguageException("Could not resolve parameter '" + parameter
-                        + "'. The language '" + language + "' is not supported.");
+            language = matcher.group(1);
+            interpreter = this.getLanguageInterpreter(language);
+            if (interpreter == null) {
+                throw new UnsupportedExpressionLanguageException(
+                        "Could not resolve parameter '" + parameter + "'. "
+                        + "The language '" + language + "' is not supported.");
             }
 
-            final String variable = matcher.group(2);
-            final String replacement = languageInterpreter.resolve(variable, this.objectModel);
+            variable = matcher.group(2);
+            result = interpreter.resolve(variable, this.objectModel);
+            if (result == null) {
+                throw new VariableNotFoundException("Variable {" + language
+                        + ":" + variable + "} not found or is null.");
+            }
 
-            if (replacement != null) {
-                result.replace(matcher.start(), matcher.end(), replacement);
-            } else {
-                throw new VariableNotFoundException("Variable {" + language + ":" + variable
-                        + "} not found or is null.");
+            if (!wholeMatch) {
+                sbResult.replace(matcher.start(), matcher.end(),
+                        result.toString());
+                matcher.reset();
             }
-            matcher.reset();
         }
 
-        return result.toString();
+        return wholeMatch ? result : sbResult.toString();
     }
 
-    private Map<String, ? extends Object> resolveParameters(final Map<String, ? extends Object> componentParameters) {
-        final Map<String, Object> resolvedParameters = new HashMap<String, Object>();
+    private Map<String, ? extends Object> resolveParameters(
+            final Map<String, ? extends Object> componentParameters) {
 
-        for (Map.Entry <String, ? extends Object> entry : 
+        final Map<String, Object> resolvedParameters =
+                new HashMap<String, Object>();
+
+        for (Map.Entry<String, ? extends Object> entry :
                 componentParameters.entrySet()) {
-            if (!(entry.getValue() instanceof String)) {
+
+            if (entry.getValue() instanceof String) {
+                resolvedParameters.put(entry.getKey(),
+                        this.resolveParameter((String) entry.getValue()));
+            } else {
                 // can only resolve strings
                 resolvedParameters.put(entry.getKey(), entry.getValue());
-                continue;
             }
-
-            final String resolvedParameter = 
-                    this.resolveParameter((String) entry.getValue());
-            resolvedParameters.put(entry.getKey(), resolvedParameter);
         }
 
         return resolvedParameters;
@@ -415,11 +450,12 @@
         this.objectModel = objectModel;
     }
 
-    public class UnsupportedExpressionLanguageException extends RuntimeException {
+    public class UnsupportedExpressionLanguageException
+            extends RuntimeException {
 
         private static final long serialVersionUID = 1L;
 
-        public UnsupportedExpressionLanguageException(String msg) {
+        public UnsupportedExpressionLanguageException(final String msg) {
             super(msg);
         }
     }
@@ -428,7 +464,7 @@
 
         private static final long serialVersionUID = 1L;
 
-        public VariableNotFoundException(String msg) {
+        public VariableNotFoundException(final String msg) {
             super(msg);
         }
     }
Index: cocoon-sample/src/main/resources/COB-INF/string-template/template.xml
===================================================================
--- cocoon-sample/src/main/resources/COB-INF/string-template/template.xml	(revisione 1195412)
+++ cocoon-sample/src/main/resources/COB-INF/string-template/template.xml	(copia locale)
@@ -24,5 +24,10 @@
   <body>
     <h3>StringTemplate demo</h3>
     <p>parameter=$parameter$</p>
+$if(booleanParameter)$
+<p>booleanParameter was TRUE</p>
+$else$
+<p>booleanParameter was FALSE</p>
+$endif$
   </body>
 </html>
Index: cocoon-sample/src/main/resources/COB-INF/sitemap.xmap
===================================================================
--- cocoon-sample/src/main/resources/COB-INF/sitemap.xmap	(revisione 1195412)
+++ cocoon-sample/src/main/resources/COB-INF/sitemap.xmap	(copia locale)
@@ -552,6 +552,7 @@
       <map:match wildcard="string-template/generator">
         <map:generate type="string-template" src="string-template/template.xml">
 	  <map:parameter name="parameter" value="A value"/>
+	  <map:parameter name="booleanParameter" value="{jexl:true}"/>
         </map:generate>
         <map:serialize/>
       </map:match>
@@ -559,6 +560,7 @@
         <map:generate src="string-template/template.xml"/>
         <map:transform type="string-template">
 	  <map:parameter name="parameter" value="Another value"/>
+	  <map:parameter name="booleanParameter" value="{jexl:false}"/>
         </map:transform>
         <map:serialize/>
       </map:match>
Index: cocoon-controller/src/main/java/org/apache/cocoon/controller/node/CallNode.java
===================================================================
--- cocoon-controller/src/main/java/org/apache/cocoon/controller/node/CallNode.java	(revisione 1195412)
+++ cocoon-controller/src/main/java/org/apache/cocoon/controller/node/CallNode.java	(copia locale)
@@ -44,10 +44,11 @@
     }
 
     @Override
-    public InvocationResult invoke(Invocation invocation) {
-        Map<String, Object> parameters = new HashMap<String, Object>();
+    public InvocationResult invoke(final Invocation invocation) {
+        final Map<String, Object> parameters = new HashMap<String, Object>();
+        Object resolvedValue;
         for (Entry<String, String> entry : this.getParameters().entrySet()) {
-            String resolvedValue = invocation.resolveParameter(entry.getValue());
+            resolvedValue = invocation.resolveParameter(entry.getValue());
             parameters.put(entry.getKey(), resolvedValue);
         }
 
Index: cocoon-servlet/src/main/java/org/apache/cocoon/servlet/collector/ResponseHeaderCollector.java
===================================================================
--- cocoon-servlet/src/main/java/org/apache/cocoon/servlet/collector/ResponseHeaderCollector.java	(revisione 1195412)
+++ cocoon-servlet/src/main/java/org/apache/cocoon/servlet/collector/ResponseHeaderCollector.java	(copia locale)
@@ -23,6 +23,7 @@
 import org.apache.cocoon.pipeline.caching.CacheKey;
 import org.apache.cocoon.pipeline.component.PipelineComponent;
 import org.apache.cocoon.sitemap.Invocation;
+import org.apache.cocoon.sitemap.InvocationImpl;
 import org.apache.cocoon.sitemap.node.InvocationResult;
 import org.apache.cocoon.sitemap.node.SerializeNode;
 import org.aspectj.lang.ProceedingJoinPoint;
@@ -106,12 +107,14 @@
     @Around("execution(* org.apache.cocoon.sitemap.node.SerializeNode.invoke(..)) && args(invocation)")
     public Object interceptInvoke(ProceedingJoinPoint proceedingJoinPoint, Invocation invocation) throws Throwable {
         SerializeNode target = (SerializeNode) proceedingJoinPoint.getTarget();
-        String statusCode = invocation.resolveParameter(target.getParameters().get("status-code"));
+        Object statusCode = invocation.resolveParameter(target.getParameters().get("status-code"));
+        if (statusCode != null && !(statusCode instanceof String))
+                throw new IllegalArgumentException("Status code must resolve to String");
 
         InvocationResult invocationResult = (InvocationResult) proceedingJoinPoint.proceed();
         if (invocationResult.isContinued() && statusCode != null) {
             try {
-                setStatusCode(Integer.valueOf(statusCode));
+                setStatusCode(Integer.valueOf((String) statusCode));
             } catch (NumberFormatException nfe) {
                 throw new InvalidStatusCodeException("The status-code '" + statusCode + " is not valid number.", nfe);
             }

Reply via email to