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