1
2
3
4
5
6
7 package org.mule.component;
8
9 import org.mule.DefaultMuleEventContext;
10 import org.mule.RequestContext;
11 import org.mule.api.DefaultMuleException;
12 import org.mule.api.MuleContext;
13 import org.mule.api.MuleEvent;
14 import org.mule.api.MuleEventContext;
15 import org.mule.api.MuleException;
16 import org.mule.api.component.JavaComponent;
17 import org.mule.api.component.LifecycleAdapter;
18 import org.mule.api.construct.FlowConstruct;
19 import org.mule.api.lifecycle.Disposable;
20 import org.mule.api.lifecycle.Initialisable;
21 import org.mule.api.lifecycle.InitialisationException;
22 import org.mule.api.lifecycle.Startable;
23 import org.mule.api.lifecycle.Stoppable;
24 import org.mule.api.model.EntryPointResolverSet;
25 import org.mule.config.i18n.CoreMessages;
26 import org.mule.config.i18n.MessageFactory;
27 import org.mule.model.resolvers.LegacyEntryPointResolverSet;
28 import org.mule.registry.JSR250ValidatorProcessor;
29 import org.mule.util.annotation.AnnotationMetaData;
30 import org.mule.util.annotation.AnnotationUtils;
31
32 import java.lang.reflect.InvocationTargetException;
33 import java.lang.reflect.Method;
34 import java.util.List;
35
36 import javax.annotation.PostConstruct;
37 import javax.annotation.PreDestroy;
38
39 import org.apache.commons.logging.Log;
40 import org.apache.commons.logging.LogFactory;
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58 public class DefaultComponentLifecycleAdapter implements LifecycleAdapter
59 {
60
61
62
63 protected static final Log logger = LogFactory.getLog(DefaultComponentLifecycleAdapter.class);
64
65 protected Object componentObject;
66
67 protected JavaComponent component;
68 protected EntryPointResolverSet entryPointResolver;
69 protected FlowConstruct flowConstruct;
70
71 protected boolean isInitialisable = false;
72 protected boolean isStartable = false;
73 protected boolean isStoppable = false;
74 protected boolean isDisposable = false;
75
76 protected Method initMethod;
77 protected Method disposeMethod;
78
79 private boolean started = false;
80 private boolean disposed = false;
81
82 protected MuleContext muleContext;
83
84 public DefaultComponentLifecycleAdapter(Object componentObject,
85 JavaComponent component,
86 FlowConstruct flowConstruct,
87 MuleContext muleContext) throws MuleException
88 {
89 if (muleContext == null)
90 {
91 throw new IllegalStateException("No muleContext provided");
92 }
93 if (componentObject == null)
94 {
95 throw new IllegalArgumentException("POJO Service cannot be null");
96 }
97
98 if (entryPointResolver == null)
99 {
100 entryPointResolver = new LegacyEntryPointResolverSet();
101 }
102 this.componentObject = componentObject;
103 this.component = component;
104 this.flowConstruct = flowConstruct;
105
106
107 this.muleContext = muleContext;
108 setLifecycleFlags();
109 BindingUtils.configureBinding(component, componentObject);
110 }
111
112 public DefaultComponentLifecycleAdapter(Object componentObject,
113 JavaComponent component,
114 FlowConstruct flowConstruct,
115 EntryPointResolverSet entryPointResolver, MuleContext muleContext) throws MuleException
116 {
117
118 this(componentObject, component, flowConstruct, muleContext);
119 this.entryPointResolver = entryPointResolver;
120 }
121
122 protected void setLifecycleFlags()
123 {
124 Object object = componentObject;
125 initMethod = findInitMethod(object);
126 disposeMethod = findDisposeMethod(object);
127 isInitialisable = initMethod!=null;
128 isDisposable = disposeMethod!=null;
129 isStartable = Startable.class.isInstance(object);
130 isStoppable = Stoppable.class.isInstance(object);
131 }
132
133 protected Method findInitMethod(Object object)
134 {
135 if(object instanceof Initialisable)
136 {
137 try
138 {
139 return object.getClass().getMethod(Initialisable.PHASE_NAME);
140 }
141 catch (NoSuchMethodException e)
142 {
143
144 }
145 }
146
147 List<AnnotationMetaData> metaData = AnnotationUtils.getMethodAnnotations(object.getClass(), PostConstruct.class);
148 if (metaData.size() == 0)
149 {
150 return null;
151 }
152 else if(metaData.size() > 1)
153 {
154 throw new IllegalArgumentException(CoreMessages.objectHasMoreThanOnePostConstructAnnotation(object.getClass()).getMessage());
155 }
156 else
157 {
158 Method m = (Method) metaData.get(0).getMember();
159 new JSR250ValidatorProcessor().validateLifecycleMethod(m);
160 return m;
161 }
162 }
163
164 protected Method findDisposeMethod(Object object)
165 {
166 if (object instanceof Disposable)
167 {
168 try
169 {
170 return object.getClass().getMethod(Disposable.PHASE_NAME);
171 }
172 catch (NoSuchMethodException e)
173 {
174
175 }
176 }
177
178 List<AnnotationMetaData> metaData = AnnotationUtils.getMethodAnnotations(object.getClass(), PreDestroy.class);
179 if (metaData.size() == 0)
180 {
181 return null;
182 }
183 else if (metaData.size() > 1)
184 {
185 throw new IllegalArgumentException(CoreMessages.objectHasMoreThanOnePreDestroyAnnotation(object.getClass()).getMessage());
186 }
187 else
188 {
189 Method m = (Method) metaData.get(0).getMember();
190 new JSR250ValidatorProcessor().validateLifecycleMethod(m);
191 return m;
192 }
193 }
194
195
196
197
198
199
200
201
202 public void initialise() throws InitialisationException
203 {
204 if (isInitialisable)
205 {
206 try
207 {
208 initMethod.invoke(componentObject);
209 }
210 catch (IllegalAccessException e)
211 {
212 throw new InitialisationException(e, this);
213 }
214 catch (InvocationTargetException e)
215 {
216 throw new InitialisationException(e.getTargetException(), this);
217 }
218 }
219 }
220
221
222
223
224
225
226 public void start() throws MuleException
227 {
228 if (isStartable)
229 {
230 try
231 {
232 ((Startable) componentObject).start();
233 started = true;
234 }
235 catch (Exception e)
236 {
237 throw new DefaultMuleException(CoreMessages.failedToStart("Service: "
238 + flowConstruct.getName()), e);
239 }
240 }
241 else
242 {
243 started = true;
244 }
245 }
246
247
248
249
250
251
252 public void stop() throws MuleException
253 {
254 if (isStoppable)
255 {
256 try
257 {
258 ((Stoppable) componentObject).stop();
259 started = false;
260 }
261 catch (Exception e)
262 {
263 throw new DefaultMuleException(CoreMessages.failedToStop("Service: "
264 + flowConstruct.getName()), e);
265 }
266 }
267 else
268 {
269 started = false;
270 }
271 }
272
273
274
275
276
277
278 public void dispose()
279 {
280 try
281 {
282 if (isDisposable)
283 {
284
285 Object o = componentObject;
286 if (o != null)
287 {
288 try
289 {
290 disposeMethod.invoke(o);
291 }
292 catch (InvocationTargetException e)
293 {
294
295 throw e.getTargetException();
296 }
297 }
298 }
299 componentObject = null;
300
301 }
302 catch (Throwable e)
303 {
304 logger.error("failed to dispose: " + flowConstruct.getName(), e);
305 }
306 disposed = true;
307 }
308
309
310
311
312 public boolean isStarted()
313 {
314 return started;
315 }
316
317
318
319
320 public boolean isDisposed()
321 {
322 return disposed;
323 }
324
325 public Object invoke(MuleEvent event) throws MuleException
326 {
327
328 MuleEventContext eventContext = new DefaultMuleEventContext(event);
329 Object result;
330 try
331 {
332 if (componentObject == null)
333 {
334 throw new ComponentException(MessageFactory.createStaticMessage("componentObject is null"), RequestContext.getEvent(), component);
335 }
336
337 if (component.getEntryPointResolverSet() != null)
338 {
339 result = component.getEntryPointResolverSet().invoke(componentObject, eventContext);
340 }
341 else
342 {
343 result = entryPointResolver.invoke(componentObject, eventContext);
344 }
345 }
346 catch (Exception e)
347 {
348 throw new ComponentException(RequestContext.getEvent(), component, e);
349 }
350
351 return result;
352 }
353 }