Author: markt
Date: Wed Jul 17 13:24:09 2013
New Revision: 1504123

URL: http://svn.apache.org/r1504123
Log:
Further improve handling of nested lambda expressions.

Modified:
    tomcat/trunk/java/org/apache/el/Messages.properties
    tomcat/trunk/java/org/apache/el/parser/AstLambdaExpression.java
    tomcat/trunk/test/org/apache/el/parser/TestAstLambdaExpression.java

Modified: tomcat/trunk/java/org/apache/el/Messages.properties
URL: 
http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/el/Messages.properties?rev=1504123&r1=1504122&r2=1504123&view=diff
==============================================================================
--- tomcat/trunk/java/org/apache/el/Messages.properties (original)
+++ tomcat/trunk/java/org/apache/el/Messages.properties Wed Jul 17 13:24:09 2013
@@ -52,3 +52,4 @@ error.context.null=ELContext was null
 
 # Parser
 error.identifier.notjava=The identifier [{0}] is not a valid Java identifier 
as required by section 1.19 of the EL specification (Identifier ::= Java 
language identifier). This check can be disabled by setting the system property 
org.apache.el.parser.SKIP_IDENTIFIER_CHECK to true.
+error.lambda.tooManyMethodParameterSets=There are more sets of method 
parameters specified than there are nested lambda expressions

Modified: tomcat/trunk/java/org/apache/el/parser/AstLambdaExpression.java
URL: 
http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/el/parser/AstLambdaExpression.java?rev=1504123&r1=1504122&r2=1504123&view=diff
==============================================================================
--- tomcat/trunk/java/org/apache/el/parser/AstLambdaExpression.java (original)
+++ tomcat/trunk/java/org/apache/el/parser/AstLambdaExpression.java Wed Jul 17 
13:24:09 2013
@@ -25,6 +25,7 @@ import javax.el.LambdaExpression;
 
 import org.apache.el.ValueExpressionImpl;
 import org.apache.el.lang.EvaluationContext;
+import org.apache.el.util.MessageFactory;
 
 public class AstLambdaExpression extends SimpleNode {
 
@@ -35,6 +36,24 @@ public class AstLambdaExpression extends
     @Override
     public Object getValue(EvaluationContext ctx) throws ELException {
 
+        // Check that there are not more sets of method parameters than there
+        // are nested lambda expressions
+        int methodParameterSetCount = jjtGetNumChildren() - 2;
+        if (methodParameterSetCount > 0) {
+            // We know this node is an expression
+            methodParameterSetCount--;
+            Node n = this.jjtGetChild(1);
+            while (methodParameterSetCount > 0) {
+                if (n.jjtGetNumChildren() <2 ||
+                        !(n.jjtGetChild(0) instanceof AstLambdaParameters)) {
+                    throw new ELException(MessageFactory.get(
+                            "error.lambda.tooManyMethodParameterSets"));
+                }
+                n = n.jjtGetChild(1);
+                methodParameterSetCount--;
+            }
+        }
+
         // First child is always parameters even if there aren't any
         AstLambdaParameters formalParametersNode =
                 (AstLambdaParameters) children[0];
@@ -54,16 +73,22 @@ public class AstLambdaExpression extends
         LambdaExpression le = new LambdaExpression(formalParameters, ve);
         le.setELContext(ctx);
 
-        if (formalParameters.isEmpty()) {
+        if (formalParameters.isEmpty() && jjtGetNumChildren() == 2) {
             // No formal parameters - invoke the expression
             return le.invoke(ctx, (Object[]) null);
         }
 
         // If there are method parameters, need to invoke the expression with
-        // those parameters. If there are multiple method parameters there
-        // should be that many nested expressions.
-        // If there are more nested expressions that parameters this will 
return
-        // a LambdaExpression
+        // those parameters. If there are multiple sets of method parameters
+        // there should be at least that many nested expressions.
+        // If there are more nested expressions than sets of method parameters
+        // this may return a LambdaExpression.
+        // If there are more sets of method parameters than nested expressions
+        // an ELException will have been thrown by the check at the start of
+        // this method.
+        // If the inner most expression(s) do not require parameters then a
+        // value will be returned once the outermost expression that does
+        // require a parameter has been evaluated.
         Object result = le;
         int i = 2;
         while (result instanceof LambdaExpression && i < jjtGetNumChildren()) {
@@ -72,10 +97,6 @@ public class AstLambdaExpression extends
             i++;
         }
 
-        if (i < jjtGetNumChildren()) {
-            throw new ELException();
-        }
-
         return result;
     }
 }

Modified: tomcat/trunk/test/org/apache/el/parser/TestAstLambdaExpression.java
URL: 
http://svn.apache.org/viewvc/tomcat/trunk/test/org/apache/el/parser/TestAstLambdaExpression.java?rev=1504123&r1=1504122&r2=1504123&view=diff
==============================================================================
--- tomcat/trunk/test/org/apache/el/parser/TestAstLambdaExpression.java 
(original)
+++ tomcat/trunk/test/org/apache/el/parser/TestAstLambdaExpression.java Wed Jul 
17 13:24:09 2013
@@ -16,6 +16,7 @@
  */
 package org.apache.el.parser;
 
+import javax.el.ELException;
 import javax.el.ELProcessor;
 
 import org.junit.Assert;
@@ -74,4 +75,53 @@ public class TestAstLambdaExpression {
                         Integer.class);
         Assert.assertEquals(Integer.valueOf(1), result);
     }
+
+
+    @Test
+    public void testInvocation01() {
+        ELProcessor processor = new ELProcessor();
+        Object result =
+                processor.getValue("(()->2)()",
+                        Integer.class);
+        Assert.assertEquals(Integer.valueOf(2), result);
+    }
+
+
+    @Test
+    public void testNested01() {
+        ELProcessor processor = new ELProcessor();
+        Object result =
+                processor.getValue("(()->y->2-y)()(1)",
+                        Integer.class);
+        Assert.assertEquals(Integer.valueOf(1), result);
+    }
+
+
+    @Test
+    public void testNested02() {
+        ELProcessor processor = new ELProcessor();
+        Object result =
+                processor.getValue("(()->y->()->2-y)()(1)()",
+                        Integer.class);
+        Assert.assertEquals(Integer.valueOf(1), result);
+    }
+
+
+    @Test(expected=ELException.class)
+    public void testNested03() {
+        ELProcessor processor = new ELProcessor();
+        // More method parameters than there are nested lambda expressions
+        processor.getValue("(()->y->()->2-y)()(1)()()",
+                    Integer.class);
+    }
+
+
+    @Test(expected=ELException.class)
+    public void testNested04() {
+        ELProcessor processor = new ELProcessor();
+        Object result =
+                processor.getValue("(()->y->()->x->x-y)()(1)()(2)",
+                        Integer.class);
+        Assert.assertEquals(Integer.valueOf(1), result);
+    }
 }



---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscr...@tomcat.apache.org
For additional commands, e-mail: dev-h...@tomcat.apache.org

Reply via email to