JSF Expression Language Tooling
|
Overview
The JSF Expression Language (JSF EL) tooling provides basic support
for design time evaluation of JSF 1.1 EL. It implements parts of
the following specifications:
JSF 1.1 Specification -- particularly chapters 5 and 9.
JSP 2.0 Specification -- particularly chapter 2.
In order to support design-time evaluation of expressions, the tooling has the following basic capabilities:
- syntax parsing
- design-time variable, property and method resolution
- semantic type analysis
- static expression evaluation
Syntax Parsing
The WTP JSP tooling provides an EL parser that the JSF EL tooling
leverage because of the syntactic commonality between JSP and JSF EL.
The parser is based on JavaCC and constructs an abstract syntax tree
(AST) that is further processed by the framework. The parser
reports syntax errors in expressions.
Design-time variable, property and method resolution
JSF EL expressions may contain variable and method bindings that
reference external objects. At runtime, this is accomplished
through several mechanisms that convert different types of
identifier symbols into objects and methods. At design-time the
JSF tooling tries to parallel these as closely as possible. These
mechanisms are:
- VariableResolver
- PropertyResolver
- MethodBinding
For more information on pluggable resolvers, see
The Design Time Application Manager.
Semantic type analysis
Type analysis of literals is performed for all expressions.
Analysis is done on all variables, properties and methods that can be
resolved. Type analysis can verify that:
- operator arguments are of a valid type or can be coerced to one.
- EL attribute values resolve to a type that is expected by its tag attribute
- the result of an EL expression supports the assignment properties expected by its tag attribute
Argument Coercability
Many EL operators expect arguments with a particular type. For
example, the arithmetic addition operator, '+', expects that both of
its operands are numeric. EL does provide for automatic type
coercions and conversions, however some operands cannot be coerced and
will cause runtime errors. The following are examples of
syntactically valid EL expressions that will cause type coercions
exceptions at runtime:
Expression
|
Problem
|
myBean.stringArrayProperty + myBean.booleanProperty
|
The first operand is an array of strings. Arrays cannot be coerced to a numeric type supported by the addition operator
|
-false
|
Boolean 'false' cannot be coerced to a numeric type expected by the unary minus operator.
|
!5
|
The numeric value '5' cannot be
coerced to a boolean required by the unary not operator (Note this is
what the specification says; some implementation use a C-style
number-to-boolean coercion and flag a warning).
|
Attribute value compatibility
For those tag attributes that are annotated with JSF tooling meta-data
providing type information, EL type information can be compared to what
is expected by the attribute. Below are some examples of
attribute values being assigned EL expressions that have incompatible
types. The tag prefix "h" represents the built-in JSF "html" tag library.
Example
|
Problem
|
<h:inputText rendered="#{myBean.arrayProperty}"/>
|
The rendered attribute expects a boolean value. An array value can be coerced or converted to boolean
|
<h:dataTable binding="#{myBeanSubClass.booleanProperty}"/>
|
The
binding attribute expects a binding to a UIComponent object. The
boolean property can be neither converted or coerced to a valid type.
|
Assignability analysis
Some JSF tag attributes support the writing back of data to an identified object, such as a bean property:
e.g. <h:inputText value=#{bean.readOnlyProperty}/>
For tags that are annotated with JSF tooling meta-data, the framework
can check if the property is writable as expected. In the example
above, the inputText will write back the value entered by the user to
bean.readOnlyProperty. However, if the bean doesn't implement a
setter for this property, the user will be issued a warning that the
tag logic may not work completely as expected.
Static Expression Evaluation
The JSF EL validation component performs design time expression
evaluation on an AST provided by the parser. The expression evaluator
is able to do the following expression evaluations:
- constant expression detection
- logical short-circuit analysis
- possible division by zero
Constant expression detection
Certain types of expressions can be statically analyzed for
deterministic evaluation. Such deterministic evaluation may imply
programmer error. For example the following expressions always
evaluate to a constant value regardless of runtime conditions:
Expression
|
Constant Evaluation
|
Reason
|
5+3
|
8
|
All values in the expression are constant at design time.
|
empty 'notEmpty'
|
false
|
Empty operator always returns false for non-null, non-empty strings.
|
empty 5
|
false
|
The empty operator always returns false if the argument is not a string, collection, array or map.
|
-null
|
0
|
The minus operator treats null as 0.
|
Logical short-circuit analysis
JSF EL supports short-circuit evaluation of boolean expressions.
Short-circuit evaluation can cause entire sub-expressions to not be
evaluated and important
side-effects may not occur. The following are examples of EL
expressions that will be short-circuited:
Expression
|
Description
|
false && myBean.x
|
This logical predicate always
evaluates to false regardless of the value of myBean.x. Because this
expression "short-circuits" on the first argument, myBean.x will never
be evaluated meaning any expected side-effects will not occur.
|
true || myBean.x
|
Similar to the above, myBean.x will never be evaluated because true or'd with any value is guaranteed to be true.
|
Possible division by zero
Division by zero can cause runtime exceptions in a JSF application.
The following are examples of EL expressions that may result in a
divide-by-zero error:
'x / 0'
'x / (5-5)'