1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package org.springframework.expression.spel;
18
19 import java.lang.annotation.ElementType;
20 import java.lang.annotation.Retention;
21 import java.lang.annotation.RetentionPolicy;
22 import java.lang.annotation.Target;
23 import java.util.ArrayList;
24 import java.util.Arrays;
25 import java.util.HashMap;
26 import java.util.List;
27 import java.util.Map;
28
29 import org.junit.Test;
30
31 import org.springframework.expression.AccessException;
32 import org.springframework.expression.EvaluationContext;
33 import org.springframework.expression.EvaluationException;
34 import org.springframework.expression.Expression;
35 import org.springframework.expression.PropertyAccessor;
36 import org.springframework.expression.TypedValue;
37 import org.springframework.expression.spel.standard.SpelExpressionParser;
38 import org.springframework.expression.spel.support.StandardEvaluationContext;
39
40 import static org.junit.Assert.*;
41
42 public class IndexingTests {
43
44 @Test
45 public void indexIntoGenericPropertyContainingMap() {
46 Map<String, String> property = new HashMap<String, String>();
47 property.put("foo", "bar");
48 this.property = property;
49 SpelExpressionParser parser = new SpelExpressionParser();
50 Expression expression = parser.parseExpression("property");
51 assertEquals("@org.springframework.expression.spel.IndexingTests$FieldAnnotation java.util.HashMap<?, ?>", expression.getValueTypeDescriptor(this).toString());
52 assertEquals(property, expression.getValue(this));
53 assertEquals(property, expression.getValue(this, Map.class));
54 expression = parser.parseExpression("property['foo']");
55 assertEquals("bar", expression.getValue(this));
56 }
57
58 @FieldAnnotation
59 public Object property;
60
61 @Test
62 public void indexIntoGenericPropertyContainingMapObject() {
63 Map<String, Map<String, String>> property = new HashMap<String, Map<String, String>>();
64 Map<String, String> map = new HashMap<String, String>();
65 map.put("foo", "bar");
66 property.put("property", map);
67 SpelExpressionParser parser = new SpelExpressionParser();
68 StandardEvaluationContext context = new StandardEvaluationContext();
69 context.addPropertyAccessor(new MapAccessor());
70 context.setRootObject(property);
71 Expression expression = parser.parseExpression("property");
72 assertEquals("java.util.HashMap<?, ?>", expression.getValueTypeDescriptor(context).toString());
73 assertEquals(map, expression.getValue(context));
74 assertEquals(map, expression.getValue(context, Map.class));
75 expression = parser.parseExpression("property['foo']");
76 assertEquals("bar", expression.getValue(context));
77 }
78
79 public static class MapAccessor implements PropertyAccessor {
80
81 @Override
82 public boolean canRead(EvaluationContext context, Object target, String name) throws AccessException {
83 return (((Map<?, ?>) target).containsKey(name));
84 }
85
86 @Override
87 public TypedValue read(EvaluationContext context, Object target, String name) throws AccessException {
88 return new TypedValue(((Map<?, ?>) target).get(name));
89 }
90
91 @Override
92 public boolean canWrite(EvaluationContext context, Object target, String name) throws AccessException {
93 return true;
94 }
95
96 @Override
97 @SuppressWarnings("unchecked")
98 public void write(EvaluationContext context, Object target, String name, Object newValue)
99 throws AccessException {
100 ((Map) target).put(name, newValue);
101 }
102
103 @Override
104 public Class<?>[] getSpecificTargetClasses() {
105 return new Class[] { Map.class };
106 }
107
108 }
109
110 @Test
111 public void setGenericPropertyContainingMap() {
112 Map<String, String> property = new HashMap<String, String>();
113 property.put("foo", "bar");
114 this.property = property;
115 SpelExpressionParser parser = new SpelExpressionParser();
116 Expression expression = parser.parseExpression("property");
117 assertEquals("@org.springframework.expression.spel.IndexingTests$FieldAnnotation java.util.HashMap<?, ?>", expression.getValueTypeDescriptor(this).toString());
118 assertEquals(property, expression.getValue(this));
119 expression = parser.parseExpression("property['foo']");
120 assertEquals("bar", expression.getValue(this));
121 expression.setValue(this, "baz");
122 assertEquals("baz", expression.getValue(this));
123 }
124
125 @Test
126 public void setPropertyContainingMap() {
127 Map<Integer, Integer> property = new HashMap<Integer, Integer>();
128 property.put(9, 3);
129 this.parameterizedMap = property;
130 SpelExpressionParser parser = new SpelExpressionParser();
131 Expression expression = parser.parseExpression("parameterizedMap");
132 assertEquals("java.util.HashMap<java.lang.Integer, java.lang.Integer>", expression.getValueTypeDescriptor(this).toString());
133 assertEquals(property, expression.getValue(this));
134 expression = parser.parseExpression("parameterizedMap['9']");
135 assertEquals(3, expression.getValue(this));
136 expression.setValue(this, "37");
137 assertEquals(37, expression.getValue(this));
138 }
139
140 public Map<Integer, Integer> parameterizedMap;
141
142 @Test
143 public void setPropertyContainingMapAutoGrow() {
144 SpelExpressionParser parser = new SpelExpressionParser(new SpelParserConfiguration(true, false));
145 Expression expression = parser.parseExpression("parameterizedMap");
146 assertEquals("java.util.Map<java.lang.Integer, java.lang.Integer>", expression.getValueTypeDescriptor(this).toString());
147 assertEquals(property, expression.getValue(this));
148 expression = parser.parseExpression("parameterizedMap['9']");
149 assertEquals(null, expression.getValue(this));
150 expression.setValue(this, "37");
151 assertEquals(37, expression.getValue(this));
152 }
153
154 @Test
155 public void indexIntoGenericPropertyContainingList() {
156 List<String> property = new ArrayList<String>();
157 property.add("bar");
158 this.property = property;
159 SpelExpressionParser parser = new SpelExpressionParser();
160 Expression expression = parser.parseExpression("property");
161 assertEquals("@org.springframework.expression.spel.IndexingTests$FieldAnnotation java.util.ArrayList<?>", expression.getValueTypeDescriptor(this).toString());
162 assertEquals(property, expression.getValue(this));
163 expression = parser.parseExpression("property[0]");
164 assertEquals("bar", expression.getValue(this));
165 }
166
167 @Test
168 public void setGenericPropertyContainingList() {
169 List<Integer> property = new ArrayList<Integer>();
170 property.add(3);
171 this.property = property;
172 SpelExpressionParser parser = new SpelExpressionParser();
173 Expression expression = parser.parseExpression("property");
174 assertEquals("@org.springframework.expression.spel.IndexingTests$FieldAnnotation java.util.ArrayList<?>", expression.getValueTypeDescriptor(this).toString());
175 assertEquals(property, expression.getValue(this));
176 expression = parser.parseExpression("property[0]");
177 assertEquals(3, expression.getValue(this));
178 expression.setValue(this, "4");
179 assertEquals("4", expression.getValue(this));
180 }
181
182 @Test
183 public void setGenericPropertyContainingListAutogrow() {
184 List<Integer> property = new ArrayList<Integer>();
185 this.property = property;
186 SpelExpressionParser parser = new SpelExpressionParser(new SpelParserConfiguration(true, true));
187 Expression expression = parser.parseExpression("property");
188 assertEquals("@org.springframework.expression.spel.IndexingTests$FieldAnnotation java.util.ArrayList<?>", expression.getValueTypeDescriptor(this).toString());
189 assertEquals(property, expression.getValue(this));
190 expression = parser.parseExpression("property[0]");
191 try {
192 expression.setValue(this, "4");
193 } catch (EvaluationException e) {
194 assertTrue(e.getMessage().startsWith("EL1053E"));
195 }
196 }
197
198 @Test
199 public void indexIntoPropertyContainingList() {
200 List<Integer> property = new ArrayList<Integer>();
201 property.add(3);
202 this.parameterizedList = property;
203 SpelExpressionParser parser = new SpelExpressionParser();
204 Expression expression = parser.parseExpression("parameterizedList");
205 assertEquals("java.util.ArrayList<java.lang.Integer>", expression.getValueTypeDescriptor(this).toString());
206 assertEquals(property, expression.getValue(this));
207 expression = parser.parseExpression("parameterizedList[0]");
208 assertEquals(3, expression.getValue(this));
209 }
210
211 public List<Integer> parameterizedList;
212
213 @Test
214 public void indexIntoPropertyContainingListOfList() {
215 List<List<Integer>> property = new ArrayList<List<Integer>>();
216 property.add(Arrays.asList(3));
217 this.parameterizedListOfList = property;
218 SpelExpressionParser parser = new SpelExpressionParser();
219 Expression expression = parser.parseExpression("parameterizedListOfList[0]");
220 assertEquals("java.util.Arrays$ArrayList<java.lang.Integer>", expression.getValueTypeDescriptor(this).toString());
221 assertEquals(property.get(0), expression.getValue(this));
222 expression = parser.parseExpression("parameterizedListOfList[0][0]");
223 assertEquals(3, expression.getValue(this));
224 }
225
226 public List<List<Integer>> parameterizedListOfList;
227
228 @Test
229 public void setPropertyContainingList() {
230 List<Integer> property = new ArrayList<Integer>();
231 property.add(3);
232 this.parameterizedList = property;
233 SpelExpressionParser parser = new SpelExpressionParser();
234 Expression expression = parser.parseExpression("parameterizedList");
235 assertEquals("java.util.ArrayList<java.lang.Integer>", expression.getValueTypeDescriptor(this).toString());
236 assertEquals(property, expression.getValue(this));
237 expression = parser.parseExpression("parameterizedList[0]");
238 assertEquals(3, expression.getValue(this));
239 expression.setValue(this, "4");
240 assertEquals(4, expression.getValue(this));
241 }
242
243 @Test
244 public void indexIntoGenericPropertyContainingNullList() {
245 SpelParserConfiguration configuration = new SpelParserConfiguration(true, true);
246 SpelExpressionParser parser = new SpelExpressionParser(configuration);
247 Expression expression = parser.parseExpression("property");
248 assertEquals("@org.springframework.expression.spel.IndexingTests$FieldAnnotation java.lang.Object", expression.getValueTypeDescriptor(this).toString());
249 assertEquals(property, expression.getValue(this));
250 expression = parser.parseExpression("property[0]");
251 try {
252 assertEquals("bar", expression.getValue(this));
253 } catch (EvaluationException e) {
254 assertTrue(e.getMessage().startsWith("EL1027E"));
255 }
256 }
257
258 @Test
259 public void indexIntoGenericPropertyContainingGrowingList() {
260 List<String> property = new ArrayList<String>();
261 this.property = property;
262 SpelParserConfiguration configuration = new SpelParserConfiguration(true, true);
263 SpelExpressionParser parser = new SpelExpressionParser(configuration);
264 Expression expression = parser.parseExpression("property");
265 assertEquals("@org.springframework.expression.spel.IndexingTests$FieldAnnotation java.util.ArrayList<?>", expression.getValueTypeDescriptor(this).toString());
266 assertEquals(property, expression.getValue(this));
267 expression = parser.parseExpression("property[0]");
268 try {
269 assertEquals("bar", expression.getValue(this));
270 } catch (EvaluationException e) {
271 assertTrue(e.getMessage().startsWith("EL1053E"));
272 }
273 }
274
275 @Test
276 public void indexIntoGenericPropertyContainingGrowingList2() {
277 List<String> property2 = new ArrayList<String>();
278 this.property2 = property2;
279 SpelParserConfiguration configuration = new SpelParserConfiguration(true, true);
280 SpelExpressionParser parser = new SpelExpressionParser(configuration);
281 Expression expression = parser.parseExpression("property2");
282 assertEquals("java.util.ArrayList<?>", expression.getValueTypeDescriptor(this).toString());
283 assertEquals(property2, expression.getValue(this));
284 expression = parser.parseExpression("property2[0]");
285 try {
286 assertEquals("bar", expression.getValue(this));
287 } catch (EvaluationException e) {
288 assertTrue(e.getMessage().startsWith("EL1053E"));
289 }
290 }
291
292 public List property2;
293
294 @Test
295 public void indexIntoGenericPropertyContainingArray() {
296 String[] property = new String[] { "bar" };
297 this.property = property;
298 SpelExpressionParser parser = new SpelExpressionParser();
299 Expression expression = parser.parseExpression("property");
300 assertEquals("@org.springframework.expression.spel.IndexingTests$FieldAnnotation java.lang.String[]", expression.getValueTypeDescriptor(this).toString());
301 assertEquals(property, expression.getValue(this));
302 expression = parser.parseExpression("property[0]");
303 assertEquals("bar", expression.getValue(this));
304 }
305
306 @Test
307 public void emptyList() {
308 listOfScalarNotGeneric = new ArrayList();
309 SpelExpressionParser parser = new SpelExpressionParser();
310 Expression expression = parser.parseExpression("listOfScalarNotGeneric");
311 assertEquals("java.util.ArrayList<?>", expression.getValueTypeDescriptor(this).toString());
312 assertEquals("", expression.getValue(this, String.class));
313 }
314
315 @SuppressWarnings("unchecked")
316 @Test
317 public void resolveCollectionElementType() {
318 listNotGeneric = new ArrayList(2);
319 listNotGeneric.add(5);
320 listNotGeneric.add(6);
321 SpelExpressionParser parser = new SpelExpressionParser();
322 Expression expression = parser.parseExpression("listNotGeneric");
323 assertEquals("@org.springframework.expression.spel.IndexingTests$FieldAnnotation java.util.ArrayList<?>", expression.getValueTypeDescriptor(this).toString());
324 assertEquals("5,6", expression.getValue(this, String.class));
325 }
326
327 @Test
328 public void resolveCollectionElementTypeNull() {
329 SpelExpressionParser parser = new SpelExpressionParser();
330 Expression expression = parser.parseExpression("listNotGeneric");
331 assertEquals("@org.springframework.expression.spel.IndexingTests$FieldAnnotation java.util.List<?>", expression.getValueTypeDescriptor(this).toString());
332 }
333
334 @FieldAnnotation
335 public List listNotGeneric;
336
337 @Target({ElementType.FIELD})
338 @Retention(RetentionPolicy.RUNTIME)
339 public @interface FieldAnnotation {
340
341 }
342
343 @SuppressWarnings("unchecked")
344 @Test
345 public void resolveMapKeyValueTypes() {
346 mapNotGeneric = new HashMap();
347 mapNotGeneric.put("baseAmount", 3.11);
348 mapNotGeneric.put("bonusAmount", 7.17);
349 SpelExpressionParser parser = new SpelExpressionParser();
350 Expression expression = parser.parseExpression("mapNotGeneric");
351 assertEquals("@org.springframework.expression.spel.IndexingTests$FieldAnnotation java.util.HashMap<?, ?>", expression.getValueTypeDescriptor(this).toString());
352 }
353
354 @FieldAnnotation
355 public Map mapNotGeneric;
356
357 @SuppressWarnings("unchecked")
358 @Test
359 public void testListOfScalar() {
360 listOfScalarNotGeneric = new ArrayList(1);
361 listOfScalarNotGeneric.add("5");
362 SpelExpressionParser parser = new SpelExpressionParser();
363 Expression expression = parser.parseExpression("listOfScalarNotGeneric[0]");
364 assertEquals(new Integer(5), expression.getValue(this, Integer.class));
365 }
366
367 public List listOfScalarNotGeneric;
368
369
370 @SuppressWarnings("unchecked")
371 @Test
372 public void testListsOfMap() {
373 listOfMapsNotGeneric = new ArrayList();
374 Map map = new HashMap();
375 map.put("fruit", "apple");
376 listOfMapsNotGeneric.add(map);
377 SpelExpressionParser parser = new SpelExpressionParser();
378 Expression expression = parser.parseExpression("listOfMapsNotGeneric[0]['fruit']");
379 assertEquals("apple", expression.getValue(this, String.class));
380 }
381
382 public List listOfMapsNotGeneric;
383
384 }