diff --git a/spring-framework-reference/src/expressions.xml b/spring-framework-reference/src/expressions.xml index e8b74de7f1c..4c7ed33209e 100644 --- a/spring-framework-reference/src/expressions.xml +++ b/spring-framework-reference/src/expressions.xml @@ -20,14 +20,14 @@ 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 + said, SpEL is based on a technology agnostic API allowing other expression language implementations to be integrated should the need arise. 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 - chapter use SpEL as if it was an independent expression language. This + chapter use SpEL as if it were an independent expression language. This requires creating a few bootstrapping 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 @@ -117,10 +117,10 @@ This section introduces the simple use of SpEL interfaces and its expression language. The complete language reference can be found in the section Language - Reference + Reference. The following code introduces the SpEL API to evaluate the literal - string expression 'Hello World' + string expression 'Hello World'. ExpressionParser parser = new SpelExpressionParser(); Expression exp = parser.parseExpression("'Hello World'"); @@ -129,7 +129,7 @@ String message = (String) exp.getValue();The value of the The SpEL classes and interfaces you are most likely to use are located in the packages org.springframework.expression - and its sub package and spel.support. + and its sub packages and spel.support. The interface ExpressionParser is responsible for parsing an expression string. In this example the @@ -140,22 +140,22 @@ String message = (String) exp.getValue();The value of the ParseException and EvaluationException when calling 'parser.parseExpression' and - 'exp.getValue' respectfully. + 'exp.getValue' respectively. SpEL supports a wide range of features, such as calling methods, - accessing properties and calling constructors. + accessing properties, and calling constructors. As an example of method invocation, we call the 'concat' method on - the string literal + the string literal. - ExpressionParser parser = new SpelExpressionParser(); + ExpressionParser parser = new SpelExpressionParser(); Expression exp = parser.parseExpression("'Hello World'.concat('!')"); String message = (String) exp.getValue(); The value of message is now 'Hello World!'. As an example of calling a JavaBean property, the String property - 'Bytes' can be called as shown below + 'Bytes' can be called as shown below. ExpressionParser parser = new SpelExpressionParser(); @@ -167,7 +167,7 @@ byte[] bytes = (byte[]) exp.getValue(); SpEL also supports nested properties using standard 'dot' notation, i.e. prop1.prop2.prop3 and the setting of property values - Public fields may also be accessed + Public fields may also be accessed. ExpressionParser parser = new SpelExpressionParser(); @@ -177,7 +177,7 @@ Expression exp = parser.parseExpression("'Hello World'.byt int length = (Integer) exp.getValue(); The String's constructor can be called instead of using a string - literal + literal. ExpressionParser parser = new SpelExpressionParser(); Expression exp = parser.parseExpression("new String('hello world').toUpperCase()"); @@ -187,19 +187,19 @@ String message = exp.getValue(String.class); getValue(Class<T> desiredResultType). Using this method removes the need to cast the value of the expression to the desired result type. An EvaluationException will be thrown if the - value an not be cast to the type T or converted using + value cannot be cast to the type T or converted using the registered type converter. - The more common usage of SpEL is provide an expression string that + The more common usage of SpEL is to provide an expression string that is evaluated against a specific object instance. In the following example - we retrieve the Name property from an instance of the + we retrieve the name property from an instance of the Inventor class. // Create and set a calendar GregorianCalendar c = new GregorianCalendar(); c.set(1856, 7, 9); -// The constructor arguments are name, birthday, and nationaltiy. +// The constructor arguments are name, birthday, and nationality. Inventor tesla = new Inventor("Nikola Tesla", c.getTime(), "Serbian"); ExpressionParser parser = new SpelExpressionParser(); @@ -211,19 +211,21 @@ context.setRootObject(tesla); String name = (String) exp.getValue(context);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 + 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. - + + 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. - As a final introductory example, the use of a boolean operator is - shown using the Inventor object in the previous example + + As a final introductory example, the use of a boolean operator is + shown using the Inventor object in the previous example. Expression exp = parser.parseExpression("name == 'Nikola Tesla'"); boolean result = exp.getValue(context, Boolean.class); // evaluates to true @@ -236,14 +238,14 @@ boolean result = exp.getValue(context, Boolean.class); // evaluates to trueStandardEvaluationContext, uses reflection to manipulate the object, caching - java.lang.reflect's Method, + java.lang.reflect's Method, Field, and Constructor instances for increased performance. The StandardEvaluationContext is where you specify the root object to evaluate against via the method setRootObject or passing the root object into - the constructor. . You can also specify variables and functions that + the constructor. You can also specify variables and functions that will be used in the expression using the methods setVariable and registerFunction. The use of variables and @@ -278,7 +280,7 @@ boolean result = exp.getValue(context, Boolean.class); // evaluates to trueBoolean before being placed in it. A simple example: - class Simple { + class Simple { public List<Boolean> booleanList = new ArrayList<Boolean>(); } @@ -330,7 +332,7 @@ Boolean b = simple.booleanList.get(0); </bean> You can also refer to other bean properties by name, for - example + example. <bean id="numberGuess" class="org.spring.samples.NumberGuess"> <property name="randomNumber" value="#{ T(java.lang.Math).random() * 100.0 }"/> @@ -354,7 +356,7 @@ Boolean b = simple.booleanList.get(0); value. Here is an example to set the default value of a field - variable + variable. public static class FieldValueTestBean @@ -376,7 +378,7 @@ Boolean b = simple.booleanList.get(0); The equivalent but on a property setter method is shown - below + below. public static class PropertyValueTestBean @@ -438,7 +440,7 @@ Boolean b = simple.booleanList.get(0); Literal expressions The types of literal expressions supported are strings, dates, - numeric values (int, real, and hex), boolean and null. String are + numeric values (int, real, and hex), boolean and null. Strings 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 @@ -473,7 +475,7 @@ Object nullValue = parser.parseExpression("null").getValue(); and tesla, were populated with data listed in the section Classes used in the examples. To navigate "down" and get Tesla's year of birth and - Pupin's city of birth the following expressions are used + Pupin's city of birth the following expressions are used. // evals to 1856 int year = (Integer) parser.parseExpression("Birthdate.Year + 1900").getValue(context); @@ -509,9 +511,9 @@ String invention = parser.parseExpression("Members[0].Inventions[6]").getValue(s The contents of maps are obtained by specifying the literal key value within the brackets. In this case, because keys for the Officers - map are strings, we can specify string literal. + map are strings, we can specify string literals. - // Officer's Dictionary + // Officer's Dictionary Inventor pupin = parser.parseExpression("Officers['president']").getValue(societyContext, Inventor.class); @@ -559,8 +561,8 @@ boolean trueValue = parser.parseExpression("2 == 2").getValue(Boolean.class); boolean falseValue = parser.parseExpression("2 < -5.0").getValue(Boolean.class); // evaluates to true -boolean trueValue = parser.parseExpression("'black' < 'block'").getValue(Boolean.class);In - addition to standard relational operators SpEL supports the +boolean trueValue = parser.parseExpression("'black' < 'block'").getValue(Boolean.class); + In addition to standard relational operators SpEL supports the 'instanceof' and regular expression based 'matches' operator. // evaluates to false @@ -581,7 +583,7 @@ boolean falseValue = Logical operators The logical operators that are supported are and, or, and not. - Their use is demonstrated below + Their use is demonstrated below. // -- AND -- @@ -619,7 +621,7 @@ boolean falseValue = parser.parseExpression(expression).getValue(societyContext, 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 + precedence is enforced. These operators are demonstrated below. // Addition int two = parser.parseExpression("1 + 1").getValue(Integer.class); // 2 @@ -659,7 +661,7 @@ int minusTwentyOne = parser.parseExpression("1+2-3*8").getValue(Integer.class); 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 + getValue. Inventor inventor = new Inventor(); StandardEvaluationContext inventorContext = new StandardEvaluationContext(inventor); @@ -781,7 +783,7 @@ List<Integer> primesGreaterThanTen = You can extend SpEL by registering user defined functions that can be called within the expression string. The function is registered with the StandardEvaluationContext using the - method + method. public void registerFunction(String name, Method m) @@ -801,7 +803,7 @@ List<Integer> primesGreaterThanTen = } This method is then registered with the evaluation context and can - be used within an expression string + be used within an expression string. ExpressionParser parser = new SpelExpressionParser(); StandardEvaluationContext context = new StandardEvaluationContext(); @@ -818,13 +820,13 @@ String helloWorldReversed = Ternary Operator (If-Then-Else) You can use the ternary operator for performing if-then-else - conditional logic inside the expression. A minimal example is; + conditional logic inside the expression. A minimal example is: String falseString = parser.parseExpression("false ? 'trueExp' : 'falseExp'").getValue(String.class); In this case, the boolean false results in returning the string - value 'falseExp'. A less artificial example is shown below. + value 'falseExp'. A more realistic example is shown below. parser.parseExpression("Name").setValue(societyContext, "IEEE"); societyContext.setVariable("queryName", "Nikola Tesla"); @@ -837,7 +839,7 @@ String queryResultString = // queryResultString = "Nikola Tesla is a member of the IEEE Society" Also see the next section on the Elvis operator for an even - shorter syntax for the ternary operator + shorter syntax for the ternary operator.
@@ -846,16 +848,16 @@ String queryResultString = The Elvis operator is a shortening of the ternary operator syntax and is used in the Groovy - language. The ternary operator syntax you usually have to repeat a - variable twice, for example + language. With the ternary operator syntax you usually have to repeat a + variable twice, for example: String name = "Elvis Presley"; String displayName = name != null ? name : "Unknown"; Instead you can use the Elvis operator, named for the resemblance - to Elvis' hair style. + to Elvis' hair style. - ExpressionParser parser = new SpelExpressionParser(); + ExpressionParser parser = new SpelExpressionParser(); String name = parser.parseExpression("null?:'Unknown'").getValue(String.class); @@ -863,9 +865,9 @@ System.out.println(name); // 'Unknown' - Here is a more complex example + Here is a more complex example. - ExpressionParser parser = new SpelExpressionParser(); + ExpressionParser parser = new SpelExpressionParser(); Inventor tesla = new Inventor("Nikola Tesla", "Serbian"); StandardEvaluationContext context = new StandardEvaluationContext(tesla); @@ -892,7 +894,7 @@ System.out.println(name); // Elvis Presley properties of the object. To avoid this, the safe navigation operator will simply return null instead of throwing an exception. - ExpressionParser parser = new SpelExpressionParser(); + ExpressionParser parser = new SpelExpressionParser(); Inventor tesla = new Inventor("Nikola Tesla", "Serbian"); tesla.setPlaceOfBirth(new PlaceOfBirth("Smiljan")); @@ -912,7 +914,7 @@ System.out.println(city); // null - does not throw NullPointerException!!! Collection Selection - Selection is a powerful expression language feature that allow you + Selection is a powerful expression language feature that allows you to transform some source collection into another by selecting from its entries. @@ -969,7 +971,7 @@ List placesOfBirth = (List)parser.parseExpression("Members.![placeOfBirth.city]" Expression templating Expression templates allow a mixing of literal text with one or - more evaluation blocks. Each evaluation block is delimited with a prefix + more evaluation blocks. Each evaluation block is delimited with prefix and suffix characters that you can define, a common choice is to use ${} as the delimiters. For example, @@ -980,14 +982,14 @@ List placesOfBirth = (List)parser.parseExpression("Members.![placeOfBirth.city]" // evaluates to "random number is 0.7038186818312008" The string is evaluated by concatenating the literal text 'random - number is' with the result of evaluating the expression inside the ${} + number is ' with the result of evaluating the expression inside the ${} delimiter, in this case the result of calling that random() method. The - second argument to the method parseExpression() of + second argument to the method parseExpression() is of the type ParserContext. The ParserContext interface is used to influence how the expression is parsed in order to support the expression templating functionality. The definition of - TemplatedParserContext is shown below + TemplatedParserContext is shown below. public class TemplatedParserContext implements ParserContext { @@ -1113,7 +1115,7 @@ public class PlaceOfBirth { Society.java - package org.spring.samples.spel.inventor; + package org.spring.samples.spel.inventor; import java.util.*;