1
2
3
4
5
6
7
8
9
10
11 package org.mule.transport;
12
13 import org.mule.api.MuleException;
14 import org.mule.api.MuleMessage;
15 import org.mule.api.config.MuleConfiguration;
16 import org.mule.api.context.WorkManager;
17 import org.mule.api.endpoint.ImmutableEndpoint;
18 import org.mule.api.lifecycle.CreateException;
19 import org.mule.api.lifecycle.InitialisationException;
20 import org.mule.api.lifecycle.LifecycleCallback;
21 import org.mule.api.lifecycle.LifecycleState;
22 import org.mule.api.lifecycle.LifecycleStateEnabled;
23 import org.mule.api.retry.RetryContext;
24 import org.mule.api.retry.RetryPolicyTemplate;
25 import org.mule.api.transport.Connectable;
26 import org.mule.api.transport.Connector;
27 import org.mule.api.transport.MuleMessageFactory;
28 import org.mule.config.i18n.CoreMessages;
29 import org.mule.config.i18n.Message;
30 import org.mule.config.i18n.MessageFactory;
31 import org.mule.context.notification.ConnectionNotification;
32 import org.mule.util.ClassUtils;
33
34 import java.util.concurrent.atomic.AtomicBoolean;
35
36 import org.apache.commons.logging.Log;
37 import org.apache.commons.logging.LogFactory;
38
39
40
41
42 public abstract class AbstractTransportMessageHandler<O> implements Connectable, LifecycleStateEnabled
43 {
44 protected transient Log logger = LogFactory.getLog(getClass());
45
46 protected ImmutableEndpoint endpoint;
47 protected final AbstractConnector connector;
48 protected RetryPolicyTemplate retryTemplate;
49 protected MuleMessageFactory muleMessageFactory = null;
50
51 protected ConnectableLifecycleManager<O> lifecycleManager;
52
53 protected final AtomicBoolean connected = new AtomicBoolean(false);
54
55 public AbstractTransportMessageHandler(ImmutableEndpoint endpoint)
56 {
57 this.endpoint = endpoint;
58 this.connector = (AbstractConnector) endpoint.getConnector();
59 this.lifecycleManager = createLifecycleManager();
60 }
61
62 protected abstract ConnectableLifecycleManager<O> createLifecycleManager();
63
64 public LifecycleState getLifecycleState()
65 {
66 return lifecycleManager.getState();
67 }
68
69 protected void disposeAndLogException()
70 {
71 try
72 {
73 dispose();
74 }
75 catch (Throwable t)
76 {
77 logger.error("Could not dispose of the message dispatcher!", t);
78 }
79 }
80
81 public boolean validate()
82 {
83
84 return !getLifecycleState().isDisposed();
85 }
86
87 public void activate()
88 {
89
90 }
91
92 public void passivate()
93 {
94
95 }
96
97 public void initialise() throws InitialisationException
98 {
99 try
100 {
101 lifecycleManager.fireInitialisePhase(new LifecycleCallback<O>()
102 {
103 public void onTransition(String phaseName, O object) throws MuleException
104 {
105 initializeRetryPolicy();
106 initializeMessageFactory();
107 doInitialise();
108 }
109 });
110 }
111 catch (InitialisationException e)
112 {
113 throw e;
114 }
115 catch (MuleException e)
116 {
117 throw new InitialisationException(e, this);
118 }
119
120 }
121
122 protected void initializeRetryPolicy()
123 {
124 if (endpoint.getRetryPolicyTemplate() != null)
125 {
126 retryTemplate = endpoint.getRetryPolicyTemplate();
127 }
128 else
129 {
130 retryTemplate = connector.getRetryPolicyTemplate();
131 }
132 }
133
134
135
136
137
138 protected void initializeMessageFactory() throws InitialisationException
139 {
140 try
141 {
142 muleMessageFactory = connector.getMuleMessageFactory();
143 }
144 catch (CreateException ce)
145 {
146 Message message = MessageFactory.createStaticMessage(ce.getMessage());
147 throw new InitialisationException(message, ce, this);
148 }
149 }
150
151
152
153
154 public synchronized void dispose()
155 {
156 try
157 {
158 if (isStarted())
159 {
160 stop();
161 }
162 if (isConnected())
163 {
164 disconnect();
165 }
166 }
167 catch (Exception e)
168 {
169 logger.warn(e.getMessage(), e);
170 }
171
172 try
173 {
174 lifecycleManager.fireDisposePhase(new LifecycleCallback<O>()
175 {
176 public void onTransition(String phaseName, O object) throws MuleException
177 {
178 doDispose();
179 }
180 });
181 }
182 catch (MuleException e)
183 {
184 logger.warn(e.getMessage(), e);
185 }
186 }
187
188 public Connector getConnector()
189 {
190 return connector;
191 }
192
193 public ImmutableEndpoint getEndpoint()
194 {
195 return endpoint;
196 }
197
198 public final synchronized void connect() throws Exception
199 {
200
201
202 if (connected.get())
203 {
204 return;
205 }
206
207 if (getLifecycleState().isDisposed())
208 {
209 throw new IllegalStateException(
210 "Requester/dispatcher has been disposed; cannot connect to resource:" + this);
211 }
212
213 if (logger.isDebugEnabled())
214 {
215 logger.debug("Connecting: " + this);
216 }
217
218 doConnect();
219 connected.set(true);
220
221 if (logger.isDebugEnabled())
222 {
223 logger.debug("Connected: " + getConnectionDescription());
224 }
225 }
226
227 public RetryContext validateConnection(RetryContext retryContext)
228 {
229 retryContext.setOk();
230 return retryContext;
231 }
232
233 public final synchronized void disconnect() throws Exception
234 {
235 if (isStarted())
236 {
237 stop();
238 }
239
240 if (logger.isDebugEnabled())
241 {
242 logger.debug("Disconnecting: " + this);
243 }
244
245 doDisconnect();
246 connected.set(false);
247
248 if (logger.isDebugEnabled())
249 {
250 logger.debug("Disconnected: " + this);
251 }
252 connector.fireNotification(new ConnectionNotification(this, getConnectEventId(endpoint),
253 ConnectionNotification.CONNECTION_DISCONNECTED));
254 }
255
256 protected String getConnectEventId(ImmutableEndpoint endpoint)
257 {
258 return connector.getName() + ".dispatcher(" + endpoint.getEndpointURI().getUri() + ")";
259 }
260
261 public final boolean isConnected()
262 {
263 return connected.get();
264 }
265
266 protected boolean isDoThreading()
267 {
268 return connector.getDispatcherThreadingProfile().isDoThreading();
269 }
270
271
272
273
274 public String getConnectionDescription()
275 {
276 return "endpoint.outbound." + endpoint.getEndpointURI().toString();
277 }
278
279
280
281
282
283
284
285
286
287
288
289 public final void start() throws MuleException
290 {
291 if (isStarted() || isStarting())
292 {
293 return;
294 }
295
296 if (!isConnected())
297 {
298 try
299 {
300 connect();
301 }
302 catch (MuleException me)
303 {
304 throw me;
305 }
306 catch (Exception e)
307 {
308 throw new ConnectException(e, this);
309 }
310 }
311
312 lifecycleManager.fireStartPhase(new LifecycleCallback<O>()
313 {
314 public void onTransition(String phaseName, O object) throws MuleException
315 {
316 doStart();
317 }
318 });
319 }
320
321 public final void stop() throws MuleException
322 {
323 lifecycleManager.fireStopPhase(new LifecycleCallback<O>()
324 {
325 public void onTransition(String phaseName, O object) throws MuleException
326 {
327 try
328 {
329 doStop();
330 }
331 catch (MuleException e)
332 {
333 logger.error(e.getMessage(), e);
334 }
335 }
336 });
337
338 }
339
340 protected void doInitialise() throws InitialisationException
341 {
342
343 }
344
345 protected void doDispose()
346 {
347
348 }
349
350 protected void doConnect() throws Exception
351 {
352
353 }
354
355 protected void doDisconnect() throws Exception
356 {
357
358 }
359
360 protected void doStart() throws MuleException
361 {
362
363 }
364
365 protected void doStop() throws MuleException
366 {
367
368 }
369
370 @Override
371 public String toString()
372 {
373 final StringBuffer sb = new StringBuffer(80);
374 sb.append(ClassUtils.getSimpleName(this.getClass()));
375 sb.append("{this=").append(Integer.toHexString(System.identityHashCode(this)));
376 sb.append(", endpoint=").append(endpoint.getEndpointURI());
377 sb.append(", disposed=").append(getLifecycleState().isDisposed());
378 sb.append('}');
379 return sb.toString();
380 }
381
382
383
384 public void setEndpoint(ImmutableEndpoint endpoint)
385 {
386 if (endpoint == null)
387 {
388 throw new IllegalArgumentException("Endpoint cannot be null");
389 }
390 this.endpoint = endpoint;
391 }
392
393 abstract protected WorkManager getWorkManager() throws MuleException;
394
395 public boolean isStarted()
396 {
397 return getLifecycleState().isStarted();
398 }
399
400 public boolean isStarting()
401 {
402 return getLifecycleState().isStarting();
403 }
404
405 public boolean isStopping()
406 {
407 return getLifecycleState().isStopping();
408 }
409
410
411
412
413
414
415 protected MuleMessageFactory createMuleMessageFactory() throws CreateException
416 {
417 return connector.createMuleMessageFactory();
418 }
419
420
421
422
423
424
425 public MuleMessage createMuleMessage(Object transportMessage, MuleMessage previousMessage,
426 String encoding) throws MuleException
427 {
428 try
429 {
430 return muleMessageFactory.create(transportMessage, previousMessage, encoding);
431 }
432 catch (Exception e)
433 {
434 throw new CreateException(CoreMessages.failedToCreate("MuleMessage"), e);
435 }
436 }
437
438
439
440
441
442 public MuleMessage createMuleMessage(Object transportMessage, String encoding) throws MuleException
443 {
444 try
445 {
446 return muleMessageFactory.create(transportMessage, encoding);
447 }
448 catch (Exception e)
449 {
450 throw new CreateException(CoreMessages.failedToCreate("MuleMessage"), e, this);
451 }
452 }
453
454
455
456
457
458
459
460 public MuleMessage createMuleMessage(Object transportMessage) throws MuleException
461 {
462 String encoding = endpoint.getMuleContext().getConfiguration().getDefaultEncoding();
463 return createMuleMessage(transportMessage, encoding);
464 }
465
466
467
468
469
470
471 protected MuleMessage createNullMuleMessage() throws MuleException
472 {
473 return createMuleMessage(null);
474 }
475 }