1
2
3
4
5
6
7
8
9
10
11 package org.mule.transformer.simple;
12
13 import org.mule.DefaultMuleMessage;
14 import org.mule.api.MuleMessage;
15 import org.mule.api.transport.PropertyScope;
16 import org.mule.routing.filters.WildcardFilter;
17 import org.mule.transformer.AbstractMessageTransformer;
18 import org.mule.transformer.types.DataTypeFactory;
19 import org.mule.transport.NullPayload;
20
21 import java.text.MessageFormat;
22 import java.util.ArrayList;
23 import java.util.Arrays;
24 import java.util.HashMap;
25 import java.util.HashSet;
26 import java.util.List;
27 import java.util.Map;
28 import java.util.Set;
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44 public class MessagePropertiesTransformer extends AbstractMessageTransformer
45 {
46 private List<String> deleteProperties = null;
47 private Map<String, Object> addProperties = null;
48
49 private Map<String, String> renameProperties;
50 private String getProperty;
51 private boolean overwrite = true;
52
53 private PropertyScope scope = PropertyScope.OUTBOUND;
54
55 public MessagePropertiesTransformer()
56 {
57 registerSourceType(DataTypeFactory.OBJECT);
58 setReturnDataType(DataTypeFactory.OBJECT);
59 }
60
61 @Override
62 public Object clone() throws CloneNotSupportedException
63 {
64 MessagePropertiesTransformer clone = (MessagePropertiesTransformer) super.clone();
65
66 if (deleteProperties != null)
67 {
68 clone.setDeleteProperties(new ArrayList<String>(deleteProperties));
69 }
70
71 if (addProperties != null)
72 {
73 clone.setAddProperties(new HashMap<String, Object>(addProperties));
74 }
75
76 if (renameProperties != null)
77 {
78 clone.setRenameProperties(new HashMap<String, String>(renameProperties));
79 }
80 return clone;
81 }
82
83 @Override
84 public Object transformMessage(MuleMessage message, String outputEncoding)
85 {
86 if (deleteProperties != null && deleteProperties.size() > 0)
87 {
88 deleteProperties(message);
89 }
90
91 if (addProperties != null && addProperties.size() > 0)
92 {
93 addProperties(message);
94 }
95
96
97 if (this.renameProperties != null && this.renameProperties.size() > 0)
98 {
99 renameProperties(message);
100 }
101
102 if (getProperty != null)
103 {
104 Object prop = message.getProperty(getProperty, scope);
105 if (prop != null)
106 {
107 message = new DefaultMuleMessage(prop, muleContext);
108 }
109 else
110 {
111 message = new DefaultMuleMessage(NullPayload.getInstance(), muleContext);
112 }
113 }
114
115 return message;
116 }
117
118 protected void deleteProperties(MuleMessage message)
119 {
120 final Set<String> propertyNames = new HashSet<String>(message.getPropertyNames(scope));
121
122 for (String expression : deleteProperties)
123 {
124 for (String key : propertyNames)
125 {
126 if (key.matches(expression))
127 {
128 if (logger.isDebugEnabled())
129 {
130 logger.debug(String.format("Removing property: '%s' from scope: '%s'", key, scope.getScopeName()));
131 }
132 message.removeProperty(key, scope);
133 }
134 else
135 {
136
137 WildcardFilter filter = new WildcardFilter(expression);
138 if (filter.accept(key))
139 {
140 message.removeProperty(key, scope);
141 }
142 }
143 }
144 }
145 }
146
147 protected void addProperties(MuleMessage message)
148 {
149 for (Map.Entry<String, Object> entry : addProperties.entrySet())
150 {
151 if (entry.getKey() == null)
152 {
153 logger.error("Setting Null property keys is not supported, this entry is being ignored");
154 }
155 else
156 {
157 final String key = entry.getKey();
158
159 Object value= entry.getValue();
160 Object realValue = value;
161
162
163 if (muleContext.getExpressionManager().isExpression(value.toString()))
164 {
165 realValue = muleContext.getExpressionManager().evaluate(value.toString(), message);
166 }
167
168 if (realValue != null)
169 {
170 if (message.getProperty(key, scope) != null)
171 {
172 if (overwrite)
173 {
174 logger.debug("Overwriting message property " + key);
175 message.setProperty(key, realValue, scope);
176 }
177 else if(logger.isDebugEnabled())
178 {
179 logger.debug(MessageFormat.format(
180 "Message already contains the property and overwrite is false, skipping: key={0}, value={1}, scope={2}",
181 key, realValue, scope));
182 }
183 }
184
185
186 else
187 {
188 message.setProperty(key, realValue, scope);
189 }
190 }
191 else if (logger.isInfoEnabled())
192 {
193 logger.info(MessageFormat.format(
194 "Property with key '{0}', not found on message using '{1}'. Since the value was marked optional, nothing was set on the message for this property",
195 key, value));
196 }
197 }
198 }
199 }
200
201 protected void renameProperties(MuleMessage message)
202 {
203 for (Map.Entry<String, String> entry : this.renameProperties.entrySet())
204 {
205 if (entry.getKey() == null)
206 {
207 logger.error("Setting Null property keys is not supported, this entry is being ignored");
208 }
209 else
210 {
211 final String key = entry.getKey();
212 String value = entry.getValue();
213
214 if (value == null)
215 {
216 logger.error("Setting Null property values for renameProperties is not supported, this entry is being ignored");
217 }
218 else
219 {
220
221 if (muleContext.getExpressionManager().isValidExpression(value))
222 {
223 Object temp = muleContext.getExpressionManager().evaluate(value, message);
224 if (temp != null)
225 {
226 value = temp.toString();
227 }
228 }
229
230
231 if (logger.isDebugEnabled() && message.getProperty(key, scope) == null)
232 {
233 logger.debug(String.format("renaming message property '%s' to '%s'", key, value));
234 }
235
236 renameInScope(key, value, scope, message);
237 }
238 }
239 }
240 }
241
242 protected void renameInScope(String oldKey, String newKey, PropertyScope propertyScope, MuleMessage message)
243 {
244 Object propValue = message.getProperty(oldKey, propertyScope);
245 message.removeProperty(oldKey, propertyScope);
246 message.setProperty(newKey, propValue, propertyScope);
247 }
248
249 public List<String> getDeleteProperties()
250 {
251 return deleteProperties;
252 }
253
254
255
256
257 public void setDeleteProperties(List<String> deleteProperties)
258 {
259 this.deleteProperties = deleteProperties;
260 }
261
262 public void setDeleteProperties(String... deleteProperties)
263 {
264 this.deleteProperties = Arrays.asList(deleteProperties);
265 }
266
267 public Map<String, Object> getAddProperties()
268 {
269 return addProperties;
270 }
271
272 public void setAddProperties(Map<String, Object> addProperties)
273 {
274 this.addProperties = addProperties;
275 }
276
277
278
279
280 public Map<String, String> getRenameProperties()
281 {
282 return this.renameProperties;
283 }
284
285
286
287
288 public void setRenameProperties(Map<String, String> renameProperties)
289 {
290 this.renameProperties = renameProperties;
291 }
292
293 public String getGetProperty()
294 {
295 return getProperty;
296 }
297
298 public void setGetProperty(String getProperty)
299 {
300 this.getProperty = getProperty;
301 }
302
303 public boolean isOverwrite()
304 {
305 return overwrite;
306 }
307
308 public void setOverwrite(final boolean overwrite)
309 {
310 this.overwrite = overwrite;
311 }
312
313 public PropertyScope getScope()
314 {
315 return scope;
316 }
317
318 public void setScope(PropertyScope scope)
319 {
320 this.scope = scope;
321 }
322
323
324
325
326
327
328 public String getScopeName()
329 {
330 return scope != null ? scope.getScopeName() : null;
331 }
332
333
334
335
336
337 public void setScopeName(String scopeName)
338 {
339 this.scope = PropertyScope.get(scopeName);
340 }
341 }