Fix #this and #root variable examples in SpEL documentation

This commit actually introduces a new example for #root variable usage,
which was previously missing.

Closes gh-31770
This commit is contained in:
Sam Brannen 2023-12-06 16:51:45 +01:00
parent 9f305bfaab
commit f14b122c9c
2 changed files with 116 additions and 30 deletions

View File

@ -53,8 +53,10 @@ Kotlin::
The `#this` variable is always defined and refers to the current evaluation object
(against which unqualified references are resolved). The `#root` variable is always
defined and refers to the root context object. Although `#this` may vary as components of
an expression are evaluated, `#root` always refers to the root. The following examples
show how to use the `#this` and `#root` variables:
an expression are evaluated, `#root` always refers to the root.
The following example shows how to use the `#this` variable in conjunction with
xref:core/expressions/language-ref/collection-selection.adoc[collection selection].
[tabs]
======
@ -62,40 +64,95 @@ Java::
+
[source,java,indent=0,subs="verbatim,quotes",role="primary"]
----
// create an array of integers
List<Integer> primes = new ArrayList<>();
primes.addAll(Arrays.asList(2,3,5,7,11,13,17));
// Create a list of prime integers.
List<Integer> primes = List.of(2, 3, 5, 7, 11, 13, 17);
// create parser and set variable 'primes' as the array of integers
// Create parser and set variable 'primes' as the list of integers.
ExpressionParser parser = new SpelExpressionParser();
EvaluationContext context = SimpleEvaluationContext.forReadOnlyDataAccess();
EvaluationContext context = SimpleEvaluationContext.forReadWriteDataBinding().build();
context.setVariable("primes", primes);
// all prime numbers > 10 from the list (using selection ?{...})
// evaluates to [11, 13, 17]
List<Integer> primesGreaterThanTen = (List<Integer>) parser.parseExpression(
"#primes.?[#this>10]").getValue(context);
// Select all prime numbers > 10 from the list (using selection ?{...}).
String expression = "#primes.?[#this > 10]";
// Evaluates to a list containing [11, 13, 17].
List<Integer> primesGreaterThanTen =
parser.parseExpression(expression).getValue(context, List.class);
----
Kotlin::
+
[source,kotlin,indent=0,subs="verbatim,quotes",role="secondary"]
----
// create an array of integers
val primes = ArrayList<Int>()
primes.addAll(listOf(2, 3, 5, 7, 11, 13, 17))
// Create a list of prime integers.
val primes = listOf(2, 3, 5, 7, 11, 13, 17)
// create parser and set variable 'primes' as the array of integers
// Create parser and set variable 'primes' as the list of integers.
val parser = SpelExpressionParser()
val context = SimpleEvaluationContext.forReadOnlyDataAccess()
val context = SimpleEvaluationContext.forReadWriteDataBinding().build()
context.setVariable("primes", primes)
// all prime numbers > 10 from the list (using selection ?{...})
// evaluates to [11, 13, 17]
val primesGreaterThanTen = parser.parseExpression(
"#primes.?[#this>10]").getValue(context) as List<Int>
// Select all prime numbers > 10 from the list (using selection ?{...}).
val expression = "#primes.?[#this > 10]"
// Evaluates to a list containing [11, 13, 17].
val primesGreaterThanTen = parser.parseExpression(expression)
.getValue(context) as List<Int>
----
======
The following example shows how to use the `#this` and `#root` variables together in
conjunction with
xref:core/expressions/language-ref/collection-projection.adoc[collection projection].
[tabs]
======
Java::
+
[source,java,indent=0,subs="verbatim,quotes",role="primary"]
----
// Create parser and evaluation context.
ExpressionParser parser = new SpelExpressionParser();
EvaluationContext context = SimpleEvaluationContext.forReadWriteDataBinding().build();
// Create an inventor to use as the root context object.
Inventor tesla = new Inventor("Nikola Tesla");
tesla.setInventions("Telephone repeater", "Tesla coil transformer");
// Iterate over all inventions of the Inventor referenced as the #root
// object, and generate a list of strings whose contents take the form
// "<inventor's name> invented the <invention>." (using projection !{...}).
String expression = "#root.inventions.![#root.name + ' invented the ' + #this + '.']";
// Evaluates to a list containing:
// "Nikola Tesla invented the Telephone repeater."
// "Nikola Tesla invented the Tesla coil transformer."
List<String> results = parser.parseExpression(expression)
.getValue(context, tesla, List.class);
----
Kotlin::
+
[source,kotlin,indent=0,subs="verbatim,quotes",role="secondary"]
----
// Create parser and evaluation context.
val parser = SpelExpressionParser()
val context = SimpleEvaluationContext.forReadWriteDataBinding().build()
// Create an inventor to use as the root context object.
val tesla = Inventor("Nikola Tesla")
tesla.setInventions("Telephone repeater", "Tesla coil transformer")
// Iterate over all inventions of the Inventor referenced as the #root
// object, and generate a list of strings whose contents take the form
// "<inventor's name> invented the <invention>." (using projection !{...}).
val expression = "#root.inventions.![#root.name + ' invented the ' + #this + '.']"
// Evaluates to a list containing:
// "Nikola Tesla invented the Telephone repeater."
// "Nikola Tesla invented the Tesla coil transformer."
val results = parser.parseExpression(expression)
.getValue(context, tesla, List::class.java)
----
======

