https://issues.apache.org/bugzilla/show_bug.cgi?id=55792

            Bug ID: 55792
           Summary: Collection literals not recognized within stream
                    lambda expression, result in syntax error
           Product: Tomcat 8
           Version: 8.0.0-RC5
          Hardware: All
                OS: All
            Status: NEW
          Severity: normal
          Priority: P2
         Component: EL
          Assignee: dev@tomcat.apache.org
          Reporter: nicho...@nicholaswilliams.net

I have the following EL expression in a JSP. The expression evaluates and
executes correctly without error:

    ${users.stream()
        .filter(u -> fn:contains(u.username, '1'))
        .sorted((u1, u2) -> (x = u1.lastName.compareTo(u2.lastName);
            x == 0 ? u1.firstName.compareTo(u2.firstName) : x))
        .toList()}

I want to apply the map operation to this as well. Section 2.3.6.4 of the JUEL
3.0 specification uses the following example, where a list-literal is used as
the right-hand side of the mapping lambda expression:

    products.stream().filter(p->p.unitPrice >= 10)
        .map(p->[p.name, p.unitPrice])
        .toList()

So I tried applying the exact same pattern to my map operation (the new map
operation is the only change to the expression):

    ${users.stream()
        .filter(u -> fn:contains(u.username, '1'))
        .sorted((u1, u2) -> (x = u1.lastName.compareTo(u2.lastName);
            x == 0 ? u1.firstName.compareTo(u2.firstName) : x))
        .map(u -> [u.username, u.firstName, u.lastName])
        .toList()}

I also tried using a map-literal:

    ${users.stream()
        .filter(u -> fn:contains(u.username, '1'))
        .sorted((u1, u2) -> (x = u1.lastName.compareTo(u2.lastName);
            x == 0 ? u1.firstName.compareTo(u2.firstName) : x))
        .map(u -> {'username':u.username, 'first':u.firstName,
            'last':u.lastName})
        .toList()}

However, using the list-literal in my map lambda expression results in this
error, indicating that it doesn't recognize the list-literal as a list-literal:

javax.el.ELException: java.lang.NumberFormatException: For input string:
"lastName"
      javax.el.BeanELResolver.invoke(BeanELResolver.java:185)
      org.apache.jasper.el.JasperELResolver.invoke(JasperELResolver.java:147)
      org.apache.el.parser.AstValue.getValue(AstValue.java:158)
      ...

And using the map-literal results in this error, indicating that it doesn't
recognize the map-literal as a map-literal (instead, it thinks the closing
brace of the map-literal is the end of the EL expression:

javax.el.ELException: Failed to parse the expression [${users.stream()
        .filter(u -> fn:contains(u.username, '1'))
        .sorted((u1, u2) -> (x = u1.lastName.compareTo(u2.lastName);
            x == 0 ? u1.firstName.compareTo(u2.firstName) : x))
        .map(u -> {'username':u.username, 'first':u.firstName,
            'last':u.lastName}]
   ...
<root cause>
org.apache.el.parser.ParseException: Encountered "<EOF>" at line 6, column 38.
Was expecting one of:
   "." ...
   ")" ...
   etc...

Putting parentheses around the list- and map-literals does not work, but the
Section 2.3.6.4 example doesn't use parentheses. Section 1.20 also indicates
that collection literals as bodies of lambda expressions are legal:

    customers.select(c->[c.name, c.orders.sum(o->o.total)])

Collection literals are described in more detail in Section 2.2.

-- 
You are receiving this mail because:
You are the assignee for the bug.

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

Reply via email to