View Javadoc

1   /*
2    * $Id: GenericLifecycleManager.java 12269 2008-07-10 04:19:03Z dfeist $
3    * --------------------------------------------------------------------------------------
4    * Copyright (c) MuleSource, Inc.  All rights reserved.  http://www.mulesource.com
5    *
6    * The software in this package is published under the terms of the CPAL v1.0
7    * license, a copy of which has been included with this distribution in the
8    * LICENSE.txt file.
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       * logger used by this class
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       * Returns the name of the currently executing phase or null if there is not current phase
95       *
96       * @return
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         //If we're currently in a phase, fire that too
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 }