Advanced Customization > Info*Engine User’s Guide > Custom Tag Libraries > Expression Language Support
  
Expression Language Support
Expression language (EL) is a mechanism for dereferencing dynamic variable content from several possible sources using a simple string syntax. EL can only be used within custom tags, and cannot be used within core library tags, such as webject, param, and task. Furthermore, the EL syntax discussed here cannot be used with JSP pages. However, it is similar to the EL supported by JSTL 1.0/JSP 2.0, which can be used from within JSP pages.
* 
For performance reasons, custom tag attributes that do not require expression language should avoid supporting it.
Using custom tag attributes that support EL, task authors can embed expressions that are evaluated at runtime against the following:
The VDB
The context collection, such as @FORM and @SERVER
The tasklet context
The IeContext object for the current request (which holds request-scoped context variables)
These locations provide the sources of the information fetched by expressions, allowing the desired information to be further refined within an expression.
An expression can also support accessors, which allow you to use brackets ([ ]) to index information into arrays, lists, and maps as well as use the . character to dereference Java bean properties. For example, an expression indexing into a list might be written as ${listName[1]}, which fetches the second element in the list named “listName.” Indexing into a map might be written as ${mapName['key']}. Fetching a property from a Java bean might be written as ${employee.name}, which returns the result of invoking the getName() method on the bean referenced by “employee.”
Expressions can also be arbitrarily complex, for example the following:
${employees['123'].name}
fetches a bean from a map using the key “123,” and then fetches the “name” property from that bean by invoking the getName() method on the bean. More examples are provided throughout this section.
Since it is common to use the . character, it is special-cased within Info*Engine data structure attribute values, specifically when the next part of the expression being evaluated is an Info*Engine element object. In this case, the next text in the expression being evaluated specifies an attribute name. For example, in the following expression:
${document[0]thePersistInfo.createStamp[0]}
if document[0] resolves to the first element in a group named “document,” then the . character found within “thePersistInfo.createStamp” would be special-cased to avoid breaking the intent of the expression. In other cases, however, the . character specifically dereferences a Java bean property, breaking the above expression. Other characters, such as the single quote () and the brace characters ({ }), also have special meaning and may need to be escaped. Preceding those characters with a back slash (\) escapes them.
Aside from fetching data from the VDB and context groups, expression evaluation resolves variable values the tasklet context, which refers to a pair of maps containing data. Each task has a unique local map to store variable data, and that map is backed by the IeContext object of the overarching request. Each Info*Engine-based request has its own instance of IeContext (com.infoengine.util.IeContext), which are able to hold contextual information specific to a given request. For example, this can be used for information that needs to be shared by disjointed pieces of source code.
A tasklet context operates similar to the IeContext, but is specific to a single task and has a lifespan that carries only through the execution of that task. However, if you want a task to call a sub-task and to share data, then you can place a request-scoped variable in the IeContext, which is visible to all other code running within the same request. The set tag supplied as part of the /com/infoengine/tlds/iejstl.tld tag library has an argument named requestScope, which you can use to differentiate between locally-scoped variables and request-scoped variables. During expression evaluation, the local tasklet context is located, and if the variable is not found the IeContext is consulted. This means that local variable data overrides request-scoped variable data. For more information, see set Tag.
* 
Since you cannot differentiate EL from standard Info*Engine substitution syntax, EL is not supported within core Info*Engine tags (such as the ie:param data attribute). However, you can programmatically include expressions in attributes using standard JSP-like expressions such as <%=evaluateExpression("${x}")%>.
For example:
<c:set var=”a” value=”${array[0]}” />
<c:set var=”a” value=”${map[‘a’]}” />
and
<ie:param name=”COUNT” data=”<%=evaluateExpression(“${group.elementCount}”)%>” />
An expression can have varying degrees of complexity, as long as its individual parts correspond upon evaluation of the expression. For example:
<!-- fetch the first element within the variable ‘list’ which
is a list of Map objects and then fetch the value of ‘a’
within that Map. -->
<c:set var=”a” value=”${list[0][‘a’]}” />
<!-- I have a group with elements containing an attribute named
‘mapAtt’ which is a map that I can index into -->
<c:set var=”a” value=”${myGroup[0]mapAtt[0][‘a’]}” />
Expressions can invoke no-arg getters on variable objects, which are accessed like Java bean properties. For example:
<!-- populate the eCount variable with the number of elements
in “myGroup” -->
<c:set var=”eCount” value=”${myGroup.elementCount}”>
A string can have multiple arbitrary expressions embedded within it. For example:
<c:if test=”${myGroup==null || myGroup.elementCount!=10}”>
<c:choose>
<c:when test=”${myGroup==null}”>
<c:set var=”err” value=”Group myGroup is null” />
</c:when>
<c:otherwise>
<c:set var=”err”
value=”Group myGroup must have 10 elements but it has ${myGroup.elementCount}” />
</c:otherwise>
</c:choose>
<ie:webject name=”Throw-Exception” type=”MGT”>
<ie:param name=”MESSAGE” data=”<%=getContextValue(“err”)%>” />
</ie:webject>
</c:if>
Unlike JSP expressions, Info*Engine EL is integrated with Info*Engine runtime concepts. During the expression evaluation, the task context collections and VDB are consulted before the tasklet and request context. For example:
<c:set var=”a” value=”${@FORM[]a[]}” />
<c:forEach var=”elm” list=”${myGroup}”>
<!-- executes once for each element in myGroup -->
</c:forEach>
<c:forEach var=”a” list=”${myGroup[0]a[*]}”>
<!-- executes once for each value of the a attribute
within the first element of myGroup -->
</c:forEach>
Unlike JSP, Info*Engine EL does not support the use of operators within expressions. The core custom tag library extends EL support somewhat specifically with the c:set, c:if/c:when tags. These tags internally use the tasklet.evaluateExpression(String) method (discussed briefly below) to extend EL to achieve their goals. For example:
<!-- the test attribute is broken into separate expressions
that are evaluated independently in order based on the
conditional expression to be evaluated.
in this case ${@FORM[]doSomething[]} ${myGroup} and
${myGroup.elementCount}. -->
<c:if test=”${@FORM[]doSomething[]==true &amp;&amp; myGroup!=null &amp;&amp;
myGroup.elementCount>0}”>
<c:set var=”idx” value=”0” />
<c:forEach var=”elm” list=”${myGroup}”>
<c:set var=”mod” value=”${idx%2}”>
<c:choose>
<c:when test=”${mod==0}”><!-- even -->/c:when>
<c:otherwise>!<-- odd -->/c:when>
</c:choose>
<!-- similar to if/when set may evaluate expressions independently
as necessary, in this case ${idx} to get what to add 1 to. -->
<c:set var=”idx” value=”${idx+1}” />
<c:forEach>
</c:if>
To support combining EL with Java scriplets, com.infoengine.SAK.Tasklet has methods defined on it to support interaction with context variables and to allow for programmatic evaluation of expressions (for reuse from within custom tag libraries).
For example, the following sets a variable within the tasklet context with task scope:
public final void setContextValue ( String name, Object value );
The following sets a variable within the tasklet context with either task or request scope. If request is set to true, then the variable is available to other tasks within the same request:
public final void setContextValue ( String name, Object value, boolean request );
The following fetches the names of all variables defined within the tasklet and request context:
public final Set<String> getContextKeys();
The following fetches a variable by name from the context:
public final Object getContextValue ( String value );
The following evaluates an expression and returns the resulting object or null. Exceptions related to syntax problems within the expression or runtime evaluation of the expression are thrown:
public Object evaluateExpression ( final String expression ) throws IEException;
For example:
<%
// programmatically sets a context variable that is an array of strings
setContextValue ( “myArray”, new String [] { “a”, “b”, “c” } );
// fetches a group named myGroup from the VDB
// ONLY for illustration
Group g = (Group)evaluateExpression ( “${myGroup}” );
// wouldn’t do this but fetches the above programmatically populated
// myArray variable
String [] myArray = (String [])getContextValue ( “myArray” );
%>
<c:forEach var=”one” list=”myArray”>
<!-- will run three times, a, b and c -->
<c:set var=”message” value=”one is ${one}” />
</c:forEach>