1
2
3
4
5
6
7
8
9
10
11
12
13
14 package org.eclipse.jetty.util.component;
15
16 import java.util.concurrent.CopyOnWriteArrayList;
17
18 import org.eclipse.jetty.util.log.Log;
19 import org.eclipse.jetty.util.log.Logger;
20
21
22
23
24
25
26 public abstract class AbstractLifeCycle implements LifeCycle
27 {
28 private static final Logger LOG = Log.getLogger(AbstractLifeCycle.class);
29 public static final String STOPPED="STOPPED";
30 public static final String FAILED="FAILED";
31 public static final String STARTING="STARTING";
32 public static final String STARTED="STARTED";
33 public static final String STOPPING="STOPPING";
34 public static final String RUNNING="RUNNING";
35
36 private final Object _lock = new Object();
37 private final int __FAILED = -1, __STOPPED = 0, __STARTING = 1, __STARTED = 2, __STOPPING = 3;
38 private volatile int _state = __STOPPED;
39
40 protected final CopyOnWriteArrayList<LifeCycle.Listener> _listeners=new CopyOnWriteArrayList<LifeCycle.Listener>();
41
42 protected void doStart() throws Exception
43 {
44 }
45
46 protected void doStop() throws Exception
47 {
48 }
49
50 public final void start() throws Exception
51 {
52 synchronized (_lock)
53 {
54 try
55 {
56 if (_state == __STARTED || _state == __STARTING)
57 return;
58 setStarting();
59 doStart();
60 setStarted();
61 }
62 catch (Exception e)
63 {
64 setFailed(e);
65 throw e;
66 }
67 catch (Error e)
68 {
69 setFailed(e);
70 throw e;
71 }
72 }
73 }
74
75 public final void stop() throws Exception
76 {
77 synchronized (_lock)
78 {
79 try
80 {
81 if (_state == __STOPPING || _state == __STOPPED)
82 return;
83 setStopping();
84 doStop();
85 setStopped();
86 }
87 catch (Exception e)
88 {
89 setFailed(e);
90 throw e;
91 }
92 catch (Error e)
93 {
94 setFailed(e);
95 throw e;
96 }
97 }
98 }
99
100 public boolean isRunning()
101 {
102 final int state = _state;
103
104 return state == __STARTED || state == __STARTING;
105 }
106
107 public boolean isStarted()
108 {
109 return _state == __STARTED;
110 }
111
112 public boolean isStarting()
113 {
114 return _state == __STARTING;
115 }
116
117 public boolean isStopping()
118 {
119 return _state == __STOPPING;
120 }
121
122 public boolean isStopped()
123 {
124 return _state == __STOPPED;
125 }
126
127 public boolean isFailed()
128 {
129 return _state == __FAILED;
130 }
131
132 public void addLifeCycleListener(LifeCycle.Listener listener)
133 {
134 _listeners.add(listener);
135 }
136
137 public void removeLifeCycleListener(LifeCycle.Listener listener)
138 {
139 _listeners.remove(listener);
140 }
141
142 public String getState()
143 {
144 switch(_state)
145 {
146 case __FAILED: return FAILED;
147 case __STARTING: return STARTING;
148 case __STARTED: return STARTED;
149 case __STOPPING: return STOPPING;
150 case __STOPPED: return STOPPED;
151 }
152 return null;
153 }
154
155 public static String getState(LifeCycle lc)
156 {
157 if (lc.isStarting()) return STARTING;
158 if (lc.isStarted()) return STARTED;
159 if (lc.isStopping()) return STOPPING;
160 if (lc.isStopped()) return STOPPED;
161 return FAILED;
162 }
163
164 private void setStarted()
165 {
166 _state = __STARTED;
167 LOG.debug(STARTED+" {}",this);
168 for (Listener listener : _listeners)
169 listener.lifeCycleStarted(this);
170 }
171
172 private void setStarting()
173 {
174 LOG.debug("starting {}",this);
175 _state = __STARTING;
176 for (Listener listener : _listeners)
177 listener.lifeCycleStarting(this);
178 }
179
180 private void setStopping()
181 {
182 LOG.debug("stopping {}",this);
183 _state = __STOPPING;
184 for (Listener listener : _listeners)
185 listener.lifeCycleStopping(this);
186 }
187
188 private void setStopped()
189 {
190 _state = __STOPPED;
191 LOG.debug("{} {}",STOPPED,this);
192 for (Listener listener : _listeners)
193 listener.lifeCycleStopped(this);
194 }
195
196 private void setFailed(Throwable th)
197 {
198 _state = __FAILED;
199 LOG.warn(FAILED+" " + this+": "+th,th);
200 for (Listener listener : _listeners)
201 listener.lifeCycleFailure(this,th);
202 }
203
204 public static abstract class AbstractLifeCycleListener implements LifeCycle.Listener
205 {
206 public void lifeCycleFailure(LifeCycle event, Throwable cause) {}
207 public void lifeCycleStarted(LifeCycle event) {}
208 public void lifeCycleStarting(LifeCycle event) {}
209 public void lifeCycleStopped(LifeCycle event) {}
210 public void lifeCycleStopping(LifeCycle event) {}
211 }
212
213 public String toString()
214 {
215 return super.toString()+"#"+getState();
216 }
217 }