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.ExpressionEvaluator;
16 import org.mule.api.expression.ExpressionManager;
17 import org.mule.api.expression.ExpressionRuntimeException;
18 import org.mule.api.expression.InvalidExpressionException;
19 import org.mule.api.expression.RequiredValueException;
20 import org.mule.api.lifecycle.Disposable;
21 import org.mule.config.i18n.CoreMessages;
22 import org.mule.util.TemplateParser;
23
24 import java.text.MessageFormat;
25 import java.util.Iterator;
26
27 import edu.emory.mathcs.backport.java.util.concurrent.ConcurrentHashMap;
28 import edu.emory.mathcs.backport.java.util.concurrent.ConcurrentMap;
29 import edu.emory.mathcs.backport.java.util.concurrent.atomic.AtomicBoolean;
30 import org.apache.commons.logging.Log;
31 import org.apache.commons.logging.LogFactory;
32
33
34
35
36
37
38
39 public class DefaultExpressionManager implements ExpressionManager, MuleContextAware
40 {
41
42
43
44
45 protected static transient final Log logger = LogFactory.getLog(DefaultExpressionManager.class);
46
47
48 private TemplateParser parser = TemplateParser.createMuleStyleParser();
49
50 private ConcurrentMap evaluators = 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
76
77
78
79
80
81 public boolean isEvaluatorRegistered(String name)
82 {
83 return evaluators.containsKey(name);
84 }
85
86
87
88
89
90
91 public ExpressionEvaluator unregisterEvaluator(String name)
92 {
93 if (name == null)
94 {
95 return null;
96 }
97
98 ExpressionEvaluator evaluator = (ExpressionEvaluator) evaluators.remove(name);
99 if (evaluator instanceof Disposable)
100 {
101 ((Disposable) evaluator).dispose();
102 }
103 return evaluator;
104 }
105
106
107
108
109
110
111
112
113
114
115
116
117
118 public Object evaluate(String expression, MuleMessage message) throws ExpressionRuntimeException
119 {
120 return evaluate(expression, message, false);
121 }
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137 public Object evaluate(String expression, MuleMessage message, boolean failIfNull) throws ExpressionRuntimeException
138 {
139 String name;
140
141 if (expression == null)
142 {
143 throw new IllegalArgumentException(CoreMessages.objectIsNull("expression").getMessage());
144 }
145 if (expression.startsWith(DEFAULT_EXPRESSION_PREFIX))
146 {
147 expression = expression.substring(2, expression.length() - 1);
148 }
149 int i = expression.indexOf(":");
150 if (i > -1)
151 {
152 name = expression.substring(0, i);
153 expression = expression.substring(i + DEFAULT_EXPRESSION_POSTFIX.length());
154 }
155 else
156 {
157 name = expression;
158 expression = null;
159 }
160 return evaluate(expression, name, message, failIfNull);
161 }
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178 public Object evaluate(String expression, String evaluator, MuleMessage message, boolean failIfNull) throws ExpressionRuntimeException
179 {
180 ExpressionEvaluator extractor = (ExpressionEvaluator) evaluators.get(evaluator);
181 if (extractor == null)
182 {
183 throw new IllegalArgumentException(CoreMessages.expressionEvaluatorNotRegistered(evaluator).getMessage());
184 }
185 Object result = extractor.evaluate(expression, message);
186
187 if (failIfNull && (result == null))
188 {
189 throw new RequiredValueException(CoreMessages.expressionEvaluatorReturnedNull(evaluator, expression));
190 }
191 if (logger.isDebugEnabled())
192 {
193 logger.debug(MessageFormat.format("Result of expression: {0}:{1} is: {2}", evaluator, expression, result));
194 }
195 return result;
196 }
197
198
199
200
201
202
203
204
205
206
207
208
209
210 public String parse(String expression, MuleMessage message) throws ExpressionRuntimeException
211 {
212 return parse(expression, message, false);
213 }
214
215
216
217
218
219
220
221
222
223
224
225
226 public String parse(final String expression, final MuleMessage message, final boolean failIfNull) throws ExpressionRuntimeException
227 {
228 return parser.parse(new TemplateParser.TemplateCallback()
229 {
230 public Object match(String token)
231 {
232 return evaluate(token, message, failIfNull);
233 }
234 }, expression);
235 }
236
237
238
239
240 public synchronized void clearEvaluators()
241 {
242 for (Iterator iterator = evaluators.values().iterator(); iterator.hasNext();)
243 {
244 ExpressionEvaluator evaluator = (ExpressionEvaluator) iterator.next();
245 if (evaluator instanceof Disposable)
246 {
247 ((Disposable) evaluator).dispose();
248 }
249 }
250 evaluators.clear();
251 }
252
253 public boolean isExpression(String string)
254 {
255 return (string.contains(DEFAULT_EXPRESSION_PREFIX));
256 }
257
258
259
260
261
262
263
264
265 public boolean isValidExpression(String expression)
266 {
267 try
268 {
269 validateExpression(expression);
270 return true;
271 }
272 catch (InvalidExpressionException e)
273 {
274 logger.warn(e.getMessage());
275 return false;
276 }
277 }
278
279 public void validateExpression(String expression) throws InvalidExpressionException
280 {
281 if (!muleContext.getConfiguration().isValidateExpressions())
282 {
283 if (logger.isDebugEnabled()) {
284 logger.debug("Validate expressions is turned off, no checking done for: " + expression);
285 }
286 return;
287 }
288 try
289 {
290 parser.validate(expression);
291 }
292 catch (IllegalArgumentException e)
293 {
294 throw new InvalidExpressionException(expression, e.getMessage());
295 }
296
297 final AtomicBoolean valid = new AtomicBoolean(true);
298 final AtomicBoolean match = new AtomicBoolean(false);
299 final StringBuffer message = new StringBuffer();
300 parser.parse(new TemplateParser.TemplateCallback()
301 {
302 public Object match(String token)
303 {
304 match.set(true);
305 if (token.indexOf(":") == -1)
306 {
307 if (valid.get())
308 {
309 valid.compareAndSet(true, false);
310 }
311 message.append(token).append(" is invalid\n");
312 }
313 return null;
314 }
315 }, expression);
316
317 if (message.length() > 0)
318 {
319 throw new InvalidExpressionException(expression, message.toString());
320 }
321 else if(!match.get())
322 {
323 throw new InvalidExpressionException(expression, "Expression string is not an expression. Use isExpression(String) to validate first");
324 }
325 }
326 }