Fix formatting in SpEL chapter

This commit is contained in:
Sam Brannen 2015-09-28 22:44:31 +02:00
parent 8d58f66c0f
commit faa2f5cc50
1 changed files with 45 additions and 45 deletions

View File

@ -78,7 +78,7 @@ The following code introduces the SpEL API to evaluate the literal string expres
[subs="verbatim,quotes"] [subs="verbatim,quotes"]
---- ----
ExpressionParser parser = new SpelExpressionParser(); ExpressionParser parser = new SpelExpressionParser();
Expression exp = parser.parseExpression("**''Hello World''**"); Expression exp = parser.parseExpression("**'Hello World'**");
String message = (String) exp.getValue(); String message = (String) exp.getValue();
---- ----
@ -91,25 +91,25 @@ The interface `ExpressionParser` is responsible for parsing an expression string
this example the expression string is a string literal denoted by the surrounding single this example the expression string is a string literal denoted by the surrounding single
quotes. The interface `Expression` is responsible for evaluating the previously defined quotes. The interface `Expression` is responsible for evaluating the previously defined
expression string. There are two exceptions that can be thrown, `ParseException` and expression string. There are two exceptions that can be thrown, `ParseException` and
`EvaluationException` when calling '`parser.parseExpression`' and '`exp.getValue`' `EvaluationException` when calling `parser.parseExpression` and `exp.getValue`
respectively. respectively.
SpEL supports a wide range of features, such as calling methods, accessing properties, SpEL supports a wide range of features, such as calling methods, accessing properties,
and calling constructors. and calling constructors.
As an example of method invocation, we call the 'concat' method on the string literal. As an example of method invocation, we call the `concat` method on the string literal.
[source,java,indent=0] [source,java,indent=0]
[subs="verbatim,quotes"] [subs="verbatim,quotes"]
---- ----
ExpressionParser parser = new SpelExpressionParser(); ExpressionParser parser = new SpelExpressionParser();
Expression exp = parser.parseExpression("**''Hello World''.concat(''!'')**"); Expression exp = parser.parseExpression("**'Hello World'.concat('!')**");
String message = (String) exp.getValue(); String message = (String) exp.getValue();
---- ----
The value of message is now 'Hello World!'. The value of message is now 'Hello World!'.
As an example of calling a JavaBean property, the String property 'Bytes' can be called As an example of calling a JavaBean property, the String property `Bytes` can be called
as shown below. as shown below.
[source,java,indent=0] [source,java,indent=0]
@ -118,11 +118,11 @@ as shown below.
ExpressionParser parser = new SpelExpressionParser(); ExpressionParser parser = new SpelExpressionParser();
// invokes 'getBytes()' // invokes 'getBytes()'
Expression exp = parser.parseExpression("**''Hello World''.bytes**"); Expression exp = parser.parseExpression("**'Hello World'.bytes**");
byte[] bytes = (byte[]) exp.getValue(); byte[] bytes = (byte[]) exp.getValue();
---- ----
SpEL also supports nested properties using standard 'dot' notation, i.e. SpEL also supports nested properties using standard _dot_ notation, i.e.
prop1.prop2.prop3 and the setting of property values prop1.prop2.prop3 and the setting of property values
Public fields may also be accessed. Public fields may also be accessed.
@ -133,7 +133,7 @@ Public fields may also be accessed.
ExpressionParser parser = new SpelExpressionParser(); ExpressionParser parser = new SpelExpressionParser();
// invokes 'getBytes().length' // invokes 'getBytes().length'
Expression exp = parser.parseExpression("**''Hello World''.bytes.length**"); Expression exp = parser.parseExpression("**'Hello World'.bytes.length**");
int length = (Integer) exp.getValue(); int length = (Integer) exp.getValue();
---- ----
@ -143,7 +143,7 @@ The String's constructor can be called instead of using a string literal.
[subs="verbatim,quotes"] [subs="verbatim,quotes"]
---- ----
ExpressionParser parser = new SpelExpressionParser(); ExpressionParser parser = new SpelExpressionParser();
Expression exp = parser.parseExpression("**new String(''hello world'').toUpperCase()**"); Expression exp = parser.parseExpression("**new String('hello world').toUpperCase()**");
String message = exp.getValue(String.class); String message = exp.getValue(String.class);
---- ----
@ -175,7 +175,7 @@ example we retrieve the `name` property from an instance of the Inventor class.
String name = (String) exp.getValue(context); String name = (String) exp.getValue(context);
---- ----
In the last line, the value of the string variable 'name' will be set to "Nikola Tesla". 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" The class StandardEvaluationContext is where you can specify which object the "name"
property will be evaluated against. This is the mechanism to use if the root object is property will be evaluated against. This is the mechanism to use if the root object is
unlikely to change, it can simply be set once in the evaluation context. If the root unlikely to change, it can simply be set once in the evaluation context. If the root
@ -226,7 +226,7 @@ Inventor object in the previous example.
[source,java,indent=0] [source,java,indent=0]
[subs="verbatim,quotes"] [subs="verbatim,quotes"]
---- ----
Expression exp = parser.parseExpression("name == ''Nikola Tesla''"); Expression exp = parser.parseExpression("name == 'Nikola Tesla'");
boolean result = exp.getValue(context, Boolean.class); // evaluates to true boolean result = exp.getValue(context, Boolean.class); // evaluates to true
---- ----
@ -237,8 +237,8 @@ Inventor object in the previous example.
The interface `EvaluationContext` is used when evaluating an expression to resolve The interface `EvaluationContext` is used when evaluating an expression to resolve
properties, methods, fields, and to help perform type conversion. The out-of-the-box properties, methods, fields, and to help perform type conversion. The out-of-the-box
implementation, `StandardEvaluationContext`, uses reflection to manipulate the object, implementation, `StandardEvaluationContext`, uses reflection to manipulate the object,
caching `java.lang.reflect`'s `Method`, `Field`, and `Constructor` instances for caching `java.lang.reflect.Method`, `java.lang.reflect.Field`, and
increased performance. `java.lang.reflect.Constructor` instances for increased performance.
The `StandardEvaluationContext` is where you may specify the root object to evaluate The `StandardEvaluationContext` is where you may specify the root object to evaluate
against via the method `setRootObject()` or passing the root object into the against via the method `setRootObject()` or passing the root object into the
@ -291,7 +291,7 @@ being placed in it. A simple example:
=== Parser configuration === Parser configuration
It is possible to configure the SpEL expression parser using a parser configuration object It is possible to configure the SpEL expression parser using a parser configuration object
(`org.springframework.expression.spel.SpelParserConfiguration`). The configuration (`org.springframework.expression.spel.SpelParserConfiguration`). The configuration
object controls the behaviour of some of the expression components. For example, if object controls the behavior of some of the expression components. For example, if
indexing into an array or collection and the element at the specified index is `null` indexing into an array or collection and the element at the specified index is `null`
it is possible to automatically create the element. This is useful when using expressions made up of a it is possible to automatically create the element. This is useful when using expressions made up of a
chain of property references. If indexing into an array or list chain of property references. If indexing into an array or list
@ -412,7 +412,7 @@ The second way to configure the compiler is for use when SpEL is embedded inside
component and it may not be possible to configure via a configuration object. component and it may not be possible to configure via a configuration object.
In these cases it is possible to use a system property. The property In these cases it is possible to use a system property. The property
`spring.expression.compiler.mode` can be set to one of the `SpelCompilerMode` `spring.expression.compiler.mode` can be set to one of the `SpelCompilerMode`
enum values (`off`, `immediate` or `mixed`). enum values (`off`, `immediate`, or `mixed`).
[[expressions-compiler-limitations]] [[expressions-compiler-limitations]]
==== Compiler limitations ==== Compiler limitations
@ -564,7 +564,7 @@ Autowired methods and constructors can also use the `@Value` annotation.
@Autowired @Autowired
public MovieRecommender(CustomerPreferenceDao customerPreferenceDao, public MovieRecommender(CustomerPreferenceDao customerPreferenceDao,
@Value("#{systemProperties[''user.country'']}") String defaultLocale) { @Value("#{systemProperties['user.country']}") String defaultLocale) {
this.customerPreferenceDao = customerPreferenceDao; this.customerPreferenceDao = customerPreferenceDao;
this.defaultLocale = defaultLocale; this.defaultLocale = defaultLocale;
} }
@ -596,7 +596,7 @@ logical comparison operator.
ExpressionParser parser = new SpelExpressionParser(); ExpressionParser parser = new SpelExpressionParser();
// evals to "Hello World" // evals to "Hello World"
String helloWorld = (String) parser.parseExpression("''Hello World''").getValue(); String helloWorld = (String) parser.parseExpression("'Hello World'").getValue();
double avogadrosNumber = (Double) parser.parseExpression("6.0221415E+23").getValue(); double avogadrosNumber = (Double) parser.parseExpression("6.0221415E+23").getValue();
@ -667,15 +667,15 @@ string literals.
---- ----
// Officer's Dictionary // Officer's Dictionary
Inventor pupin = parser.parseExpression("Officers[''president'']").getValue( Inventor pupin = parser.parseExpression("Officers['president']").getValue(
societyContext, Inventor.class); societyContext, Inventor.class);
// evaluates to "Idvor" // evaluates to "Idvor"
String city = parser.parseExpression("Officers[''president''].PlaceOfBirth.City").getValue( String city = parser.parseExpression("Officers['president'].PlaceOfBirth.City").getValue(
societyContext, String.class); societyContext, String.class);
// setting values // setting values
parser.parseExpression("Officers[''advisors''][0].PlaceOfBirth.Country").setValue( parser.parseExpression("Officers['advisors'][0].PlaceOfBirth.Country").setValue(
societyContext, "Croatia"); societyContext, "Croatia");
---- ----
@ -691,7 +691,7 @@ Lists can be expressed directly in an expression using `{}` notation.
// evaluates to a Java list containing the four numbers // evaluates to a Java list containing the four numbers
List numbers = (List) parser.parseExpression("{1,2,3,4}").getValue(context); List numbers = (List) parser.parseExpression("{1,2,3,4}").getValue(context);
List listOfLists = (List) parser.parseExpression("{{''a'',''b''},{''x'',''y''}}").getValue(context); List listOfLists = (List) parser.parseExpression("{{'a','b'},{'x','y'}}").getValue(context);
---- ----
`{}` by itself means an empty list. For performance reasons, if the list is itself `{}` by itself means an empty list. For performance reasons, if the list is itself
@ -706,9 +706,9 @@ Maps can also be expressed directly in an expression using `{key:value}` notatio
[subs="verbatim,quotes"] [subs="verbatim,quotes"]
---- ----
// evaluates to a Java map containing the two entries // evaluates to a Java map containing the two entries
Map inventorInfo = (Map) parser.parseExpression("{name:''Nikola'',dob:''10-July-1856''}").getValue(context); Map inventorInfo = (Map) parser.parseExpression("{name:'Nikola',dob:'10-July-1856'}").getValue(context);
Map mapOfMaps = (Map) parser.parseExpression("{name:{first:''Nikola'',last:''Tesla''},dob:{day:10,month:''July'',year:1856}}").getValue(context); Map mapOfMaps = (Map) parser.parseExpression("{name:{first:'Nikola',last:'Tesla'},dob:{day:10,month:'July',year:1856}}").getValue(context);
---- ----
`{:}` by itself means an empty map. For performance reasons, if the map is itself composed `{:}` by itself means an empty map. For performance reasons, if the map is itself composed
of fixed literals or other nested constant structures (lists or maps) then a constant map is created of fixed literals or other nested constant structures (lists or maps) then a constant map is created
@ -746,10 +746,10 @@ on literals. Varargs are also supported.
[subs="verbatim,quotes"] [subs="verbatim,quotes"]
---- ----
// string literal, evaluates to "bc" // string literal, evaluates to "bc"
String c = parser.parseExpression("''abc''.substring(2, 3)").getValue(String.class); String c = parser.parseExpression("'abc'.substring(2, 3)").getValue(String.class);
// evaluates to true // evaluates to true
boolean isMember = parser.parseExpression("isMember(''Mihajlo Pupin'')").getValue( boolean isMember = parser.parseExpression("isMember('Mihajlo Pupin')").getValue(
societyContext, Boolean.class); societyContext, Boolean.class);
---- ----
@ -774,7 +774,7 @@ and greater than or equal are supported using standard operator notation.
boolean falseValue = parser.parseExpression("2 < -5.0").getValue(Boolean.class); boolean falseValue = parser.parseExpression("2 < -5.0").getValue(Boolean.class);
// evaluates to true // evaluates to true
boolean trueValue = parser.parseExpression("''black'' < ''block''").getValue(Boolean.class); boolean trueValue = parser.parseExpression("'black' < 'block'").getValue(Boolean.class);
---- ----
In addition to standard relational operators SpEL supports the `instanceof` and regular In addition to standard relational operators SpEL supports the `instanceof` and regular
@ -785,15 +785,15 @@ expression based `matches` operator.
---- ----
// evaluates to false // evaluates to false
boolean falseValue = parser.parseExpression( boolean falseValue = parser.parseExpression(
"''xyz'' instanceof T(int)").getValue(Boolean.class); "'xyz' instanceof T(int)").getValue(Boolean.class);
// evaluates to true // evaluates to true
boolean trueValue = parser.parseExpression( boolean trueValue = parser.parseExpression(
"''5.00'' matches ''\^-?\\d+(\\.\\d{2})?$''").getValue(Boolean.class); "'5.00' matches '\^-?\\d+(\\.\\d{2})?$'").getValue(Boolean.class);
//evaluates to false //evaluates to false
boolean falseValue = parser.parseExpression( boolean falseValue = parser.parseExpression(
"''5.0067'' matches ''\^-?\\d+(\\.\\d{2})?$''").getValue(Boolean.class); "'5.0067' matches '\^-?\\d+(\\.\\d{2})?$'").getValue(Boolean.class);
---- ----
Each symbolic operator can also be specified as a purely alphabetic equivalent. This Each symbolic operator can also be specified as a purely alphabetic equivalent. This
@ -817,7 +817,7 @@ below.
boolean falseValue = parser.parseExpression("true and false").getValue(Boolean.class); boolean falseValue = parser.parseExpression("true and false").getValue(Boolean.class);
// evaluates to true // evaluates to true
String expression = "isMember(''Nikola Tesla'') and isMember(''Mihajlo Pupin'')"; String expression = "isMember('Nikola Tesla') and isMember('Mihajlo Pupin')";
boolean trueValue = parser.parseExpression(expression).getValue(societyContext, Boolean.class); boolean trueValue = parser.parseExpression(expression).getValue(societyContext, Boolean.class);
// -- OR -- // -- OR --
@ -826,7 +826,7 @@ below.
boolean trueValue = parser.parseExpression("true or false").getValue(Boolean.class); boolean trueValue = parser.parseExpression("true or false").getValue(Boolean.class);
// evaluates to true // evaluates to true
String expression = "isMember(''Nikola Tesla'') or isMember(''Albert Einstein'')"; String expression = "isMember('Nikola Tesla') or isMember('Albert Einstein')";
boolean trueValue = parser.parseExpression(expression).getValue(societyContext, Boolean.class); boolean trueValue = parser.parseExpression(expression).getValue(societyContext, Boolean.class);
// -- NOT -- // -- NOT --
@ -835,7 +835,7 @@ below.
boolean falseValue = parser.parseExpression("!true").getValue(Boolean.class); boolean falseValue = parser.parseExpression("!true").getValue(Boolean.class);
// -- AND and NOT -- // -- AND and NOT --
String expression = "isMember(''Nikola Tesla'') and !isMember(''Mihajlo Pupin'')"; String expression = "isMember('Nikola Tesla') and !isMember('Mihajlo Pupin')";
boolean falseValue = parser.parseExpression(expression).getValue(societyContext, Boolean.class); boolean falseValue = parser.parseExpression(expression).getValue(societyContext, Boolean.class);
---- ----
@ -854,7 +854,7 @@ operators are demonstrated below.
int two = parser.parseExpression("1 + 1").getValue(Integer.class); // 2 int two = parser.parseExpression("1 + 1").getValue(Integer.class); // 2
String testString = parser.parseExpression( String testString = parser.parseExpression(
"''test'' + '' '' + ''string''").getValue(String.class); // 'test string' "'test' + ' ' + 'string'").getValue(String.class); // 'test string'
// Subtraction // Subtraction
int four = parser.parseExpression("1 - -3").getValue(Integer.class); // 4 int four = parser.parseExpression("1 - -3").getValue(Integer.class); // 4
@ -898,7 +898,7 @@ done within a call to `setValue` but can also be done inside a call to `getValue
// alternatively // alternatively
String aleks = parser.parseExpression( String aleks = parser.parseExpression(
"Name = ''Alexandar Seovic''").getValue(inventorContext, String.class); "Name = 'Alexandar Seovic'").getValue(inventorContext, String.class);
---- ----
@ -936,13 +936,13 @@ used).
[subs="verbatim,quotes"] [subs="verbatim,quotes"]
---- ----
Inventor einstein = p.parseExpression( Inventor einstein = p.parseExpression(
"new org.spring.samples.spel.inventor.Inventor(''Albert Einstein'', ''German'')") "new org.spring.samples.spel.inventor.Inventor('Albert Einstein', 'German')")
.getValue(Inventor.class); .getValue(Inventor.class);
//create new inventor instance within add method of List //create new inventor instance within add method of List
p.parseExpression( p.parseExpression(
"Members.add(new org.spring.samples.spel.inventor.Inventor( "Members.add(new org.spring.samples.spel.inventor.Inventor(
''Albert Einstein'', ''German''))").getValue(societyContext); 'Albert Einstein', 'German'))").getValue(societyContext);
---- ----
@ -1035,7 +1035,7 @@ expression string.
StringUtils.class.getDeclaredMethod("reverseString", new Class[] { String.class })); StringUtils.class.getDeclaredMethod("reverseString", new Class[] { String.class }));
String helloWorldReversed = parser.parseExpression( String helloWorldReversed = parser.parseExpression(
"#reverseString(''hello'')").getValue(context, String.class); "#reverseString('hello')").getValue(context, String.class);
---- ----
@ -1067,7 +1067,7 @@ the expression. A minimal example is:
[subs="verbatim,quotes"] [subs="verbatim,quotes"]
---- ----
String falseString = parser.parseExpression( String falseString = parser.parseExpression(
"false ? ''trueExp'' : ''falseExp''").getValue(String.class); "false ? 'trueExp' : 'falseExp'").getValue(String.class);
---- ----
In this case, the boolean false results in returning the string value 'falseExp'. A more In this case, the boolean false results in returning the string value 'falseExp'. A more
@ -1079,8 +1079,8 @@ realistic example is shown below.
parser.parseExpression("Name").setValue(societyContext, "IEEE"); parser.parseExpression("Name").setValue(societyContext, "IEEE");
societyContext.setVariable("queryName", "Nikola Tesla"); societyContext.setVariable("queryName", "Nikola Tesla");
expression = "isMember(#queryName)? #queryName + '' is a member of the '' " + expression = "isMember(#queryName)? #queryName + ' is a member of the ' " +
"+ Name + '' Society'' : #queryName + '' is not a member of the '' + Name + '' Society''"; "+ Name + ' Society' : #queryName + ' is not a member of the ' + Name + ' Society'";
String queryResultString = parser.parseExpression(expression) String queryResultString = parser.parseExpression(expression)
.getValue(societyContext, String.class); .getValue(societyContext, String.class);
@ -1113,7 +1113,7 @@ Instead you can use the Elvis operator, named for the resemblance to Elvis' hair
---- ----
ExpressionParser parser = new SpelExpressionParser(); ExpressionParser parser = new SpelExpressionParser();
String name = parser.parseExpression("null?:''Unknown''").getValue(String.class); String name = parser.parseExpression("null?:'Unknown'").getValue(String.class);
System.out.println(name); // 'Unknown' System.out.println(name); // 'Unknown'
---- ----
@ -1128,13 +1128,13 @@ Here is a more complex example.
Inventor tesla = new Inventor("Nikola Tesla", "Serbian"); Inventor tesla = new Inventor("Nikola Tesla", "Serbian");
StandardEvaluationContext context = new StandardEvaluationContext(tesla); StandardEvaluationContext context = new StandardEvaluationContext(tesla);
String name = parser.parseExpression("Name?:''Elvis Presley''").getValue(context, String.class); String name = parser.parseExpression("Name?:'Elvis Presley'").getValue(context, String.class);
System.out.println(name); // Nikola Tesla System.out.println(name); // Nikola Tesla
tesla.setName(null); tesla.setName(null);
name = parser.parseExpression("Name?:''Elvis Presley''").getValue(context, String.class); name = parser.parseExpression("Name?:'Elvis Presley'").getValue(context, String.class);
System.out.println(name); // Elvis Presley System.out.println(name); // Elvis Presley
---- ----
@ -1177,7 +1177,7 @@ The Elvis operator can be used to apply default values in expressions, e.g. in a
[source,java,indent=0] [source,java,indent=0]
[subs="verbatim,quotes"] [subs="verbatim,quotes"]
---- ----
@Value("#{systemProperties[''pop3.port''] ?: 25}") @Value("#{systemProperties['pop3.port'] ?: 25}")
---- ----
This will inject a system property `pop3.port` if it is defined or 25 if not. This will inject a system property `pop3.port` if it is defined or 25 if not.
@ -1198,7 +1198,7 @@ selection would allow us to easily get a list of Serbian inventors:
[subs="verbatim,quotes"] [subs="verbatim,quotes"]
---- ----
List<Inventor> list = (List<Inventor>) parser.parseExpression( List<Inventor> list = (List<Inventor>) parser.parseExpression(
"Members.?[Nationality == ''Serbian'']").getValue(societyContext); "Members.?[Nationality == 'Serbian']").getValue(societyContext);
---- ----
Selection is possible upon both lists and maps. In the former case the selection Selection is possible upon both lists and maps. In the former case the selection