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