1
2
3
4
5
6
7
8
9
10
11 package org.mule.providers.jms;
12
13 import org.mule.impl.MuleMessage;
14 import org.mule.providers.AbstractMessageReceiver;
15 import org.mule.providers.ConnectException;
16 import org.mule.providers.jms.filters.JmsSelectorFilter;
17 import org.mule.transaction.TransactionCallback;
18 import org.mule.transaction.TransactionCoordination;
19 import org.mule.transaction.TransactionTemplate;
20 import org.mule.umo.UMOComponent;
21 import org.mule.umo.UMOException;
22 import org.mule.umo.UMOTransaction;
23 import org.mule.umo.endpoint.UMOEndpoint;
24 import org.mule.umo.lifecycle.InitialisationException;
25 import org.mule.umo.lifecycle.LifecycleException;
26 import org.mule.umo.provider.UMOConnector;
27 import org.mule.umo.provider.UMOMessageAdapter;
28 import org.mule.util.ClassUtils;
29
30 import javax.jms.Destination;
31 import javax.jms.JMSException;
32 import javax.jms.Message;
33 import javax.jms.MessageConsumer;
34 import javax.jms.MessageListener;
35 import javax.jms.Session;
36 import javax.jms.Topic;
37 import javax.resource.spi.work.Work;
38
39 public class TransactedSingleResourceJmsMessageReceiver extends AbstractMessageReceiver
40 implements MessageListener
41 {
42 protected JmsConnector connector;
43 protected RedeliveryHandler redeliveryHandler;
44 protected MessageConsumer consumer;
45 protected Session session;
46 protected boolean startOnConnect = false;
47
48
49 protected boolean receiveMessagesInTransaction = true;
50
51
52 protected boolean useMultipleReceivers = true;
53
54
55
56
57
58
59
60 public TransactedSingleResourceJmsMessageReceiver(UMOConnector connector,
61 UMOComponent component,
62 UMOEndpoint endpoint) throws InitialisationException
63 {
64 super(connector, component, endpoint);
65 this.connector = (JmsConnector)connector;
66
67
68
69
70 try
71 {
72 redeliveryHandler = this.connector.createRedeliveryHandler();
73 redeliveryHandler.setConnector(this.connector);
74 }
75 catch (Exception e)
76 {
77 throw new InitialisationException(e, this);
78 }
79 }
80
81 protected void doDispose()
82 {
83
84 }
85
86 protected void doConnect() throws Exception
87 {
88 try
89 {
90 JmsSupport jmsSupport = this.connector.getJmsSupport();
91
92 if (session == null)
93 {
94 session = this.connector.getSession(endpoint);
95 }
96
97
98 boolean topic = connector.getTopicResolver().isTopic(endpoint, true);
99
100 Destination dest = jmsSupport.createDestination(session, endpoint.getEndpointURI().getAddress(),
101 topic);
102
103
104 String selector = null;
105 if (endpoint.getFilter() != null && endpoint.getFilter() instanceof JmsSelectorFilter)
106 {
107 selector = ((JmsSelectorFilter)endpoint.getFilter()).getExpression();
108 }
109 else if (endpoint.getProperties() != null)
110 {
111
112
113 selector = (String)endpoint.getProperties().get(JmsConstants.JMS_SELECTOR_PROPERTY);
114 }
115 String tempDurable = (String)endpoint.getProperties().get(JmsConstants.DURABLE_PROPERTY);
116 boolean durable = connector.isDurable();
117 if (tempDurable != null)
118 {
119 durable = Boolean.valueOf(tempDurable).booleanValue();
120 }
121
122
123 String durableName = (String)endpoint.getProperties().get(JmsConstants.DURABLE_NAME_PROPERTY);
124 if (durableName == null && durable && dest instanceof Topic)
125 {
126 durableName = "mule." + connector.getName() + "." + endpoint.getEndpointURI().getAddress();
127 logger.debug("Jms Connector for this receiver is durable but no durable name has been specified. Defaulting to: "
128 + durableName);
129 }
130
131
132 consumer = jmsSupport.createConsumer(session, dest, selector, connector.isNoLocal(), durableName,
133 topic);
134 }
135 catch (JMSException e)
136 {
137 throw new ConnectException(e, this);
138 }
139 }
140
141 protected void doStart() throws UMOException
142 {
143 try
144 {
145
146
147
148
149 if (consumer == null)
150 {
151 startOnConnect = true;
152 }
153 else
154 {
155 startOnConnect = false;
156 this.consumer.setMessageListener(this);
157 }
158 }
159 catch (JMSException e)
160 {
161 throw new LifecycleException(e, this);
162 }
163 }
164
165 protected void doStop() throws UMOException
166 {
167 try
168 {
169 if (consumer != null)
170 {
171 consumer.setMessageListener(null);
172 }
173 }
174 catch (JMSException e)
175 {
176 throw new LifecycleException(e, this);
177 }
178 }
179
180 public void doDisconnect() throws Exception
181 {
182 closeConsumer();
183 }
184
185 protected void closeConsumer()
186 {
187 connector.closeQuietly(consumer);
188 consumer = null;
189 connector.closeQuietly(session);
190 session = null;
191 }
192
193 public void onMessage(Message message)
194 {
195 try
196 {
197 getWorkManager().scheduleWork(new MessageReceiverWorker(message));
198 }
199 catch (Exception e)
200 {
201 handleException(e);
202 }
203 }
204
205 protected class MessageReceiverWorker implements Work
206 {
207 Message message;
208
209 public MessageReceiverWorker(Message message)
210 {
211 this.message = message;
212 }
213
214 public void run()
215 {
216 try
217 {
218 TransactionTemplate tt = new TransactionTemplate(endpoint.getTransactionConfig(),
219 connector.getExceptionListener());
220
221 if (receiveMessagesInTransaction)
222 {
223 TransactionCallback cb = new MessageTransactionCallback(message)
224 {
225
226 public Object doInTransaction() throws Exception
227 {
228
229 UMOTransaction tx = TransactionCoordination.getInstance().getTransaction();
230 if (tx != null)
231 {
232 tx.bindResource(connector.getConnection(), session);
233 }
234 if (tx instanceof JmsClientAcknowledgeTransaction)
235 {
236 tx.bindResource(message, message);
237 }
238
239 if (logger.isDebugEnabled())
240 {
241 logger.debug("Message received it is of type: " +
242 ClassUtils.getSimpleName(message.getClass()));
243 if (message.getJMSDestination() != null)
244 {
245 logger.debug("Message received on " + message.getJMSDestination() + " ("
246 + message.getJMSDestination().getClass().getName() + ")");
247 }
248 else
249 {
250 logger.debug("Message received on unknown destination");
251 }
252 logger.debug("Message CorrelationId is: " + message.getJMSCorrelationID());
253 logger.debug("Jms Message Id is: " + message.getJMSMessageID());
254 }
255
256 if (message.getJMSRedelivered())
257 {
258 if (logger.isDebugEnabled())
259 {
260 logger.debug("Message with correlationId: "
261 + message.getJMSCorrelationID()
262 + " is redelivered. handing off to Exception Handler");
263 }
264 redeliveryHandler.handleRedelivery(message);
265 }
266
267 UMOMessageAdapter adapter = connector.getMessageAdapter(message);
268 routeMessage(new MuleMessage(adapter));
269 return null;
270 }
271 };
272 tt.execute(cb);
273 }
274 else
275 {
276 UMOMessageAdapter adapter = connector.getMessageAdapter(message);
277 routeMessage(new MuleMessage(adapter));
278 }
279
280 }
281 catch (Exception e)
282 {
283 getConnector().handleException(e);
284 }
285
286 }
287
288 public void release()
289 {
290
291 }
292
293 }
294
295 }