duminică, 25 ianuarie 2015

Programmatically Inspect a ValueExpression Using OmniFaces

OmniFaces comes with an entire package dedicated to manipulate EL artifacts, named org.omnifaces.el. In this post, I will focus on a class named ExpressionInspector, which can be very useful when you need to programmatically inspect a ValueExpression. One of the most important method of this class is named, getMethodReference(), and, as its name suggest, it gets a MethodReference from a ValueExpression. If the ValueExpression refers to a method, this will contain the actual method. If it refers to a property, this will contain the corresponding getter method. Via the MethodReference, we have access to several information as follows:

·         MethodReference#getBase() - Returns the base of the EL method expression. Usually, this is the backing bean on which the method behind MethodReference#getMethod() should be invoked.
·         MethodReference#getMethod() - Returns the concrete java.lang.reflect.Method instance of the EL method expression. Usually, this is a method of the class behind getBase().
·         MethodReference#getActualParameters() - Returns the actual (evaluated) parameters of the method call. If there are no params, then this returns an empty array, never null. Those should be passed to Method#invoke(Object, Object...).
·         MethodReference#isFromMethod() - Returns true if this method reference is from an actual method call and not from a getter of a property.
·         MethodReference#getMethodInfo() - Returns the standard EL MethodInfo of the MethodExpression where this MethodReference has been extracted from.

In order to have some examples, we apply the below code to several ValueExpressions:

import org.omnifaces.el.ExpressionInspector;
import org.omnifaces.el.MethodReference;
import org.omnifaces.util.Faces;
...
ELContext elc = Faces.getELContext();
ValueExpression ve = getValueExpression("value");
       
System.out.println("-------------------------ExpressionInspector------------------------------");
System.out.println("getValueExpression(\"value\"): " + ve);
MethodReference methodReference = ExpressionInspector.getMethodReference(elc, ve);
System.out.println("MethodReference#getBase(): " + methodReference.getBase());
System.out.println("MethodReference#getMethod(): " + methodReference.getMethod());
System.out.println("MethodReference#getMethodInfo()#getName(): " + methodReference.getMethodInfo().getName());
System.out.println("MethodReference#getMethodInfo()#getReturnType(): " + methodReference.getMethodInfo().getReturnType());
System.out.println("MethodReference#getMethodInfo()#getParamTypes(): ");
Class<?>[] paramTypes = methodReference.getMethodInfo().getParamTypes();
for (Class paramType : paramTypes) {
     System.out.println("Parameter info:\n name:" + paramType.getName() + ", simple name: " + paramType.getSimpleName() + ", type:" + paramType.getTypeName());
}
System.out.println("MethodReference#getActualParameters(): ");
Object[] actualParams = methodReference.getActualParameters();
for (Object actualParam : actualParams) {
     System.out.println("Actual parameter: " + actualParam);
}
System.out.println("MethodReference#isFromMethod(): " + methodReference.isFromMethod());
System.out.println("--------------------------------------------------------------------------");


·         in the first case we have a simple managed bean (PlayerBean) with a field, named atp. The inspected ValueExpression will be: #{playerBean.atp}. See below figure:


Output:
-------------------------ExpressionInspector-------------------------------

getValueExpression("value"): /index.xhtml @14,56 value="#{playerBean.atp}"
MethodReference#getBase(): atp.singles.PlayerBean@3b45398a
MethodReference#getMethod(): public java.lang.String atp.singles.PlayerBean.getAtp()
MethodReference#getMethodInfo()#getName(): getAtp
MethodReference#getMethodInfo()#getReturnType(): class java.lang.String
MethodReference#getMethodInfo()#getParamTypes():
MethodReference#getActualParameters():
MethodReference#isFromMethod(): false

---------------------------------------------------------------------------

·         next, we inspect a ValueExpression that point out a field encapsulated in another field.  The inspected ValueExpression will be: #{playerBean.player.name}. See below figure:


Output:
--------------------------ExpressionInspector-------------------------------

getValueExpression("value"): /index.xhtml @14,64 value="#{playerBean.player.name}"
MethodReference#getBase(): atp.singles.Player@5a268b
MethodReference#getMethod(): public java.lang.String atp.singles.Player.getName()
MethodReference#getMethodInfo()#getName(): getName
MethodReference#getMethodInfo()#getReturnType(): class java.lang.String
MethodReference#getMethodInfo()#getParamTypes():
MethodReference#getActualParameters():
MethodReference#isFromMethod(): false

Info:   ----------------------------------------------------------------------------

·         further, we inspect an ValueExpression that points out a managed bean method (not a getter) without arguments  that returns a String. The inspected ValueExpression will be: #{playerBean.uppercasePlayer()}. See below figure:


Output:
--------------------------ExpressionInspector-------------------------------

getValueExpression("value"): /index.xhtml @14,70 value="#{playerBean.uppercasePlayer()}"
MethodReference#getBase(): atp.singles.PlayerBean@5d8b700b
MethodReference#getMethod(): public java.lang.String atp.singles.PlayerBean.uppercasePlayer()
MethodReference#getMethodInfo()#getName(): uppercasePlayer
MethodReference#getMethodInfo()#getReturnType(): class java.lang.String
MethodReference#getMethodInfo()#getParamTypes():
MethodReference#getActualParameters():
MethodReference#isFromMethod(): true

----------------------------------------------------------------------------

·         finally, we inspect a ValueExpression representing a call of a managed bean method that receive two arguments and returns. The inspected ValueExpression will be: #{playerBean.changeRank(2, 5)}. See below figure:


Output:
--------------------------ExpressionInspector-------------------------------

getValueExpression("value"): /index.xhtml @14,69 value="#{playerBean.changeRank(2, 5)}"
MethodReference#getBase(): atp.singles.PlayerBean@253bf759
MethodReference#getMethod(): public atp.singles.Rank atp.singles.PlayerBean.changeRank(int,int)
MethodReference#getMethodInfo()#getName(): changeRank
MethodReference#getMethodInfo()#getReturnType(): class atp.singles.Rank
MethodReference#getMethodInfo()#getParamTypes():
  Parameter info:
  name:int, simple name: int, type:int
  Parameter info:
  name:int, simple name: int, type:int
MethodReference#getActualParameters():
  Actual parameter: 2
  Actual parameter: 5
MethodReference#isFromMethod(): true

Info:   ----------------------------------------------------------------------------

Enjoy!

Niciun comentariu:

Trimiteți un comentariu