myfaces-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Apache Wiki <wikidi...@apache.org>
Subject [Myfaces Wiki] Update of "Parameters In EL Functions" by SimonKitching
Date Thu, 12 Apr 2007 23:04:24 GMT
Dear Wiki user,

You have subscribed to a wiki page or wiki category on "Myfaces Wiki" for change notification.

The following page has been changed by SimonKitching:
http://wiki.apache.org/myfaces/Parameters_In_EL_Functions

------------------------------------------------------------------------------
  ## page was renamed from Parameters In EL
  ##language:en
  == How to pass parameters in an EL expression function ==
- To pass a parameter to a method inside an el expression, extend the 
- {{{DummyMap}}} class (below) and implement the get(Object obj) method to 
- pass obj as a parameter to that method.
  
- note - if you're using facelets, you can simply create a real changeToUpperCase() user-defined
el function.
+ When using Facelets or JSF1.2/JSP2.1, creating a user-defined function that can be invoked
from an EL expression is simple.
  
+ However when using JSF1.1/JSP2.0, there is no direct support for user-defined functions
or parameters. There are a couple of ways of doing this, however:
+  1. If you are willing to use a !MyFaces-specific solution then a custom !FunctionMapper
can be registered.
+  2. A portable (but less flexible) solution is to take advantage of the fact that EL supports
Maps: when evaluating "foo.bar" or "foo['bar']", if foo is a Map then foo.get("bar") is invoked.
It is therefore possible to write a method that takes a single parameter by implementing that
method as the get(key) method of a Map.
+ 
+ == FunctionMapper Solution ==
+ 
+ While JSP EL expressions allow access to functions, JSF expressions are only supposed to
support access to bean properties. The !MyFaces code is nicely
+ designed to be extensible, however; it calls a standard el !FunctionMapper instance to resolve
any functions found in el-expressions, then provides a default
+ implementation that just throws an exception from its resolveFunction method (ie complies
with the JSF spec requirements). Implementing real functions
+ within JSF EL expression with !MyFaces is therefore simply a matter of writing an alternate
implementation that implements resolveFunction appropriately,
+ and installing it as the !FunctionMapper to use.
+ 
+ First, create a subclass of !ValueBindingImpl in order to modify static variable s_functionMapper.
This can only be done from a subclass as it
+ is not a public variable. Of course something needs to force this class to be loaded at
app startup.
+ {{{
+ public class MyValueBindingImpl extends org.apache.myfaces.el.ValueBindingImpl {
+     static {
+         // Set up our own function mapper to add support for custom
+         // functions in JSF expressions, by overriding the member defined in
+         // the parent class.
+         s_functionMapper = new MyFunctionMapper();
+     }
+ }
+ }}}
+ 
+ Now define the !MyFunctionMapper class to extend javax.servlet.jsp.el.!FunctionMapper and
implement the resolveFunction method (which returns a
+ Method object). The standard EL implementation will then handle mapping parameters from
the EL expression into the parameters required by the
+ returned Method object.
+ 
+ Beware, however, of the fact that s_functionMapper is a *static* variable. If your MyFaces
library is in a shared directory then this will have a global effect across all webapps that
share that same Class instance. It might also cause problems (memory leaks) with webapp unloads.
However smarter variants of this idea which solve these issues can probably be created.
+ 
+ == Map Solution ==
  
  === Example ===
  As a trivial example, to pass a parameter to the changeToUpperCase() method, the get() method
takes the String, testBean.widget here, as a parameter and calls changeToUpperCase() with
that parameter.

Mime
View raw message