The Black Bean Source™
User Guide for EL-Functors 1.0.2

Expression Syntax

The detailed functor expression syntax is described in this section.

Configuration

The string values used to identify property names as functor references are configurable through servlet-context parameters set in the web.xml descriptor.

Context Parameter Name Default Value Description
beanface.el.functor.FunctorIdicator $ The string used to identify a property as a functor (rather than a standard bean property). The default value of $ has the advantage of being a legal part of a Java identifier, but not normally part of a bean property name. Any value can be used, but if it also occurs in bean property names it could shadow those properties and prevent them from being directly accessed. If characters that are not a legal part of a java identifier are used (eg '@'), then any EL expressions will have to use the [] syntax rather than the . syntax (eg: ${mybean['myMethod@'][a][b]} rather than ${mybean.myMethod$[a][b]}).
beanface.el.functor.DeferredIdicator _ Suffix used to identify a functor as deferred. A normal functor invokes the target method as soon as an appropriate number of parameters have been applied. A deferred functor doesn't immediately invoke the method, allowing one of the functor's own methods to be referenced in an EL method expression. eg: action="#{mybean.someaction$[extraParam1].action}. This allows extra parameters to be passed in addition to what the method expression usually specifies.
beanface.el.functor.ImplicitClassObjectName class The name of the implicit object used to initiate references to static methods (via fully qualified class names). eg: #{class.java.util.Collections.unmodifiableList$[mylist]}
beanface.el.functor.ConstructorName new The name used to refer to constructors of a class, to allow creation of new instances through functors. eg: #{class.java.net.URL.new$1['http://java.sun.com/']}

In most cases there should be no need to override the default values, and these values are assumed in all the examples that follow.

Dynamic Methods

For basic method references (eg. ${mypattern.matcher$[params.input].matches$}), the number of parameters is determined by the method name. However, there can also be overloaded methods with the same name and differing number of parameters, or methods that use the var-args syntax. In this case, the number of parameters is ambiguous, and can be specified by adding a number after the functor indicator ($). For example: ${someStr.substring$1[3]}.

Static Methods

Static methods are invoked by introducing a reference to the fully qualified Java class name, then specifying a method using the same syntax as for dynamic methods. For example, ${class.java.math.BigInteger.valueOf$[42]}.

Final Static Fields

Constant values (final static fields) from classes can be accessed through the same fully qualified Java class name reference that is used for static methods. For example, ${class.java.math.BigInteger.ONE}.

As a special case, class is supported as a pseudo-static field, so ${class.java.math.BigInteger.class} will resolve to the java.math.BigInteger class object. This allows expressions such as ${class.java.util.Collection.class.isInstance$[it.value]} to test whether it.value is an instance of java.util.Collection

Constructors

A constructor is invoked by treating it as a psuedo-static method called new in the class to be constructed. For example, ${class.java.net.URL.new$1["http://nowhere.net/"]}.

Java Server Faces deferred method references

The EL provides support for deferred method expressions, where all components but the last resolve to an object, and the final component identifies a method on that object (with a specified type signature). JavaServer Faces uses these deferred method expressions for action and validation references on tags.

Using the EL-Functors resolver, a reference to a method taking 2 parameters can be converted to a reference to a function taking no parameters (for example) by applying two parameters. By adding the deferred indicator (_) to the functor identifier, the automatic invocation of the method (when the appropriate number of parameters has been supplied) is suppressed, so the final functor can be used in an EL method expression.

Three method signatures are currently supported:

  1. String action() allows any method to be converted to an action method by supplying any needed parameters first. The result of the action will be the return value of the method when it is invoked, converted to a String. For example #{myMap.put$_[key][value].action} will create an action that puts the value into the map if invoked.
  2. void validate(FacesContext context, UIComponent toValidate, Object value) allows extra parameters to be passed to a validation method. For example, if a method has been defined as
    	public void validateDate(String requiredFormat, FacesContext context, UIComponent component, Object toValidate)
    	{
    		// validate the 'toValidate' object against the required format
    		...
    	}	
    	
    then a faces tag can invoke it through an attribute like validator="#{mybean.validateDate$_['YYYY-MM-dd'].validate}"
  3. void processValueChange(ValueChangeEvent event) allows extra parameters to be passed to a value-change method. This can be specified in a tag like valueChangeListener="#{mybean.onSomeChange$_[it.key].processValueChange}".