1
2
3
4
5
6
7
8
9
10
11 package org.mule;
12
13 import org.mule.api.ExceptionPayload;
14 import org.mule.api.MuleMessage;
15 import org.mule.api.MuleRuntimeException;
16 import org.mule.api.ThreadSafeAccess;
17 import org.mule.api.transformer.Transformer;
18 import org.mule.api.transformer.TransformerException;
19 import org.mule.api.transport.MessageAdapter;
20 import org.mule.api.transport.MutableMessageAdapter;
21 import org.mule.api.transport.PropertyScope;
22 import org.mule.config.i18n.CoreMessages;
23 import org.mule.transport.AbstractMessageAdapter;
24 import org.mule.transport.DefaultMessageAdapter;
25 import org.mule.transport.NullPayload;
26 import org.mule.util.ClassUtils;
27
28 import java.io.InputStream;
29 import java.lang.reflect.Proxy;
30 import java.util.ArrayList;
31 import java.util.Iterator;
32 import java.util.List;
33 import java.util.Map;
34 import java.util.Set;
35
36 import javax.activation.DataHandler;
37
38 import edu.emory.mathcs.backport.java.util.concurrent.CopyOnWriteArrayList;
39
40 import org.apache.commons.logging.Log;
41 import org.apache.commons.logging.LogFactory;
42
43
44
45
46
47
48 public class DefaultMuleMessage implements MuleMessage, ThreadSafeAccess
49 {
50
51 private static final long serialVersionUID = 1541720810851984842L;
52 private static Log logger = LogFactory.getLog(DefaultMuleMessage.class);
53
54 private MessageAdapter adapter;
55 private MessageAdapter originalAdapter = null;
56 private transient List appliedTransformerHashCodes = new CopyOnWriteArrayList();
57 private byte[] cache;
58
59 private static final List consumableClasses = new ArrayList();
60
61 static
62 {
63 try
64 {
65 consumableClasses.add(ClassUtils.loadClass("javax.xml.stream.XMLStreamReader",
66 DefaultMuleMessage.class));
67 }
68 catch (ClassNotFoundException e)
69 {
70 }
71 }
72 public DefaultMuleMessage(Object message)
73 {
74 this(message, (Map) null);
75 }
76
77 public DefaultMuleMessage(Object message, Map properties)
78 {
79 if (message instanceof MessageAdapter)
80 {
81 adapter = (MessageAdapter) message;
82 }
83 else
84 {
85 adapter = new DefaultMessageAdapter(message);
86 }
87 addProperties(properties);
88 resetAccessControl();
89 }
90
91
92 public DefaultMuleMessage(Object message, MessageAdapter previous)
93 {
94 if (message instanceof MessageAdapter)
95 {
96 adapter = (MessageAdapter) message;
97 ((ThreadSafeAccess) adapter).resetAccessControl();
98 }
99 else
100 {
101 adapter = new DefaultMessageAdapter(message, previous);
102 }
103 if (previous.getExceptionPayload() != null)
104 {
105 setExceptionPayload(previous.getExceptionPayload());
106 }
107 setEncoding(previous.getEncoding());
108 if (previous.getAttachmentNames().size() > 0)
109 {
110 Set attNames = adapter.getAttachmentNames();
111 synchronized (attNames)
112 {
113 for (Iterator iterator = attNames.iterator(); iterator.hasNext();)
114 {
115 String s = (String) iterator.next();
116 try
117 {
118 addAttachment(s, adapter.getAttachment(s));
119 }
120 catch (Exception e)
121 {
122 throw new MuleRuntimeException(CoreMessages.failedToReadAttachment(s), e);
123 }
124 }
125 }
126 }
127 resetAccessControl();
128 }
129
130
131 public Object getPayload(Class outputType) throws TransformerException
132 {
133 return getPayload(outputType, getEncoding());
134 }
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149 protected Object getPayload(Class outputType, String encoding) throws TransformerException
150 {
151
152 if (outputType == null)
153 {
154 return getPayload();
155 }
156
157 Class inputCls = getPayload().getClass();
158
159
160 if (Proxy.isProxyClass(inputCls))
161 {
162 inputCls = inputCls.getInterfaces()[0];
163 }
164
165
166 if (outputType.isAssignableFrom(inputCls))
167 {
168 return getPayload();
169 }
170
171
172
173
174 Transformer transformer = null;
175 transformer = MuleServer.getMuleContext().getRegistry().lookupTransformer(inputCls, outputType);
176
177
178 if (transformer == null)
179 {
180 throw new TransformerException(CoreMessages.noTransformerFoundForMessage(inputCls, outputType));
181 }
182
183
184 Object result = transformer.transform(this);
185
186
187 if (!outputType.isAssignableFrom(result.getClass()))
188 {
189 throw new TransformerException(CoreMessages.transformOnObjectNotOfSpecifiedType(outputType.getName(), result.getClass()));
190 }
191
192
193
194 if (isPayloadConsumed(inputCls))
195 {
196 setPayload(result);
197 }
198
199 return result;
200 }
201
202
203
204
205
206
207
208
209
210 protected boolean isPayloadConsumed(Class inputCls)
211 {
212 return InputStream.class.isAssignableFrom(inputCls) || isConsumedFromAdditional(inputCls);
213 }
214
215 private boolean isConsumedFromAdditional(Class inputCls)
216 {
217 if (consumableClasses.isEmpty())
218 {
219 return false;
220 }
221
222 for (Iterator itr = consumableClasses.iterator(); itr.hasNext();)
223 {
224 Class c = (Class) itr.next();
225
226 if (c.isAssignableFrom(inputCls))
227 {
228 return true;
229 }
230 }
231 return false;
232 }
233
234
235 public MessageAdapter getAdapter()
236 {
237 return adapter;
238 }
239
240
241 public Object getOrginalPayload()
242 {
243 return (originalAdapter == null ? adapter.getPayload() : originalAdapter.getPayload());
244 }
245
246
247 public MessageAdapter getOriginalAdapter()
248 {
249 return (originalAdapter == null ? adapter : originalAdapter);
250 }
251
252
253 public void setProperty(String key, Object value, PropertyScope scope)
254 {
255 adapter.setProperty(key, value, scope);
256 }
257
258
259
260 public Object getProperty(String key)
261 {
262 return adapter.getProperty(key);
263 }
264
265
266 public Object removeProperty(String key)
267 {
268 return adapter.removeProperty(key);
269 }
270
271
272 public void setProperty(String key, Object value)
273 {
274 adapter.setProperty(key, value);
275 }
276
277
278 public final String getPayloadAsString() throws Exception
279 {
280 assertAccess(READ);
281 return getPayloadAsString(getEncoding());
282 }
283
284
285 public byte[] getPayloadAsBytes() throws Exception
286 {
287 assertAccess(READ);
288 if (cache != null)
289 {
290 return cache;
291 }
292 byte[] result = (byte[]) getPayload(byte[].class);
293 if (MuleServer.getMuleContext().getConfiguration().isCacheMessageAsBytes())
294 {
295 cache = result;
296 }
297 return result;
298 }
299
300
301 public String getPayloadAsString(String encoding) throws Exception
302 {
303 assertAccess(READ);
304 if (cache != null)
305 {
306 return new String(cache, encoding);
307 }
308 String result = (String) getPayload(String.class);
309 if (MuleServer.getMuleContext().getConfiguration().isCacheMessageAsBytes())
310 {
311 cache = result.getBytes(encoding);
312 }
313 return result;
314 }
315
316
317 public Set getPropertyNames()
318 {
319 return adapter.getPropertyNames();
320 }
321
322 /
323 public double getDoubleProperty(String name, double defaultValue)
324 {
325 return adapter.getDoubleProperty(name, defaultValue);
326 }
327
328
329 public void setDoubleProperty(String name, double value)
330 {
331 adapter.setDoubleProperty(name, value);
332 }
333
334
335 public String getUniqueId()
336 {
337 return adapter.getUniqueId();
338 }
339
340
341 public Object getProperty(String name, Object defaultValue)
342 {
343 return adapter.getProperty(name, defaultValue);
344 }
345
346
347 public int getIntProperty(String name, int defaultValue)
348 {
349 return adapter.getIntProperty(name, defaultValue);
350 }
351
352
353 public long getLongProperty(String name, long defaultValue)
354 {
355 return adapter.getLongProperty(name, defaultValue);
356 }
357
358
359 public boolean getBooleanProperty(String name, boolean defaultValue)
360 {
361 return adapter.getBooleanProperty(name, defaultValue);
362 }
363
364
365 public void setBooleanProperty(String name, boolean value)
366 {
367 adapter.setBooleanProperty(name, value);
368 }
369
370
371 public void setIntProperty(String name, int value)
372 {
373 adapter.setIntProperty(name, value);
374 }
375
376
377 public void setLongProperty(String name, long value)
378 {
379 adapter.setLongProperty(name, value);
380 }
381
382
383 public void setCorrelationId(String id)
384 {
385 adapter.setCorrelationId(id);
386 }
387
388
389 public String getCorrelationId()
390 {
391 return adapter.getCorrelationId();
392 }
393
394
395 public void setReplyTo(Object replyTo)
396 {
397 adapter.setReplyTo(replyTo);
398 }
399
400
401 public Object getReplyTo()
402 {
403 return adapter.getReplyTo();
404 }
405
406
407 public int getCorrelationSequence()
408 {
409 return adapter.getCorrelationSequence();
410 }
411
412
413 public void setCorrelationSequence(int sequence)
414 {
415 adapter.setCorrelationSequence(sequence);
416 }
417
418
419 public int getCorrelationGroupSize()
420 {
421 return adapter.getCorrelationGroupSize();
422 }
423
424 /
425 public void setCorrelationGroupSize(int size)
426 {
427 adapter.setCorrelationGroupSize(size);
428 }
429
430
431 public ExceptionPayload getExceptionPayload()
432 {
433 return adapter.getExceptionPayload();
434 }
435
436
437 public void setExceptionPayload(ExceptionPayload exceptionPayload)
438 {
439 adapter.setExceptionPayload(exceptionPayload);
440 }
441
442
443 public String toString()
444 {
445 return adapter.toString();
446 }
447
448
449 public void addAttachment(String name, DataHandler dataHandler) throws Exception
450 {
451 adapter.addAttachment(name, dataHandler);
452 }
453
454
455 public void removeAttachment(String name) throws Exception
456 {
457 adapter.removeAttachment(name);
458 }
459
460
461 public DataHandler getAttachment(String name)
462 {
463 return adapter.getAttachment(name);
464 }
465
466
467 public Set getAttachmentNames()
468 {
469 return adapter.getAttachmentNames();
470 }
471
472
473 public String getEncoding()
474 {
475 return adapter.getEncoding();
476 }
477
478
479 public void setEncoding(String encoding)
480 {
481 adapter.setEncoding(encoding);
482 }
483
484
485 public String getStringProperty(String name, String defaultValue)
486 {
487 return adapter.getStringProperty(name, defaultValue);
488 }
489
490
491 public void setStringProperty(String name, String value)
492 {
493 adapter.setStringProperty(name, value);
494 }
495
496
497
498 public void addProperties(Map properties)
499 {
500 adapter.addProperties(properties);
501 }
502
503
504 public void addProperties(Map properties, PropertyScope scope)
505 {
506 adapter.addProperties(properties, scope);
507 }
508
509
510 public void clearProperties()
511 {
512 adapter.clearProperties();
513 }
514
515
516 public Object getPayload()
517 {
518 return adapter.getPayload();
519 }
520
521
522 public synchronized void setPayload(Object payload)
523 {
524
525 if (!(adapter instanceof MutableMessageAdapter))
526 {
527 adapter = new DefaultMessageAdapter(payload, adapter);
528 }
529 else
530 {
531 ((MutableMessageAdapter) adapter).setPayload(payload);
532 }
533 cache = null;
534 }
535
536
537 public void release()
538 {
539 adapter.release();
540 if (originalAdapter != null)
541 {
542 originalAdapter.release();
543 }
544 cache = null;
545 appliedTransformerHashCodes.clear();
546 }
547
548
549 public void applyTransformers(List transformers) throws TransformerException
550 {
551 applyTransformers(transformers, null);
552 }
553
554 public void applyTransformers(List transformers, Class outputType) throws TransformerException
555 {
556 if (!transformers.isEmpty() && !appliedTransformerHashCodes.contains(new Integer(transformers.hashCode())))
557 {
558 applyAllTransformers(transformers);
559 appliedTransformerHashCodes.add(new Integer(transformers.hashCode()));
560 }
561
562 if (null != outputType && !getPayload().getClass().isAssignableFrom(outputType))
563 {
564 setPayload(getPayload(outputType));
565 }
566 }
567
568 protected void applyAllTransformers(List transformers) throws TransformerException
569 {
570 if (!transformers.isEmpty())
571 {
572
573 Iterator iterator = transformers.iterator();
574 while (iterator.hasNext())
575 {
576 Transformer transformer = (Transformer) iterator.next();
577
578 if (getPayload() == null)
579 {
580 if (transformer.isAcceptNull())
581 {
582 setPayload(NullPayload.getInstance());
583 }
584 else
585 {
586 if (logger.isDebugEnabled())
587 {
588 logger.debug("Transformer " + transformer +
589 " doesn't support the null payload, exiting from transformer chain.");
590 }
591 break;
592 }
593 }
594
595 Class srcCls = getPayload().getClass();
596 if (transformer.isSourceTypeSupported(srcCls))
597 {
598 Object result = transformer.transform(this);
599
600 if (originalAdapter == null && MuleServer.getMuleContext().getConfiguration().isCacheMessageOriginalPayload())
601 {
602 originalAdapter = adapter;
603 }
604
605 if (result instanceof MuleMessage)
606 {
607 synchronized (this)
608 {
609 adapter = ((MuleMessage) result).getAdapter();
610 }
611 }
612 else
613 {
614 setPayload(result);
615 }
616 }
617 else
618 {
619 if (logger.isDebugEnabled())
620 {
621 logger.debug("Transformer " + transformer + " doesn't support the source payload: " + srcCls);
622 }
623 if (!transformer.isIgnoreBadInput())
624 {
625 if (logger.isDebugEnabled())
626 {
627 logger.debug("Exiting from transformer chain (ignoreBadInput = false)");
628 }
629 break;
630 }
631 }
632 }
633 }
634 }
635
636
637
638
639 public ThreadSafeAccess newThreadCopy()
640 {
641 if (adapter instanceof ThreadSafeAccess)
642 {
643 logger.debug("new copy of message for " + Thread.currentThread());
644 return new DefaultMuleMessage(((ThreadSafeAccess) adapter).newThreadCopy(), this);
645 }
646 else
647 {
648
649 return this;
650 }
651 }
652
653
654 public void resetAccessControl()
655 {
656 if (adapter instanceof AbstractMessageAdapter)
657 {
658 ((AbstractMessageAdapter) adapter).resetAccessControl();
659 }
660 if (originalAdapter instanceof AbstractMessageAdapter)
661 {
662 ((AbstractMessageAdapter) originalAdapter).resetAccessControl();
663 }
664 }
665
666
667 public void assertAccess(boolean write)
668 {
669 if (adapter instanceof AbstractMessageAdapter)
670 {
671 ((AbstractMessageAdapter) adapter).assertAccess(write);
672 }
673 }
674 }