1
2
3
4
5
6
7
8
9
10 package org.mule;
11
12 import org.mule.api.MuleEvent;
13 import org.mule.api.MuleSession;
14 import org.mule.api.transport.PropertyScope;
15 import org.mule.util.CaseInsensitiveHashMap;
16 import org.mule.util.MapUtils;
17 import org.mule.util.ObjectUtils;
18
19 import java.io.IOException;
20 import java.io.Serializable;
21 import java.util.Collections;
22 import java.util.HashMap;
23 import java.util.HashSet;
24 import java.util.Map;
25 import java.util.Set;
26 import java.util.TreeMap;
27 import java.util.TreeSet;
28
29 import org.apache.commons.logging.Log;
30 import org.apache.commons.logging.LogFactory;
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47 public class MessagePropertiesContext implements Serializable
48 {
49 private static final long serialVersionUID = -5230693402768953742L;
50 private static final PropertyScope DEFAULT_SCOPE = PropertyScope.OUTBOUND;
51
52 private static Log logger = LogFactory.getLog(MessagePropertiesContext.class);
53
54
55
56
57 protected Map<PropertyScope, Map<String, Object>> scopedMap;
58
59
60
61
62 protected Set<String> keySet;
63
64
65 @SuppressWarnings("unchecked")
66 public MessagePropertiesContext()
67 {
68 keySet = new TreeSet<String>();
69 scopedMap = new TreeMap<PropertyScope, Map<String, Object>>(new PropertyScope.ScopeComparator());
70
71 scopedMap.put(PropertyScope.INVOCATION, new CaseInsensitiveHashMap
72 scopedMap.put(PropertyScope.INBOUND, new CaseInsensitiveHashMap
73 scopedMap.put(PropertyScope.OUTBOUND, new CaseInsensitiveHashMap
74 }
75
76 protected Map<String, Object> getScopedProperties(PropertyScope scope)
77 {
78 Map<String, Object> map = scopedMap.get(scope);
79 if (map == null)
80 {
81 throw new IllegalArgumentException("Scope not registered: " + scope);
82 }
83 return map;
84 }
85
86 public PropertyScope getDefaultScope()
87 {
88 return DEFAULT_SCOPE;
89 }
90
91 protected void addInboundProperties(Map<String, Object> properties)
92 {
93 if (properties != null)
94 {
95 Map<String, Object> props = new HashMap<String, Object>(properties.size());
96 for (String key : properties.keySet())
97 {
98 props.put(key, properties.get(key));
99 }
100 getScopedProperties(PropertyScope.INBOUND).putAll(props);
101 keySet.addAll(props.keySet());
102 }
103 }
104
105
106
107
108
109
110 @Deprecated
111 public Object getProperty(String key)
112 {
113 return getProperty(key, PropertyScope.OUTBOUND);
114 }
115
116 @SuppressWarnings("unchecked")
117 public <T> T getProperty(String key, PropertyScope scope)
118 {
119 if (scope == null)
120 {
121 scope = PropertyScope.OUTBOUND;
122 }
123
124 T value = null;
125 if (PropertyScope.SESSION.equals(scope))
126 {
127 if (RequestContext.getEvent() != null)
128 {
129 value = (T) RequestContext.getEvent().getSession().getProperty(key);
130 }
131 }
132 else
133 {
134 value = (T) scopedMap.get(scope).get(key);
135 }
136 return value;
137 }
138
139
140
141
142
143 public void clearProperties()
144 {
145 Map<String, Object> props = getScopedProperties(PropertyScope.INVOCATION);
146 keySet.removeAll(props.keySet());
147 props.clear();
148 props = getScopedProperties(PropertyScope.OUTBOUND);
149 keySet.removeAll(props.keySet());
150 props.clear();
151 }
152
153 public void clearProperties(PropertyScope scope)
154 {
155 if (scope == null)
156 {
157 clearProperties();
158 return;
159 }
160
161
162 if (PropertyScope.SESSION.equals(scope))
163 {
164 if (RequestContext.getEvent() != null)
165 {
166 MuleSession session = RequestContext.getEvent().getSession();
167 for (Object key : session.getPropertyNamesAsSet())
168 {
169 session.removeProperty(key);
170 }
171 }
172 }
173 else
174 {
175 Map<String, Object> props = getScopedProperties(scope);
176 keySet.removeAll(props.keySet());
177 props.clear();
178 }
179 }
180
181
182
183
184
185
186
187
188 public Object removeProperty(String key)
189 {
190 Object value = getScopedProperties(PropertyScope.OUTBOUND).remove(key);
191 Object inv = getScopedProperties(PropertyScope.INVOCATION).remove(key);
192
193 keySet.remove(key);
194
195 if (value == null)
196 {
197 value = inv;
198 }
199
200 return value;
201 }
202
203
204
205
206
207
208
209 public Object removeProperty(String key, PropertyScope scope)
210 {
211 if (scope == null)
212 {
213 return removeProperty(key);
214 }
215
216 Object value = null;
217 if (PropertyScope.SESSION.equals(scope))
218 {
219 if (RequestContext.getEvent() != null)
220 {
221 value = RequestContext.getEvent().getSession().removeProperty(key);
222 }
223 }
224 else
225 {
226 value = getScopedProperties(scope).remove(key);
227 }
228
229
230 if (getProperty(key, PropertyScope.OUTBOUND) == null
231 && getProperty(key, PropertyScope.INVOCATION) == null
232 && getProperty(key, PropertyScope.INBOUND) == null)
233 {
234 keySet.remove(key);
235 }
236
237 return value;
238 }
239
240
241
242
243
244
245
246
247 @Deprecated
248 public void setProperty(String key, Object value)
249 {
250 getScopedProperties(DEFAULT_SCOPE).put(key, value);
251 keySet.add(key);
252 }
253
254
255
256
257
258
259
260
261
262 public void setProperty(String key, Object value, PropertyScope scope)
263 {
264
265 if (PropertyScope.SESSION.equals(scope))
266 {
267 if (RequestContext.getEvent() != null)
268 {
269 RequestContext.getEvent().getSession().setProperty(key, value);
270 }
271 else
272 {
273 logger.warn(String.format("Detected an attempt to set a session property, " +
274 "but MuleEvent isn't available in this thread. Key/value: %s=%s %s",
275 key, value, Thread.currentThread()));
276 }
277 }
278 else
279 {
280 getScopedProperties(scope).put(key, value);
281 keySet.add(key);
282 }
283 }
284
285
286
287
288 @Deprecated
289 public Set<String> getPropertyNames()
290 {
291 Set<String> allProps = new HashSet<String>();
292 allProps.addAll(keySet);
293 if (RequestContext.getEvent() != null)
294 {
295 allProps.addAll(RequestContext.getEvent().getSession().getPropertyNamesAsSet());
296 }
297 return allProps;
298 }
299
300
301
302
303 public Set<String> getPropertyNames(PropertyScope scope)
304 {
305 if (PropertyScope.SESSION.equals(scope))
306 {
307 if (RequestContext.getEvent() != null)
308 {
309 return RequestContext.getEvent().getSession().getPropertyNamesAsSet();
310 }
311 else
312 {
313 return Collections.emptySet();
314 }
315 }
316 else
317 {
318 return Collections.unmodifiableSet(getScopedProperties(scope).keySet());
319 }
320 }
321
322 protected void checkScopeForWriteAccess(PropertyScope scope)
323 {
324 if (scope == null || PropertyScope.INBOUND.equals(scope))
325 {
326 throw new IllegalArgumentException("Scope is invalid for writing properties: " + scope);
327 }
328 }
329
330 public Object getProperty(String key, Object defaultValue)
331 {
332 Object value = getProperty(key);
333 if (value == null)
334 {
335 value = defaultValue;
336 }
337 return value;
338 }
339
340 public byte getByteProperty(String name, byte defaultValue)
341 {
342 return ObjectUtils.getByte(getProperty(name), defaultValue);
343 }
344
345 public short getShortProperty(String name, short defaultValue)
346 {
347 return ObjectUtils.getShort(getProperty(name), defaultValue);
348 }
349
350 public int getIntProperty(String name, int defaultValue)
351 {
352 return ObjectUtils.getInt(getProperty(name), defaultValue);
353 }
354
355 public long getLongProperty(String name, long defaultValue)
356 {
357 return ObjectUtils.getLong(getProperty(name), defaultValue);
358 }
359
360 public float getFloatProperty(String name, float defaultValue)
361 {
362 return ObjectUtils.getFloat(getProperty(name), defaultValue);
363 }
364
365 public double getDoubleProperty(String name, double defaultValue)
366 {
367 return ObjectUtils.getDouble(getProperty(name), defaultValue);
368 }
369
370 public boolean getBooleanProperty(String name, boolean defaultValue)
371 {
372 return ObjectUtils.getBoolean(getProperty(name), defaultValue);
373 }
374
375 @Deprecated
376 public String getStringProperty(String name, String defaultValue)
377 {
378 return getStringProperty(name, PropertyScope.OUTBOUND, defaultValue);
379 }
380
381 public String getStringProperty(String name, PropertyScope scope, String defaultValue)
382 {
383 return ObjectUtils.getString(getProperty(name, scope), defaultValue);
384 }
385
386 @Override
387 public String toString()
388 {
389 StringBuffer buf = new StringBuffer(128);
390 buf.append("Properties{");
391 for (Map.Entry<PropertyScope, Map<String, Object>> entry : scopedMap.entrySet())
392 {
393 buf.append(entry.getKey()).append(":");
394 buf.append(MapUtils.toString(entry.getValue(), false));
395 buf.append(", ");
396 }
397 buf.append("}");
398 return buf.toString();
399 }
400
401
402
403
404 private void writeObject(java.io.ObjectOutputStream out) throws IOException
405 {
406 for (Map.Entry<PropertyScope, Map<String, Object>> context : scopedMap.entrySet())
407 {
408 for (Map.Entry<String, Object> entry : context.getValue().entrySet())
409 {
410 Object value = entry.getValue();
411 if (value != null && !(value instanceof Serializable))
412 {
413 String message = String.format("Unable to serialize the %s message property %s, which is of type %s ",
414 context.getKey(), entry.getKey(), value);
415 logger.error(message);
416 throw new IOException(message);
417 }
418 }
419 }
420 out.defaultWriteObject();
421 }
422 }