eclipse-ee4j / expressly

Expressly, a Jakarta Expression Language implementation
Other
10 stars 6 forks source link

Support of static functions with varargs #11

Open ishegelman opened 1 year ago

ishegelman commented 1 year ago

Expression Language API allows one to use a FunctionMapper to register a static function mapped to a Method. For example, ${str:format(...)} could be mapped to String.format() function.

However, this does not work for methods with varargs. Thus, evaluation of ${str:format('%s%s', 'a', 'b')} fails with:

jakarta.el.ELException: Function 'str:format' specifies 2 params, but 3 were supplied

    at org.glassfish.expressly.lang.ExpressionBuilder.visit(ExpressionBuilder.java:244)
    at org.glassfish.expressly.parser.SimpleNode.accept(SimpleNode.java:157)
    at org.glassfish.expressly.lang.ExpressionBuilder.prepare(ExpressionBuilder.java:195)
    at org.glassfish.expressly.lang.ExpressionBuilder.build(ExpressionBuilder.java:206)
    at org.glassfish.expressly.lang.ExpressionBuilder.createValueExpression(ExpressionBuilder.java:255)
    at org.glassfish.expressly.ExpressionFactoryImpl.createValueExpression(ExpressionFactoryImpl.java:95)

By contrast, varargs methods are supported for Java Beans. If "str" was registered as a String bean, then the following expression would work (note the '.' instead of the ':'): ${str.format('%s%s', 'a', 'b')}.

There are two issues in expressly code:

  1. org.glassfish.expressly.parser.AstFunction.getValue() contains a loop that coerces function arguments to the proper method parameter data types. This loop does not handle varargs. Instead, you may consider using jakarta.el.ELUtil.buildParameters() which does support varargs.
  2. org.glassfish.expressly.lang.ExpressionBuilder.visit() compares the number of provided function arguments to the number of parameters of the method implementing this function. This logic does not consider variable number of arguments for varargs methods.