View Javadoc

1   //========================================================================
2   //$Id: AbstractLifeCycle.java,v 1.3 2005/11/11 22:55:41 gregwilkins Exp $
3   //Copyright 2004-2005 Mort Bay Consulting Pty. Ltd.
4   //------------------------------------------------------------------------
5   //Licensed under the Apache License, Version 2.0 (the "License");
6   //you may not use this file except in compliance with the License.
7   //You may obtain a copy of the License at
8   //http://www.apache.org/licenses/LICENSE-2.0
9   //Unless required by applicable law or agreed to in writing, software
10  //distributed under the License is distributed on an "AS IS" BASIS,
11  //WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  //See the License for the specific language governing permissions and
13  //limitations under the License.
14  //========================================================================
15  
16  package org.mortbay.component;
17  
18  import org.mortbay.log.Log;
19  import org.mortbay.util.LazyList;
20  
21  /**
22   * Basic implementation of the life cycle interface for components.
23   * 
24   * @author gregw
25   */
26  public abstract class AbstractLifeCycle implements LifeCycle
27  {
28      private Object _lock = new Object();
29      private final int FAILED = -1, STOPPED = 0, STARTING = 1, STARTED = 2, STOPPING = 3;
30      private volatile int _state = STOPPED;
31      protected LifeCycle.Listener[] _listeners;
32  
33      protected void doStart() throws Exception
34      {
35      }
36  
37      protected void doStop() throws Exception
38      {
39      }
40  
41      public final void start() throws Exception
42      {
43          synchronized (_lock)
44          {
45              try
46              {
47                  if (_state == STARTED || _state == STARTING)
48                      return;
49                  setStarting();
50                  doStart();
51                  Log.debug("started {}",this);
52                  setStarted();
53              }
54              catch (Exception e)
55              {
56                  setFailed(e);
57                  throw e;
58              }
59              catch (Error e)
60              {
61                  setFailed(e);
62                  throw e;
63              }
64          }
65      }
66  
67      public final void stop() throws Exception
68      {
69          synchronized (_lock)
70          {
71              try
72              {
73                  if (_state == STOPPING || _state == STOPPED)
74                      return;
75                  setStopping();
76                  doStop();
77                  Log.debug("stopped {}",this);
78                  setStopped();
79              }
80              catch (Exception e)
81              {
82                  setFailed(e);
83                  throw e;
84              }
85              catch (Error e)
86              {
87                  setFailed(e);
88                  throw e;
89              }
90          }
91      }
92  
93      public boolean isRunning()
94      {
95          return _state == STARTED || _state == STARTING;
96      }
97  
98      public boolean isStarted()
99      {
100         return _state == STARTED;
101     }
102 
103     public boolean isStarting()
104     {
105         return _state == STARTING;
106     }
107 
108     public boolean isStopping()
109     {
110         return _state == STOPPING;
111     }
112 
113     public boolean isStopped()
114     {
115         return _state == STOPPED;
116     }
117 
118     public boolean isFailed()
119     {
120         return _state == FAILED;
121     }
122 
123     public void addLifeCycleListener(LifeCycle.Listener listener)
124     {
125         _listeners = (LifeCycle.Listener[])LazyList.addToArray(_listeners,listener,LifeCycle.Listener.class);
126     }
127 
128     public void removeLifeCycleListener(LifeCycle.Listener listener)
129     {
130         _listeners = (LifeCycle.Listener[])LazyList.removeFromArray(_listeners,listener);
131     }
132 
133     private void setStarted()
134     {
135         _state = STARTED;
136         if (_listeners != null)
137         {
138             for (int i = 0; i < _listeners.length; i++)
139             {
140                 _listeners[i].lifeCycleStarted(this);
141             }
142         }
143     }
144 
145     private void setStarting()
146     {
147         _state = STARTING;
148         if (_listeners != null)
149         {
150             for (int i = 0; i < _listeners.length; i++)
151             {
152                 _listeners[i].lifeCycleStarting(this);
153             }
154         }
155     }
156 
157     private void setStopping()
158     {
159         _state = STOPPING;
160         if (_listeners != null)
161         {
162             for (int i = 0; i < _listeners.length; i++)
163             {
164                 _listeners[i].lifeCycleStopping(this);
165             }
166         }
167     }
168 
169     private void setStopped()
170     {
171         _state = STOPPED;
172         if (_listeners != null)
173         {
174             for (int i = 0; i < _listeners.length; i++)
175             {
176                 _listeners[i].lifeCycleStopped(this);
177             }
178         }
179     }
180 
181     private void setFailed(Throwable th)
182     {
183         Log.warn("failed "+this+": "+th);
184         Log.debug(th);
185         _state = FAILED;
186         if (_listeners != null)
187         {
188             for (int i = 0; i < _listeners.length; i++)
189             {
190                 _listeners[i].lifeCycleFailure(this,th);
191             }
192         }
193     }
194 
195 }