Help

Switch Workspace

Built with Seam

You can find the full source code for this website in the Seam package in the directory /examples/wiki. It is licensed under the LGPL.

Proposed enhancements to Unified EL 2.1

This document is history! Please see the EL wishlist to find Red Hat's proposals for the (planned) Unified EL JSR.

This page consists of an agenda and proposals put forth by Red Hat and its community for the Unified EL 2.1 (actually called EL 2.2) specification. Currently the Unified EL specification exists as Part II of JSR-245: JavaServer Pages 2.1.

Current status

See the expression language portion of the JSR-245 specification for information about the Unified EL.

Invocation of arbitrary methods (P1) (FIXED)

For as long as there has been an expression language in Java EE, there has been the implicit translation in value expressions between an EL segment and the bean property getter method on the resolved instance:

  • person.name -> getName() method on the instance variable named person

While this shorthand is certainly convenient, it's an unnecessary restriction that the EL only support this convention for accessing data of a bean instance in a value expression. In addition to this shorthand, the EL should support explicit method calls. The name of the method is taken literally if followed by brackets like a no-arguments method call in Java.

  • person.formatName() -> formatName() method on the instance variable named person

* This feature is now supported in EL 2.2

Parameterized methods (P1) (FIXED)

The EL syntax does not permit the use of brackets at the end of a non-root segment. On the one hand, this simplifies the EL syntax and allows an implicit translation to a concrete method. For value expressions, the EL translates non-root segments into bean property getter methods.

  • person.name -> getName() method on the instance variable named person

In method expressions, the last segment is assumed to be a no-arguments method with the same name.

  • registration.register -> register() method on the instance variable named registration

However, there are two limitations of taking this approach:

  1. Value expressions and method expressions have different implicit translation rules, potentially confusing to newcomers
  2. Expressions to not support methods taking arguments (parametrized methods)

The EL would net tremendous flexibility if method arguments were supported. The rules would be simple. If brackets are used at the end of a non-root segment, the implicit translation would not take place, instance variable names used between the brackets would be used to select the proper method and the values of those instance variables would be passed into the method. The values of the method arguments would be resolved from instance variables when the expression is evaluated, just like the root segment of the expression.

  • person.formatName(formatType) -> formatName(java.lang.String) method on the instance variable named person, passing the value of the formatType instance variable as an argument
  • registration.register(person) -> register(com.acme.Person) method on the instance variable named registration, passing the value of the person instance variable as an argument

* This feature is now supported in EL 2.2

Parameterized methods with formal type parameters (P2) (FIXED)

As an extension to the parameterized methods feature request, it would also be convenient to have reserved parameters for integration with event listeners. This way, the application developer could have additional parameters appended to a fixed parameter that is provided by the framework.

Parameterized methods allows:

#{bb.action(myparam)}

Which matches a method with signature such as:

public String action(String myparam) {}

But this does not cover the following case:

#{bb.valueChangeListener(myparam)}

Ideal this call would match a method with signature such as:

public void valueChangeListener(ValueChangeEvent ev, String myparam) {}

However, with parameterized method support along, it would only match a signature such as:

public void valueChangeListener(String myparam) {}

What is lost is the ValueChangeEvent, which was provided by the JSF framework as a parameter to the invoke-call in the Method-Expression instance (we will only receive the parsed parameters). So we are looking for EL to allow the framework to be able to add any number of formal type parameters at the front of the method signature.

* This feature is now supported in EL 2.2

Invocation of static members (P2)

The EL has always dealt with instance methods, but there is no reason why static methods--or even static members in general--cannot be supported. In this case, both non-static and static members are searched when resolving a method.

  • person.formatName(person, formatType) -> formatName(com.acme.Person, java.lang.String) static method on the com.acme.Person class, passing the value of the person and formatType instance variables as arguments

It would also be convenient to support direct access of public static fields as well

  • registration.DEFAULT_ROLE -> DEFAULT_ROLE static field on the com.acme.Registration class

In both cases, the resolved base serves only to determine the class to search (rather than a specific instance).

Support for Java 5 Enums (P1)

Need first class support for Java 5 Enums constants. Either the constants should be allowed to be referenced from a base that resolves to the Enum:

  • days.MONDAY -> com.acme.Days.MONDAY

or the EL should allow the fully qualified Enum class to be referenced:

  • com.acme.Days.MONDAY -> com.acme.Days.MONDAY

The second option may be better because it doesn't require a context variable to resolve to an Enum instance just to access the other constants.

Projections (P3)

Projections are rudimentary closures that allow the dynamic creation of collections from properties of child elements:

  • blocks.{b|b.color} -> a collection (java.util.List) of colors read from each block in the collection resolved from the instance variable named blocks

EL namespaces (P2)

JSR-299 is introducing several standard EL names, one of which is javax.enterprise.conversation. As you can see, the name uses the familiar namespace syntax from Java. Therefore, it would be ideal if EL could formally recognize the use of namespaces for two reasons:

  1. Efficiency in resolving
  2. Namespace imports

Importing namespaces would allow for libraries to define standard EL names with namespace prefixes, but allow the page author the convince of using the unqualified name. The import mechanism should be a feature of the EL API and the declaration of the import be left up to the EL environment (e.g., JSF template).

Bootstrapping the ELContext (P1)

Current the ELContext is created in the UI layer, either by JavaServer Faces or JSP. However, EL is an essential part of the Java EE programming model. It would make a lot more sense if the ELContext would be created at the start of the request so that components such as filters, custom servlets and third-party frameworks could access the EL. Currently, it's necessary to manually construct an EL context if an expression needs to be resolved outside of JSF or JSP.

What we are looking for is something similar to the bootstrap that was introduced for Bean Validation. Like Bean Validation, EL transcends the layers of the programming model and should therefore be universally accessible.

Simplifying the expression evaluator API (P1)

It's way too complicated to resolve an EL expression. If you think about it, the task is quite simple. Take an expression string and get a result. We need to make the API as simple as the task.

Part of the problem with the Unified EL is that just trying to figure out what you need to actually resolve an expression is a nightmare. It breaks down into three parts:

  • ELContext - Simply put, To evaluate an Expression, an ELContext must be provided. A real bitch.
  • ExpressionFactory - Needed to create a ValueExpression or MethodExpression from a string
  • ELResolver - The thing that actually parses the expression and deferences its parts; each job is handled by a different resolver (one being to find CDI beans by name) and those resolvers are wrapped in a resolver which is a chain of resolver

What isn't provided is a simple API to just take an expression and get a result from it.

Coercion (P2)

This could be an issue which is specific to an EL consumer, such as Facelets, but there are some concerns over the way that values are coerced by the EL. The issue is described in the following blog entry: