1
2
3
4
5
6
7
8
9
10
11 package org.mule.component;
12
13 import org.mule.DefaultMuleEvent;
14 import org.mule.DefaultMuleMessage;
15 import org.mule.OptimizedRequestContext;
16 import org.mule.VoidResult;
17 import org.mule.api.MuleContext;
18 import org.mule.api.MuleEvent;
19 import org.mule.api.MuleException;
20 import org.mule.api.MuleMessage;
21 import org.mule.api.component.Component;
22 import org.mule.api.construct.FlowConstruct;
23 import org.mule.api.context.MuleContextAware;
24 import org.mule.api.context.notification.ServerNotificationHandler;
25 import org.mule.api.interceptor.Interceptor;
26 import org.mule.api.lifecycle.Initialisable;
27 import org.mule.api.lifecycle.InitialisationException;
28 import org.mule.api.lifecycle.Lifecycle;
29 import org.mule.api.lifecycle.LifecycleException;
30 import org.mule.api.processor.MessageProcessor;
31 import org.mule.api.transformer.Transformer;
32 import org.mule.config.i18n.CoreMessages;
33 import org.mule.config.i18n.MessageFactory;
34 import org.mule.context.notification.ComponentMessageNotification;
35 import org.mule.context.notification.OptimisedNotificationHandler;
36 import org.mule.management.stats.ComponentStatistics;
37 import org.mule.processor.builder.InterceptingChainMessageProcessorBuilder;
38 import org.mule.transformer.TransformerTemplate;
39 import org.mule.transport.NullPayload;
40
41 import java.util.ArrayList;
42 import java.util.Collections;
43 import java.util.List;
44
45 import org.apache.commons.logging.Log;
46 import org.apache.commons.logging.LogFactory;
47
48
49
50
51 public abstract class AbstractComponent implements Component, MuleContextAware, Lifecycle
52 {
53
54
55
56
57 protected final Log logger = LogFactory.getLog(this.getClass());
58
59 protected FlowConstruct flowConstruct;
60 protected ComponentStatistics statistics = null;
61 protected ServerNotificationHandler notificationHandler;
62 protected List<Interceptor> interceptors = new ArrayList<Interceptor>();
63 protected MessageProcessor interceptorChain;
64 protected MuleContext muleContext;
65
66 public void setMuleContext(MuleContext context)
67 {
68 this.muleContext = context;
69 }
70
71 public List<Interceptor> getInterceptors()
72 {
73 return interceptors;
74 }
75
76 public void setInterceptors(List<Interceptor> interceptors)
77 {
78 this.interceptors = interceptors;
79 }
80
81 public AbstractComponent()
82 {
83 statistics = new ComponentStatistics();
84 }
85
86 private MuleEvent invokeInternal(MuleEvent event) throws MuleException
87 {
88
89 OptimizedRequestContext.unsafeSetEvent(event);
90
91 if (logger.isTraceEnabled())
92 {
93 logger.trace("Invoking " + this.getClass().getName() + "component for service "
94 + flowConstruct.getName());
95 }
96
97 if (!flowConstruct.getLifecycleState().isStarted() || flowConstruct.getLifecycleState().isStopping())
98 {
99 throw new LifecycleException(CoreMessages.isStopped(flowConstruct.getName()), this);
100 }
101
102
103 try
104 {
105 fireComponentNotification(event.getMessage(), ComponentMessageNotification.COMPONENT_PRE_INVOKE);
106
107 long startTime = 0;
108 if (statistics.isEnabled())
109 {
110 startTime = System.currentTimeMillis();
111 }
112
113 Object result = doInvoke(event);
114
115 if (statistics.isEnabled())
116 {
117 statistics.addExecutionTime(System.currentTimeMillis() - startTime);
118 }
119
120 MuleEvent resultEvent = createResultEvent(event, result);
121
122 resultEvent.setStopFurtherProcessing(event.isStopFurtherProcessing());
123 fireComponentNotification(resultEvent.getMessage(), ComponentMessageNotification.COMPONENT_POST_INVOKE);
124
125 return resultEvent;
126 }
127 catch (MuleException me)
128 {
129 throw me;
130 }
131 catch (Exception e)
132 {
133 throw new ComponentException(CoreMessages.failedToInvoke(this.toString()), event,
134 this, e);
135 }
136 }
137
138 public MuleEvent process(MuleEvent event) throws MuleException
139 {
140 if (interceptorChain == null)
141 {
142 return invokeInternal(event);
143 }
144 else
145 {
146 return interceptorChain.process(event);
147 }
148 }
149
150 protected MuleEvent createResultEvent(MuleEvent event, Object result) throws MuleException
151 {
152 if (result instanceof MuleMessage)
153 {
154 return new DefaultMuleEvent((MuleMessage) result, event);
155 }
156 else if (result instanceof VoidResult)
157 {
158 return event;
159 }
160 else if (result != null)
161 {
162 event.getMessage().applyTransformers(
163 event, Collections.<Transformer>singletonList(new TransformerTemplate(
164 new TransformerTemplate.OverwitePayloadCallback(result))));
165 return event;
166 }
167 else
168 {
169 return new DefaultMuleEvent(new DefaultMuleMessage(NullPayload.getInstance(), muleContext), event);
170 }
171 }
172
173 protected abstract Object doInvoke(MuleEvent event) throws Exception;
174
175 @Override
176 public String toString()
177 {
178 StringBuilder buf = new StringBuilder(this.getClass().getName());
179
180 if (flowConstruct != null)
181 {
182 buf.append(" component for: ").append(flowConstruct.toString());
183 }
184 else
185 {
186 buf.append(" no component");
187 }
188
189 return buf.toString();
190 }
191
192 public void release()
193 {
194
195 }
196
197 public ComponentStatistics getStatistics()
198 {
199 return statistics;
200 }
201
202 public void setFlowConstruct(FlowConstruct flowConstruct)
203 {
204 this.flowConstruct = flowConstruct;
205
206
207 if (this.muleContext == null && flowConstruct.getMuleContext() != null)
208 {
209 this.muleContext = flowConstruct.getMuleContext();
210 }
211
212 }
213
214 public FlowConstruct getFlowConstruct()
215 {
216 return flowConstruct;
217 }
218
219 public final void initialise() throws InitialisationException
220 {
221 if (logger.isInfoEnabled())
222 {
223 logger.info("Initialising: " + this);
224 }
225 if (flowConstruct == null)
226 {
227 throw new InitialisationException(
228 MessageFactory.createStaticMessage("Component has not been initialized properly, no service."),
229 this);
230 }
231
232 InterceptingChainMessageProcessorBuilder chainBuilder = new InterceptingChainMessageProcessorBuilder(flowConstruct);
233 for (Interceptor interceptor : interceptors)
234 {
235 chainBuilder.chain(interceptor);
236 }
237 chainBuilder.chain(new MessageProcessor()
238 {
239 public MuleEvent process(MuleEvent event) throws MuleException
240 {
241 return invokeInternal(event);
242 }
243 });
244
245 try
246 {
247 interceptorChain = chainBuilder.build();
248 if (interceptorChain instanceof Initialisable)
249 {
250 ((Initialisable) interceptorChain).initialise();
251 }
252 }
253 catch (MuleException e)
254 {
255 throw new InitialisationException(e, this);
256 }
257
258 doInitialise();
259 }
260
261 protected void doInitialise() throws InitialisationException
262 {
263
264 }
265
266 public void dispose()
267 {
268 if(flowConstruct.getLifecycleState().isDisposed())
269 {
270 return;
271 }
272
273 try
274 {
275
276 if (flowConstruct.getLifecycleState().isStarted())
277 {
278 stop();
279 }
280 }
281 catch (MuleException e)
282 {
283 logger.error(CoreMessages.failedToStop(toString()));
284 }
285 try
286 {
287 doDispose();
288
289 }
290 catch (Exception e)
291 {
292 logger.warn(CoreMessages.failedToDispose(toString()), e);
293 }
294 }
295
296 protected void doDispose()
297 {
298
299 }
300
301 public void stop() throws MuleException
302 {
303 if(flowConstruct.getLifecycleState().isStopped())
304 {
305 return;
306 }
307 if (logger.isInfoEnabled())
308 {
309 logger.info("Stopping: " + this);
310 }
311 doStop();
312 }
313
314 protected void doStart() throws MuleException
315 {
316
317 }
318
319 public void start() throws MuleException
320 {
321 if(flowConstruct.getLifecycleState().isStarted())
322 {
323 return;
324 }
325
326 if (logger.isInfoEnabled())
327 {
328 logger.info("Starting: " + this);
329 }
330 notificationHandler = new OptimisedNotificationHandler(flowConstruct.getMuleContext()
331 .getNotificationManager(), ComponentMessageNotification.class);
332 doStart();
333 }
334
335 protected void doStop() throws MuleException
336 {
337
338 }
339
340 protected void fireComponentNotification(MuleMessage message, int action)
341 {
342 if (notificationHandler != null && notificationHandler.isNotificationEnabled(ComponentMessageNotification.class))
343 {
344 notificationHandler.fireNotification(new ComponentMessageNotification(message, this, flowConstruct, action));
345 }
346 }
347
348 }