I have proposed the following API for mapping static methods to EL
functions in ELProcessor:
/*
* Define an EL function.
* @param prefix The prefix of the function, or "" if prefix not used.
* @param localName The short name of the function.
* @param className The name of the Java class that implements the
function
* @param method The name (without the parenthesis) or the signature
* (as in the Java Language Spec) of the method that implements the
* function. If the name (e.g. "sum") is given, the first declared
* method in class that matches the name is selected. If the
signature
* (e.g. "int sum(int, int)" ) is given, then the declared method
* with the signature is selected.
*
* @throws ClassNoFoundException if the specified class does not
exists.
* @throws NoSuchMethodException if the method (with or without the
* signature) is not a declared method of the class, or if the
method
* signature is not valid.
*/
public void defineFunction(String prefix, String localName,
String className,
String method)
throws ClassNotFoundException, NoSuchMethodException
The intend is to provide a way to define EL functions without the need
for configurations, such the the TLD in JSP. That's why the parameters
in this method directly corresponds to the entries in the TLD.
This provides an alternate way to invoke the static methods directly in
the EL expressions. It also allows an user to specify the exact method,
using the method signature. This is something that cannot be done in
direct method calls in EL expressions.
I think most user would also not bother with the prefix, or even with a
localName different from the method name. I am thinking of combining
the pefix with the localName into a single parameter:
/*
* Define an EL function.
* @param function The name of the function, with optional
namespace prefix
* (e.g "ps:func"). If null or empty (""), it is defaulted to
the method name.
* @param className The name of the Java class that implements the
function
* @param method The name (without the parenthesis) or the signature
* (as in the Java Language Spec) of the method that implements the
* function. If the name (e.g. "sum") is given, the first declared
* method in the class that matches the name is selected. If
the signature
* (e.g. "int sum(int, int)" ) is given, then the declared method
* with the signature is selected.
*
* @throws ClassNoFoundException if the specified class does not
exists.
* @throws NoSuchMethodException if the method (with or without the
* signature) is not a declared method of the class, or if the
method
* signature is not valid.
*/
public void defineFunction(String function,
String className,
String method)
throws ClassNotFoundException, NoSuchMethodException
Note this API also allows a method to be specified by just the name,
without the signature. This is is something that cannot be done in a
TLD, but is probably what an user would most likely use, for methods
that are not overloaded. For overloaded methods, the method selection
algorithm used here is a simple one: just pick the first one. This is
different from the algorithm used for resolving overloaded methods when
invoked directly in EL expressions. I have no choice here, because
functions in EL 2.2 are "mapped, resolved, and bound at parse time" (EL
1.15). Even with such inconsistencies, this is still useful.
Comments?
Kin-man