1
2
3
4
5
6
7
8
9
10
11 package org.mule.component;
12
13 import org.mule.OptimizedRequestContext;
14 import org.mule.api.DefaultMuleException;
15 import org.mule.api.MuleEvent;
16 import org.mule.api.MuleException;
17 import org.mule.api.MuleMessage;
18 import org.mule.api.component.Component;
19 import org.mule.api.context.notification.ServerNotificationHandler;
20 import org.mule.api.endpoint.InboundEndpoint;
21 import org.mule.api.lifecycle.DisposeException;
22 import org.mule.api.lifecycle.InitialisationException;
23 import org.mule.api.service.Service;
24 import org.mule.api.service.ServiceException;
25 import org.mule.config.i18n.CoreMessages;
26 import org.mule.config.i18n.MessageFactory;
27 import org.mule.context.notification.ComponentMessageNotification;
28 import org.mule.context.notification.OptimisedNotificationHandler;
29 import org.mule.management.stats.ComponentStatistics;
30
31 import edu.emory.mathcs.backport.java.util.concurrent.atomic.AtomicBoolean;
32
33 import org.apache.commons.logging.Log;
34 import org.apache.commons.logging.LogFactory;
35
36
37
38
39 public abstract class AbstractComponent implements Component
40 {
41
42
43
44
45 protected final Log logger = LogFactory.getLog(this.getClass());
46
47 protected Service service;
48 protected ComponentStatistics statistics = null;
49 protected final AtomicBoolean started = new AtomicBoolean(false);
50 protected final AtomicBoolean stopping = new AtomicBoolean(false);
51 protected final AtomicBoolean initialised = new AtomicBoolean(false);
52 protected final AtomicBoolean disposing = new AtomicBoolean(false);
53 protected final AtomicBoolean disposed = new AtomicBoolean(false);
54 protected ServerNotificationHandler notificationHandler;
55
56 public AbstractComponent()
57 {
58 statistics = new ComponentStatistics();
59 }
60
61 public MuleMessage onCall(MuleEvent event) throws MuleException
62 {
63
64 OptimizedRequestContext.unsafeSetEvent(event);
65
66 if (logger.isTraceEnabled())
67 {
68 logger.trace("Invoking " + this.getClass().getName() + "component for service " + service.getName());
69 }
70
71
72
73 checkDisposed();
74 if (!(event.getEndpoint() instanceof InboundEndpoint))
75 {
76 throw new IllegalStateException(
77 "Unable to process outbound event, components only process incoming events.");
78 }
79 if (stopping.get() || !started.get())
80 {
81 throw new DefaultMuleException(CoreMessages.componentIsStopped(service.getName()));
82 }
83
84
85 try
86 {
87
88 fireComponentNotification(event.getMessage(), ComponentMessageNotification.COMPONENT_PRE_INVOKE);
89
90 long startTime = 0;
91 if (statistics.isEnabled())
92 {
93 startTime = System.currentTimeMillis();
94 }
95
96 MuleMessage result = doOnCall(event);
97
98 if (statistics.isEnabled())
99 {
100 statistics.addExecutionTime(System.currentTimeMillis() - startTime);
101 }
102
103 fireComponentNotification(result, ComponentMessageNotification.COMPONENT_POST_INVOKE);
104
105 return result;
106 }
107 catch (MuleException me)
108 {
109 throw me;
110 }
111 catch (Exception e)
112 {
113 throw new ServiceException(CoreMessages.failedToInvoke(this.toString()), event.getMessage(), service, e);
114 }
115 }
116
117 protected abstract MuleMessage doOnCall(MuleEvent event) throws Exception;
118
119 public String toString()
120 {
121 return this.getClass().getName() + " component for: " + service.toString();
122 }
123
124 public void release()
125 {
126
127 }
128
129 public ComponentStatistics getStatistics()
130 {
131 return statistics;
132 }
133
134 public void setService(Service service)
135 {
136 this.service = service;
137 }
138
139 public Service getService()
140 {
141 return service;
142 }
143
144 public final void initialise() throws InitialisationException
145 {
146 if (!initialised.get())
147 {
148 if (logger.isInfoEnabled())
149 {
150 logger.info("Initialising: " + this);
151 }
152 if (service == null)
153 {
154 throw new InitialisationException(
155 MessageFactory.createStaticMessage("Component has not been initialized properly, no service."),
156 this);
157 }
158 doInitialise();
159 initialised.set(true);
160 }
161 }
162
163 protected void doInitialise() throws InitialisationException
164 {
165
166 }
167
168 public void dispose()
169 {
170 disposing.set(true);
171 try
172 {
173 if (started.get())
174 {
175 stop();
176 }
177 }
178 catch (MuleException e)
179 {
180 logger.error(CoreMessages.failedToStop(toString()));
181 }
182 try
183 {
184 doDispose();
185 }
186 catch (Exception e)
187 {
188 logger.warn(CoreMessages.failedToDispose(toString()), e);
189 }
190 finally
191 {
192 disposed.set(true);
193 disposing.set(false);
194 initialised.set(false);
195 }
196 }
197
198 protected void doDispose()
199 {
200
201 }
202
203 public void stop() throws MuleException
204 {
205
206
207 if (!disposed.get() && started.get() && !stopping.get())
208 {
209 stopping.set(true);
210 if (logger.isInfoEnabled())
211 {
212 logger.info("Stopping: " + this);
213 }
214 doStop();
215 started.set(false);
216 stopping.set(false);
217 }
218 }
219
220 protected void doStart() throws MuleException
221 {
222
223 }
224
225 public void start() throws MuleException
226 {
227 checkDisposed();
228 if (!started.get())
229 {
230 if (logger.isInfoEnabled())
231 {
232 logger.info("Starting: " + this);
233 }
234 notificationHandler = new OptimisedNotificationHandler(service.getMuleContext()
235 .getNotificationManager(), ComponentMessageNotification.class);
236 doStart();
237 started.set(true);
238 }
239 }
240
241 protected void doStop() throws MuleException
242 {
243
244 }
245
246 protected void checkDisposed() throws DisposeException
247 {
248 if (disposed.get())
249 {
250 throw new DisposeException(CoreMessages.createStaticMessage("Cannot use a disposed component"), this);
251 }
252 }
253
254 protected void fireComponentNotification(MuleMessage message, int action)
255 {
256 if (notificationHandler.isNotificationEnabled(ComponentMessageNotification.class))
257 {
258 notificationHandler.fireNotification(new ComponentMessageNotification(message, this, action));
259 }
260 }
261
262 }