1
2
3
4
5
6
7
8
9
10 package org.mule.lifecycle;
11
12 import org.mule.RegistryContext;
13 import org.mule.api.MuleContext;
14 import org.mule.api.MuleException;
15 import org.mule.api.lifecycle.LifecycleException;
16 import org.mule.api.lifecycle.LifecyclePhase;
17 import org.mule.api.registry.Registry;
18 import org.mule.config.i18n.CoreMessages;
19 import org.mule.util.ClassUtils;
20 import org.mule.util.StringMessageUtils;
21
22 import java.lang.reflect.Method;
23 import java.util.ArrayList;
24 import java.util.Collection;
25 import java.util.HashSet;
26 import java.util.Iterator;
27 import java.util.LinkedHashSet;
28 import java.util.List;
29 import java.util.Set;
30
31 import org.apache.commons.logging.Log;
32 import org.apache.commons.logging.LogFactory;
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48 public class DefaultLifecyclePhase implements LifecyclePhase
49 {
50 protected transient final Log logger = LogFactory.getLog(DefaultLifecyclePhase.class);
51 private Class lifecycleClass;
52 private Method lifecycleMethod;
53 private Set orderedLifecycleObjects = new LinkedHashSet(6);
54 private Class[] ignorredObjectTypes;
55 private String name;
56 private String oppositeLifecyclePhase;
57 private Set supportedPhases;
58 private int registryScope = Registry.SCOPE_REMOTE;
59
60 public DefaultLifecyclePhase(String name, Class lifecycleClass, String oppositeLifecyclePhase)
61 {
62 this.name = name;
63 this.lifecycleClass = lifecycleClass;
64
65 lifecycleMethod = lifecycleClass.getMethods()[0];
66 this.oppositeLifecyclePhase = oppositeLifecyclePhase;
67 }
68
69 public void fireLifecycle(MuleContext muleContext, String currentPhase) throws MuleException
70 {
71 if (logger.isDebugEnabled())
72 {
73 logger.debug("Attempting to fire lifecycle phase: " + getName());
74 }
75 if (currentPhase.equals(name))
76 {
77 if (logger.isDebugEnabled())
78 {
79 logger.debug("Not firing, already in lifecycle phase: " + getName());
80 }
81 return;
82 }
83 if (!isPhaseSupported(currentPhase))
84 {
85 throw new IllegalStateException("Lifecycle phase: " + name + " does not support current phase: "
86 + currentPhase + ". Phases supported are: " + StringMessageUtils.toString(supportedPhases));
87 }
88
89
90 Set duplicates = new HashSet();
91
92 for (Iterator iterator = orderedLifecycleObjects.iterator(); iterator.hasNext();)
93 {
94 LifecycleObject lo = (LifecycleObject) iterator.next();
95
96 Collection lifecycleInstances = RegistryContext.getRegistry().lookupObjects(lo.getType(), getRegistryScope());
97 if (lifecycleInstances.size() == 0)
98 {
99 continue;
100 }
101 List targets = this.sortLifecycleInstances(lifecycleInstances, lo);
102
103 lo.firePreNotification(muleContext);
104
105 for (Iterator target = targets.iterator(); target.hasNext();)
106 {
107 Object o = target.next();
108
109 if (duplicates.contains(o))
110 {
111 target.remove();
112 }
113 else
114 {
115 if (logger.isDebugEnabled())
116 {
117 logger.debug("lifecycle phase: " + getName() + " for object: " + o);
118 }
119 this.applyLifecycle(o);
120 target.remove();
121 duplicates.add(o);
122 }
123 }
124
125 lo.firePostNotification(muleContext);
126 }
127 }
128
129
130
131
132
133
134
135
136
137
138
139 protected List sortLifecycleInstances(Collection objects, LifecycleObject lo)
140 {
141 return new ArrayList(objects);
142 }
143
144 public void addOrderedLifecycleObject(LifecycleObject lco)
145 {
146 orderedLifecycleObjects.add(lco);
147 }
148
149 public void removeOrderedLifecycleObject(LifecycleObject lco)
150 {
151 orderedLifecycleObjects.remove(lco);
152 }
153
154 protected boolean ignoreType(Class type)
155 {
156 if (ignorredObjectTypes == null)
157 {
158 return false;
159 }
160 else
161 {
162 for (int i = 0; i < ignorredObjectTypes.length; i++)
163 {
164 Class ignorredObjectType = ignorredObjectTypes[i];
165 if (ignorredObjectType.isAssignableFrom(type))
166 {
167 return true;
168 }
169 }
170 }
171 return false;
172 }
173
174 public Set getOrderedLifecycleObjects()
175 {
176 return orderedLifecycleObjects;
177 }
178
179 public void setOrderedLifecycleObjects(Set orderedLifecycleObjects)
180 {
181 this.orderedLifecycleObjects = orderedLifecycleObjects;
182 }
183
184 public Class[] getIgnoredObjectTypes()
185 {
186 return ignorredObjectTypes;
187 }
188
189 public void setIgnoredObjectTypes(Class[] ignorredObjectTypes)
190 {
191 this.ignorredObjectTypes = ignorredObjectTypes;
192 }
193
194 public Class getLifecycleClass()
195 {
196 return lifecycleClass;
197 }
198
199 public void setLifecycleClass(Class lifecycleClass)
200 {
201 this.lifecycleClass = lifecycleClass;
202 }
203
204 public String getName()
205 {
206 return name;
207 }
208
209 public Set getSupportedPhases()
210 {
211 return supportedPhases;
212 }
213
214 public void setSupportedPhases(Set supportedPhases)
215 {
216 this.supportedPhases = supportedPhases;
217 }
218
219 public void registerSupportedPhase(String phase)
220 {
221 if (supportedPhases == null)
222 {
223 supportedPhases = new HashSet();
224 }
225 supportedPhases.add(phase);
226 }
227
228 public boolean isPhaseSupported(String phase)
229 {
230 if (getSupportedPhases() == null)
231 {
232 return true;
233 }
234 else
235 {
236 if (getSupportedPhases().contains(ALL_PHASES))
237 {
238 return true;
239 }
240 else
241 {
242 return getSupportedPhases().contains(phase);
243 }
244 }
245 }
246
247 public void applyLifecycle(Object o) throws LifecycleException
248 {
249 if (o == null)
250 {
251 return;
252 }
253 if (ignoreType(o.getClass()))
254 {
255 return;
256 }
257 if (!getLifecycleClass().isAssignableFrom(o.getClass()))
258 {
259 return;
260 }
261 try
262 {
263 lifecycleMethod.invoke(o, ClassUtils.NO_ARGS);
264 }
265 catch (Exception e)
266 {
267 throw new LifecycleException(CoreMessages.failedToInvokeLifecycle(lifecycleMethod.getName(), o), e, this);
268 }
269 }
270
271 public int getRegistryScope()
272 {
273 return registryScope;
274 }
275
276 public void setRegistryScope(int registryScope)
277 {
278 this.registryScope = registryScope;
279 }
280
281 public String getOppositeLifecyclePhase()
282 {
283 return oppositeLifecyclePhase;
284 }
285 }
286
287
288
289