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.awt.Color;
20 import java.util.ArrayList;
21 import java.util.Arrays;
22 import java.util.HashMap;
23 import java.util.List;
24 import java.util.Map;
25
26 import org.junit.Test;
27
28 import org.springframework.expression.AccessException;
29 import org.springframework.expression.EvaluationContext;
30 import org.springframework.expression.EvaluationException;
31 import org.springframework.expression.Expression;
32 import org.springframework.expression.ParseException;
33 import org.springframework.expression.PropertyAccessor;
34 import org.springframework.expression.TypedValue;
35 import org.springframework.expression.spel.standard.SpelExpressionParser;
36 import org.springframework.expression.spel.support.StandardEvaluationContext;
37
38 import static org.junit.Assert.*;
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63 public class ExpressionLanguageScenarioTests extends AbstractExpressionTests {
64
65
66
67
68 @Test
69 public void testScenario_UsingStandardInfrastructure() {
70 try {
71
72 SpelExpressionParser parser = new SpelExpressionParser();
73
74 Expression expr = parser.parseRaw("new String('hello world')");
75
76 Object value = expr.getValue();
77
78 value = expr.getValue();
79
80 assertEquals("hello world", value);
81 assertEquals(String.class, value.getClass());
82 } catch (EvaluationException ee) {
83 ee.printStackTrace();
84 fail("Unexpected Exception: " + ee.getMessage());
85 } catch (ParseException pe) {
86 pe.printStackTrace();
87 fail("Unexpected Exception: " + pe.getMessage());
88 }
89 }
90
91
92
93
94 @Test
95 public void testScenario_DefiningVariablesThatWillBeAccessibleInExpressions() throws Exception {
96
97 SpelExpressionParser parser = new SpelExpressionParser();
98
99 StandardEvaluationContext ctx = new StandardEvaluationContext();
100 ctx.setVariable("favouriteColour","blue");
101 List<Integer> primes = new ArrayList<Integer>();
102 primes.addAll(Arrays.asList(2,3,5,7,11,13,17));
103 ctx.setVariable("primes",primes);
104
105 Expression expr = parser.parseRaw("#favouriteColour");
106 Object value = expr.getValue(ctx);
107 assertEquals("blue", value);
108
109 expr = parser.parseRaw("#primes.get(1)");
110 value = expr.getValue(ctx);
111 assertEquals(3, value);
112
113
114 expr = parser.parseRaw("#primes.?[#this>10]");
115 value = expr.getValue(ctx);
116 assertEquals("[11, 13, 17]", value.toString());
117 }
118
119
120 static class TestClass {
121 public String str;
122 private int property;
123 public int getProperty() { return property; }
124 public void setProperty(int i) { property = i; }
125 }
126
127
128
129
130 @Test
131 public void testScenario_UsingADifferentRootContextObject() throws Exception {
132
133 SpelExpressionParser parser = new SpelExpressionParser();
134
135 StandardEvaluationContext ctx = new StandardEvaluationContext();
136
137 TestClass tc = new TestClass();
138 tc.setProperty(42);
139 tc.str = "wibble";
140 ctx.setRootObject(tc);
141
142
143 Expression expr = parser.parseRaw("str");
144 Object value = expr.getValue(ctx);
145 assertEquals("wibble", value);
146 expr = parser.parseRaw("str");
147 expr.setValue(ctx, "wobble");
148 expr = parser.parseRaw("str");
149 value = expr.getValue(ctx);
150 assertEquals("wobble", value);
151
152 expr = parser.parseRaw("str='wabble'");
153 value = expr.getValue(ctx);
154 expr = parser.parseRaw("str");
155 value = expr.getValue(ctx);
156 assertEquals("wabble", value);
157
158
159 expr = parser.parseRaw("property");
160 value = expr.getValue(ctx);
161 assertEquals(42, value);
162
163
164 expr = parser.parseRaw("property=4");
165 value = expr.getValue(ctx);
166 expr = parser.parseRaw("property");
167 value = expr.getValue(ctx);
168 assertEquals(4,value);
169 }
170
171 public static String repeat(String s) { return s+s; }
172
173
174
175
176 @Test
177 public void testScenario_RegisteringJavaMethodsAsFunctionsAndCallingThem() throws SecurityException, NoSuchMethodException {
178 try {
179
180 SpelExpressionParser parser = new SpelExpressionParser();
181
182 StandardEvaluationContext ctx = new StandardEvaluationContext();
183 ctx.registerFunction("repeat",ExpressionLanguageScenarioTests.class.getDeclaredMethod("repeat",String.class));
184
185 Expression expr = parser.parseRaw("#repeat('hello')");
186 Object value = expr.getValue(ctx);
187 assertEquals("hellohello", value);
188
189 } catch (EvaluationException ee) {
190 ee.printStackTrace();
191 fail("Unexpected Exception: " + ee.getMessage());
192 } catch (ParseException pe) {
193 pe.printStackTrace();
194 fail("Unexpected Exception: " + pe.getMessage());
195 }
196 }
197
198
199
200
201 @Test
202 public void testScenario_AddingYourOwnPropertyResolvers_1() throws Exception {
203
204 SpelExpressionParser parser = new SpelExpressionParser();
205
206 StandardEvaluationContext ctx = new StandardEvaluationContext();
207
208 ctx.addPropertyAccessor(new FruitColourAccessor());
209 Expression expr = parser.parseRaw("orange");
210 Object value = expr.getValue(ctx);
211 assertEquals(Color.orange, value);
212
213 try {
214 expr.setValue(ctx, Color.blue);
215 fail("Should not be allowed to set oranges to be blue !");
216 } catch (SpelEvaluationException ee) {
217 assertEquals(ee.getMessageCode(), SpelMessage.PROPERTY_OR_FIELD_NOT_WRITABLE_ON_NULL);
218 }
219 }
220
221 @Test
222 public void testScenario_AddingYourOwnPropertyResolvers_2() throws Exception {
223
224 SpelExpressionParser parser = new SpelExpressionParser();
225
226 StandardEvaluationContext ctx = new StandardEvaluationContext();
227
228 ctx.addPropertyAccessor(new VegetableColourAccessor());
229 Expression expr = parser.parseRaw("pea");
230 Object value = expr.getValue(ctx);
231 assertEquals(Color.green, value);
232
233 try {
234 expr.setValue(ctx, Color.blue);
235 fail("Should not be allowed to set peas to be blue !");
236 }
237 catch (SpelEvaluationException ee) {
238 assertEquals(ee.getMessageCode(), SpelMessage.PROPERTY_OR_FIELD_NOT_WRITABLE_ON_NULL);
239 }
240 }
241
242
243
244
245
246
247 private static class FruitColourAccessor implements PropertyAccessor {
248
249 private static Map<String,Color> propertyMap = new HashMap<String,Color>();
250
251 static {
252 propertyMap.put("banana",Color.yellow);
253 propertyMap.put("apple",Color.red);
254 propertyMap.put("orange",Color.orange);
255 }
256
257
258
259
260 @Override
261 public Class<?>[] getSpecificTargetClasses() {
262 return null;
263 }
264
265 @Override
266 public boolean canRead(EvaluationContext context, Object target, String name) throws AccessException {
267 return propertyMap.containsKey(name);
268 }
269
270 @Override
271 public TypedValue read(EvaluationContext context, Object target, String name) throws AccessException {
272 return new TypedValue(propertyMap.get(name));
273 }
274
275 @Override
276 public boolean canWrite(EvaluationContext context, Object target, String name) throws AccessException {
277 return false;
278 }
279
280 @Override
281 public void write(EvaluationContext context, Object target, String name, Object newValue)
282 throws AccessException {
283 }
284
285 }
286
287
288
289
290
291
292 private static class VegetableColourAccessor implements PropertyAccessor {
293
294 private static Map<String,Color> propertyMap = new HashMap<String,Color>();
295
296 static {
297 propertyMap.put("carrot",Color.orange);
298 propertyMap.put("pea",Color.green);
299 }
300
301
302
303
304 @Override
305 public Class<?>[] getSpecificTargetClasses() {
306 return null;
307 }
308
309 @Override
310 public boolean canRead(EvaluationContext context, Object target, String name) throws AccessException {
311 return propertyMap.containsKey(name);
312 }
313
314 @Override
315 public TypedValue read(EvaluationContext context, Object target, String name) throws AccessException {
316 return new TypedValue(propertyMap.get(name));
317 }
318
319 @Override
320 public boolean canWrite(EvaluationContext context, Object target, String name) throws AccessException {
321 return false;
322 }
323
324 @Override
325 public void write(EvaluationContext context, Object target, String name, Object newValue) throws AccessException {
326 }
327
328 }
329 }