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