OGNL is the Object Graph Navigation Language - see http://www.ognl.org/ for the full documentation of OGNL. Here, we will cover a few examples of OGNL features that co-exist with the framework. To review basic concepts, refer to OGNL Basics.
The framework uses a standard naming context to evaluate OGNL expressions. The top level object dealing with OGNL is a Map (usually referred as a context map or context). OGNL has a notion of there being a root (or default) object within the context. In expression, the properties of the root object can be referenced without any special "marker" notion. References to other objects are marked with a pound sign (#
).
The framework sets the OGNL context to be our ActionContext, and the value stack to be the OGNL root object. (The value stack is a set of several objects, but to OGNL it appears to be a single object.) Along with the value stack, the framework places other objects in the ActionContext, including Maps representing the application, session, and request. These objects coexist in the ActionContext, alongside the value stack (our OGNL root).
No Format |
---|
|--request
|
|--application
|
|--session
context map---|
|--value stack(root)
|
|--request
|
|
There are other objects in the context map. The diagram is for example only.
The Action instance is always pushed onto the value stack. Because the Action is on the stack, and the stack is the OGNL root, references to Action properties can omit the #
marker. But, to access other objects in the ActionContext, we must use the #
notation so OGNL knows not to look in the root object, but for some other object in the ActionContext.
Code Block |
---|
| xml |
---|
| xml |
---|
title | Referencing an Action property |
---|
|
<saf:property value="postalCode"/>
|
Other (non-root) objects in the ActionContext can be rendered use the #
notation.
Code Block |
---|
| xml |
---|
| xml |
---|
1 | title:Reference Another Object in the ActionContext |
---|
|
<saf:property value="#session.mySessionPropKey"/> or
<saf:property value="#session["mySessionPropKey"]"/> or
<saf:property value="#request["mySessionPropKey"]/>
|
The ActionContext is also exposed to Action classes via a static method.
Code Block |
---|
|
ActionContext.getContext().getSession().put("mySessionPropKey", mySessionObject);
|
Collections (Maps, Lists, Sets)
Dealing with Collections (Maps, Lists, and Sets) in the framework comes often, so here are a few examples using the select tag.
Syntax for list: {e1,e2,e3}. This idiom creates a List containing the String "name1", "name2" and "name3". It also selects "name2" as the default value.
Code Block |
---|
|
<saf:select label="label" name="name" list="{'name1','name2','name3'}" value="%{'name2'}" />
|
Syntax for map: #{key1:value1,key2:value2}. This idiom creates a map that maps the string "foo" to the string "foovalue" and "bar" to the string "barvalue":
Code Block |
---|
|
<saf:select label="label" name="name" list="#{'foo':'foovalue', 'bar':'barvalue'}" />
|
To determine if an element exists in a Collection, use the operations in
and not in
.
Code Block |
---|
|
<saf:if test="'foo' in {'foo','bar'}">
muhahaha
</saf:if>
<saf:else>
boo
</saf:else>
<saf:if test="'foo' not in {'foo','bar'}">
muhahaha
</saf:if>
<saf:else>
boo
</saf:else>
|
To select a subset of a collection (called projection), use a wildcard within the collection.
- ? - All elements matching the selection logic
- ^ - Only the first element matching the selection logic
- $ - Only the last element matching the selection logic
To obtain a subset of just male relatives from the object person:
Code Block |
---|
|
person.relatives.{? #this.gender == 'male'}
|
Lambda Expressions
OGNL supports basic lamba expression syntax enabling you to write simple functions.
(Dedicated to all you math majors who didn't think you would ever see this one again.)
Fibonacci: if n==0 return 0; elseif n==1 return 1; else return fib(n-2)+fib(n-1);
fib(0) = 0
fib(1) = 1
fib(11) = 89
Info |
---|
title | How the expression works |
---|
|
The lambda expression is everything inside the brackets. The #this variable holds the argument to the expression, which is initially starts at 11. |
Code Block |
---|
|
<saf:property value="#fib =:[#this==0 ? 0 : #this==1 ? 1 : #fib(#this-2)+#fib(#this-1)], #fib(11)" />
|