View Javadoc

1   // ========================================================================
2   // Copyright (c) 2004-2009 Mort Bay Consulting Pty. Ltd.
3   // ------------------------------------------------------------------------
4   // All rights reserved. This program and the accompanying materials
5   // are made available under the terms of the Eclipse Public License v1.0
6   // and Apache License v2.0 which accompanies this distribution.
7   // The Eclipse Public License is available at 
8   // http://www.eclipse.org/legal/epl-v10.html
9   // The Apache License v2.0 is available at
10  // http://www.opensource.org/licenses/apache2.0.php
11  // You may elect to redistribute this code under either of these licenses. 
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   * Basic implementation of the life cycle interface for components.
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 }