1
2
3
4
5
6
7
8
9
10 package org.mule.lifecycle;
11
12 import org.mule.api.MuleContext;
13 import org.mule.api.MuleException;
14 import org.mule.api.lifecycle.LifecycleManager;
15 import org.mule.api.lifecycle.LifecyclePhase;
16 import org.mule.lifecycle.phases.NotInLifecyclePhase;
17 import org.mule.util.StringMessageUtils;
18
19 import java.util.HashMap;
20 import java.util.HashSet;
21 import java.util.Iterator;
22 import java.util.Map;
23 import java.util.Set;
24
25 import org.apache.commons.collections.set.ListOrderedSet;
26 import org.apache.commons.logging.Log;
27 import org.apache.commons.logging.LogFactory;
28
29
30 public class GenericLifecycleManager implements LifecycleManager
31 {
32
33
34
35 private static final Log logger = LogFactory.getLog(GenericLifecycleManager.class);
36 protected static final NotInLifecyclePhase notInLifecyclePhase = new NotInLifecyclePhase();
37 protected String currentPhase = notInLifecyclePhase.getName();
38 protected String executingPhase = null;
39 protected ListOrderedSet lifecycles = new ListOrderedSet();
40 protected Map index = new HashMap(6);
41 protected Set completedPhases = new HashSet(6);
42
43 public Set getLifecycles()
44 {
45 return lifecycles;
46 }
47
48 public void setLifecycles(Set lifecycles)
49 {
50 for (Iterator iterator = lifecycles.iterator(); iterator.hasNext();)
51 {
52 LifecyclePhase phase = (LifecyclePhase) iterator.next();
53 registerLifecycle(phase);
54 }
55 }
56
57 public void registerLifecycle(LifecyclePhase lci)
58 {
59 index.put(lci.getName(), new Integer(lifecycles.size()));
60 lifecycles.add(lci);
61 }
62
63 public void firePhase(MuleContext muleContext, String phase) throws MuleException
64 {
65 if (currentPhase.equalsIgnoreCase(phase))
66 {
67 logger.debug("Already in lifecycle phase: " + phase);
68 return;
69 }
70 Integer phaseIndex = (Integer) index.get(phase);
71 if (phaseIndex == null)
72 {
73 throw new IllegalArgumentException("No lifeccycle phase registered with name: " + phase);
74 }
75 try
76 {
77 setExecutingPhase(phase);
78 LifecyclePhase li = (LifecyclePhase) lifecycles.get(phaseIndex.intValue());
79 li.fireLifecycle(muleContext, currentPhase);
80 setCurrentPhase(li);
81 }
82 finally
83 {
84 setExecutingPhase(null);
85 }
86 }
87
88 public String getCurrentPhase()
89 {
90 return currentPhase;
91 }
92
93
94
95
96
97
98 public String getExecutingPhase()
99 {
100 return executingPhase;
101 }
102
103 protected synchronized void setCurrentPhase(LifecyclePhase phase)
104 {
105 completedPhases.add(phase.getName());
106 completedPhases.remove(phase.getOppositeLifecyclePhase());
107 this.currentPhase = phase.getName();
108 }
109
110 protected synchronized void setExecutingPhase(String phase)
111 {
112 this.executingPhase = phase;
113 }
114
115 public void reset()
116 {
117 setExecutingPhase(null);
118 completedPhases.clear();
119 setCurrentPhase(notInLifecyclePhase);
120 }
121
122 public boolean isPhaseComplete(String phaseName)
123 {
124 return completedPhases.contains(phaseName);
125 }
126
127 public void applyLifecycle(MuleContext muleContext, Object object) throws MuleException
128 {
129 logger.debug("applying lifecycle to " + object);
130
131 LifecyclePhase lcp;
132 String phase;
133 Integer phaseIndex;
134 for (Iterator iterator = completedPhases.iterator(); iterator.hasNext();)
135 {
136 phase = (String) iterator.next();
137 phaseIndex = (Integer) index.get(phase);
138 lcp = (LifecyclePhase) lifecycles.get(phaseIndex.intValue());
139
140 if (logger.isDebugEnabled())
141 {
142 logger.debug("phase: " + lcp);
143 }
144 lcp.applyLifecycle(object);
145 }
146
147 if (getExecutingPhase() != null)
148 {
149 phaseIndex = (Integer) index.get(getExecutingPhase());
150 lcp = (LifecyclePhase) lifecycles.get(phaseIndex.intValue());
151
152 if (logger.isDebugEnabled())
153 {
154 logger.debug("and executing: " + lcp);
155 }
156 lcp.applyLifecycle(object);
157 }
158 }
159
160 public void checkPhase(String name) throws IllegalStateException
161 {
162 if (completedPhases.contains(name))
163 {
164 throw new IllegalStateException("Phase '" + name + "' has already been executed");
165 }
166
167 if (name.equalsIgnoreCase(executingPhase))
168 {
169 throw new IllegalStateException("Phase '" + name + "' is already currently being executed");
170 }
171
172 if (executingPhase != null)
173 {
174 throw new IllegalStateException("Currently executing lifecycle phase: " + executingPhase);
175 }
176
177 Integer phaseIndex = (Integer) index.get(name);
178 if (phaseIndex == null)
179 {
180 throw new IllegalStateException("Phase does not exist: " + name);
181 }
182 if (NotInLifecyclePhase.PHASE_NAME.equals(currentPhase))
183 {
184 if (phaseIndex.intValue() > 0)
185 {
186 throw new IllegalStateException("The first lifecycle phase has to be called before the '" + name + "' phase");
187 }
188 }
189 else
190 {
191 LifecyclePhase phase = (LifecyclePhase) lifecycles.get(phaseIndex.intValue());
192 if (!phase.isPhaseSupported(currentPhase))
193 {
194 throw new IllegalStateException("Lifecycle phase: " + currentPhase + " does not support current phase: "
195 + name + ". Phases supported are: " + StringMessageUtils.toString(phase.getSupportedPhases()));
196 }
197 }
198 }
199 }