1
2
3
4
5
6
7
8
9
10
11 package org.mule.construct;
12
13 import org.mule.api.AnnotatedObject;
14 import org.mule.api.MuleContext;
15 import org.mule.api.MuleException;
16 import org.mule.api.construct.FlowConstruct;
17 import org.mule.api.construct.FlowConstructAware;
18 import org.mule.api.construct.FlowConstructInvalidException;
19 import org.mule.api.context.MuleContextAware;
20 import org.mule.api.exception.MessagingExceptionHandler;
21 import org.mule.api.lifecycle.Disposable;
22 import org.mule.api.lifecycle.Initialisable;
23 import org.mule.api.lifecycle.InitialisationException;
24 import org.mule.api.lifecycle.Lifecycle;
25 import org.mule.api.lifecycle.LifecycleCallback;
26 import org.mule.api.lifecycle.LifecycleState;
27 import org.mule.api.lifecycle.Startable;
28 import org.mule.api.lifecycle.Stoppable;
29 import org.mule.api.processor.MessageProcessor;
30 import org.mule.api.routing.MessageInfoMapping;
31 import org.mule.api.source.MessageSource;
32 import org.mule.exception.DefaultMessagingExceptionStrategy;
33 import org.mule.management.stats.FlowConstructStatistics;
34 import org.mule.routing.MuleMessageInfoMapping;
35 import org.mule.util.ClassUtils;
36
37 import java.beans.ExceptionListener;
38 import java.util.Collections;
39 import java.util.Map;
40 import java.util.concurrent.ConcurrentHashMap;
41
42 import javax.xml.namespace.QName;
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
65 public abstract class AbstractFlowConstruct implements FlowConstruct, Lifecycle, AnnotatedObject
66 {
67 protected transient Log logger = LogFactory.getLog(getClass());
68
69 protected String name;
70 protected MessagingExceptionHandler exceptionListener;
71 protected final FlowConstructLifecycleManager lifecycleManager;
72 protected final MuleContext muleContext;
73 protected FlowConstructStatistics statistics;
74 protected MessageInfoMapping messageInfoMapping = new MuleMessageInfoMapping();
75 private final Map<QName, Object> annotations = new ConcurrentHashMap<QName, Object>();
76
77 public AbstractFlowConstruct(String name, MuleContext muleContext)
78 {
79 this.muleContext = muleContext;
80 this.name = name;
81 this.lifecycleManager = new FlowConstructLifecycleManager(this, muleContext);
82 this.exceptionListener = new DefaultMessagingExceptionStrategy(muleContext);
83 }
84
85 public final void initialise() throws InitialisationException
86 {
87 try
88 {
89 lifecycleManager.fireInitialisePhase(new LifecycleCallback<FlowConstruct>()
90 {
91 public void onTransition(String phaseName, FlowConstruct object) throws MuleException
92 {
93 injectFlowConstructMuleContext(exceptionListener);
94 initialiseIfInitialisable(exceptionListener);
95
96 doInitialise();
97
98 validateConstruct();
99 }
100 });
101
102 }
103 catch (InitialisationException e)
104 {
105 throw e;
106 }
107 catch (MuleException e)
108 {
109 throw new InitialisationException(e, this);
110 }
111 }
112
113 public final void start() throws MuleException
114 {
115 lifecycleManager.fireStartPhase(new LifecycleCallback<FlowConstruct>()
116 {
117 public void onTransition(String phaseName, FlowConstruct object) throws MuleException
118 {
119 startIfStartable(exceptionListener);
120 doStart();
121 }
122 });
123 }
124
125 public final void stop() throws MuleException
126 {
127 lifecycleManager.fireStopPhase(new LifecycleCallback<FlowConstruct>()
128 {
129 public void onTransition(String phaseName, FlowConstruct object) throws MuleException
130 {
131 doStop();
132 stopIfStoppable(exceptionListener);
133 }
134 });
135 }
136
137 public final void dispose()
138 {
139 try
140 {
141 if (isStarted())
142 {
143 stop();
144 }
145
146 lifecycleManager.fireDisposePhase(new LifecycleCallback<FlowConstruct>()
147 {
148 public void onTransition(String phaseName, FlowConstruct object) throws MuleException
149 {
150 doDispose();
151 disposeIfDisposable(exceptionListener);
152 }
153 });
154 }
155 catch (MuleException e)
156 {
157 logger.error("Failed to stop service: " + name, e);
158 }
159 }
160
161 public boolean isStarted()
162 {
163 return lifecycleManager.getState().isStarted();
164 }
165
166 public boolean isStopped()
167 {
168 return lifecycleManager.getState().isStopped();
169 }
170
171 public boolean isStopping()
172 {
173 return lifecycleManager.getState().isStopping();
174 }
175
176 public String getName()
177 {
178 return name;
179 }
180
181 public MessagingExceptionHandler getExceptionListener()
182 {
183 return exceptionListener;
184 }
185
186 public void setExceptionListener(MessagingExceptionHandler exceptionListener)
187 {
188 this.exceptionListener = exceptionListener;
189 }
190
191 public LifecycleState getLifecycleState()
192 {
193 return lifecycleManager.getState();
194 }
195
196 public MuleContext getMuleContext()
197 {
198 return muleContext;
199 }
200
201 public FlowConstructStatistics getStatistics()
202 {
203 return statistics;
204 }
205
206 public MessageInfoMapping getMessageInfoMapping()
207 {
208 return messageInfoMapping;
209 }
210
211 public void setMessageInfoMapping(MessageInfoMapping messageInfoMapping)
212 {
213 this.messageInfoMapping = messageInfoMapping;
214 }
215
216 protected void doInitialise() throws MuleException
217 {
218 configureStatistics();
219 }
220
221 protected void configureStatistics()
222 {
223 statistics = new FlowConstructStatistics(getConstructType(), name);
224 statistics.setEnabled(muleContext.getStatistics().isEnabled());
225 muleContext.getStatistics().add(statistics);
226 }
227
228 protected void doStart() throws MuleException
229 {
230
231 }
232
233 protected void doStop() throws MuleException
234 {
235
236 }
237
238 protected void doDispose()
239 {
240 muleContext.getStatistics().remove(statistics);
241 }
242
243
244
245
246
247
248
249 protected void validateConstruct() throws FlowConstructInvalidException
250 {
251
252 }
253
254 protected void injectFlowConstructMuleContext(Object candidate)
255 {
256 if (candidate instanceof FlowConstructAware)
257 {
258 ((FlowConstructAware) candidate).setFlowConstruct(this);
259 }
260 if (candidate instanceof MuleContextAware)
261 {
262 ((MuleContextAware) candidate).setMuleContext(muleContext);
263 }
264 }
265
266 @Override
267 public String toString()
268 {
269 return String.format("%s{%s}", ClassUtils.getSimpleName(this.getClass()), getName());
270 }
271
272 protected void initialiseIfInitialisable(Object candidate) throws InitialisationException
273 {
274 if (candidate instanceof Initialisable)
275 {
276 ((Initialisable) candidate).initialise();
277 }
278 }
279
280 protected void startIfStartable(Object candidate) throws MuleException
281 {
282 if (candidate instanceof Startable)
283 {
284 ((Startable) candidate).start();
285 }
286 }
287
288 protected void stopIfStoppable(Object candidate) throws MuleException
289 {
290 if (candidate instanceof Stoppable)
291 {
292 ((Stoppable) candidate).stop();
293 }
294 }
295
296 protected void disposeIfDisposable(Object candidate)
297 {
298 if (candidate instanceof Disposable)
299 {
300 ((Disposable) candidate).dispose();
301 }
302 }
303
304 public final Object getAnnotation(QName name)
305 {
306 return annotations.get(name);
307 }
308
309 public final Map<QName, Object> getAnnotations()
310 {
311 return Collections.unmodifiableMap(annotations);
312 }
313
314 public synchronized final void setAnnotations(Map<QName, Object> newAnnotations)
315 {
316 annotations.clear();
317 annotations.putAll(newAnnotations);
318 }
319
320
321
322
323
324 public abstract String getConstructType();
325 }