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