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