ADF Code Corner: 003. Advanced Expression Language Techniques
ADF Code Corner: 003. Advanced Expression Language Techniques
Expression Language is a dot notated scripting format that allows you to access in memory and Java objects. In JavaServer Faces, you use Expression Language to to bind UI components to managed beans or to the Oracle ADF binding layer. Using EL from a page or page fragment in Oracle JDeveloper 11g is as easy as opening the Expression Builder dialog to select the object to reference. However, usecases exist that need you to work with Expression Language in Java. For example, developers that create JavaServer Faces component instances dynamically at runtime need to apply Expression Language to the component to access the binding layer to read or write data. This blog article focuses on how to work with Expression Language in Java.
twitter.com/adfcodecorner Author: Frank Nimphius, Oracle Corporation twitter.com/fnimphiu 21-MAY-2009
Oracle ADF Code Corner is a loose blog-style series of how-to documents that provide solutions to real world coding problems. Disclaimer: All samples are provided as is with no guarantee for future upgrades or error correction. No support can be given through Oracle customer support. Please post questions or report problems related to the samples in this series on the OTN forum for Oracle JDeveloper: http://forums.oracle.com/forums/forum.jspa?forumID=83
Introduction
Before getting started with the topic, using Expression Language in Java should be an exception. There are use cases in ADF that require EL to be used in Java. For exmple, the "row" variable that is used to populate a table with data is only accessible in EL. So to implement conditional row formatting when the table renders, you must use EL to access the current row values. Another usecase that requires EL in Java is to programmatically create a method binding on a component. Accessing the ADF binding layer from Expression Language also is ..... not a good usecase. You can access the binding layer from the BindingContext object, which provides a native Java access. This blog entry is a take out from the Oracle Press "Oracle Fusion Developer Guide: Building Rich Internet Applications with Oracle ADF Business Components and ADF Faces" book that Lynn Munsinger and I wrote for McGraw Hill.
Advanced EL techniques
There exist two types of expressions in EL value expressions and method expressions. Value expressions address a bean property, expecting the provided expression to resolve to a valid pair of getter and setter methods. Method expressions reference methods that are exposed on an EL accessible object. The following classes are used when working with expressions from Java in JavaServer Faces ELContext The ELContext class is used as an argument to the ExpressionFactory class methods to create value and method bindings. It also exposes the ELResolver instance, which can be used to resolve model properties. JSF uses the ELResolver instance to resolve references like #{managedBean.firstname}. To access an instance of ELContext from a managed bean in JSF, you use
FacesContext fctx = FacesContext.getCurrentInstance(); ELContext elctx = fctx.getELContext();
FacesContext fctx = FacesContext.getCurrentInstance(); ELContext elctx = fctx.getELContext(); Application application = fctx.getApplication(); ExpressionFactory exprFactory = application.getExpressionFactory(); ValueExpression valueExpr = exprFactory.createValueExpression( elctx, "#{bindings.DepartmentId.inputValue}", Object.class); oracle.jbo.domain.Number departmentId = null; departmentId = (oracle.jbo.domain.Number) valueExpr.getValue(elctx);
Using ADF Business Components as a business service, the ADF binding reference returns oracle.jbo.domain object types for attributes that use ADF Business Component special types like Number, Date and DBSequence. To write a value back to the binding layer, use the setValue method of the ValueExpression.
valueExpr.setValue(elctx, <object>);
Note: You can access the ADF binding layer without using EL. For this call BindingContext.getCurrent() and getCurrentBindingsEntry(). You can then access all bindings by their ID. Personally, I prefer using the BindingContext object as it means less code to write.
To dynamically reference this action from an existing command component, or a newly created component, use the following code below, assuming the handle to the command component instance is commandButton
FacesContext fctx = FacesContext.getCurrentInstance(); ELContext elctx = fctx.getELContext(); Application application = fctx.getApplication(); ExpressionFactory exprFactory = application.getExpressionFactory(); //Create method expression that expects an ActionEvent argument to //be passed in MethodExpression methodExpr = null; methodExpr = exprFactory.createMethodExpression( elctx, "#{CustomBean.handleButtonPressed}", null, new Class[] {ActionEvent.class}); //Create a new ActionListener based on a method expression MethodExpressionActionListener actionListener = null; actionListener = new MethodExpressionActionListener(methodExpr); //add listener to the commandButton instance commandButton.addActionListener(actionListener);
Similar, to add a ValueChangeListener to an input component, like InputText, that invokes the handleValueChange method in a managed bean to handle the value change event
MethodExpression methodExpr = null;