1 /*
2 * $Id: JmsMessageAdapter.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.jms;
12
13 import org.mule.api.MessagingException;
14 import org.mule.api.ThreadSafeAccess;
15 import org.mule.api.config.MuleProperties;
16 import org.mule.api.transport.MessageTypeNotSupportedException;
17 import org.mule.transport.AbstractMessageAdapter;
18
19 import java.util.Enumeration;
20
21 import javax.jms.Destination;
22 import javax.jms.JMSException;
23 import javax.jms.Message;
24
25 /**
26 * <code>JmsMessageAdapter</code> allows a <code>DefaultMuleEvent</code> to access the
27 * properties and payload of a JMS Message in a uniform way. The JmsMessageAdapter
28 * expects a message of type <i>javax.jms.Message</i> and will throw an
29 * IllegalArgumentException if the source message type is not compatible. The
30 * JmsMessageAdapter should be suitable for all JMS Connector implementations.
31 */
32 public class JmsMessageAdapter extends AbstractMessageAdapter
33 {
34 /**
35 * Serial version
36 */
37 private static final long serialVersionUID = -8151716840620558143L;
38
39 private String jmsSpec;
40 private Message jmsMessage;
41
42 public JmsMessageAdapter(Object message) throws MessagingException
43 {
44 super();
45 this.setMessage(message);
46 }
47
48 protected JmsMessageAdapter(JmsMessageAdapter template)
49 {
50 super(template);
51 jmsSpec = template.jmsSpec;
52 jmsMessage = template.jmsMessage;
53 }
54
55 public void setSpecification(String newSpec)
56 {
57 if (JmsConstants.JMS_SPECIFICATION_11.equals(newSpec)
58 || (JmsConstants.JMS_SPECIFICATION_102B.equals(newSpec)))
59 {
60 this.jmsSpec = newSpec;
61 }
62 else
63
64 {
65 throw new IllegalArgumentException(
66 "JMS specification needs to be one of the defined values in JmsConstants but was: " + newSpec);
67 }
68 }
69
70 /**
71 * Converts the message implementation into a String representation
72 *
73 * @param encoding The encoding to use when transforming the message (if
74 * necessary). The parameter is used when converting from a byte array
75 * @return String representation of the message payload
76 * @throws Exception Implementation may throw an endpoint specific exception
77 */
78 public String getPayloadAsString(String encoding) throws Exception
79 {
80 return new String(getPayloadAsBytes(), encoding);
81 }
82
83 /**
84 * Converts the message implementation into a String representation
85 *
86 * @return String representation of the message
87 * @throws Exception Implemetation may throw an endpoint specific exception
88 */
89 public byte[] getPayloadAsBytes() throws Exception
90 {
91 return JmsMessageUtils.toByteArray(jmsMessage, jmsSpec);
92 }
93
94 /**
95 * @return the current message
96 */
97 public Object getPayload()
98 {
99 return jmsMessage;
100 }
101
102 /**
103 * @param message new value for the message
104 */
105 private void setMessage(Object message) throws MessagingException
106 {
107 if (message instanceof Message)
108 {
109 this.jmsMessage = (Message)message;
110 }
111 else
112 {
113 throw new MessageTypeNotSupportedException(message, getClass());
114 }
115
116 try
117 {
118 String value = this.jmsMessage.getJMSCorrelationID();
119 if (value != null)
120 {
121 setProperty(JmsConstants.JMS_CORRELATION_ID, value);
122 }
123 }
124 catch (JMSException e)
125 {
126 // ignored
127 }
128
129 try
130 {
131 int value = this.jmsMessage.getJMSDeliveryMode();
132 setProperty(JmsConstants.JMS_DELIVERY_MODE, new Integer(value));
133 }
134 catch (JMSException e)
135 {
136 // ignored
137 }
138
139 try
140 {
141 Destination value = this.jmsMessage.getJMSDestination();
142 if (value != null)
143 {
144 setProperty(JmsConstants.JMS_DESTINATION, value);
145 }
146 }
147 catch (JMSException e)
148 {
149 // ignored
150 }
151
152 try
153 {
154 long value = this.jmsMessage.getJMSExpiration();
155 setProperty(JmsConstants.JMS_EXPIRATION, new Long(value));
156 }
157 catch (JMSException e)
158 {
159 // ignored
160 }
161
162 try
163 {
164 String value = this.jmsMessage.getJMSMessageID();
165 if (value != null)
166 {
167 setProperty(JmsConstants.JMS_MESSAGE_ID, value);
168 }
169 }
170 catch (JMSException e)
171 {
172 // ignored
173 }
174
175 try
176 {
177 int value = this.jmsMessage.getJMSPriority();
178 setProperty(JmsConstants.JMS_PRIORITY, new Integer(value));
179 }
180 catch (JMSException e)
181 {
182 // ignored
183 }
184
185 try
186 {
187 boolean value = this.jmsMessage.getJMSRedelivered();
188 setProperty(JmsConstants.JMS_REDELIVERED, Boolean.valueOf(value));
189 }
190 catch (JMSException e)
191 {
192 // ignored
193 }
194
195 try
196 {
197 Destination value = this.jmsMessage.getJMSReplyTo();
198 if (value != null)
199 {
200 setProperty(JmsConstants.JMS_REPLY_TO, value);
201 }
202 }
203 catch (JMSException e)
204 {
205 // ignored
206 }
207
208 try
209 {
210 long value = this.jmsMessage.getJMSTimestamp();
211 setProperty(JmsConstants.JMS_TIMESTAMP, new Long(value));
212 }
213 catch (JMSException e)
214 {
215 // ignored
216 }
217
218 try
219 {
220 String value = this.jmsMessage.getJMSType();
221 if (value != null)
222 {
223 setProperty(JmsConstants.JMS_TYPE, value);
224 }
225 }
226 catch (JMSException e)
227 {
228 // ignored
229 }
230
231 try
232 {
233 Enumeration e = this.jmsMessage.getPropertyNames();
234 while (e.hasMoreElements())
235 {
236 String key = (String)e.nextElement();
237 try
238 {
239 Object value = this.jmsMessage.getObjectProperty(key);
240 if (value != null)
241 {
242 setProperty(key, value);
243 }
244 }
245 catch (JMSException e1)
246 {
247 // ignored
248 }
249 }
250 }
251 catch (JMSException e1)
252 {
253 // ignored
254 }
255 }
256
257 public String getUniqueId()
258 {
259 return (String)getProperty(JmsConstants.JMS_MESSAGE_ID);
260 }
261
262 /**
263 * Sets a correlationId for this message. The correlation Id can be used by
264 * components in the system to manage message relations <p/> transport protocol.
265 * As such not all messages will support the notion of a correlationId i.e. tcp
266 * or file. In this situation the correlation Id is set as a property of the
267 * message where it's up to developer to keep the association with the message.
268 * For example if the message is serialised to xml the correlationId will be
269 * available in the message.
270 *
271 * @param id the Id reference for this relationship
272 */
273 public void setCorrelationId(String id)
274 {
275 setProperty(JmsConstants.JMS_CORRELATION_ID, id);
276 }
277
278 /**
279 * Sets a correlationId for this message. The correlation Id can be used by
280 * components in the system to manage message relations. <p/> The correlationId
281 * is associated with the message using the underlying transport protocol. As
282 * such not all messages will support the notion of a correlationId i.e. tcp or
283 * file. In this situation the correlation Id is set as a property of the message
284 * where it's up to developer to keep the association with the message. For
285 * example if the message is serialised to xml the correlationId will be
286 * available in the message.
287 *
288 * @return the correlationId for this message or null if one hasn't been set
289 */
290 public String getCorrelationId()
291 {
292 return (String)getProperty(JmsConstants.JMS_CORRELATION_ID);
293 }
294
295 /**
296 * Sets a replyTo address for this message. This is useful in an asynchronous
297 * environment where the caller doesn't wait for a response and the response
298 * needs to be routed somewhere for further processing. The value of this field
299 * can be any valid endpointUri url.
300 *
301 * @param replyTo the endpointUri url to reply to
302 */
303 public void setReplyTo(Object replyTo)
304 {
305 if (replyTo instanceof Destination)
306 {
307 setProperty(JmsConstants.JMS_REPLY_TO, replyTo);
308 }
309 else
310 {
311 super.setReplyTo(replyTo);
312 }
313 }
314
315 /**
316 * Sets a replyTo address for this message. This is useful in an asynchronous
317 * environment where the caller doesn't wait for a response and the response
318 * needs to be routed somewhere for further processing. The value of this field
319 * can be any valid endpointUri url.
320 *
321 * @return the endpointUri url to reply to or null if one has not been set
322 */
323 public Object getReplyTo()
324 {
325 Object replyTo = getProperty(JmsConstants.JMS_REPLY_TO);
326 if (replyTo == null)
327 {
328 replyTo = getProperty(MuleProperties.MULE_REPLY_TO_PROPERTY);
329 }
330 return replyTo;
331 }
332
333 public ThreadSafeAccess newThreadCopy()
334 {
335 return new JmsMessageAdapter(this);
336 }
337
338 }