Previous Section  < Day Day Up >  Next Section

B.4 Expressions and Operators

The combination of literal values, variables, and the following operators form an EL expression:

Operator

Precedence

Operation performed

.

1

Access a bean property or Map entry.

[]

1

Access an array or List element.

( )

2

Group a subexpression to change the evaluation order.

? :

10

Conditional test: condition ? ifTrue : ifFalse.

+

5

Addition.

-

5

Subtraction.

-

3

Negation of a value.

*

4

Multiplication.

/ or div

4

Division.

% or mod

4

Modulo (remainder).

== or eq

7

Test for equality.

!= or ne

7

Test for inequality.

< or lt

6

Test for less than.

> or gt

6

Test for greater than.

<= or le

6

Test for less than or equal.

>= or ge

6

Test for greater than or equal.

&& or and

8

Test for logical AND.

|| or or

9

Test for logical OR.

! or not

3

Unary Boolean complement.

empty

3

Test for empty variable values (null or an empty String, array, Map or Collection).

Expressions are evaluated in the order defined by the operator precedence and left to right for operators of the same precedence.

B.4.1 Operand Evaluation and Coercing Rules

Before the operator is applied, the EL evaluator coerces the types of the operand values. An exception is thrown if no rule matches, the coercing fails, or applying the operator leads to an exception.

B.4.1.1 Property and array accessor operators

An expression of the form #{exprA.identifierB} is evaluated the same way as #{exprA['identifierB']}. When used as value binding expression to bind an input component's value to a property of an application bean, the expression is used both to read and write the property value.

When read, an expression of the form #{exprA[exprB]} is evaluated according to the following rules by default:

  1. If exprA is null, return null

  2. If exprB is null, return null

  3. If exprA is a Map with a key matching exprB, return the value

  4. If exprA is a List or array with an index matching exprB coerced to an int, return the value

  5. If exprA is a bean with a property matching exprB coerced to a String, return the value.

When written, an expression of the form #{exprA[exprB]} is evaluated according to the following rules by default:

  1. If exprA is null, throw a PropertyNotFoundException

  2. If exprB is null, throw a PropertyNotFoundException

  3. If exprA is a Map, call its put() method with the evaluation result of exprB as the key and the component's value as the value

  4. If exprA is a List or array, call its set() method or the java.lang.reflect.Array.set() method with an index matching exprB coerced to an int and the component's value. If an exception is thrown, rethrow it wrapped in a PropertyNotFoundException

  5. If exprA is a bean with a writeable property matching exprB coerced to a String, call the setter method with the component's value. If an exception is thrown, rethrow it wrapped in a ReferenceSyntaxException. If exprB doesn't match a writable property name, throw a PropertyNotFoundException

When written, an expression containing a single identifier is evaluated according to the following rules by default:

  1. If the identifier matches an implicit variable name, throw a ReferenceSyntaxException

  2. If the identifier matches a variable in the request, session, or application scope, replace the variable value with the component's value

  3. Otherwise, create a new request scope variable with the component's value.

An expression may also be used as a method binding, binding an application bean method to a component. Such an expression must be of the form #{exprA.identifierB} or #{exprA['identifierB']}, where identifierB must be the name of a method with the appropriate signature, as defined per attribute that accepts a method binding expression.

B.4.1.2 Arithmetic operators

For addition, subtraction and multiplication, if any operand is null, the result is 0. Otherwise both operands are coerced to numbers (to BigDecimal if one of them is BigDecimal or if one is BigInteger and the other is Float, Double, or a String with floating-point syntax, to double if one of them is Float, Double, or a String with floating-point syntax, to BigInteger if one of them is BigInteger, to long otherwise), and the result of applying the operator is returned.

For division, if any operand is null, the result is 0. Otherwise both operands are coerced to numbers (to BigDecimal if one of them is BigInteger or BigDecimal, to double otherwise), and the result of applying the operator is returned.

For modulo, if any operand is null, the result is 0. Otherwise both operands are coerced to numbers (to double if one of them is BigDecimal, Float, Double, or a String with floating-point syntax, to BigInteger if one of them is BigInteger, to long otherwise), and the result of applying the operator is returned.

For negation, if the operand is null, the result is 0. Otherwise if the operand is a String, it's coerced to a number (to double if it represents a floating-point value, to long otherwise), and the result of applying the operator is returned. For numeric types, the operator is applied without coercing the value and the result is returned.

B.4.1.3 Relational operators

For "less than," "greater than," "less than or equal," and "greater than or equal," if the operands are equal, true is returned for "less than or equal" and "greater than or equal"; false otherwise. If the operands are not equal and one of them is null, false is returned. If one of the operands is a BigDecimal, the other is coerced to BigDecimal and the result of compareTo() is returned. If one of the operands is a Float or a Double, both are coerced to Double, and the result of applying the operator is returned. If one of the operands is a BigInteger, the other is coerced to BigInteger and the result of compareTo() is returned. If one of the operands is a Byte, Short, Character, Integer, or Long, both are coerced to long, and the result of applying the operator is returned. If one operand is a String, the other is coerced to a String, and the result of compareTo( ) is returned. Otherwise, if one of the operands is a Comparable, the result of comparing it to the other with the compareTo() method is returned.

For "equal" and "not equal," if the operands are equal, the operator is applied and the result is returned. If one of the operands is null, false is returned for "equal" and true for "not equal." If one of the operands is a BigDecimal, the other is coerced to BigDecimal and the result of equals( ) is used, negated for "not equal." If one of the operands is a Float or a Double, both are coerced to double, and the result of applying the operator is returned. If one of the operands is a BigInteger, the other is coerced to BigInteger and the result of equals( ) is used, negated for "not equal." If one of the operands is a Byte, Short, Character, Integer, or Long, both are coerced to long, and the result of applying the operator is returned. If one of the operands is a Boolean, both are coerced to boolean, and the result of applying the operator is returned. Otherwise, the result of comparing the values with the equals() method is returned, negated for "not equal."

B.4.1.4 Logical operators

For "and" and "or," both operands are coerced to boolean, and the result of applying the operator is returned. The evaluation stops as soon as the result can be determined, i.e., for the expression #{a && b && c && d}, only #{a && b} is evaluated if b is false.

For "not," the operand is coerced to boolean and the result of applying the operator is returned.

B.4.1.5 Empty operator

The "empty" operator returns true if the operand is null or an empty string, an empty array, an empty Map, or an empty Collection; otherwise it returns false.

    Previous Section  < Day Day Up >  Next Section