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 transient 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                  Log.warn("failed " + this,e);
57                  setFailed(e);
58                  throw e;
59              }
60              catch (Error e)
61              {
62                  Log.warn("failed " + this,e);
63                  setFailed(e);
64                  throw e;
65              }
66          }
67      }
68  
69      public final void stop() throws Exception
70      {
71          synchronized (_lock)
72          {
73              try
74              {
75                  if (_state == STOPPING || _state == STOPPED)
76                      return;
77                  setStopping();
78                  doStop();
79                  Log.debug("stopped {}",this);
80                  setStopped();
81              }
82              catch (Exception e)
83              {
84                  Log.warn("failed " + this,e);
85                  setFailed(e);
86                  throw e;
87              }
88              catch (Error e)
89              {
90                  Log.warn("failed " + this,e);
91                  setFailed(e);
92                  throw e;
93              }
94          }
95      }
96  
97      public boolean isRunning()
98      {
99          return _state == STARTED || _state == STARTING;
100     }
101 
102     public boolean isStarted()
103     {
104         return _state == STARTED;
105     }
106 
107     public boolean isStarting()
108     {
109         return _state == STARTING;
110     }
111 
112     public boolean isStopping()
113     {
114         return _state == STOPPING;
115     }
116 
117     public boolean isStopped()
118     {
119         return _state == STOPPED;
120     }
121 
122     public boolean isFailed()
123     {
124         return _state == FAILED;
125     }
126 
127     public void addLifeCycleListener(LifeCycle.Listener listener)
128     {
129         _listeners = (LifeCycle.Listener[])LazyList.addToArray(_listeners,listener,LifeCycle.Listener.class);
130     }
131 
132     public void removeLifeCycleListener(LifeCycle.Listener listener)
133     {
134         LazyList.removeFromArray(_listeners,listener);
135     }
136 
137     private void setStarted()
138     {
139         _state = STARTED;
140         if (_listeners != null)
141         {
142             for (int i = 0; i < _listeners.length; i++)
143             {
144                 _listeners[i].lifeCycleStarted(this);
145             }
146         }
147     }
148 
149     private void setStarting()
150     {
151         _state = STARTING;
152         if (_listeners != null)
153         {
154             for (int i = 0; i < _listeners.length; i++)
155             {
156                 _listeners[i].lifeCycleStarting(this);
157             }
158         }
159     }
160 
161     private void setStopping()
162     {
163         _state = STOPPING;
164         if (_listeners != null)
165         {
166             for (int i = 0; i < _listeners.length; i++)
167             {
168                 _listeners[i].lifeCycleStopping(this);
169             }
170         }
171     }
172 
173     private void setStopped()
174     {
175         _state = STOPPED;
176         if (_listeners != null)
177         {
178             for (int i = 0; i < _listeners.length; i++)
179             {
180                 _listeners[i].lifeCycleStopped(this);
181             }
182         }
183     }
184 
185     private void setFailed(Throwable error)
186     {
187         _state = FAILED;
188         if (_listeners != null)
189         {
190             for (int i = 0; i < _listeners.length; i++)
191             {
192                 _listeners[i].lifeCycleFailure(this,error);
193             }
194         }
195     }
196 
197 }