1
2
3
4
5
6
7
8
9
10 package org.mule.lifecycle;
11
12 import org.mule.api.lifecycle.Disposable;
13 import org.mule.api.lifecycle.Initialisable;
14 import org.mule.api.lifecycle.LifecycleCallback;
15 import org.mule.api.lifecycle.LifecycleException;
16 import org.mule.api.lifecycle.LifecycleManager;
17 import org.mule.api.lifecycle.LifecycleState;
18 import org.mule.api.lifecycle.Startable;
19 import org.mule.api.lifecycle.Stoppable;
20 import org.mule.lifecycle.phases.NotInLifecyclePhase;
21
22 import java.util.HashSet;
23 import java.util.LinkedHashSet;
24 import java.util.Set;
25 import java.util.TreeMap;
26
27 import org.apache.commons.logging.Log;
28 import org.apache.commons.logging.LogFactory;
29
30
31
32
33
34
35
36
37
38 public abstract class AbstractLifecycleManager<O> implements LifecycleManager
39 {
40
41
42
43 protected transient final Log logger = LogFactory.getLog(AbstractLifecycleManager.class);
44
45 protected String lifecycleManagerId;
46 protected String currentPhase = NotInLifecyclePhase.PHASE_NAME;
47 protected String executingPhase = null;
48 private Set<String> directTransitions = new HashSet<String>();
49 protected Set<String> phaseNames = new LinkedHashSet<String>(4);
50 protected Set<String> completedPhases = new LinkedHashSet<String>(4);
51 protected O object;
52 protected LifecycleState state;
53
54 private TreeMap<String, LifecycleCallback> callbacks = new TreeMap<String, LifecycleCallback>();
55
56
57 public AbstractLifecycleManager(String id, O object)
58 {
59 lifecycleManagerId = id;
60 this.object = object;
61 state = createLifecycleState();
62
63 currentPhase = NotInLifecyclePhase.PHASE_NAME;
64 completedPhases.add(currentPhase);
65 registerTransitions();
66 }
67
68 protected abstract void registerTransitions();
69
70 public void registerLifecycleCallback(String phaseName, LifecycleCallback<O> callback)
71 {
72 callbacks.put(phaseName, callback);
73 }
74
75 protected LifecycleState createLifecycleState()
76 {
77 return new DefaultLifecycleState(this);
78 }
79
80 protected void addDirectTransition(String phase1, String phase2)
81 {
82 directTransitions.add(phase1 + "-" + phase2);
83 phaseNames.add(phase1);
84 phaseNames.add(phase2);
85 }
86
87 public void checkPhase(String name) throws IllegalStateException
88 {
89 if (executingPhase != null)
90 {
91 if (name.equalsIgnoreCase(executingPhase))
92 {
93 throw new IllegalStateException("Phase '" + name + "' is already currently being executed");
94 }
95 else
96 {
97 throw new IllegalStateException("Cannot fire phase '" + name + "', currently executing lifecycle phase: " + executingPhase);
98 }
99 }
100
101 if (name.equalsIgnoreCase(currentPhase))
102 {
103 throw new IllegalStateException("Already in lifecycle phase '" + name + "', cannot fire the same phase twice");
104 }
105
106
107 if (!phaseNames.contains(name))
108 {
109 throw new IllegalStateException("Phase does not exist: " + name);
110 }
111 else
112 {
113 if (isDirectTransition(name))
114 {
115 return;
116 }
117
118 throw new IllegalStateException("Lifecycle Manager '" + lifecycleManagerId + "' phase '" + currentPhase + "' does not support phase '" + name + "'");
119 }
120 }
121
122 public O getLifecycleObject()
123 {
124 return object;
125 }
126
127 public void fireLifecycle(String phase) throws LifecycleException
128 {
129 checkPhase(phase);
130 invokePhase(phase, object, callbacks.get(phase));
131 }
132
133 protected void invokePhase(String phase, Object object, LifecycleCallback callback) throws LifecycleException
134 {
135 try
136 {
137 setExecutingPhase(phase);
138 callback.onTransition(phase, object);
139 setCurrentPhase(phase);
140 }
141 catch(LifecycleException e)
142 {
143 throw e;
144 }
145 catch(Exception e)
146 {
147 throw new LifecycleException(e, object);
148 }
149 finally
150 {
151 setExecutingPhase(null);
152 }
153
154 }
155
156 public boolean isDirectTransition(String destinationPhase)
157 {
158 return isDirectTransition(getCurrentPhase(), destinationPhase);
159 }
160
161 protected boolean isDirectTransition(String startPhase, String endPhase)
162 {
163 String key = startPhase + "-" + endPhase;
164 return directTransitions.contains(key);
165 }
166
167 public String getCurrentPhase()
168 {
169 return currentPhase;
170 }
171
172 protected void setCurrentPhase(String currentPhase)
173 {
174 this.currentPhase = currentPhase;
175 completedPhases.add(currentPhase);
176
177 if(currentPhase.equals(Stoppable.PHASE_NAME))
178 {
179 completedPhases.remove(Startable.PHASE_NAME);
180 }
181 else if(currentPhase.equals(Disposable.PHASE_NAME))
182 {
183 completedPhases.remove(Initialisable.PHASE_NAME);
184 }
185
186 notifyTransition(currentPhase);
187
188 }
189
190 public String getExecutingPhase()
191 {
192 return executingPhase;
193 }
194
195 protected void setExecutingPhase(String executingPhase)
196 {
197 this.executingPhase = executingPhase;
198 }
199
200
201
202
203
204
205
206
207 protected void notifyTransition(String currentPhase)
208 {
209
210 }
211
212 public void reset()
213 {
214 completedPhases.clear();
215 setExecutingPhase(null);
216 setCurrentPhase(NOT_IN_LIFECYCLE_PHASE.getName());
217 completedPhases.add(getCurrentPhase());
218 }
219
220 public boolean isPhaseComplete(String phaseName)
221 {
222 return completedPhases.contains(phaseName);
223 }
224
225 public LifecycleState getState()
226 {
227 return state;
228 }
229
230
231 }