1
2
3
4
5
6
7
8
9
10
11 package org.mule.construct;
12
13 import org.mule.DefaultMuleEvent;
14 import org.mule.RequestContext;
15 import org.mule.api.MuleContext;
16 import org.mule.api.MuleEvent;
17 import org.mule.api.MuleException;
18 import org.mule.api.construct.FlowConstruct;
19 import org.mule.api.construct.FlowConstructAware;
20 import org.mule.api.construct.FlowConstructInvalidException;
21 import org.mule.api.context.MuleContextAware;
22 import org.mule.api.exception.MessagingExceptionHandler;
23 import org.mule.api.lifecycle.Disposable;
24 import org.mule.api.lifecycle.Initialisable;
25 import org.mule.api.lifecycle.InitialisationException;
26 import org.mule.api.lifecycle.Lifecycle;
27 import org.mule.api.lifecycle.LifecycleCallback;
28 import org.mule.api.lifecycle.LifecycleState;
29 import org.mule.api.lifecycle.Startable;
30 import org.mule.api.lifecycle.Stoppable;
31 import org.mule.api.processor.MessageProcessor;
32 import org.mule.api.processor.MessageProcessorBuilder;
33 import org.mule.api.routing.MessageInfoMapping;
34 import org.mule.api.source.MessageSource;
35 import org.mule.exception.DefaultServiceExceptionStrategy;
36 import org.mule.management.stats.FlowConstructStatistics;
37 import org.mule.processor.AbstractInterceptingMessageProcessor;
38 import org.mule.processor.builder.InterceptingChainMessageProcessorBuilder;
39 import org.mule.routing.MuleMessageInfoMapping;
40 import org.mule.util.ClassUtils;
41
42 import java.beans.ExceptionListener;
43
44 import org.apache.commons.logging.Log;
45 import org.apache.commons.logging.LogFactory;
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64 public abstract class AbstractFlowConstruct implements FlowConstruct, Lifecycle, MessageProcessor
65 {
66 protected transient Log logger = LogFactory.getLog(getClass());
67
68 protected String name;
69 protected MessageSource messageSource;
70 protected MessageProcessor messageProcessorChain;
71 protected MessagingExceptionHandler exceptionListener;
72 protected final FlowConstructLifecycleManager lifecycleManager;
73 protected final MuleContext muleContext;
74 protected final FlowConstructStatistics statistics;
75 protected MessageInfoMapping messageInfoMapping = new MuleMessageInfoMapping();
76
77 public AbstractFlowConstruct(String name, MuleContext muleContext)
78 {
79 this.muleContext = muleContext;
80 this.name = name;
81 this.lifecycleManager = new FlowConstructLifecycleManager(this);
82 this.statistics = new FlowConstructStatistics(name);
83 this.exceptionListener = new DefaultServiceExceptionStrategy(muleContext);
84 }
85
86 public final void initialise() throws InitialisationException
87 {
88 try
89 {
90 lifecycleManager.fireInitialisePhase(new LifecycleCallback<FlowConstruct>()
91 {
92 public void onTransition(String phaseName, FlowConstruct object) throws MuleException
93 {
94 createMessageProcessor();
95
96 if (messageSource != null)
97 {
98
99 messageSource.setListener(new AbstractInterceptingMessageProcessor()
100 {
101 public MuleEvent process(MuleEvent event) throws MuleException
102 {
103 return messageProcessorChain.process(event);
104 }
105 });
106 }
107
108 injectFlowConstructMuleContext(messageSource);
109 injectFlowConstructMuleContext(messageProcessorChain);
110 initialiseIfInitialisable(messageSource);
111 initialiseIfInitialisable(messageProcessorChain);
112
113 doInitialise();
114
115 validateConstruct();
116 }
117 });
118
119 }
120 catch (InitialisationException e)
121 {
122 throw e;
123 }
124 catch (MuleException e)
125 {
126 throw new InitialisationException(e, this);
127 }
128 }
129
130 public final void start() throws MuleException
131 {
132 lifecycleManager.fireStartPhase(new LifecycleCallback<FlowConstruct>()
133 {
134 public void onTransition(String phaseName, FlowConstruct object) throws MuleException
135 {
136 startIfStartable(messageProcessorChain);
137 startIfStartable(messageSource);
138 doStart();
139 }
140 });
141 }
142
143 public final void stop() throws MuleException
144 {
145 lifecycleManager.fireStopPhase(new LifecycleCallback<FlowConstruct>()
146 {
147 public void onTransition(String phaseName, FlowConstruct object) throws MuleException
148 {
149 stopIfStoppable(messageSource);
150 stopIfStoppable(messageProcessorChain);
151 doStop();
152 }
153 });
154 }
155
156 public final void dispose()
157 {
158 try
159 {
160 if (isStarted())
161 {
162 stop();
163 }
164
165 lifecycleManager.fireDisposePhase(new LifecycleCallback<FlowConstruct>()
166 {
167 public void onTransition(String phaseName, FlowConstruct object) throws MuleException
168 {
169 disposeIfDisposable(messageProcessorChain);
170 disposeIfDisposable(messageSource);
171 doDispose();
172 }
173 });
174 }
175 catch (MuleException e)
176 {
177 logger.error("Failed to stop service: " + name, e);
178 }
179 }
180
181 public boolean isStarted()
182 {
183 return lifecycleManager.getState().isStarted();
184 }
185
186 public boolean isStopped()
187 {
188 return lifecycleManager.getState().isStopped();
189 }
190
191 public boolean isStopping()
192 {
193 return lifecycleManager.getState().isStopping();
194 }
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210 protected void createMessageProcessor() throws MuleException
211 {
212 InterceptingChainMessageProcessorBuilder builder = new InterceptingChainMessageProcessorBuilder(this);
213 configureMessageProcessors(builder);
214 messageProcessorChain = builder.build();
215 }
216
217
218
219
220
221
222
223
224
225
226
227
228 protected abstract void configureMessageProcessors(InterceptingChainMessageProcessorBuilder builder) throws MuleException;
229
230 public String getName()
231 {
232 return name;
233 }
234
235 public MessagingExceptionHandler getExceptionListener()
236 {
237 return exceptionListener;
238 }
239
240 public void setExceptionListener(MessagingExceptionHandler exceptionListener)
241 {
242 this.exceptionListener = exceptionListener;
243 }
244
245 public LifecycleState getLifecycleState()
246 {
247 return lifecycleManager.getState();
248 }
249
250 public MuleContext getMuleContext()
251 {
252 return muleContext;
253 }
254
255 public MessageSource getMessageSource()
256 {
257 return messageSource;
258 }
259
260 public void setMessageSource(MessageSource messageSource)
261 {
262 this.messageSource = messageSource;
263 }
264
265 public FlowConstructStatistics getStatistics()
266 {
267 return statistics;
268 }
269
270 public MessageInfoMapping getMessageInfoMapping()
271 {
272 return messageInfoMapping;
273 }
274
275 public void setMessageInfoMapping(MessageInfoMapping messageInfoMapping)
276 {
277 this.messageInfoMapping = messageInfoMapping;
278 }
279
280 protected void doInitialise() throws InitialisationException
281 {
282
283 }
284
285 protected void doStart() throws MuleException
286 {
287
288 }
289
290 protected void doStop() throws MuleException
291 {
292
293 }
294
295 protected void doDispose()
296 {
297
298 }
299
300
301
302
303
304
305
306 protected void validateConstruct() throws FlowConstructInvalidException
307 {
308
309 }
310
311 private void injectFlowConstructMuleContext(Object candidate)
312 {
313 if (candidate instanceof FlowConstructAware)
314 {
315 ((FlowConstructAware) candidate).setFlowConstruct(this);
316 }
317 if (candidate instanceof MuleContextAware)
318 {
319 ((MuleContextAware) candidate).setMuleContext(muleContext);
320 }
321 }
322
323 @Override
324 public String toString()
325 {
326 return String.format("%s{%s}", ClassUtils.getSimpleName(this.getClass()), getName());
327 }
328
329 private void initialiseIfInitialisable(Object candidate) throws InitialisationException
330 {
331 if (candidate instanceof Initialisable)
332 {
333 ((Initialisable) candidate).initialise();
334 }
335 }
336
337 private void startIfStartable(Object candidate) throws MuleException
338 {
339 if (candidate instanceof Startable)
340 {
341 ((Startable) candidate).start();
342 }
343 }
344
345 private void stopIfStoppable(Object candidate) throws MuleException
346 {
347 if (candidate instanceof Stoppable)
348 {
349 ((Stoppable) candidate).stop();
350 }
351 }
352
353 private void disposeIfDisposable(Object candidate)
354 {
355 if (candidate instanceof Disposable)
356 {
357 ((Disposable) candidate).dispose();
358 }
359 }
360
361 public MuleEvent process(MuleEvent event) throws MuleException
362 {
363 MuleEvent newEvent = new DefaultMuleEvent(event.getMessage(), event.getEndpoint(), this, event);
364 RequestContext.setEvent(newEvent);
365 return messageProcessorChain.process(newEvent);
366 }
367
368 }