1
2
3
4
5
6
7
8
9
10 package org.mule.expression;
11
12 import org.mule.api.MuleContext;
13 import org.mule.api.MuleMessage;
14 import org.mule.api.context.MuleContextAware;
15 import org.mule.api.expression.ExpressionEnricher;
16 import org.mule.api.expression.ExpressionEvaluator;
17 import org.mule.api.expression.ExpressionManager;
18 import org.mule.api.expression.ExpressionRuntimeException;
19 import org.mule.api.expression.InvalidExpressionException;
20 import org.mule.api.expression.RequiredValueException;
21 import org.mule.api.lifecycle.Disposable;
22 import org.mule.config.i18n.CoreMessages;
23 import org.mule.util.TemplateParser;
24
25 import java.text.MessageFormat;
26 import java.util.Iterator;
27 import java.util.concurrent.ConcurrentHashMap;
28 import java.util.concurrent.ConcurrentMap;
29 import java.util.concurrent.atomic.AtomicBoolean;
30
31 import org.apache.commons.logging.Log;
32 import org.apache.commons.logging.LogFactory;
33
34
35
36
37
38
39
40 public class DefaultExpressionManager implements ExpressionManager, MuleContextAware
41 {
42
43
44
45
46 protected static transient final Log logger = LogFactory.getLog(DefaultExpressionManager.class);
47
48
49 private TemplateParser parser = TemplateParser.createMuleStyleParser();
50
51 private ConcurrentMap evaluators = new ConcurrentHashMap(8);
52 private ConcurrentMap enrichers = new ConcurrentHashMap(8);
53
54 private MuleContext muleContext;
55
56 public void setMuleContext(MuleContext context)
57 {
58 this.muleContext = context;
59 }
60
61 public void registerEvaluator(ExpressionEvaluator evaluator)
62 {
63 if (evaluator == null)
64 {
65 throw new IllegalArgumentException(CoreMessages.objectIsNull("evaluator").getMessage());
66 }
67
68 final String name = evaluator.getName();
69
70 if (logger.isDebugEnabled())
71 {
72 logger.debug("Evaluators already contain an object named '" + name + "'. The previous object will be overwritten.");
73 }
74 evaluators.put(evaluator.getName(), evaluator);
75 }
76
77 public void registerEnricher(ExpressionEnricher enricher)
78 {
79 if (enricher == null)
80 {
81 throw new IllegalArgumentException(CoreMessages.objectIsNull("enricher").getMessage());
82 }
83
84 final String name = enricher.getName();
85
86 if (logger.isDebugEnabled())
87 {
88 logger.debug("Enrichers already contain an object named '" + name + "'. The previous object will be overwritten.");
89 }
90 enrichers.put(enricher.getName(), enricher);
91 }
92
93
94
95
96
97
98
99 public boolean isEvaluatorRegistered(String name)
100 {
101 return evaluators.containsKey(name);
102 }
103
104
105
106
107
108
109
110 public boolean isEnricherRegistered(String name)
111 {
112 return enrichers.containsKey(name);
113 }
114
115
116
117
118
119
120 public ExpressionEvaluator unregisterEvaluator(String name)
121 {
122 if (name == null)
123 {
124 return null;
125 }
126
127 ExpressionEvaluator evaluator = (ExpressionEvaluator) evaluators.remove(name);
128 if (evaluator instanceof Disposable)
129 {
130 ((Disposable) evaluator).dispose();
131 }
132 return evaluator;
133 }
134
135
136
137
138
139
140 public ExpressionEnricher unregisterEnricher(String name)
141 {
142 if (name == null)
143 {
144 return null;
145 }
146
147 ExpressionEnricher enricher = (ExpressionEnricher) enrichers.remove(name);
148 if (enricher instanceof Disposable)
149 {
150 ((Disposable) enricher).dispose();
151 }
152 return enricher;
153 }
154
155
156
157
158
159
160
161
162
163
164
165
166
167 public Object evaluate(String expression, MuleMessage message) throws ExpressionRuntimeException
168 {
169 return evaluate(expression, message, false);
170 }
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186 public Object evaluate(String expression, MuleMessage message, boolean failIfNull) throws ExpressionRuntimeException
187 {
188 String name;
189
190 if (expression == null)
191 {
192 throw new IllegalArgumentException(CoreMessages.objectIsNull("expression").getMessage());
193 }
194 if (expression.startsWith(DEFAULT_EXPRESSION_PREFIX))
195 {
196 expression = expression.substring(2, expression.length() - 1);
197 }
198 int i = expression.indexOf(":");
199 if (i > -1)
200 {
201 name = expression.substring(0, i);
202 expression = expression.substring(i + DEFAULT_EXPRESSION_POSTFIX.length());
203 }
204 else
205 {
206 name = expression;
207 expression = null;
208 }
209 return evaluate(expression, name, message, failIfNull);
210 }
211
212
213 public void enrich(String expression, MuleMessage message, Object object)
214 throws ExpressionRuntimeException
215 {
216 String enricherName;
217
218 if (expression == null)
219 {
220 throw new IllegalArgumentException(CoreMessages.objectIsNull("expression").getMessage());
221 }
222 if (expression.startsWith(DEFAULT_EXPRESSION_PREFIX))
223 {
224 expression = expression.substring(2, expression.length() - 1);
225 }
226 int i = expression.indexOf(":");
227 if (i > -1)
228 {
229 enricherName = expression.substring(0, i);
230 expression = expression.substring(i + DEFAULT_EXPRESSION_POSTFIX.length());
231 }
232 else
233 {
234 enricherName = expression;
235 expression = null;
236 }
237 enrich(expression, enricherName, message, object);
238 }
239
240 public void enrich(String expression, String enricherName, MuleMessage message, Object object)
241 {
242 ExpressionEnricher enricher = (ExpressionEnricher) enrichers.get(enricherName);
243 if (enricher == null)
244 {
245 throw new IllegalArgumentException(CoreMessages.expressionEnricherNotRegistered(enricherName)
246 .getMessage());
247 }
248 enricher.enrich(expression, message, object);
249 }
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266 public Object evaluate(String expression, String evaluator, MuleMessage message, boolean failIfNull) throws ExpressionRuntimeException
267 {
268 ExpressionEvaluator extractor = (ExpressionEvaluator) evaluators.get(evaluator);
269 if (extractor == null)
270 {
271 throw new IllegalArgumentException(CoreMessages.expressionEvaluatorNotRegistered(evaluator).getMessage());
272 }
273 Object result = extractor.evaluate(expression, message);
274
275 if (failIfNull && (result == null))
276 {
277 throw new RequiredValueException(CoreMessages.expressionEvaluatorReturnedNull(evaluator, expression));
278 }
279 if (logger.isDebugEnabled())
280 {
281 logger.debug(MessageFormat.format("Result of expression: {0}:{1} is: {2}", evaluator, expression, result));
282 }
283 return result;
284 }
285
286 public boolean evaluateBoolean(String expression, String evaluator, MuleMessage message)
287 throws ExpressionRuntimeException
288 {
289 return evaluateBoolean(expression, evaluator, message, false, false);
290 }
291
292 public boolean evaluateBoolean(String expression, MuleMessage message) throws ExpressionRuntimeException
293 {
294 return evaluateBoolean(expression, message, false, false);
295 }
296
297 public boolean evaluateBoolean(String expression,
298 String evaluator,
299 MuleMessage message,
300 boolean nullReturnsTrue,
301 boolean nonBooleanReturnsTrue) throws ExpressionRuntimeException
302 {
303 try
304 {
305 return resolveBoolean(evaluate(expression, evaluator, message, false), nullReturnsTrue,
306 nonBooleanReturnsTrue, expression);
307 }
308 catch (RequiredValueException e)
309 {
310 return nullReturnsTrue;
311 }
312 }
313
314 public boolean evaluateBoolean(String expression,
315 MuleMessage message,
316 boolean nullReturnsTrue,
317 boolean nonBooleanReturnsTrue) throws ExpressionRuntimeException
318 {
319 try
320 {
321 return resolveBoolean(evaluate(expression, message, false), nullReturnsTrue,
322 nonBooleanReturnsTrue, expression);
323 }
324 catch (RequiredValueException e)
325 {
326 return nullReturnsTrue;
327 }
328 }
329
330 protected boolean resolveBoolean(Object result,
331 boolean nullReturnsTrue,
332 boolean nonBooleanReturnsTrue,
333 String expression)
334 {
335 if (result == null)
336 {
337 return nullReturnsTrue;
338 }
339 else if (result instanceof Boolean)
340 {
341 return (Boolean) result;
342 }
343 else if (result instanceof String)
344 {
345 if (result.toString().toLowerCase().equalsIgnoreCase("false"))
346 {
347 return false;
348 }
349 else if (result.toString().toLowerCase().equalsIgnoreCase("true"))
350 {
351 return true;
352 }
353 else
354 {
355 return nonBooleanReturnsTrue;
356 }
357 }
358 else
359 {
360 logger.warn("Expression: " + expression + ", returned an non-boolean result. Returning: "
361 + nonBooleanReturnsTrue);
362 return nonBooleanReturnsTrue;
363 }
364 }
365
366
367
368
369
370
371
372
373
374
375
376
377 public String parse(String expression, MuleMessage message) throws ExpressionRuntimeException
378 {
379 return parse(expression, message, false);
380 }
381
382
383
384
385
386
387
388
389
390
391
392
393 public String parse(final String expression, final MuleMessage message, final boolean failIfNull) throws ExpressionRuntimeException
394 {
395 return parser.parse(new TemplateParser.TemplateCallback()
396 {
397 public Object match(String token)
398 {
399 Object result = evaluate(token, message, failIfNull);
400 if (result instanceof MuleMessage)
401 {
402 return ((MuleMessage) result).getPayload();
403 }
404 else
405 {
406 return result;
407 }
408 }
409 }, expression);
410 }
411
412
413
414
415 public synchronized void clearEvaluators()
416 {
417 for (Iterator iterator = evaluators.values().iterator(); iterator.hasNext();)
418 {
419 ExpressionEvaluator evaluator = (ExpressionEvaluator) iterator.next();
420 if (evaluator instanceof Disposable)
421 {
422 ((Disposable) evaluator).dispose();
423 }
424 }
425 evaluators.clear();
426 }
427
428 public void clearEnrichers()
429 {
430 for (Iterator iterator = enrichers.values().iterator(); iterator.hasNext();)
431 {
432 ExpressionEnricher enricher = (ExpressionEnricher) iterator.next();
433 if (enricher instanceof Disposable)
434 {
435 ((Disposable) enricher).dispose();
436 }
437 }
438 enrichers.clear();
439 }
440
441 public boolean isExpression(String string)
442 {
443 return (string.contains(DEFAULT_EXPRESSION_PREFIX));
444 }
445
446
447
448
449
450
451
452
453 public boolean isValidExpression(String expression)
454 {
455 try
456 {
457 validateExpression(expression);
458 return true;
459 }
460 catch (InvalidExpressionException e)
461 {
462 logger.warn(e.getMessage());
463 return false;
464 }
465 }
466
467 public void validateExpression(String expression) throws InvalidExpressionException
468 {
469 if (!muleContext.getConfiguration().isValidateExpressions())
470 {
471 if (logger.isDebugEnabled()) {
472 logger.debug("Validate expressions is turned off, no checking done for: " + expression);
473 }
474 return;
475 }
476 try
477 {
478 parser.validate(expression);
479 }
480 catch (IllegalArgumentException e)
481 {
482 throw new InvalidExpressionException(expression, e.getMessage());
483 }
484
485 final AtomicBoolean valid = new AtomicBoolean(true);
486 final AtomicBoolean match = new AtomicBoolean(false);
487 final StringBuffer message = new StringBuffer();
488 parser.parse(new TemplateParser.TemplateCallback()
489 {
490 public Object match(String token)
491 {
492 match.set(true);
493 if (token.indexOf(":") == -1)
494 {
495 if (valid.get())
496 {
497 valid.compareAndSet(true, false);
498 }
499 message.append(token).append(" is invalid\n");
500 }
501 return null;
502 }
503 }, expression);
504
505 if (message.length() > 0)
506 {
507 throw new InvalidExpressionException(expression, message.toString());
508 }
509 else if(!match.get())
510 {
511 throw new InvalidExpressionException(expression, "Expression string is not an expression. Use isExpression(String) to validate first");
512 }
513 }
514
515 }