1
1
/*
2
- * Copyright 2002-2024 the original author or authors.
2
+ * Copyright 2002-2025 the original author or authors.
3
3
*
4
4
* Licensed under the Apache License, Version 2.0 (the "License");
5
5
* you may not use this file except in compliance with the License.
16
16
17
17
package org .springframework .expression .spel ;
18
18
19
- import java .util .ArrayList ;
20
19
import java .util .Collection ;
21
- import java .util .Collections ;
22
20
import java .util .List ;
21
+ import java .util .Set ;
23
22
24
- import org .junit .jupiter .api .BeforeEach ;
25
23
import org .junit .jupiter .api .Test ;
26
24
27
25
import org .springframework .core .MethodParameter ;
28
- import org .springframework .core .convert .ConversionService ;
29
26
import org .springframework .core .convert .TypeDescriptor ;
30
- import org .springframework .core .convert .support .DefaultConversionService ;
31
- import org .springframework .expression .EvaluationException ;
32
27
import org .springframework .expression .Expression ;
33
28
import org .springframework .expression .TypeConverter ;
34
29
import org .springframework .expression .spel .support .StandardEvaluationContext ;
30
+ import org .springframework .expression .spel .support .StandardTypeConverter ;
31
+ import org .springframework .util .ReflectionUtils ;
35
32
36
33
import static org .assertj .core .api .Assertions .assertThat ;
37
34
38
35
/**
39
- * Expression evaluation where the TypeConverter plugged in is the
36
+ * Expression evaluation where the TypeConverter plugged in uses the
40
37
* {@link org.springframework.core.convert.support.GenericConversionService}.
41
38
*
42
39
* @author Andy Clement
43
40
* @author Dave Syer
44
41
*/
45
42
class ExpressionWithConversionTests extends AbstractExpressionTests {
46
43
47
- private static List <String > listOfString = new ArrayList <>();
48
- private static TypeDescriptor typeDescriptorForListOfString = null ;
49
- private static List <Integer > listOfInteger = new ArrayList <>();
50
- private static TypeDescriptor typeDescriptorForListOfInteger = null ;
51
-
52
- static {
53
- listOfString .add ("1" );
54
- listOfString .add ("2" );
55
- listOfString .add ("3" );
56
- listOfInteger .add (4 );
57
- listOfInteger .add (5 );
58
- listOfInteger .add (6 );
59
- }
44
+ private static final List <String > listOfString = List .of ("1" , "2" , "3" );
45
+ private static final List <Integer > listOfInteger = List .of (4 , 5 , 6 );
60
46
61
- @ BeforeEach
62
- void setUp () throws Exception {
63
- ExpressionWithConversionTests .typeDescriptorForListOfString = new TypeDescriptor (ExpressionWithConversionTests .class .getDeclaredField ("listOfString" ));
64
- ExpressionWithConversionTests .typeDescriptorForListOfInteger = new TypeDescriptor (ExpressionWithConversionTests .class .getDeclaredField ("listOfInteger" ));
65
- }
47
+ private static final TypeDescriptor typeDescriptorForListOfString =
48
+ new TypeDescriptor (ReflectionUtils .findField (ExpressionWithConversionTests .class , "listOfString" ));
49
+ private static TypeDescriptor typeDescriptorForListOfInteger =
50
+ new TypeDescriptor (ReflectionUtils .findField (ExpressionWithConversionTests .class , "listOfInteger" ));
66
51
67
52
68
53
/**
69
54
* Test the service can convert what we are about to use in the expression evaluation tests.
70
55
*/
71
56
@ Test
72
- void testConversionsAvailable () {
73
- TypeConvertorUsingConversionService tcs = new TypeConvertorUsingConversionService ();
57
+ void conversionsAreSupportedByStandardTypeConverter () {
58
+ StandardTypeConverter typeConverter = new StandardTypeConverter ();
74
59
75
- // ArrayList containing List<Integer> to List<String>
60
+ // List<Integer> to List<String>
76
61
Class <?> clazz = typeDescriptorForListOfString .getElementTypeDescriptor ().getType ();
77
62
assertThat (clazz ).isEqualTo (String .class );
78
- List <?> l = (List <?>) tcs .convertValue (listOfInteger , TypeDescriptor .forObject (listOfInteger ), typeDescriptorForListOfString );
63
+ List <?> l = (List <?>) typeConverter .convertValue (listOfInteger , TypeDescriptor .forObject (listOfInteger ), typeDescriptorForListOfString );
79
64
assertThat (l ).isNotNull ();
80
65
81
- // ArrayList containing List<String> to List<Integer>
66
+ // List<String> to List<Integer>
82
67
clazz = typeDescriptorForListOfInteger .getElementTypeDescriptor ().getType ();
83
68
assertThat (clazz ).isEqualTo (Integer .class );
84
69
85
- l = (List <?>) tcs .convertValue (listOfString , TypeDescriptor .forObject (listOfString ), typeDescriptorForListOfString );
70
+ l = (List <?>) typeConverter .convertValue (listOfString , TypeDescriptor .forObject (listOfString ), typeDescriptorForListOfString );
86
71
assertThat (l ).isNotNull ();
87
72
}
88
73
89
74
@ Test
90
- void testSetParameterizedList () {
75
+ void setParameterizedList () {
91
76
StandardEvaluationContext context = TestScenarioCreator .getTestEvaluationContext ();
77
+
92
78
Expression e = parser .parseExpression ("listOfInteger.size()" );
93
79
assertThat (e .getValue (context , Integer .class )).isZero ();
94
- context . setTypeConverter ( new TypeConvertorUsingConversionService ());
80
+
95
81
// Assign a List<String> to the List<Integer> field - the component elements should be converted
96
82
parser .parseExpression ("listOfInteger" ).setValue (context ,listOfString );
97
83
// size now 3
@@ -101,7 +87,7 @@ void testSetParameterizedList() {
101
87
}
102
88
103
89
@ Test
104
- void testCoercionToCollectionOfPrimitive () throws Exception {
90
+ void coercionToCollectionOfPrimitive () throws Exception {
105
91
106
92
class TestTarget {
107
93
@ SuppressWarnings ("unused" )
@@ -115,28 +101,28 @@ public int sum(Collection<Integer> numbers) {
115
101
}
116
102
117
103
StandardEvaluationContext evaluationContext = new StandardEvaluationContext ();
104
+ TypeConverter typeConverter = evaluationContext .getTypeConverter ();
118
105
119
106
TypeDescriptor collectionType = new TypeDescriptor (new MethodParameter (TestTarget .class .getDeclaredMethod (
120
107
"sum" , Collection .class ), 0 ));
121
108
// The type conversion is possible
122
- assertThat (evaluationContext .getTypeConverter ()
123
- .canConvert (TypeDescriptor .valueOf (String .class ), collectionType )).isTrue ();
109
+ assertThat (typeConverter .canConvert (TypeDescriptor .valueOf (String .class ), collectionType )).isTrue ();
124
110
// ... and it can be done successfully
125
- assertThat (evaluationContext .getTypeConverter ().convertValue ("1,2,3,4" , TypeDescriptor .valueOf (String .class ), collectionType ).toString ()).isEqualTo ("[1, 2, 3, 4]" );
111
+ assertThat (typeConverter .convertValue ("1,2,3,4" , TypeDescriptor .valueOf (String .class ), collectionType ))
112
+ .hasToString ("[1, 2, 3, 4]" );
126
113
127
114
evaluationContext .setVariable ("target" , new TestTarget ());
128
115
129
116
// OK up to here, so the evaluation should be fine...
130
117
// ... but this fails
131
- int result = (Integer ) parser .parseExpression ("#target.sum(#root)" ).getValue (evaluationContext , "1,2,3,4" );
132
- assertThat (result ).as ("Wrong result: " + result ).isEqualTo (10 );
133
-
118
+ int result = parser .parseExpression ("#target.sum(#root)" ).getValue (evaluationContext , "1,2,3,4" , int .class );
119
+ assertThat (result ).isEqualTo (10 );
134
120
}
135
121
136
122
@ Test
137
- void testConvert () {
123
+ void convert () {
138
124
Foo root = new Foo ("bar" );
139
- Collection <String > foos = Collections . singletonList ("baz" );
125
+ Collection <String > foos = Set . of ("baz" );
140
126
141
127
StandardEvaluationContext context = new StandardEvaluationContext (root );
142
128
@@ -163,26 +149,7 @@ void testConvert() {
163
149
expression = parser .parseExpression ("setFoos(getFoosAsObjects())" );
164
150
expression .getValue (context );
165
151
baz = root .getFoos ().iterator ().next ();
166
- assertThat (baz .value ).isEqualTo ("baz" );
167
- }
168
-
169
-
170
- /**
171
- * Type converter that uses the core conversion service.
172
- */
173
- private static class TypeConvertorUsingConversionService implements TypeConverter {
174
-
175
- private final ConversionService service = new DefaultConversionService ();
176
-
177
- @ Override
178
- public boolean canConvert (TypeDescriptor sourceType , TypeDescriptor targetType ) {
179
- return this .service .canConvert (sourceType , targetType );
180
- }
181
-
182
- @ Override
183
- public Object convertValue (Object value , TypeDescriptor sourceType , TypeDescriptor targetType ) throws EvaluationException {
184
- return this .service .convert (value , sourceType , targetType );
185
- }
152
+ assertThat (baz .value ).isEqualTo ("quux" );
186
153
}
187
154
188
155
@@ -205,11 +172,11 @@ public Collection<Foo> getFoos() {
205
172
}
206
173
207
174
public Collection <String > getFoosAsStrings () {
208
- return Collections . singletonList ("baz" );
175
+ return Set . of ("baz" );
209
176
}
210
177
211
178
public Collection <?> getFoosAsObjects () {
212
- return Collections . singletonList ( "baz " );
179
+ return Set . of ( "quux " );
213
180
}
214
181
}
215
182
0 commit comments