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 public static Object getPropertyWithScope(String expression, MuleMessage msg)
40 {
41 return getPropertyWithScope(expression, msg, Object.class);
42 }
43
44
45
46
47
48
49
50
51
52
53
54 @SuppressWarnings("unchecked")
55 public static <T> T getPropertyWithScope(String expression, MuleMessage msg, Class<T> type)
56 {
57 PropertyScope defaultScope = getScope(expression);
58 if (defaultScope != null)
59 {
60
61 expression = expression.substring(defaultScope.getScopeName().length() + 1);
62 }
63 else
64 {
65
66 defaultScope = PropertyScope.OUTBOUND;
67 }
68
69 if (expression.contains(ALL_ARGUMENT))
70 {
71 WildcardFilter filter = new WildcardFilter(expression);
72 if (Map.class.isAssignableFrom(type))
73 {
74 Map<String, Object> props = new HashMap<String, Object>();
75 for (String name : msg.getPropertyNames(defaultScope))
76 {
77 if (filter.accept(name))
78 {
79 props.put(name, msg.getProperty(name, defaultScope));
80 }
81 }
82 return (T) returnMap(props, defaultScope);
83 }
84 else if (List.class.isAssignableFrom(type))
85 {
86 List<Object> values = new ArrayList<Object>();
87 for (String name : msg.getPropertyNames(defaultScope))
88 {
89 if (filter.accept(name))
90 {
91 values.add(msg.getProperty(name, defaultScope));
92 }
93 }
94 return (T) returnList(values, defaultScope);
95 }
96 else
97 {
98
99 throw new IllegalArgumentException("Type specified is not a collection type but '" + ALL_ARGUMENT + "' was specified for all properties. Type is: " + type);
100 }
101 }
102 else if (Map.class.isAssignableFrom(type))
103 {
104 String[] names = expression.split(DELIM);
105 Map<String, Object> props = new HashMap<String, Object>();
106 for (String name : names)
107 {
108 boolean required = true;
109 name = name.trim();
110 PropertyScope scope = getScope(name);
111 if (scope != null)
112 {
113
114 name = name.substring(scope.getScopeName().length() + 1);
115 }
116 else
117 {
118 scope = defaultScope;
119 }
120 if (name.endsWith(OPTIONAL_ARGUMENT))
121 {
122 name = name.substring(0, name.length() - OPTIONAL_ARGUMENT.length());
123 required = false;
124 }
125 Object value = msg.getProperty(name, scope);
126 if (value == null && required)
127 {
128 throw new RequiredValueException(CoreMessages.expressionEvaluatorReturnedNull("headers", scope.getScopeName() + ":" + name));
129 }
130 else if (value != null)
131 {
132 props.put(name, value);
133 }
134 }
135 return (T) returnMap(props, defaultScope);
136 }
137 else if (List.class.isAssignableFrom(type))
138 {
139 String[] names = expression.split(DELIM);
140 List<Object> values = new ArrayList<Object>();
141 for (String name : names)
142 {
143 boolean required = true;
144 name = name.trim();
145 PropertyScope scope = getScope(name);
146 if (scope != null)
147 {
148
149 name = name.substring(scope.getScopeName().length() + 1);
150 }
151 else
152 {
153 scope = defaultScope;
154 }
155 if (name.endsWith(OPTIONAL_ARGUMENT))
156 {
157 name = name.substring(0, name.length() - OPTIONAL_ARGUMENT.length());
158 required = false;
159 }
160 name = name.trim();
161 Object value = msg.getProperty(name, scope);
162 if (value == null && required)
163 {
164 throw new RequiredValueException(CoreMessages.expressionEvaluatorReturnedNull("headers-list", scope.getScopeName() + ":" + name));
165 }
166 else if (value != null)
167 {
168 values.add(value);
169 }
170 }
171 return (T) returnList(values, defaultScope);
172 }
173 else
174 {
175 boolean required = true;
176 if (expression.endsWith(OPTIONAL_ARGUMENT))
177 {
178 expression = expression.substring(0, expression.length() - OPTIONAL_ARGUMENT.length());
179 required = false;
180 }
181 Object result = msg.getProperty(expression.trim(), defaultScope);
182 if (result == null && required)
183 {
184 throw new RequiredValueException(CoreMessages.expressionEvaluatorReturnedNull("header", defaultScope.getScopeName() + ":" + expression));
185
186 }
187 return (T) result;
188 }
189 }
190
191 private static Map<String, Object> returnMap(Map<String, Object> props, PropertyScope scope)
192 {
193 Map<String, Object> p = (props.size() == 0 ? Collections.<String, Object>emptyMap() : props);
194 if (scope.equals(PropertyScope.INBOUND))
195 {
196 p = Collections.unmodifiableMap(p);
197 }
198 return p;
199 }
200
201 private static List<Object> returnList(List<Object> values, PropertyScope scope)
202 {
203 List<Object> l = (values.size() == 0 ? Collections.emptyList() : values);
204 if (scope.equals(PropertyScope.INBOUND))
205 {
206 l = Collections.unmodifiableList(l);
207 }
208 return l;
209 }
210
211 private static PropertyScope getScope(String expression)
212 {
213
214 final String[] tokens = expression.split(":", 2);
215 PropertyScope scope;
216 if (tokens.length == 2)
217 {
218 final String candidate = tokens[0];
219 scope = PropertyScope.get(candidate.toLowerCase());
220 if (scope == null)
221 {
222 throw new IllegalArgumentException(String.format("'%s' is not a valid property scope.", candidate));
223 }
224
225 return scope;
226 }
227 return null;
228 }
229 }