]> WPIA git - gigi.git/blob - lib/jetty/org/eclipse/jetty/util/component/AbstractLifeCycle.java
Merge "Update notes about password security"
[gigi.git] / lib / jetty / org / eclipse / jetty / util / component / AbstractLifeCycle.java
1 //
2 //  ========================================================================
3 //  Copyright (c) 1995-2016 Mort Bay Consulting Pty. Ltd.
4 //  ------------------------------------------------------------------------
5 //  All rights reserved. This program and the accompanying materials
6 //  are made available under the terms of the Eclipse Public License v1.0
7 //  and Apache License v2.0 which accompanies this distribution.
8 //
9 //      The Eclipse Public License is available at
10 //      http://www.eclipse.org/legal/epl-v10.html
11 //
12 //      The Apache License v2.0 is available at
13 //      http://www.opensource.org/licenses/apache2.0.php
14 //
15 //  You may elect to redistribute this code under either of these licenses.
16 //  ========================================================================
17 //
18
19 package org.eclipse.jetty.util.component;
20
21 import java.util.concurrent.CopyOnWriteArrayList;
22
23 import org.eclipse.jetty.util.Uptime;
24 import org.eclipse.jetty.util.annotation.ManagedAttribute;
25 import org.eclipse.jetty.util.annotation.ManagedObject;
26 import org.eclipse.jetty.util.log.Log;
27 import org.eclipse.jetty.util.log.Logger;
28
29 /**
30  * Basic implementation of the life cycle interface for components.
31  */
32 @ManagedObject("Abstract Implementation of LifeCycle")
33 public abstract class AbstractLifeCycle implements LifeCycle
34 {
35     private static final Logger LOG = Log.getLogger(AbstractLifeCycle.class);
36     
37     public static final String STOPPED="STOPPED";
38     public static final String FAILED="FAILED";
39     public static final String STARTING="STARTING";
40     public static final String STARTED="STARTED";
41     public static final String STOPPING="STOPPING";
42     public static final String RUNNING="RUNNING";
43
44     private final CopyOnWriteArrayList<LifeCycle.Listener> _listeners=new CopyOnWriteArrayList<LifeCycle.Listener>();
45     private final Object _lock = new Object();
46     private final int __FAILED = -1, __STOPPED = 0, __STARTING = 1, __STARTED = 2, __STOPPING = 3;
47     private volatile int _state = __STOPPED;
48     private long _stopTimeout = 30000;
49
50     protected void doStart() throws Exception
51     {
52     }
53
54     protected void doStop() throws Exception
55     {
56     }
57     
58     @Override
59     public final void start() throws Exception
60     {
61         synchronized (_lock)
62         {
63             try
64             {
65                 if (_state == __STARTED || _state == __STARTING)
66                     return;
67                 setStarting();
68                 doStart();
69                 setStarted();
70             }
71             catch (Throwable e)
72             {
73                 setFailed(e);
74                 throw e;
75             }
76         }
77     }
78
79     @Override
80     public final void stop() throws Exception
81     {
82         synchronized (_lock)
83         {
84             try
85             {
86                 if (_state == __STOPPING || _state == __STOPPED)
87                     return;
88                 setStopping();
89                 doStop();
90                 setStopped();
91             }
92             catch (Throwable e)
93             {
94                 setFailed(e);
95                 throw e;
96             }
97         }
98     }
99
100     @Override
101     public boolean isRunning()
102     {
103         final int state = _state;
104
105         return state == __STARTED || state == __STARTING;
106     }
107
108     @Override
109     public boolean isStarted()
110     {
111         return _state == __STARTED;
112     }
113
114     @Override
115     public boolean isStarting()
116     {
117         return _state == __STARTING;
118     }
119
120     @Override
121     public boolean isStopping()
122     {
123         return _state == __STOPPING;
124     }
125
126     @Override
127     public boolean isStopped()
128     {
129         return _state == __STOPPED;
130     }
131
132     @Override
133     public boolean isFailed()
134     {
135         return _state == __FAILED;
136     }
137
138     @Override
139     public void addLifeCycleListener(LifeCycle.Listener listener)
140     {
141         _listeners.add(listener);
142     }
143
144     @Override
145     public void removeLifeCycleListener(LifeCycle.Listener listener)
146     {
147         _listeners.remove(listener);
148     }
149
150     @ManagedAttribute(value="Lifecycle State for this instance", readonly=true)
151     public String getState()
152     {
153         switch(_state)
154         {
155             case __FAILED: return FAILED;
156             case __STARTING: return STARTING;
157             case __STARTED: return STARTED;
158             case __STOPPING: return STOPPING;
159             case __STOPPED: return STOPPED;
160         }
161         return null;
162     }
163
164     public static String getState(LifeCycle lc)
165     {
166         if (lc.isStarting()) return STARTING;
167         if (lc.isStarted()) return STARTED;
168         if (lc.isStopping()) return STOPPING;
169         if (lc.isStopped()) return STOPPED;
170         return FAILED;
171     }
172
173     private void setStarted()
174     {
175         _state = __STARTED;
176         if (LOG.isDebugEnabled())
177             LOG.debug(STARTED+" @{}ms {}",Uptime.getUptime(),this);
178         for (Listener listener : _listeners)
179             listener.lifeCycleStarted(this);
180     }
181
182     private void setStarting()
183     {
184         if (LOG.isDebugEnabled())
185             LOG.debug("starting {}",this);
186         _state = __STARTING;
187         for (Listener listener : _listeners)
188             listener.lifeCycleStarting(this);
189     }
190
191     private void setStopping()
192     {
193         if (LOG.isDebugEnabled())
194             LOG.debug("stopping {}",this);
195         _state = __STOPPING;
196         for (Listener listener : _listeners)
197             listener.lifeCycleStopping(this);
198     }
199
200     private void setStopped()
201     {
202         _state = __STOPPED;
203         if (LOG.isDebugEnabled())
204             LOG.debug("{} {}",STOPPED,this);
205         for (Listener listener : _listeners)
206             listener.lifeCycleStopped(this);
207     }
208
209     private void setFailed(Throwable th)
210     {
211         _state = __FAILED;
212         LOG.warn(FAILED+" " + this+": "+th,th);
213         for (Listener listener : _listeners)
214             listener.lifeCycleFailure(this,th);
215     }
216
217     @ManagedAttribute(value="The stop timeout in milliseconds")
218     public long getStopTimeout()
219     {
220         return _stopTimeout;
221     }
222
223     public void setStopTimeout(long stopTimeout)
224     {
225         this._stopTimeout = stopTimeout;
226     }
227
228     public static abstract class AbstractLifeCycleListener implements LifeCycle.Listener
229     {
230         @Override public void lifeCycleFailure(LifeCycle event, Throwable cause) {}
231         @Override public void lifeCycleStarted(LifeCycle event) {}
232         @Override public void lifeCycleStarting(LifeCycle event) {}
233         @Override public void lifeCycleStopped(LifeCycle event) {}
234         @Override public void lifeCycleStopping(LifeCycle event) {}
235     }
236 }