Classes in this File | Line Coverage | Branch Coverage | Complexity | ||||
ExpressionEvaluatorManager |
|
| 2.4615384615384617;2.462 | ||||
ExpressionEvaluatorManager$1 |
|
| 2.4615384615384617;2.462 |
1 | /* | |
2 | * $Id: ExpressionEvaluatorManager.java 12100 2008-06-19 08:58:48Z rossmason $ | |
3 | * -------------------------------------------------------------------------------------- | |
4 | * Copyright (c) MuleSource, Inc. All rights reserved. http://www.mulesource.com | |
5 | * | |
6 | * The software in this package is published under the terms of the CPAL v1.0 | |
7 | * license, a copy of which has been included with this distribution in the | |
8 | * LICENSE.txt file. | |
9 | */ | |
10 | package org.mule.util.expression; | |
11 | ||
12 | import org.mule.api.lifecycle.Disposable; | |
13 | import org.mule.config.i18n.CoreMessages; | |
14 | import org.mule.util.TemplateParser; | |
15 | ||
16 | import java.util.Iterator; | |
17 | ||
18 | import edu.emory.mathcs.backport.java.util.concurrent.ConcurrentHashMap; | |
19 | import edu.emory.mathcs.backport.java.util.concurrent.ConcurrentMap; | |
20 | ||
21 | /** | |
22 | * Provides universal access for evaluating expressions embedded in Mule configurations, such as Xml, Java, | |
23 | * scripting and annotations. | |
24 | * | |
25 | * Users can register or unregister {@link ExpressionEvaluator} through this interface. | |
26 | * */ | |
27 | 0 | public class ExpressionEvaluatorManager |
28 | { | |
29 | ||
30 | public static final String DEFAULT_EXPRESSION_PREFIX = "${"; | |
31 | ||
32 | 2 | private static TemplateParser parser = TemplateParser.createAntStyleParser(); |
33 | ||
34 | 2 | private static ConcurrentMap evaluators = new ConcurrentHashMap(8); |
35 | ||
36 | public static void registerEvaluator(ExpressionEvaluator extractor) | |
37 | { | |
38 | 13756 | if (extractor == null) |
39 | { | |
40 | 2 | throw new IllegalArgumentException(CoreMessages.objectIsNull("extractor").getMessage()); |
41 | } | |
42 | 13754 | Object previous = evaluators.putIfAbsent(extractor.getName(), extractor); |
43 | 13754 | if (previous != null) |
44 | { | |
45 | 2 | throw new IllegalArgumentException(CoreMessages.objectAlreadyExists(extractor.getName()).getMessage()); |
46 | } | |
47 | 13752 | } |
48 | ||
49 | /** | |
50 | * Checks whether an evaluator is registered with the manager | |
51 | * @param name the name of the expression evaluator | |
52 | * @return true if the evaluator is registered with the manager, false otherwise | |
53 | */ | |
54 | public static boolean isEvaluatorRegistered(String name) | |
55 | { | |
56 | 8 | return evaluators.containsKey(name); |
57 | } | |
58 | ||
59 | /** | |
60 | * Removes the evaluator with the given name | |
61 | * @param name the name of the evaluator to remove | |
62 | */ | |
63 | public static ExpressionEvaluator unregisterEvaluator(String name) | |
64 | { | |
65 | 2 | if (name==null) |
66 | { | |
67 | 2 | return null; |
68 | } | |
69 | ||
70 | 0 | ExpressionEvaluator evaluator = (ExpressionEvaluator) ExpressionEvaluatorManager.evaluators.remove(name); |
71 | 0 | if (evaluator instanceof Disposable) |
72 | { | |
73 | 0 | ((Disposable) evaluator).dispose(); |
74 | } | |
75 | 0 | return evaluator; |
76 | } | |
77 | ||
78 | /** | |
79 | * Evaluates the given expression. The expression should be a single expression definition with or without | |
80 | * enclosing braces. i.e. "mule:serviceName" and "${mule:serviceName}" are both valid. For situations where | |
81 | * one or more expressions need to be parsed within a single text, the {@link #parse(String, Object, boolean)} | |
82 | * method should be used since it will iterate through all expressions in a string. | |
83 | * | |
84 | * @param expression a single expression i.e. xpath://foo | |
85 | * @param object The object (usually {@link org.mule.api.MuleMessage}) to evaluate the expression on. | |
86 | * @return the result of the evaluation | |
87 | * @throws ExpressionRuntimeException if the expression is invalid, or a null is found for the expression and | |
88 | * 'failIfNull is set to true. | |
89 | */ | |
90 | public static Object evaluate(String expression, Object object) throws ExpressionRuntimeException | |
91 | { | |
92 | 116 | return evaluate(expression, object, DEFAULT_EXPRESSION_PREFIX, false); |
93 | } | |
94 | ||
95 | /** | |
96 | * Evaluates the given expression. The expression should be a single expression definition with or without | |
97 | * enclosing braces. i.e. "mule:serviceName" and "${mule:serviceName}" are both valid. For situations where | |
98 | * one or more expressions need to be parsed within a single text, the {@link #parse(String, Object, boolean)} | |
99 | * method should be used since it will iterate through all expressions in a string. | |
100 | * | |
101 | * @param expression a single expression i.e. xpath://foo | |
102 | * @param object The object (usually {@link org.mule.api.MuleMessage}) to evaluate the expression on. | |
103 | * @param failIfNull determines if an exception should be thrown if expression could not be evaluated or returns | |
104 | * null. | |
105 | * @return the result of the evaluation | |
106 | * @throws ExpressionRuntimeException if the expression is invalid, or a null is found for the expression and | |
107 | * 'failIfNull is set to true. | |
108 | */ | |
109 | public static Object evaluate(String expression, Object object, boolean failIfNull) throws ExpressionRuntimeException | |
110 | { | |
111 | 16 | return evaluate(expression, object, DEFAULT_EXPRESSION_PREFIX, failIfNull); |
112 | } | |
113 | ||
114 | /** | |
115 | * Evaluates the given expression. The expression should be a single expression definition with or without | |
116 | * enclosing braces. i.e. "mule:serviceName" and "${mule:serviceName}" are both valid. For situations where | |
117 | * one or more expressions need to be parsed within a single text, the {@link #parse(String, Object, boolean)} | |
118 | * method should be used since it will iterate through all expressions in a string. | |
119 | * | |
120 | * @param expression a single expression i.e. xpath://foo | |
121 | * @param evaluator the evaluator to use when executing the expression | |
122 | * @param object The object (usually {@link org.mule.api.MuleMessage}) to evaluate the expression on. | |
123 | * It is unlikely that users will want to change this execpt maybe to use "[" instead. | |
124 | * @param failIfNull determines if an exception should be thrown if expression could not be evaluated or returns | |
125 | * null. | |
126 | * @return the result of the evaluation | |
127 | * @throws ExpressionRuntimeException if the expression is invalid, or a null is found for the expression and | |
128 | * 'failIfNull is set to true. | |
129 | */ | |
130 | public static Object evaluate(String expression, String evaluator, Object object, boolean failIfNull) throws ExpressionRuntimeException | |
131 | { | |
132 | 132 | ExpressionEvaluator extractor = (ExpressionEvaluator) evaluators.get(evaluator); |
133 | 132 | if (extractor == null) |
134 | { | |
135 | 0 | throw new IllegalArgumentException(CoreMessages.expressionEvaluatorNotRegistered(evaluator).getMessage()); |
136 | } | |
137 | 132 | Object result = extractor.evaluate(expression, object); |
138 | 126 | if (result == null && failIfNull) |
139 | { | |
140 | 0 | throw new ExpressionRuntimeException(CoreMessages.expressionEvaluatorReturnedNull(evaluator, expression)); |
141 | } | |
142 | 126 | return result; |
143 | } | |
144 | /** | |
145 | * Evaluates the given expression. The expression should be a single expression definition with or without | |
146 | * enclosing braces. i.e. "mule:serviceName" and "${mule:serviceName}" are both valid. For situations where | |
147 | * one or more expressions need to be parsed within a single text, the {@link #parse(String, Object, boolean)} | |
148 | * method should be used since it will iterate through all expressions in a string. | |
149 | * | |
150 | * @param expression a single expression i.e. xpath://foo | |
151 | * @param object The object (usually {@link org.mule.api.MuleMessage}) to evaluate the expression on. | |
152 | * @param expressionPrefix the expression prefix to use. The default is "${" but any character is valid. | |
153 | * It is unlikely that users will want to change this except maybe to use "[" instead. | |
154 | * @param failIfNull determines if an exception should be thrown if expression could not be evaluated or returns | |
155 | * null. | |
156 | * @return the result of the evaluation | |
157 | * @throws ExpressionRuntimeException if the expression is invalid, or a null is found for the expression and | |
158 | * 'failIfNull is set to true. | |
159 | */ | |
160 | public static Object evaluate(String expression, Object object, String expressionPrefix, boolean failIfNull) throws ExpressionRuntimeException | |
161 | { | |
162 | String name; | |
163 | ||
164 | 132 | if (expression == null) |
165 | { | |
166 | 0 | throw new IllegalArgumentException(CoreMessages.objectIsNull("expression").getMessage()); |
167 | } | |
168 | 132 | if (expression.startsWith(expressionPrefix)) |
169 | { | |
170 | 60 | expression = expression.substring(2, expression.length()-1); |
171 | } | |
172 | 132 | int i = expression.indexOf(":"); |
173 | 132 | if (i >- 1) |
174 | { | |
175 | 126 | name = expression.substring(0, i); |
176 | 126 | expression = expression.substring(i+1); |
177 | } | |
178 | else | |
179 | { | |
180 | 6 | name = expression; |
181 | 6 | expression = null; |
182 | } | |
183 | 132 | return evaluate(expression, name, object, failIfNull); |
184 | ||
185 | ||
186 | } | |
187 | ||
188 | /** | |
189 | * Evaluates expressions in a given string. This method will iterate through each expression and evaluate it. If | |
190 | * a user needs to evaluate a single expression they can use {@link #evaluate(String, Object, boolean)}. | |
191 | * | |
192 | * @param expression a single expression i.e. xpath://foo | |
193 | * @param object The object (usually {@link org.mule.api.MuleMessage}) to evaluate the expression on. | |
194 | ||
195 | * @return the result of the evaluation | |
196 | * @throws ExpressionRuntimeException if the expression is invalid, or a null is found for the expression and | |
197 | * 'failIfNull is set to true. | |
198 | */ | |
199 | public static String parse(String expression, Object object) throws ExpressionRuntimeException | |
200 | { | |
201 | 0 | return parse(expression, object, false); |
202 | } | |
203 | ||
204 | /** | |
205 | * Evaluates expressions in a given string. This method will iterate through each expression and evaluate it. If | |
206 | * a user needs to evaluate a single expression they can use {@link #evaluate(String, Object, boolean)}. | |
207 | * | |
208 | * @param expression a single expression i.e. xpath://foo | |
209 | * @param object The object (usually {@link org.mule.api.MuleMessage}) to evaluate the expression on. | |
210 | * @param failIfNull determines if an exception should be thrown if expression could not be evaluated or returns | |
211 | * null. | |
212 | * @return the result of the evaluation | |
213 | * @throws ExpressionRuntimeException if the expression is invalid, or a null is found for the expression and | |
214 | * 'failIfNull is set to true. | |
215 | */ | |
216 | public static String parse(final String expression, final Object object, final boolean failIfNull) throws ExpressionRuntimeException | |
217 | { | |
218 | 14 | return parser.parse(new TemplateParser.TemplateCallback() { |
219 | 14 | public Object match(String token) |
220 | { | |
221 | 14 | return evaluate(token, object, failIfNull); |
222 | } | |
223 | }, expression); | |
224 | } | |
225 | ||
226 | /** | |
227 | * Clears all registered evaluators from the manager. | |
228 | */ | |
229 | public static synchronized void clearEvaluators() | |
230 | { | |
231 | 2304 | for (Iterator iterator = evaluators.values().iterator(); iterator.hasNext();) |
232 | { | |
233 | 13752 | ExpressionEvaluator evaluator = (ExpressionEvaluator)iterator.next(); |
234 | 13752 | if(evaluator instanceof Disposable) |
235 | { | |
236 | 0 | ((Disposable) evaluator).dispose(); |
237 | } | |
238 | 13752 | } |
239 | 2304 | evaluators.clear(); |
240 | 2304 | } |
241 | ||
242 | /** | |
243 | * Determines if the expression is valid or not. This only validates single expressions. | |
244 | * @param expression the expression to validate | |
245 | * @return true if the expression evaluator is recognised | |
246 | */ | |
247 | public static boolean isValidExpression(String expression) | |
248 | { | |
249 | 8 | return isValidExpression(expression, DEFAULT_EXPRESSION_PREFIX); |
250 | } | |
251 | ||
252 | /** | |
253 | * Determines if the expression is valid or not. This only validates single expressions. | |
254 | * @param expression the expression to validate | |
255 | * @param expressionPrefix the prefix used for this expression. if the expression is ${bean:msg.header} | |
256 | * the prefix is "${" | |
257 | * @return true if the expression evaluator is recognised | |
258 | */ | |
259 | public static boolean isValidExpression(String expression, String expressionPrefix) | |
260 | { | |
261 | 8 | if(expression.startsWith(expressionPrefix)) |
262 | { | |
263 | 0 | expression = expression.substring(2, expression.length()-1); |
264 | } | |
265 | String name; | |
266 | 8 | int i = expression.indexOf(":"); |
267 | 8 | if(i>-1) |
268 | { | |
269 | 8 | name = expression.substring(0, i); |
270 | } | |
271 | else | |
272 | { | |
273 | 0 | name = expression; |
274 | } | |
275 | 8 | return isEvaluatorRegistered(name); |
276 | } | |
277 | ||
278 | } |