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