Seam uses JBoss EL which provides an extension to the standard Unified
Expression Language (EL). JBoss EL provides a number of enhancements that
increase the expressiveness and power of EL expressions.
Standard EL does not allow you to use a method with user defined
parameters — of course, JSF listener methods (e.g. a
valueChangeListener
) take parameters provided by JSF.
JBoss EL removes this restriction. For example:
<h:commandButton action="#{hotelBooking.bookHotel(hotel)}" value="Book Hotel"/>
@Name("hotelBooking")
public class HotelBooking {
public String bookHotel(Hotel hotel) {
// Book the hotel
}
}
Just as in calls to method from Java, parameters are surrounded by
parentheses, and separated by commas:
<h:commandButton action="#{hotelBooking.bookHotel(hotel, user)}" value="Book Hotel"/>
The parameters hotel
and user
will be evaluated as value expressions and passed to the
bookHotel()
method of the component.
Any value expression may be used as a parameter:
<h:commandButton
action="#{hotelBooking.bookHotel(hotel.id, user.username)}"
value="Book Hotel"/>
It's important to fully understand how this extension to EL works.
When the page is rendered, the parameter names
are stored (for example, hotel.id
and
user.username
), and evaluated (as value
expressions) when the page is submitted. You can't pass objects as
parameters!
You must ensure that the parameters are available not only when the
page is rendered, but also when it is submittedIf the arguments can
not be resolved when the page is submitted the action method will be
called with null
arguments!
You can also pass literal strings using single quotes:
<h:commandLink action="#{printer.println('Hello world!')}" value="Hello"/>
Unified EL also supports value expressions, used to bind a field to
a backing bean. Value expressions use JavaBean naming conventions
and expect a getter/setter pair. Often JSF expects a value
expression where only retrieval (get) is needed (e.g. the
rendered
attribute). Many objects, however, don't
have appropriately named property accessors or require parameters.
JBoss EL removes this restriction by allowing values to be retrieved
using the method syntax. For example:
<h:outputText value="#{person.name}" rendered="#{person.name.length() > 5}" />
You can access the size of a collection in a similar manner:
#{searchResults.size()}
In general any expression of the form #{obj.property} would be
identical to the expression #{obj.getProperty()}.
Parameters are also allowed. The following example calls the
productsByColorMethod
with a literal string
argument:
#{controller.productsByColor('blue')}
JBoss EL supports a limited projection syntax. A projection expression
maps a sub-expression across a multi-valued (list, set, etc...)
expression. For instance, the expression:
#{company.departments}
might return a list of departments. If you only need a list of
department names, your only option is to iterate over the list to
retrieve the values. JBoss EL allows this with a projection expression:
#{company.departments.{d|d.name}}
The subexpression is enclosed in braces. In this example, the
expression d.name
is evaluated for each department,
using d
as an alias to the department object. The
result of this expression will be a list of String values.
Any valid expression can be used in an expression, so it would be
perfectly valid to write the following, assuming you had a use for the
lengths of all the department names in a company:
#{company.departments.{d|d.size()}}
Projections can be nested. The following expression returns the last
names of every employee in every department:
#{company.departments.{d|d.employees.{emp|emp.lastName}}}
Nested projections can be slightly tricky, however. The following
expression looks like it returns a list of all the employees in all the
departments:
#{company.departments.{d|d.employees}}
However, it actually returns a list containing a list of the employees
for each individual department. To combine the values, it is necessary
to use a slightly longer expression:
#{company.departments.{d|d.employees.{e|e}}}
It is important to note that this syntax cannot be parsed by Facelets
or JSP and thus cannot be used in xhtml or JSP files. We anticipate
that the projection syntax will change in future versions of JBoss EL.