1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 package org.mortbay.component;
17
18 import org.mortbay.log.Log;
19 import org.mortbay.util.LazyList;
20
21
22
23
24
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 }