Polishing (backported from main)
This commit is contained in:
@@ -4,7 +4,7 @@
|
|||||||
Projection lets a collection drive the evaluation of a sub-expression, and the result is
|
Projection lets a collection drive the evaluation of a sub-expression, and the result is
|
||||||
a new collection. The syntax for projection is `.![projectionExpression]`. For example,
|
a new collection. The syntax for projection is `.![projectionExpression]`. For example,
|
||||||
suppose we have a list of inventors but want the list of cities where they were born.
|
suppose we have a list of inventors but want the list of cities where they were born.
|
||||||
Effectively, we want to evaluate 'placeOfBirth.city' for every entry in the inventor
|
Effectively, we want to evaluate `placeOfBirth.city` for every entry in the inventor
|
||||||
list. The following example uses projection to do so:
|
list. The following example uses projection to do so:
|
||||||
|
|
||||||
[tabs]
|
[tabs]
|
||||||
@@ -13,16 +13,18 @@ Java::
|
|||||||
+
|
+
|
||||||
[source,java,indent=0,subs="verbatim,quotes",role="primary"]
|
[source,java,indent=0,subs="verbatim,quotes",role="primary"]
|
||||||
----
|
----
|
||||||
// returns ['Smiljan', 'Idvor' ]
|
// evaluates to ["SmilJan", "Idvor"]
|
||||||
List placesOfBirth = (List)parser.parseExpression("members.![placeOfBirth.city]");
|
List placesOfBirth = parser.parseExpression("members.![placeOfBirth.city]")
|
||||||
|
.getValue(societyContext, List.class);
|
||||||
----
|
----
|
||||||
|
|
||||||
Kotlin::
|
Kotlin::
|
||||||
+
|
+
|
||||||
[source,kotlin,indent=0,subs="verbatim,quotes",role="secondary"]
|
[source,kotlin,indent=0,subs="verbatim,quotes",role="secondary"]
|
||||||
----
|
----
|
||||||
// returns ['Smiljan', 'Idvor' ]
|
// evaluates to ["SmilJan", "Idvor"]
|
||||||
val placesOfBirth = parser.parseExpression("members.![placeOfBirth.city]") as List<*>
|
val placesOfBirth = parser.parseExpression("members.![placeOfBirth.city]")
|
||||||
|
.getValue(societyContext) as List<*>
|
||||||
----
|
----
|
||||||
======
|
======
|
||||||
|
|
||||||
|
|||||||
@@ -28,13 +28,14 @@ Kotlin::
|
|||||||
======
|
======
|
||||||
|
|
||||||
Selection is supported for arrays and anything that implements `java.lang.Iterable` or
|
Selection is supported for arrays and anything that implements `java.lang.Iterable` or
|
||||||
`java.util.Map`. For a list or array, the selection criteria is evaluated against each
|
`java.util.Map`. For an array or `Iterable`, the selection expression is evaluated
|
||||||
individual element. Against a map, the selection criteria is evaluated against each map
|
against each individual element. Against a map, the selection expression is evaluated
|
||||||
entry (objects of the Java type `Map.Entry`). Each map entry has its `key` and `value`
|
against each map entry (objects of the Java type `Map.Entry`). Each map entry has its
|
||||||
accessible as properties for use in the selection.
|
`key` and `value` accessible as properties for use in the selection.
|
||||||
|
|
||||||
The following expression returns a new map that consists of those elements of the
|
Given a `Map` stored in a variable named `#map`, the following expression returns a new
|
||||||
original map where the entry's value is less than 27:
|
map that consists of those elements of the original map where the entry's value is less
|
||||||
|
than 27:
|
||||||
|
|
||||||
[tabs]
|
[tabs]
|
||||||
======
|
======
|
||||||
@@ -42,21 +43,21 @@ Java::
|
|||||||
+
|
+
|
||||||
[source,java,indent=0,subs="verbatim,quotes",role="primary"]
|
[source,java,indent=0,subs="verbatim,quotes",role="primary"]
|
||||||
----
|
----
|
||||||
Map newMap = parser.parseExpression("map.?[value<27]").getValue();
|
Map newMap = parser.parseExpression("#map.?[value < 27]").getValue(Map.class);
|
||||||
----
|
----
|
||||||
|
|
||||||
Kotlin::
|
Kotlin::
|
||||||
+
|
+
|
||||||
[source,kotlin,indent=0,subs="verbatim,quotes",role="secondary"]
|
[source,kotlin,indent=0,subs="verbatim,quotes",role="secondary"]
|
||||||
----
|
----
|
||||||
val newMap = parser.parseExpression("map.?[value<27]").getValue()
|
val newMap = parser.parseExpression("#map.?[value < 27]").getValue() as Map
|
||||||
----
|
----
|
||||||
======
|
======
|
||||||
|
|
||||||
In addition to returning all the selected elements, you can retrieve only the first or
|
In addition to returning all the selected elements, you can retrieve only the first or
|
||||||
the last element. To obtain the first element matching the selection, the syntax is
|
the last element. To obtain the first element matching the selection expression, the
|
||||||
`.^[selectionExpression]`. To obtain the last matching selection, the syntax is
|
syntax is `.^[selectionExpression]`. To obtain the last element matching the selection
|
||||||
`.$[selectionExpression]`.
|
expression, the syntax is `.$[selectionExpression]`.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -152,7 +152,7 @@ Kotlin::
|
|||||||
@Autowired
|
@Autowired
|
||||||
lateinit var accountService: AccountService
|
lateinit var accountService: AccountService
|
||||||
|
|
||||||
lateinit mockMvc: MockMvc
|
lateinit var mockMvc: MockMvc
|
||||||
|
|
||||||
@BeforeEach
|
@BeforeEach
|
||||||
fun setup(wac: WebApplicationContext) {
|
fun setup(wac: WebApplicationContext) {
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2002-2023 the original author or authors.
|
* Copyright 2002-2024 the original author or authors.
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
@@ -22,7 +22,8 @@ import org.springframework.util.ObjectUtils;
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Encapsulates an object and a {@link TypeDescriptor} that describes it.
|
* Encapsulates an object and a {@link TypeDescriptor} that describes it.
|
||||||
* The type descriptor can contain generic declarations that would not
|
*
|
||||||
|
* <p>The type descriptor can contain generic declarations that would not
|
||||||
* be accessible through a simple {@code getClass()} call on the object.
|
* be accessible through a simple {@code getClass()} call on the object.
|
||||||
*
|
*
|
||||||
* @author Andy Clement
|
* @author Andy Clement
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2002-2022 the original author or authors.
|
* Copyright 2002-2024 the original author or authors.
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
@@ -36,7 +36,9 @@ import org.springframework.util.ObjectUtils;
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Represents selection over a map or collection.
|
* Represents selection over a map or collection.
|
||||||
* For example: {1,2,3,4,5,6,7,8,9,10}.?{#isEven(#this) == 'y'} returns [2, 4, 6, 8, 10]
|
*
|
||||||
|
* <p>For example, <code>{1,2,3,4,5,6,7,8,9,10}.?{#isEven(#this)}</code> evaluates
|
||||||
|
* to {@code [2, 4, 6, 8, 10]}.
|
||||||
*
|
*
|
||||||
* <p>Basically a subset of the input data is returned based on the
|
* <p>Basically a subset of the input data is returned based on the
|
||||||
* evaluation of the expression supplied as selection criteria.
|
* evaluation of the expression supplied as selection criteria.
|
||||||
@@ -100,11 +102,10 @@ public class Selection extends SpelNodeImpl {
|
|||||||
Object val = selectionCriteria.getValueInternal(state).getValue();
|
Object val = selectionCriteria.getValueInternal(state).getValue();
|
||||||
if (val instanceof Boolean b) {
|
if (val instanceof Boolean b) {
|
||||||
if (b) {
|
if (b) {
|
||||||
|
result.put(entry.getKey(), entry.getValue());
|
||||||
if (this.variant == FIRST) {
|
if (this.variant == FIRST) {
|
||||||
result.put(entry.getKey(), entry.getValue());
|
|
||||||
return new ValueRef.TypedValueHolderValueRef(new TypedValue(result), this);
|
return new ValueRef.TypedValueHolderValueRef(new TypedValue(result), this);
|
||||||
}
|
}
|
||||||
result.put(entry.getKey(), entry.getValue());
|
|
||||||
lastKey = entry.getKey();
|
lastKey = entry.getKey();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -120,22 +121,22 @@ public class Selection extends SpelNodeImpl {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if ((this.variant == FIRST || this.variant == LAST) && result.isEmpty()) {
|
if ((this.variant == FIRST || this.variant == LAST) && result.isEmpty()) {
|
||||||
return new ValueRef.TypedValueHolderValueRef(new TypedValue(null), this);
|
return new ValueRef.TypedValueHolderValueRef(TypedValue.NULL, this);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (this.variant == LAST) {
|
if (this.variant == LAST) {
|
||||||
Map<Object, Object> resultMap = new HashMap<>();
|
Map<Object, Object> resultMap = new HashMap<>();
|
||||||
Object lastValue = result.get(lastKey);
|
Object lastValue = result.get(lastKey);
|
||||||
resultMap.put(lastKey,lastValue);
|
resultMap.put(lastKey, lastValue);
|
||||||
return new ValueRef.TypedValueHolderValueRef(new TypedValue(resultMap),this);
|
return new ValueRef.TypedValueHolderValueRef(new TypedValue(resultMap), this);
|
||||||
}
|
}
|
||||||
|
|
||||||
return new ValueRef.TypedValueHolderValueRef(new TypedValue(result),this);
|
return new ValueRef.TypedValueHolderValueRef(new TypedValue(result), this);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (operand instanceof Iterable || ObjectUtils.isArray(operand)) {
|
if (operand instanceof Iterable || ObjectUtils.isArray(operand)) {
|
||||||
Iterable<?> data = (operand instanceof Iterable<?> iterable ?
|
Iterable<?> data = (operand instanceof Iterable<?> iterable ? iterable :
|
||||||
iterable : Arrays.asList(ObjectUtils.toObjectArray(operand)));
|
Arrays.asList(ObjectUtils.toObjectArray(operand)));
|
||||||
|
|
||||||
List<Object> result = new ArrayList<>();
|
List<Object> result = new ArrayList<>();
|
||||||
int index = 0;
|
int index = 0;
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2002-2023 the original author or authors.
|
* Copyright 2002-2024 the original author or authors.
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
@@ -106,6 +106,7 @@ public abstract class RequestPredicates {
|
|||||||
* against the given path pattern.
|
* against the given path pattern.
|
||||||
* @param pattern the pattern to match to
|
* @param pattern the pattern to match to
|
||||||
* @return a predicate that tests against the given path pattern
|
* @return a predicate that tests against the given path pattern
|
||||||
|
* @see org.springframework.web.util.pattern.PathPattern
|
||||||
*/
|
*/
|
||||||
public static RequestPredicate path(String pattern) {
|
public static RequestPredicate path(String pattern) {
|
||||||
Assert.notNull(pattern, "'pattern' must not be null");
|
Assert.notNull(pattern, "'pattern' must not be null");
|
||||||
@@ -168,6 +169,7 @@ public abstract class RequestPredicates {
|
|||||||
* @param pattern the path pattern to match against
|
* @param pattern the path pattern to match against
|
||||||
* @return a predicate that matches if the request method is GET and if the given pattern
|
* @return a predicate that matches if the request method is GET and if the given pattern
|
||||||
* matches against the request path
|
* matches against the request path
|
||||||
|
* @see org.springframework.web.util.pattern.PathPattern
|
||||||
*/
|
*/
|
||||||
public static RequestPredicate GET(String pattern) {
|
public static RequestPredicate GET(String pattern) {
|
||||||
return method(HttpMethod.GET).and(path(pattern));
|
return method(HttpMethod.GET).and(path(pattern));
|
||||||
@@ -179,6 +181,7 @@ public abstract class RequestPredicates {
|
|||||||
* @param pattern the path pattern to match against
|
* @param pattern the path pattern to match against
|
||||||
* @return a predicate that matches if the request method is HEAD and if the given pattern
|
* @return a predicate that matches if the request method is HEAD and if the given pattern
|
||||||
* matches against the request path
|
* matches against the request path
|
||||||
|
* @see org.springframework.web.util.pattern.PathPattern
|
||||||
*/
|
*/
|
||||||
public static RequestPredicate HEAD(String pattern) {
|
public static RequestPredicate HEAD(String pattern) {
|
||||||
return method(HttpMethod.HEAD).and(path(pattern));
|
return method(HttpMethod.HEAD).and(path(pattern));
|
||||||
@@ -190,6 +193,7 @@ public abstract class RequestPredicates {
|
|||||||
* @param pattern the path pattern to match against
|
* @param pattern the path pattern to match against
|
||||||
* @return a predicate that matches if the request method is POST and if the given pattern
|
* @return a predicate that matches if the request method is POST and if the given pattern
|
||||||
* matches against the request path
|
* matches against the request path
|
||||||
|
* @see org.springframework.web.util.pattern.PathPattern
|
||||||
*/
|
*/
|
||||||
public static RequestPredicate POST(String pattern) {
|
public static RequestPredicate POST(String pattern) {
|
||||||
return method(HttpMethod.POST).and(path(pattern));
|
return method(HttpMethod.POST).and(path(pattern));
|
||||||
@@ -201,6 +205,7 @@ public abstract class RequestPredicates {
|
|||||||
* @param pattern the path pattern to match against
|
* @param pattern the path pattern to match against
|
||||||
* @return a predicate that matches if the request method is PUT and if the given pattern
|
* @return a predicate that matches if the request method is PUT and if the given pattern
|
||||||
* matches against the request path
|
* matches against the request path
|
||||||
|
* @see org.springframework.web.util.pattern.PathPattern
|
||||||
*/
|
*/
|
||||||
public static RequestPredicate PUT(String pattern) {
|
public static RequestPredicate PUT(String pattern) {
|
||||||
return method(HttpMethod.PUT).and(path(pattern));
|
return method(HttpMethod.PUT).and(path(pattern));
|
||||||
@@ -212,6 +217,7 @@ public abstract class RequestPredicates {
|
|||||||
* @param pattern the path pattern to match against
|
* @param pattern the path pattern to match against
|
||||||
* @return a predicate that matches if the request method is PATCH and if the given pattern
|
* @return a predicate that matches if the request method is PATCH and if the given pattern
|
||||||
* matches against the request path
|
* matches against the request path
|
||||||
|
* @see org.springframework.web.util.pattern.PathPattern
|
||||||
*/
|
*/
|
||||||
public static RequestPredicate PATCH(String pattern) {
|
public static RequestPredicate PATCH(String pattern) {
|
||||||
return method(HttpMethod.PATCH).and(path(pattern));
|
return method(HttpMethod.PATCH).and(path(pattern));
|
||||||
@@ -223,6 +229,7 @@ public abstract class RequestPredicates {
|
|||||||
* @param pattern the path pattern to match against
|
* @param pattern the path pattern to match against
|
||||||
* @return a predicate that matches if the request method is DELETE and if the given pattern
|
* @return a predicate that matches if the request method is DELETE and if the given pattern
|
||||||
* matches against the request path
|
* matches against the request path
|
||||||
|
* @see org.springframework.web.util.pattern.PathPattern
|
||||||
*/
|
*/
|
||||||
public static RequestPredicate DELETE(String pattern) {
|
public static RequestPredicate DELETE(String pattern) {
|
||||||
return method(HttpMethod.DELETE).and(path(pattern));
|
return method(HttpMethod.DELETE).and(path(pattern));
|
||||||
@@ -234,6 +241,7 @@ public abstract class RequestPredicates {
|
|||||||
* @param pattern the path pattern to match against
|
* @param pattern the path pattern to match against
|
||||||
* @return a predicate that matches if the request method is OPTIONS and if the given pattern
|
* @return a predicate that matches if the request method is OPTIONS and if the given pattern
|
||||||
* matches against the request path
|
* matches against the request path
|
||||||
|
* @see org.springframework.web.util.pattern.PathPattern
|
||||||
*/
|
*/
|
||||||
public static RequestPredicate OPTIONS(String pattern) {
|
public static RequestPredicate OPTIONS(String pattern) {
|
||||||
return method(HttpMethod.OPTIONS).and(path(pattern));
|
return method(HttpMethod.OPTIONS).and(path(pattern));
|
||||||
@@ -317,7 +325,6 @@ public abstract class RequestPredicates {
|
|||||||
else {
|
else {
|
||||||
return newPattern;
|
return newPattern;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -337,6 +344,7 @@ public abstract class RequestPredicates {
|
|||||||
* Receive notification of a path predicate.
|
* Receive notification of a path predicate.
|
||||||
* @param pattern the path pattern that makes up the predicate
|
* @param pattern the path pattern that makes up the predicate
|
||||||
* @see RequestPredicates#path(String)
|
* @see RequestPredicates#path(String)
|
||||||
|
* @see org.springframework.web.util.pattern.PathPattern
|
||||||
*/
|
*/
|
||||||
void path(String pattern);
|
void path(String pattern);
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user