1
2
3
4
5
6
7
8
9
10
11 package org.mule.expression;
12
13 import org.mule.api.MuleMessage;
14 import org.mule.api.expression.RequiredValueException;
15 import org.mule.api.transport.PropertyScope;
16 import org.mule.config.i18n.CoreMessages;
17 import org.mule.routing.filters.WildcardFilter;
18
19 import java.util.ArrayList;
20 import java.util.Collections;
21 import java.util.HashMap;
22 import java.util.List;
23 import java.util.Map;
24
25 import static org.mule.expression.ExpressionConstants.ALL_ARGUMENT;
26 import static org.mule.expression.ExpressionConstants.DELIM;
27 import static org.mule.expression.ExpressionConstants.OPTIONAL_ARGUMENT;
28
29
30
31
32 public final class ExpressionUtils
33 {
34 private ExpressionUtils()
35 {
36
37 }
38
39
40
41
42
43
44
45
46
47
48 public static Object getPropertyWithScope(String expression, MuleMessage msg)
49 {
50 return getPropertyWithScope(expression, msg, Object.class);
51 }
52
53
54
55
56
57
58
59
60
61
62
63
64
65 public static <T> T getPropertyWithScope(String expression, MuleMessage msg, Class<T> type)
66 {
67 return getPropertyInternal(expression, PropertyScope.OUTBOUND, true, msg, type);
68 }
69
70
71
72
73
74 public static Object getProperty(String expression, PropertyScope scope, MuleMessage msg)
75 {
76 return getProperty(expression, scope, msg, Object.class);
77 }
78
79
80
81
82
83
84
85
86
87 public static <T> T getProperty(String expression, PropertyScope scope, MuleMessage msg, Class<T> type)
88 {
89 return getPropertyInternal(expression, scope, false, msg, type);
90 }
91
92
93
94
95
96
97
98
99
100
101
102 @SuppressWarnings("unchecked")
103 protected static <T> T getPropertyInternal(String expression, PropertyScope scope, boolean parseScope, MuleMessage msg, Class<T> type)
104 {
105 if (parseScope)
106 {
107 PropertyScope tempScope = getScope(expression);
108 if (tempScope != null)
109 {
110
111 expression = expression.substring(tempScope.getScopeName().length() + 1);
112 scope = tempScope;
113 }
114 }
115
116 if (expression.contains(ALL_ARGUMENT))
117 {
118 WildcardFilter filter = new WildcardFilter(expression);
119 if (Map.class.isAssignableFrom(type))
120 {
121 Map<String, Object> props = new HashMap<String, Object>();
122 for (String name : msg.getPropertyNames(scope))
123 {
124 if (filter.accept(name))
125 {
126 props.put(name, msg.getProperty(name, scope));
127 }
128 }
129 return (T) returnMap(props, scope);
130 }
131 else if (List.class.isAssignableFrom(type))
132 {
133 List<Object> values = new ArrayList<Object>();
134 for (String name : msg.getPropertyNames(scope))
135 {
136 if (filter.accept(name))
137 {
138 values.add(msg.getProperty(name, scope));
139 }
140 }
141 return (T) returnList(values, scope);
142 }
143 else
144 {
145
146 throw new IllegalArgumentException("Type specified is not a collection type but '" + ALL_ARGUMENT + "' was specified for all properties. Type is: " + type);
147 }
148 }
149 else if (Map.class.isAssignableFrom(type))
150 {
151 String[] names = expression.split(DELIM);
152 Map<String, Object> props = new HashMap<String, Object>();
153 for (String name : names)
154 {
155 boolean required = true;
156 name = name.trim();
157 PropertyScope entryScope = scope;
158 if (parseScope)
159 {
160 entryScope = getScope(name);
161 if (entryScope != null)
162 {
163
164 name = name.substring(entryScope.getScopeName().length() + 1);
165 }
166 else
167 {
168 entryScope = scope;
169 }
170 }
171 if (name.endsWith(OPTIONAL_ARGUMENT))
172 {
173 name = name.substring(0, name.length() - OPTIONAL_ARGUMENT.length());
174 required = false;
175 }
176 Object value = msg.getProperty(name, entryScope);
177 if (value == null && required)
178 {
179 throw new RequiredValueException(CoreMessages.expressionEvaluatorReturnedNull("headers", entryScope.getScopeName() + ":" + name));
180 }
181 else if (value != null)
182 {
183 props.put(name, value);
184 }
185 }
186 return (T) returnMap(props, scope);
187 }
188 else if (List.class.isAssignableFrom(type))
189 {
190 String[] names = expression.split(DELIM);
191 List<Object> values = new ArrayList<Object>();
192 for (String name : names)
193 {
194 boolean required = true;
195 name = name.trim();
196 PropertyScope itemScope = scope;
197 if (parseScope)
198 {
199 itemScope = getScope(name);
200 if (itemScope != null)
201 {
202
203 name = name.substring(itemScope.getScopeName().length() + 1);
204 }
205 else
206 {
207 itemScope = scope;
208 }
209 }
210 if (name.endsWith(OPTIONAL_ARGUMENT))
211 {
212 name = name.substring(0, name.length() - OPTIONAL_ARGUMENT.length());
213 required = false;
214 }
215 name = name.trim();
216 Object value = msg.getProperty(name, itemScope);
217 if (value == null && required)
218 {
219 throw new RequiredValueException(CoreMessages.expressionEvaluatorReturnedNull("headers-list", itemScope.getScopeName() + ":" + name));
220 }
221 else if (value != null)
222 {
223 values.add(value);
224 }
225 }
226 return (T) returnList(values, scope);
227 }
228 else
229 {
230 boolean required = true;
231 if (expression.endsWith(OPTIONAL_ARGUMENT))
232 {
233 expression = expression.substring(0, expression.length() - OPTIONAL_ARGUMENT.length());
234 required = false;
235 }
236 Object result = msg.getProperty(expression.trim(), scope);
237 if (result == null && required)
238 {
239 throw new RequiredValueException(CoreMessages.expressionEvaluatorReturnedNull("header", scope.getScopeName() + ":" + expression));
240
241 }
242 return (T) result;
243 }
244 }
245
246 private static Map<String, Object> returnMap(Map<String, Object> props, PropertyScope scope)
247 {
248 Map<String, Object> p = (props.size() == 0 ? Collections.<String, Object>emptyMap() : props);
249 if (scope.equals(PropertyScope.INBOUND))
250 {
251 p = Collections.unmodifiableMap(p);
252 }
253 return p;
254 }
255
256 private static List<Object> returnList(List<Object> values, PropertyScope scope)
257 {
258 List<Object> l = (values.size() == 0 ? Collections.emptyList() : values);
259 if (scope.equals(PropertyScope.INBOUND))
260 {
261 l = Collections.unmodifiableList(l);
262 }
263 return l;
264 }
265
266 protected static PropertyScope getScope(String expression)
267 {
268
269 final String[] tokens = expression.split(":", 2);
270 PropertyScope scope;
271 if (tokens.length == 2)
272 {
273 final String candidate = tokens[0];
274 scope = PropertyScope.get(candidate.toLowerCase());
275 if (scope == null)
276 {
277 throw new IllegalArgumentException(String.format("'%s' is not a valid property scope.", candidate));
278 }
279
280 return scope;
281 }
282 return null;
283 }
284 }