View Javadoc

1   //
2   //  ========================================================================
3   //  Copyright (c) 1995-2013 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.annotation.ManagedAttribute;
24  import org.eclipse.jetty.util.annotation.ManagedObject;
25  import org.eclipse.jetty.util.log.Log;
26  import org.eclipse.jetty.util.log.Logger;
27  
28  /**
29   * Basic implementation of the life cycle interface for components.
30   *
31   *
32   */
33  @ManagedObject("Abstract Implementation of LifeCycle")
34  public abstract class AbstractLifeCycle implements LifeCycle
35  {
36      private static final Logger LOG = Log.getLogger(AbstractLifeCycle.class);
37  
38      public static final String STOPPED="STOPPED";
39      public static final String FAILED="FAILED";
40      public static final String STARTING="STARTING";
41      public static final String STARTED="STARTED";
42      public static final String STOPPING="STOPPING";
43      public static final String RUNNING="RUNNING";
44  
45      private final CopyOnWriteArrayList<LifeCycle.Listener> _listeners=new CopyOnWriteArrayList<LifeCycle.Listener>();
46      private final Object _lock = new Object();
47      private final int __FAILED = -1, __STOPPED = 0, __STARTING = 1, __STARTED = 2, __STOPPING = 3;
48      private volatile int _state = __STOPPED;
49      private long _stopTimeout = 30000;
50  
51      protected void doStart() throws Exception
52      {
53      }
54  
55      protected void doStop() throws Exception
56      {
57      }
58      
59      @Override
60      public final void start() throws Exception
61      {
62          synchronized (_lock)
63          {
64              try
65              {
66                  if (_state == __STARTED || _state == __STARTING)
67                      return;
68                  setStarting();
69                  doStart();
70                  setStarted();
71              }
72              catch (Throwable e)
73              {
74                  setFailed(e);
75                  throw e;
76              }
77          }
78      }
79  
80      @Override
81      public final void stop() throws Exception
82      {
83          synchronized (_lock)
84          {
85              try
86              {
87                  if (_state == __STOPPING || _state == __STOPPED)
88                      return;
89                  setStopping();
90                  doStop();
91                  setStopped();
92              }
93              catch (Throwable e)
94              {
95                  setFailed(e);
96                  throw e;
97              }
98          }
99      }
100 
101     @Override
102     public boolean isRunning()
103     {
104         final int state = _state;
105 
106         return state == __STARTED || state == __STARTING;
107     }
108 
109     @Override
110     public boolean isStarted()
111     {
112         return _state == __STARTED;
113     }
114 
115     @Override
116     public boolean isStarting()
117     {
118         return _state == __STARTING;
119     }
120 
121     @Override
122     public boolean isStopping()
123     {
124         return _state == __STOPPING;
125     }
126 
127     @Override
128     public boolean isStopped()
129     {
130         return _state == __STOPPED;
131     }
132 
133     @Override
134     public boolean isFailed()
135     {
136         return _state == __FAILED;
137     }
138 
139     @Override
140     public void addLifeCycleListener(LifeCycle.Listener listener)
141     {
142         _listeners.add(listener);
143     }
144 
145     @Override
146     public void removeLifeCycleListener(LifeCycle.Listener listener)
147     {
148         _listeners.remove(listener);
149     }
150 
151     @ManagedAttribute(value="Lifecycle State for this instance", readonly=true)
152     public String getState()
153     {
154         switch(_state)
155         {
156             case __FAILED: return FAILED;
157             case __STARTING: return STARTING;
158             case __STARTED: return STARTED;
159             case __STOPPING: return STOPPING;
160             case __STOPPED: return STOPPED;
161         }
162         return null;
163     }
164 
165     public static String getState(LifeCycle lc)
166     {
167         if (lc.isStarting()) return STARTING;
168         if (lc.isStarted()) return STARTED;
169         if (lc.isStopping()) return STOPPING;
170         if (lc.isStopped()) return STOPPED;
171         return FAILED;
172     }
173 
174     private void setStarted()
175     {
176         _state = __STARTED;
177         LOG.debug(STARTED+" {}",this);
178         for (Listener listener : _listeners)
179             listener.lifeCycleStarted(this);
180     }
181 
182     private void setStarting()
183     {
184         LOG.debug("starting {}",this);
185         _state = __STARTING;
186         for (Listener listener : _listeners)
187             listener.lifeCycleStarting(this);
188     }
189 
190     private void setStopping()
191     {
192         LOG.debug("stopping {}",this);
193         _state = __STOPPING;
194         for (Listener listener : _listeners)
195             listener.lifeCycleStopping(this);
196     }
197 
198     private void setStopped()
199     {
200         _state = __STOPPED;
201         LOG.debug("{} {}",STOPPED,this);
202         for (Listener listener : _listeners)
203             listener.lifeCycleStopped(this);
204     }
205 
206     private void setFailed(Throwable th)
207     {
208         _state = __FAILED;
209         LOG.warn(FAILED+" " + this+": "+th,th);
210         for (Listener listener : _listeners)
211             listener.lifeCycleFailure(this,th);
212     }
213 
214     @ManagedAttribute(value="The stop timeout in milliseconds")
215     public long getStopTimeout()
216     {
217         return _stopTimeout;
218     }
219 
220     public void setStopTimeout(long stopTimeout)
221     {
222         this._stopTimeout = stopTimeout;
223     }
224 
225     public static abstract class AbstractLifeCycleListener implements LifeCycle.Listener
226     {
227         @Override public void lifeCycleFailure(LifeCycle event, Throwable cause) {}
228         @Override public void lifeCycleStarted(LifeCycle event) {}
229         @Override public void lifeCycleStarting(LifeCycle event) {}
230         @Override public void lifeCycleStopped(LifeCycle event) {}
231         @Override public void lifeCycleStopping(LifeCycle event) {}
232     }
233 }