I have an EL 3.0 edge case that I need help understanding. Am I doing something 
wrong (I don't think so) or is the Tomcat 8.0 implementation missing something?

Consider the following EL expression:

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

This works as expected. However, it results in potentially evaluating 
u1.lastName.compareTo(u2.lastName) twice. My understanding is that the 
right-hand side of a lambda expression can be any valid EL expression, so I 
believe this should also work:

        ${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()}

However, this doesn't evaluate. I get the following error instead:

org.apache.el.parser.ParseException: Encountered " "=" "= "" at line 3, column 
38.
Was expecting one of:
    "." ...
    ")" ...
    etc ...

Next I tried to reduce the properties present in each user using the stream 
"map" method. Once again, with the understanding that the right-hand side of a 
lambda expression can be any valid EL expression, I use an EL Map literal to 
construct a reduced set of properties:

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

However, that doesn't work and I get this error:

org.apache.el.parser.ParseException: Encountered "<EOF>" at line 3, column 88.
Was expecting one of:
    "." ...
    ")" ...
    etc ...

Section 2.3.6.4 of the 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()

I tried to use this exact syntax, as shown in the spec, with my example:

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

And now I get this lovely error:

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)
        ...

I'm sure I'm doing something wrong here, but I'm not exactly sure what. On the 
other hand, it's possible that the Tomcat 8.0 implementation is just wrong. Can 
someone shed some light on this?

Thanks,

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

Reply via email to