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 
doStart()33     protected void doStart() throws Exception
34     {
35     }
36 
doStop()37     protected void doStop() throws Exception
38     {
39     }
40 
start()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 
stop()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 
isRunning()97     public boolean isRunning()
98     {
99         return _state == STARTED || _state == STARTING;
100     }
101 
isStarted()102     public boolean isStarted()
103     {
104         return _state == STARTED;
105     }
106 
isStarting()107     public boolean isStarting()
108     {
109         return _state == STARTING;
110     }
111 
isStopping()112     public boolean isStopping()
113     {
114         return _state == STOPPING;
115     }
116 
isStopped()117     public boolean isStopped()
118     {
119         return _state == STOPPED;
120     }
121 
isFailed()122     public boolean isFailed()
123     {
124         return _state == FAILED;
125     }
126 
addLifeCycleListener(LifeCycle.Listener listener)127     public void addLifeCycleListener(LifeCycle.Listener listener)
128     {
129         _listeners = (LifeCycle.Listener[])LazyList.addToArray(_listeners,listener,LifeCycle.Listener.class);
130     }
131 
removeLifeCycleListener(LifeCycle.Listener listener)132     public void removeLifeCycleListener(LifeCycle.Listener listener)
133     {
134         LazyList.removeFromArray(_listeners,listener);
135     }
136 
setStarted()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 
setStarting()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 
setStopping()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 
setStopped()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 
setFailed(Throwable error)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 }
198