View Javadoc

1   /*
2    * $Id: DefaultMessageAdapter.java 10489 2008-01-23 17:53:38Z dfeist $
3    * --------------------------------------------------------------------------------------
4    * Copyright (c) MuleSource, Inc.  All rights reserved.  http://www.mulesource.com
5    *
6    * The software in this package is published under the terms of the CPAL v1.0
7    * license, a copy of which has been included with this distribution in the
8    * LICENSE.txt file.
9    */
10  
11  package org.mule.transport;
12  
13  import org.mule.api.MuleRuntimeException;
14  import org.mule.api.ThreadSafeAccess;
15  import org.mule.api.transport.MessageAdapter;
16  import org.mule.api.transport.MutableMessageAdapter;
17  import org.mule.config.i18n.CoreMessages;
18  
19  import java.util.Iterator;
20  import java.util.Map;
21  
22  import javax.activation.DataHandler;
23  
24  /**
25   * <code>DefaultMessageAdapter</code> can be used to wrap an arbitary object where
26   * no special 'apapting' is needed. The adapter allows for a set of properties to be
27   * associated with an object.
28   */
29  
30  public final class DefaultMessageAdapter extends AbstractMessageAdapter implements MutableMessageAdapter
31  {
32      /**
33       * Serial version
34       */
35      private static final long serialVersionUID = 1908152148142575505L;
36  
37      /**
38       * The message object wrapped by this adapter
39       */
40      protected Object message;
41  
42      
43      protected DefaultMessageAdapter()
44      {
45          super();
46      }
47  
48      /**
49       * Creates a default message adapter with properties and attachments
50       *
51       * @param message the message to wrap. If this is null and NullPayload object
52       *            will be used
53       * @see NullPayload
54       */
55      public DefaultMessageAdapter(Object message)
56      {
57          if (message == null)
58          {
59              this.message = NullPayload.getInstance();
60          }
61          else
62          {
63              this.message = message;
64          }
65      }
66  
67      public DefaultMessageAdapter(Object message, MessageAdapter previous)
68      {
69          super(previous);
70          if (previous != null)
71          {
72              if (message == null)
73              {
74                  this.message = NullPayload.getInstance();
75              }
76              else
77              {
78                  this.message = message;
79              }
80              // MULE-1564
81              // this is an iterator over a concurrent map and so is weakly consistent (not fail-safe)
82              // that means we don't get errors here, but may see changed values.
83              // so we can make this safe to null values (although not predictable) by simply checking values
84              for (Iterator iterator = previous.getAttachmentNames().iterator(); iterator.hasNext();)
85              {
86                  String name = (String) iterator.next();
87                  try
88                  {
89                      DataHandler dh = previous.getAttachment(name);
90                      if (null == dh)
91                      {
92                          logger.warn("Detected concurrent access to attachment " + name + " for " + previous);
93  //                        new Throwable().printStackTrace();
94                      }
95                      else
96                      {
97                          addAttachment(name, dh);
98                      }
99                  }
100                 catch (Exception e)
101                 {
102                     throw new MuleRuntimeException(CoreMessages.failedToReadPayload(), e);
103                 }
104             }
105             for (Iterator iterator = previous.getPropertyNames().iterator(); iterator.hasNext();)
106             {
107                 String name = (String) iterator.next();
108                 try
109                 {
110                     Object value = previous.getProperty(name);
111                     if (null == value)
112                     {
113                         logger.warn("Detected concurrent access to property " + name + " for " + previous);
114 //                        new Throwable().printStackTrace();
115                     }
116                     else
117                     {
118                         setProperty(name, value);
119                     }
120                 }
121                 catch (Exception e)
122                 {
123                     throw new MuleRuntimeException(CoreMessages.failedToReadPayload(), e);
124                 }
125             }
126         }
127         else
128         {
129             throw new IllegalArgumentException("previousAdapter may not be null");
130         }
131     }
132 
133     /**
134      * Creates a default message adapter with properties and attachments
135      *
136      * @param message the message to wrap. If this is null and NullPayload object
137      *            will be used
138      * @param properties a map properties to set on the adapter. Can be null.
139      * @param attachments a map attaches (DataHandler objects) to set on the adapter.
140      *            Can be null.
141      * @see NullPayload
142      * @see javax.activation.DataHandler
143      */
144     public DefaultMessageAdapter(Object message, Map properties, Map attachments)
145     {
146         this(message);
147         if (properties != null)
148         {
149             this.properties.addInboundProperties(properties);
150         }
151         if (attachments != null)
152         {
153             this.attachments.putAll(attachments);
154         }
155     }
156 
157     /** {@inheritDoc} */
158     public Object getPayload()
159     {
160         return message;
161     }
162 
163     /** {@inheritDoc} */
164     public void setPayload(Object payload)
165     {
166         synchronized(message)
167         {
168             message = payload;
169         }
170     }
171 
172     /** {@inheritDoc} */
173     public String getUniqueId()
174     {
175         return id;
176     }
177 
178     ////////////////////////// ThreadSafeAccess impl ////////////////////
179 
180     /** {@inheritDoc} */
181     public ThreadSafeAccess newThreadCopy()
182     {
183         return new DefaultMessageAdapter(getPayload(), this);
184     }
185 
186 }