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