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