View File

@ -20,7 +20,6 @@ import java.lang.invoke.MethodHandle;
import java.lang.invoke.MethodHandles;
import java.lang.invoke.MethodType;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date;
import java.util.GregorianCalendar;
import java.util.HashMap;
@ -374,20 +373,50 @@ class SpelDocumentationTests extends AbstractExpressionTests {
@Test
@SuppressWarnings("unchecked")
void specialVariables() throws Exception {
// create an array of integers
List<Integer> primes = Arrays.asList(2, 3, 5, 7, 11, 13, 17);
void thisVariable() {
// Create a list of prime integers.
List<Integer> primes = List.of(2, 3, 5, 7, 11, 13, 17);
// create parser and set variable 'primes' as the array of integers
// Create parser and set variable 'primes' as the list of integers.
ExpressionParser parser = new SpelExpressionParser();
StandardEvaluationContext context = new StandardEvaluationContext();
context.setVariable("primes",primes);
EvaluationContext context = SimpleEvaluationContext.forReadWriteDataBinding().build();
context.setVariable("primes", primes);
// all prime numbers > 10 from the list (using selection ?{...})
List<Integer> primesGreaterThanTen = (List<Integer>) parser.parseExpression("#primes.?[#this>10]").getValue(context);
assertThat(primesGreaterThanTen.toString()).isEqualTo("[11, 13, 17]");
// Select all prime numbers > 10 from the list (using selection ?{...}).
String expression = "#primes.?[#this > 10]";
// Evaluates to a list containing [11, 13, 17].
List<Integer> primesGreaterThanTen =
parser.parseExpression(expression).getValue(context, List.class);
assertThat(primesGreaterThanTen).containsExactly(11, 13, 17);
}
@Test
@SuppressWarnings("unchecked")
void thisAndRootVariables() {
// Create parser and evaluation context.
ExpressionParser parser = new SpelExpressionParser();
EvaluationContext context = SimpleEvaluationContext.forReadWriteDataBinding().build();
// Create an inventor to use as the root context object.
Inventor tesla = new Inventor("Nikola Tesla");
tesla.setInventions("Telephone repeater", "Tesla coil transformer");
// Iterate over all inventions of the Inventor referenced as the #root
// object, and generate a list of strings whose contents take the form
// "<inventor's name> invented the <invention>." (using projection !{...}).
String expression = "#root.inventions.![#root.name + ' invented the ' + #this + '.']";
// Evaluates to a list containing:
// Nikola Tesla invented the Telephone repeater.
// Nikola Tesla invented the Tesla coil transformer.
List<String> results = parser.parseExpression(expression).getValue(context, tesla, List.class);
assertThat(results).containsExactly(
"Nikola Tesla invented the Telephone repeater.",
"Nikola Tesla invented the Tesla coil transformer.");
}
@Test
void functions() throws Exception {