org.apache.commons.jexl2
Class UnifiedJEXL

An evaluator similar to the Unified EL evaluator used in JSP/JSF based on JEXL.
It is intended to be used in configuration modules, XML based frameworks or JSP taglibs
and facilitate the implementation of expression evaluation.

An expression can mix immediate, deferred and nested sub-expressions as well as string constants;

The "immediate" syntax is of the form "...${jexl-expr}..."

The "deferred" syntax is of the form "...#{jexl-expr}..."

The "nested" syntax is of the form "...#{...${jexl-expr0}...}..."

The "composite" syntax is of the form "...${jexl-expr0}... #{jexl-expr1}..."

Deferred & immediate expression carry different intentions:

An immediate expression indicate that evaluation is intended to be performed close to
the definition/parsing point.

A deferred expression indicate that evaluation is intended to occur at a later stage.

For instance: "Hello ${name}, now is #{time}" is a composite "deferred" expression since one
of its subexpressions is deferred. Furthermore, this (composite) expression intent is
to perform two evaluations; one close to its definition and another one in a later
phase.

The API reflects this feature in 2 methods, prepare and evaluate. The prepare method
will evaluate the immediate subexpression and return an expression that contains only
the deferred subexpressions (& constants), a prepared expression. Such a prepared expression
is suitable for a later phase evaluation that may occur with a different JexlContext.
Note that it is valid to call evaluate without prepare in which case the same JexlContext
is used for the 2 evaluation phases.

In the most common use-case where deferred expressions are to be kept around as properties of objects,
one should parse & prepare an expression before storing it and evaluate it each time
the property storing it is accessed.

Note that nested expression use the JEXL syntax as in:
"#{${bar}+'.charAt(2)'}"
The most common mistake leading to an invalid expression being the following:
"#{${bar}charAt(2)}"

Also note that methods that parse evaluate expressions may throw unchecked exceptions;
The UnifiedJEXL.Exception are thrown when the engine instance is in "non-silent" mode
but since these are RuntimeException, user-code should catch them where appropriate.