You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
729 lines
28 KiB
729 lines
28 KiB
<?xml version="1.0" encoding="UTF-8"?> |
|
<chapter id="expressions"> |
|
<title>Spring Expression Language (SpEL)</title> |
|
|
|
<section id="expressions-intro"> |
|
<title>Introduction</title> |
|
|
|
<para>The Spring Expression Language (SpEL for short) is a powerful |
|
expression language that supports querying and manipulating an object |
|
graph at runtime. The language syntax is similar to Unified EL but offers |
|
additional features, most notably method invocation and basic string |
|
templating functionality. </para> |
|
|
|
<para>While there are several other Java expression languages available, |
|
OGNL, MVEL, and JBoss EL, to name a few, the Spring Expression Language |
|
was created to provide the Spring community with a single well supported |
|
expression language that can used across all the products in the Spring |
|
portfolio. Its language features are driven by the requirements of the |
|
projects in the Spring portfolio, including tooling requirements for code |
|
completion support within the eclipse based SpringSource Tool Suite. That |
|
said, SpEL is based on an technology agnostic API allowing other |
|
expression language implementations to be integreated should the need |
|
arise.</para> |
|
|
|
<para>While SpEL serves as the foundation for expression evaluation within |
|
the Spring portfolio, it is not directly tied to Spring and can be used |
|
independently. In order to be self contained, many of the examples in this |
|
chatper use SpEL as if it was an independent expression language. This |
|
requires creating a few boostrapping infrastructure classes such as the |
|
parser. Most Spring users will not need to deal with this infrastructure |
|
and will instead only author expression strings for evaluation. An example |
|
of this typical use is the integration of SpEL into creating XML or |
|
annotated based bean definitions as shown in the section <link |
|
linkend="expressions-beandef">Expression support for defining bean |
|
definitions.</link></para> |
|
|
|
<para>This chapter covers the features of the expression language, its |
|
API, and its language sytnax. In several places an Inventor and Inventor's |
|
Society class are used as the target objects for expression evaluation. |
|
These class declarations and the data used to populate them are listed at |
|
the end of the chapter. </para> |
|
</section> |
|
|
|
<section id="expressions-features"> |
|
<title>Feature Overview</title> |
|
|
|
<para>The expression language support the following functionality</para> |
|
|
|
<itemizedlist> |
|
<listitem> |
|
<para>Literal expressions</para> |
|
</listitem> |
|
|
|
<listitem> |
|
<para>Boolean and relational operators</para> |
|
</listitem> |
|
|
|
<listitem> |
|
<para>Regular expressions</para> |
|
</listitem> |
|
|
|
<listitem> |
|
<para>Class expressions</para> |
|
</listitem> |
|
|
|
<listitem> |
|
<para>Accessing properties, arrays, lists, maps</para> |
|
</listitem> |
|
|
|
<listitem> |
|
<para>Method invocation</para> |
|
</listitem> |
|
|
|
<listitem> |
|
<para>Relational operators</para> |
|
</listitem> |
|
|
|
<listitem> |
|
<para>Assignment</para> |
|
</listitem> |
|
|
|
<listitem> |
|
<para>Calling constructors</para> |
|
</listitem> |
|
|
|
<listitem> |
|
<para>Ternary operator</para> |
|
</listitem> |
|
|
|
<listitem> |
|
<para>Variables</para> |
|
</listitem> |
|
|
|
<listitem> |
|
<para>User defined functions</para> |
|
</listitem> |
|
|
|
<listitem> |
|
<para>Templated expressions</para> |
|
</listitem> |
|
</itemizedlist> |
|
</section> |
|
|
|
<section id="expressions-evaluation"> |
|
<title>Expression Evaluation using Spring's Expression Interface</title> |
|
|
|
<para>This section introduces the simple use of SpEL interfaces and its |
|
expression language. The complete language reference can be found in the |
|
section <link lang="" linkend="expressions-language-ref">Language |
|
Reference</link></para> |
|
|
|
<para>The following code introduces the SpEL API to evaluate the literal |
|
string expression 'Hello World'</para> |
|
|
|
<para><programlisting language="java">ExpressionParser parser = new SpelAntlrExpressionParser(); |
|
Expression exp = parser.parseExpression("<emphasis role="bold">'Hello World'</emphasis>"); |
|
String message = (String) exp.getValue();</programlisting>The value of the |
|
message variable is simply 'Hello World'. </para> |
|
|
|
<para>The SpEL classes and interfaces you are most likely to use are |
|
located in the packages <package>org.springframework.expression</package> |
|
and its subpackages <package>spel.antlr</package> and |
|
<package>spel.support</package>.</para> |
|
|
|
<para>The expression language is based on a grammar and uses ANTLR to |
|
construct the lexer and parser. The interface |
|
<interfacename>ExpressionParser</interfacename> is responsible for parsing |
|
an expression string. In this example the expression string is a string |
|
literal denoted by the surrounding single quotes. The interface |
|
<interfacename>Expression</interfacename> is responsible for evaluating |
|
the previously defined expression string. There are two exceptions that |
|
can be thrown, <classname>ParseException</classname> and |
|
<classname>EvaluationException</classname> when calling |
|
'<literal>parser.parseExpression</literal>' and |
|
'<literal>exp.getValue</literal>' respectfully.</para> |
|
|
|
<para>SpEL supports a wide range of features, such a calling methods, |
|
accessing properties and calling constructors. </para> |
|
|
|
<para>As an example of method invocation, we call the 'concat' method on |
|
the string literal</para> |
|
|
|
<programlisting lang="" language="java">ExpressionParser parser = new SpelAntlrExpressionParser(); |
|
Expression exp = parser.parseExpression("<emphasis role="bold">'Hello World'.concat(!)</emphasis>"); |
|
String message = (String) exp.getValue();</programlisting> |
|
|
|
<para>The value of message is now 'Hello World!'. </para> |
|
|
|
<para>As an example of calling a JavaBean property, the String property |
|
'Bytes' can be called as shown below</para> |
|
|
|
<programlisting language="java">ExpressionParser parser = new SpelAntlrExpressionParser(); |
|
Expression exp = parser.parseExpression("<emphasis role="bold">'Hello World'.bytes</emphasis>"); // invokes 'getBytes()' |
|
byte[] bytes = (byte[]) exp.getValue();</programlisting> |
|
|
|
<para>Upper or lowercase can be used to specify the property name. SpEL |
|
also supports nested properties using standard 'dot' notation, i.e. |
|
prop1.prop2.prop3 and the setting of property values</para> |
|
|
|
<para>Public fields may also be accessed</para> |
|
|
|
<programlisting language="java">ExpressionParser parser = new SpelAntlrExpressionParser(); |
|
Expression exp = parser.parseExpression("<emphasis role="bold">'Hello World'.bytes.length</emphasis>"); // invokes 'getBytes().length' |
|
int length = (Integer) exp.getValue();</programlisting> |
|
|
|
<para>The String's constructor can be called instead of using a string |
|
literal</para> |
|
|
|
<programlisting language="java">ExpressionParser parser = new SpelAntlrExpressionParser(); |
|
Expression exp = parser.parseExpression("<emphasis role="bold">new String('hello world').toUpperCase()</emphasis>"); |
|
String message = exp.getValue(String.class);</programlisting> |
|
|
|
<para>Note the use of the generic method <literal>public <T> T |
|
getValue(Class<T> desiredResultType)</literal>. Using this method |
|
removes the need to cast the value of the expression to the desired result |
|
type. An <classname>EvaluationException</classname> will be thrown if the |
|
value an not be cast to the type <literal>T</literal> or converted using |
|
the registered type converter.</para> |
|
|
|
<para>The more common usage of SpEL is provide an expression string that |
|
is evaluated against a specific object instance. In the following example |
|
we retrieve the <literal>Name</literal> property from an instance of the |
|
Inventor class. </para> |
|
|
|
<para><programlisting language="java">// Create and set a calendar |
|
GregorianCalendar c = new GregorianCalendar(); |
|
c.set(1856, 7, 9); |
|
|
|
// The constructor arguments are name, birthday, and nationaltiy. |
|
Inventor tesla = new Inventor("Nikola Tesla", c.getTime(), "Serbian"); |
|
|
|
ExpressionParser parser = new SpelAntlrExpressionParser(); |
|
Expression exp = parser.parseExpression("<emphasis role="bold">name</emphasis>"); |
|
|
|
EvaluationContext context = new StandardEvaluationContext(); |
|
context.setRootObject(tesla); |
|
|
|
String name = (String) exp.getValue(context);</programlisting>In the last |
|
line, the value of the string variable 'name' will be set to "Nikola |
|
Tesla". The class StandardEvaluationContext is where you can specify which |
|
object the "Name" property will be evaluated against. You can reuse the |
|
same expression over and over again and set a new root object on the |
|
evaluation context. Expressions are evaluated using reflection. </para> |
|
|
|
<para><note> |
|
<para>In standalone usage of SpEL you will need to create the parser |
|
as well as provide an evaluation context. However, more common usage |
|
is to provide only the SpEL expression string as part of a |
|
configuration file, for example for Spring bean or Spring Web Flow |
|
definitions. In this case, the parser, evaluation context, root object |
|
and any predefined variables will be set up for you implicitly.</para> |
|
</note>As a final introductory example, the use of a boolean operator is |
|
shown using the Inventor object in the previous example</para> |
|
|
|
<programlisting language="java">Expression exp = parser.parseExpression("name == 'Nikola Tesla'"); |
|
boolean isEqual = exp.getValue(context, Boolean.class); // evaluates to true</programlisting> |
|
|
|
<section> |
|
<title>The EvaluationContext interface </title> |
|
|
|
<para>The interface <interfacename>EvaluationContext</interfacename> is |
|
used when evaluating an expression to resolve properties, methods |
|
,fields, and to help perform type conversion. The out-of-the-box |
|
implementation, <classname>StandardEvaluationContext</classname> ,uses |
|
reflection to manipulate the object, caching |
|
j<package>ava.lang.reflect</package>'s <classname>Method</classname>, |
|
<classname>Field</classname>, and <classname>Constructor</classname> |
|
instances for increased performance.</para> |
|
|
|
<para>The <classname>StandardEvaluationContext</classname> is where you |
|
specify the root object to evaluate against via the method |
|
<methodname>setRootObject</methodname> . You can also specify variables |
|
and functions that will be used in the expression using the methods |
|
<methodname>setVariable</methodname> and |
|
<methodname>registerFunction</methodname>. The use of variables and |
|
functions are described in the language reference sections <link |
|
linkend="expressions-ref-variables">Variables</link> and <link lang="" |
|
linkend="expressions-ref-functions">Functions</link>.</para> |
|
|
|
<section> |
|
<title>Type Conversion</title> |
|
|
|
<para>The StandardEvaluationContext uses an instance of |
|
<classname>org.springframework.expression.TypeConverter</classname>. A |
|
simple implementation of this interface, |
|
<classname>StandardTypeConverter</classname>, that converts basic |
|
types, primitive values, booleans and characters is used but will be |
|
replaced with an updated type conversion framework that is to be |
|
included as part of Spring 3.0</para> |
|
</section> |
|
</section> |
|
</section> |
|
|
|
<section id="expressions-beandef"> |
|
<title>Expression support for defining bean definitions</title> |
|
|
|
<para>SpEL expressions can be used with XML or annotation based |
|
configuration metadata for defining BeanDefinitions. In both cases the |
|
syntax to define the expression is of the form <literal>#{ <expression |
|
string> }</literal>.</para> |
|
|
|
<section id="expressions-beandef-xml-based"> |
|
<title>XML based configuration</title> |
|
|
|
<para>A property or constructor-arg value can be set using expressions |
|
as shown below</para> |
|
|
|
<programlisting language="xml"><bean id="numberGuess" class="org.spring.samples.NumberGuess"> |
|
<property name="randomNumber" value="#{ T(java.lang.Math).random() * 100.0 }"/> |
|
|
|
<!-- other properties --> |
|
</bean></programlisting> |
|
|
|
<para>The variable 'systemProperties' is predefined, so you can use it |
|
in your expressions as shown below.</para> |
|
|
|
<programlisting language="xml"><bean id="taxCalculator" class="org.spring.samples.TaxCalculator"> |
|
<property name="defaultLocale" value="#{ systemProperties['user.region'] }"/> |
|
|
|
<!-- other properties --> |
|
</bean></programlisting> |
|
|
|
<para>You can also refer to other bean properties by name, for |
|
example</para> |
|
|
|
<para><programlisting language="xml"><bean id="numberGuess" class="org.spring.samples.NumberGuess"> |
|
<property name="randomNumber" value="#{ T(java.lang.Math).random() * 100.0 }"/> |
|
|
|
<!-- other properties --> |
|
</bean> |
|
|
|
|
|
<bean id="shapeGuess" class="org.spring.samples.ShapeGuess"> |
|
<property name="initialShapeSeed" value="#{ numberGuess.randomNumber }"/> |
|
|
|
<!-- other properties --> |
|
</bean></programlisting></para> |
|
</section> |
|
|
|
<section id="expressions-beandef-annotation-based"> |
|
<title>Annotation-based configuration</title> |
|
|
|
<para>The <literal>@Value</literal> annotation can be placed on fields, |
|
methods and method/constructor parameters to specify a default |
|
value.</para> |
|
|
|
<para>Here is an example to set the default value of a field |
|
variable</para> |
|
|
|
<programlisting language="java">public static class FieldValueTestBean |
|
|
|
@Value("#{ systemProperties['user.region'] }") |
|
private String defaultLocale; |
|
|
|
public void setDefaultLocale(String defaultLocale) |
|
{ |
|
this.defaultLocale = defaultLocale; |
|
} |
|
|
|
public String getDefaultLocale() |
|
{ |
|
return this.defaultLocale; |
|
} |
|
|
|
} |
|
|
|
</programlisting> |
|
|
|
<para>The equivalent but on a property setter method is shown |
|
below</para> |
|
|
|
<programlisting language="java">public static class PropertyValueTestBean |
|
|
|
private String defaultLocale; |
|
|
|
@Value("#{ systemProperties['user.region'] }") |
|
public void setDefaultLocale(String defaultLocale) |
|
{ |
|
this.defaultLocale = defaultLocale; |
|
} |
|
|
|
public String getDefaultLocale() |
|
{ |
|
return this.defaultLocale; |
|
} |
|
|
|
}</programlisting> |
|
|
|
<para>Autowired methods and constructors can also use the |
|
<literal>@Value</literal> annotation.</para> |
|
|
|
<programlisting language="java">public class SimpleMovieLister { |
|
|
|
private MovieFinder movieFinder; |
|
private String defaultLocale; |
|
|
|
@Autowired |
|
public void configure(MovieFinder movieFinder, |
|
@Value("#{ systemProperties['user.region'] } String defaultLocale) { |
|
this.movieFinder = movieFinder; |
|
this.defaultLocale = defaultLocale; |
|
} |
|
|
|
// ... |
|
}</programlisting> |
|
|
|
<para><programlisting language="java">public class MovieRecommender { |
|
|
|
private String defaultLocale; |
|
|
|
private CustomerPreferenceDao customerPreferenceDao; |
|
|
|
@Autowired |
|
public MovieRecommender(CustomerPreferenceDao customerPreferenceDao, |
|
@Value("#{ systemProperties['user.region'] } String defaultLocale) { |
|
this.customerPreferenceDao = customerPreferenceDao; |
|
this.defaultLocale = defaultLocale; |
|
} |
|
|
|
// ... |
|
}</programlisting></para> |
|
</section> |
|
</section> |
|
|
|
<section id="expressions-language-ref"> |
|
<title>Language Reference</title> |
|
|
|
<section id="expressions-ref-literal"> |
|
<title>Literal expressions</title> |
|
|
|
<para>The types of literal expressions supported are strings, dates, |
|
numeric values (int, real, and hex), boolean and null. String are |
|
delimited by single quotes. To put a single quote itself in a string use |
|
the backslash character. The following listing shows simple usage of |
|
literals. Typically they would not be used in isolation like this, but |
|
as part of a more complex expression, for example using a literal on one |
|
side of a logical comparison operator. </para> |
|
|
|
<programlisting language="java">ExpressionParser parser = new SpelAntlrExpressionParser(); |
|
|
|
String helloWorld = (String) parser.parseExpression("'Hello World'").getValue(); // evals to "Hello World" |
|
|
|
double avogadrosNumber = (Double) parser.parseExpression("6.0221415E+23").getValue(); |
|
|
|
int maxValue = (Integer) parser.parseExpression("0x7FFFFFFF").getValue(); // evals to 2147483647 |
|
|
|
boolean trueValue = (Boolean) parser.parseExpression("true").getValue(); |
|
|
|
Object nullValue = parser.parseExpression("null").getValue(); |
|
</programlisting> |
|
|
|
<para>Numbers support the use of the negative sign, exponential |
|
notation, and decimal points. By default real numbers are parsed using |
|
Double.parseDouble().</para> |
|
</section> |
|
|
|
<section> |
|
<title>Properties, Arrays, Lists, Dictionaries, Indexers</title> |
|
|
|
<para>Navigating through properties is easy, just use a period to |
|
indicate a nested property value. The instances of Inventor class, pupin |
|
and tesla, were populated with data listed in section Section <link |
|
linkend="expressions-examples-classes">Classes used in the |
|
examples</link>. To navigate "down" and get Tesla's year of birth and |
|
Pupin's city of birth the following expressions are used </para> |
|
|
|
<programlisting lang="" language="java">int year = (Integer) parser.parseExpression("Birthdate.Year + 1900").getValue(context); // 1856 |
|
|
|
|
|
String city = (String) parser.parseExpression("placeOfBirth.City").getValue(context);</programlisting> |
|
|
|
<para>Case insensitivty is allowed for the first letter of proprety |
|
names. The contents of arrays and lists are obtained using square |
|
bracket notation. </para> |
|
|
|
<programlisting language="java">ExpressionParser parser = new SpelAntlrExpressionParser(); |
|
|
|
// Inventions Array |
|
StandardEvaluationContext teslaContext = new StandardEvaluationContext(); |
|
teslaContext.setRootObject(tesla); |
|
|
|
// evaluates to "Induction motor" |
|
String invention = parser.parseExpression("inventions[3]").getValue(teslaContext, String.class); |
|
|
|
|
|
// Members List |
|
StandardEvaluationContext societyContext = new StandardEvaluationContext(); |
|
societyContext.setRootObject(ieee); |
|
|
|
// evaluates to "Nikola Tesla" |
|
String name = parser.parseExpression("Members[0].Name").getValue(societyContext, String.class); |
|
|
|
// List and Array navigation |
|
// evaluates to "Wireless communication" |
|
String invention = parser.parseExpression("Members[0].Inventions[6]").getValue(societyContext, String.class); |
|
</programlisting> |
|
|
|
<para>The contents of dictionaries are obtained by specifying the |
|
literal key value within the brackets. In this case, because keys for |
|
the Officers dictionary are strings, we can specify string |
|
literal.</para> |
|
|
|
<programlisting lang="" language="java">// Officer's Dictionary |
|
|
|
Inventor pupin = parser.parseExpression("Officers['president']").getValue(societyContext, Inventor.class); |
|
|
|
// evaluates to "Idvor" |
|
String city = parser.parseExpression("Officers['president'].PlaceOfBirth.City").getValue(societyContext, String.class); |
|
|
|
// setting values |
|
parser.parseExpression("Officers['advisors'][0].PlaceOfBirth.Country").setValue(societyContext, "Croatia"); |
|
|
|
</programlisting> |
|
</section> |
|
|
|
<section> |
|
<title>Methods</title> |
|
|
|
<para>Methods are invoked using typical Java programming syntax. You may |
|
also invoke methods on literals. Varargs are also supported.</para> |
|
|
|
<programlisting language="java">// string literal, evaluates to "bc" |
|
String c = parser.parseExpression("'abc'.substring(2, 3)").getValue(String.class); |
|
|
|
// evaluates to true |
|
boolean isMember = parser.parseExpression("isMember('Mihajlo Pupin')").getValue(societyContext, Boolean.class);</programlisting> |
|
</section> |
|
|
|
<section> |
|
<title>Operators</title> |
|
|
|
<section> |
|
<title>Relational operators</title> |
|
|
|
<para>The relational operators; equal, not equal, less than, less than |
|
or equal, greater than, and greater than or equal are supported using |
|
standard operator notation. Support is not yet implemented for objects |
|
that implement the Comparable interface.</para> |
|
|
|
<para><programlisting language="java">// evaluats to true |
|
boolean isEqual = parser.parseExpression("2 == 2").getValue(Boolean.class); |
|
|
|
// evaluates to false |
|
boolean isEqual = parser.parseExpression("2 < -5.0").getValue(Boolean.class); |
|
|
|
// evaluates to true |
|
boolean isEqual = parser.parseExpression("'black' < 'block'").getValue(Boolean.class);</programlisting>In |
|
addition to standard relational operators SpEL supports the |
|
'instanceof' and regular expression based 'matches' operator.</para> |
|
|
|
<programlisting language="java">// evaluates to false |
|
boolean falseValue = parser.parseExpression("'xyz' instanceof T(int)").getValue(Boolean.class); |
|
|
|
// evaluates to true |
|
boolean trueValue = parser.parseExpression("'5.00' matches '^-?\\d+(\\.\\d{2})?$'").getValue(Boolean.class); |
|
|
|
//evaluates to false |
|
boolean falseValue = parser.parseExpression("'5.0067' matches '^-?\\d+(\\.\\d{2})?$'").getValue(Boolean.class); |
|
|
|
</programlisting> |
|
</section> |
|
|
|
<section> |
|
<title>Logical operators</title> |
|
|
|
<para>The logical operators that are supported are and, or, and not. |
|
Their use is demonstrated below</para> |
|
|
|
<para><programlisting language="java">// -- AND -- |
|
|
|
// evaluates to false |
|
boolean falseValue = parser.parseExpression("true and false").getValue(Boolean.class); |
|
|
|
// evaluates to true |
|
String expression = "isMember('Nikola Tesla') and isMember('Mihajlo Pupin')"; |
|
boolean trueValue = parser.parseExpression(expression).getValue(societyContext, Boolean.class); |
|
|
|
// -- OR -- |
|
|
|
// evaluates to false |
|
boolean falseValue = parser.parseExpression("true or false").getValue(Boolean.class); |
|
|
|
// evaluates to true |
|
String expression = "isMember('Nikola Tesla') or isMember('Albert Einstien')"; |
|
boolean trueValue = parser.parseExpression(expression).getValue(societyContext, Boolean.class); |
|
|
|
// -- NOT -- |
|
|
|
// evaluates to false |
|
boolean falseValue = parser.parseExpression("!true").getValue(Boolean.class); |
|
|
|
|
|
// -- AND and NOT -- |
|
String expression = "isMember('Nikola Tesla') and !isMember('Mihajlo Pupin')"; |
|
boolean falseValue = parser.parseExpression(expression).getValue(societyContext, Boolean.class);</programlisting></para> |
|
</section> |
|
|
|
<section> |
|
<title>Mathematical operators</title> |
|
|
|
<para>The addition operator can be used on numbers, strings and dates. |
|
Subtraction can be used on numbers and dates. Multiplication and |
|
division can be used only on numbers. Other mathematical operators |
|
supported are modulus (%) and exponential power (^). Standard operator |
|
precedence is enforced. These operators are demonstrated below </para> |
|
|
|
<para><programlisting>// Addition |
|
int two = parser.parseExpression("1 + 1").getValue(Integer.class); // 2 |
|
|
|
String testString = parser.parseExpression("'test' + ' ' + 'string'").getValue(String.class); // 'test string' |
|
|
|
// Subtraction |
|
int four = parser.parseExpression("1 - -3").getValue(Integer.class); // 4 |
|
|
|
double d = parser.parseExpression("1000.00 - 1e4").getValue(Double.class); // -9000 |
|
|
|
// Multiplication |
|
int six = parser.parseExpression("-2 * -3").getValue(Integer.class); // 6 |
|
|
|
double twentyFour = parser.parseExpression("2.0 * 3e0 * 4").getValue(Double.class); // 24.0 |
|
|
|
// Division |
|
int minusTwo = parser.parseExpression("6 / -3").getValue(Integer.class); // -2 |
|
|
|
double one = parser.parseExpression("8.0 / 4e0 / 2").getValue(Double.class); // 1.0 |
|
|
|
// Modulus |
|
int three = parser.parseExpression("7 % 4").getValue(Integer.class); // 3 |
|
|
|
int one = parser.parseExpression("8 / 5 % 2").getValue(Integer.class); // 1 |
|
|
|
// Operator precedence |
|
int minusTwentyOne = parser.parseExpression("1+2-3*8").getValue(Integer.class); // -21 |
|
|
|
|
|
|
|
</programlisting></para> |
|
</section> |
|
</section> |
|
|
|
<section> |
|
<title>Assignment</title> |
|
|
|
<para>Setting of a property is done by using the assignment operator. |
|
This would typically be done within a call to SetValue but can also be |
|
done inside a call to GetValue </para> |
|
|
|
<programlisting>Inventor inventor = new Inventor(); |
|
StandardEvaluationContext inventorContext = new StandardEvaluationContext(); |
|
inventorContext.setRootObject(inventor); |
|
|
|
parser.parseExpression("Name").setValue(inventorContext, "Alexander Seovic2"); |
|
|
|
// alternatively |
|
|
|
String aleks = parser.parseExpression("Name = 'Alexandar Seovic'").getValue(inventorContext, String.class); |
|
|
|
</programlisting> |
|
|
|
<para></para> |
|
</section> |
|
|
|
<section> |
|
<title>Types</title> |
|
|
|
<para>The specic 'T' operator can be used to specify an instance of |
|
java.lang.Class (the 'type'). Static methods are invoked using this |
|
operator as well</para> |
|
|
|
<programlisting>Class dateClass = parser.parseExpression("T(java.util.Date)").getValue(Class.class); |
|
|
|
|
|
boolean isEqual = parser.parseExpression("T(java.math.RoundingMode).CEILING < T(java.math.RoundingMode).FLOOR").getValue(Boolean.class); |
|
</programlisting> |
|
</section> |
|
|
|
<section> |
|
<title>Constructors</title> |
|
|
|
<para>Constructors can be invoked using the new operator. The fully |
|
qualified classname should be used for all but the primitive type and |
|
String (where int, float, etc, can be used).</para> |
|
|
|
<programlisting>Inventor einstein = |
|
parser.parseExpression("new org.spring.samples.spel.inventor.Inventor('Albert Einstein', 'German')").getValue(Inventor.class); |
|
|
|
//create new inventor instance within add method of List |
|
parser.parseExpression("Members.add(new org.spring.samples.spel.inventor.Inventor('Albert Einstein', 'German'))").getValue(societyContext); |
|
</programlisting> |
|
</section> |
|
|
|
<section id="expressions-ref-variables"> |
|
<title>Variables</title> |
|
|
|
<para>Variables can referenced in the expression using the syntax |
|
#variableName. Variables are set using the method setVariable on the |
|
StandardEvaluationContext. </para> |
|
|
|
<programlisting>Inventor tesla = new Inventor("Nikola Tesla", "Serbian"); |
|
StandardEvaluationContext context = new StandardEvaluationContext(); |
|
context.setVariable("newName", "Mike Tesla"); |
|
context.setRootObject(tesla); |
|
|
|
parser.parseExpression("Name = #newName").getValue(context); |
|
|
|
System.out.println(tesla.getName()) // "Mike Tesla"</programlisting> |
|
|
|
<section> |
|
<title>The #this and #root variables</title> |
|
|
|
<para>blah blah </para> |
|
</section> |
|
</section> |
|
|
|
<section id="expressions-ref-functions"> |
|
<title>Functions</title> |
|
|
|
<para>blah blah</para> |
|
</section> |
|
|
|
<section> |
|
<title>Ternary Operator (If-Then-Else)</title> |
|
|
|
<para>You can use the ternary operator for performing if-then-else |
|
conditional logic inside the expression. A minimal example is; </para> |
|
|
|
<programlisting language="java">String falseString = parser.parseExpression("false ? 'trueExp' : 'falseExp'").getValue(String.class);</programlisting> |
|
|
|
<para>In this case, the boolean false results in returning the string |
|
value 'falseExp'. A less artificial example is shown below.</para> |
|
|
|
<programlisting>parser.parseExpression("Name").setValue(societyContext, "IEEE"); |
|
societyContext.setVariable("queryName", "Nikola Tesla"); |
|
|
|
expression = "isMember(#queryName)? #queryName + ' is a member of the ' " + |
|
"+ Name + ' Society' : #queryName + ' is not a member of the ' + Name + ' Society'"; |
|
|
|
String queryResultString = parser.parseExpression(expression).getValue(societyContext, String.class);</programlisting> |
|
</section> |
|
|
|
<section> |
|
<title>List Selection</title> |
|
|
|
<para>List selection is a powerful expression language feature that |
|
allow you to transform the source list into another list by selecting |
|
from its "rows". In other words, selection is comparable to using SQL |
|
with a WHERE clause.</para> |
|
|
|
<para>Selection uses the syntax ?{projectionExpression}. This will |
|
filter the list and return a new list containing a subset of the |
|
original element list. For example, selection would allow us to easily |
|
get a list of Serbian inventors:</para> |
|
|
|
<programlisting>List<Inventor> list = (List<Inventor>) parser.parseExpression("Members.?{Nationality == 'Serbian'}").getValue(societyContext);</programlisting> |
|
</section> |
|
|
|
<section> |
|
<title>Expression templating</title> |
|
|
|
<para>blah blah</para> |
|
</section> |
|
</section> |
|
|
|
<section id="expressions-example-classes"> |
|
<title>Classes used in the examples</title> |
|
|
|
<para></para> |
|
</section> |
|
</chapter> |