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