Saturday, October 20, 2012

JSF 2.x Tip of the Day: Programmatically Creating EL MethodExpression

A common need is to create a MethodExpression for use in binding a JSF component action, or actionListener attributes to a value in the JSF/CDI managed beans.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
/**
 * This is a convenience method that parses an expression into a
 * {@link MethodExpression} for later evaluation. Use this method for
 * expressions that refer to methods. If the expression is a {@code String}
 * literal, a {@link MethodExpression} is created, which when invoked,
 * returns the {@code String} literal, coerced to expectedReturnType. An
 * {@link ELException} is thrown if expectedReturnType is {@code void} or if
 * the coercion of the {@code String} literal to the expectedReturnType
 * yields an error. This method should perform syntactic validation of the
 * expression. If in doing so it detects errors, it should raise an
 * {@link ELException}.
 *
 * @param methodExpression The expression to parse.
 * @param expectedReturnType The expected return type for the method to be
 * found. After evaluating the expression, the {@link MethodExpression} must
 * check that the return type of the actual method matches this type.
 * Passing in a value of {@code null} indicates the caller does not care
 * what the return type is, and the check is disabled.
 * @param expectedParamTypes The expected parameter types for the method to
 * be found. Must be an array with no elements if there are no parameters
 * expected. It is illegal to pass {@code null}, unless the method is
 * specified with arguments in the EL expression, in which case these
 * arguments are used for method selection, and this parameter is ignored.
 * @return The parsed expression.
 */
public static MethodExpression createMethodExpression(String methodExpression, Class<?> expectedReturnType, Class<?>[] expectedParamTypes) {
    FacesContext context = FacesContext.getCurrentInstance();
    return context.getApplication().getExpressionFactory()
            .createMethodExpression(context.getELContext(), methodExpression, expectedReturnType, expectedParamTypes);
}
Here is an example of how to use the method. In the example below I use both a ValueExpression and a MethodExpression for clarity. The MethodExpression is bound to a method called sort() in the IndexBean. Since this is bound to the action on the UICommandLink, it is expected that a String is returned which is used for determining navigation. Also note that an empty new Class[]{} array is passed as the expected parameter type.
1
2
3
UICommandLink clink = (UICommandLink) application.createComponent(UICommandLink.COMPONENT_TYPE);
clink.setValueExpression("value", createValueExpression("#{indexBean.columnHeader}", String.class));
clink.setActionExpression(createMethodExpression("#{indexBean.sort()}", String.class, new Class<?>[]{}));

0 comments :

Popular Posts