1 // 2 // ======================================================================== 3 // Copyright (c) 1995-2014 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 doStart()47 protected void doStart() throws Exception 48 { 49 } 50 doStop()51 protected void doStop() throws Exception 52 { 53 } 54 start()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 stop()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 isRunning()105 public boolean isRunning() 106 { 107 final int state = _state; 108 109 return state == __STARTED || state == __STARTING; 110 } 111 isStarted()112 public boolean isStarted() 113 { 114 return _state == __STARTED; 115 } 116 isStarting()117 public boolean isStarting() 118 { 119 return _state == __STARTING; 120 } 121 isStopping()122 public boolean isStopping() 123 { 124 return _state == __STOPPING; 125 } 126 isStopped()127 public boolean isStopped() 128 { 129 return _state == __STOPPED; 130 } 131 isFailed()132 public boolean isFailed() 133 { 134 return _state == __FAILED; 135 } 136 addLifeCycleListener(LifeCycle.Listener listener)137 public void addLifeCycleListener(LifeCycle.Listener listener) 138 { 139 _listeners.add(listener); 140 } 141 removeLifeCycleListener(LifeCycle.Listener listener)142 public void removeLifeCycleListener(LifeCycle.Listener listener) 143 { 144 _listeners.remove(listener); 145 } 146 getState()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 getState(LifeCycle lc)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 setStarted()169 private void setStarted() 170 { 171 _state = __STARTED; 172 LOG.debug(STARTED+" {}",this); 173 for (Listener listener : _listeners) 174 listener.lifeCycleStarted(this); 175 } 176 setStarting()177 private void setStarting() 178 { 179 LOG.debug("starting {}",this); 180 _state = __STARTING; 181 for (Listener listener : _listeners) 182 listener.lifeCycleStarting(this); 183 } 184 setStopping()185 private void setStopping() 186 { 187 LOG.debug("stopping {}",this); 188 _state = __STOPPING; 189 for (Listener listener : _listeners) 190 listener.lifeCycleStopping(this); 191 } 192 setStopped()193 private void setStopped() 194 { 195 _state = __STOPPED; 196 LOG.debug("{} {}",STOPPED,this); 197 for (Listener listener : _listeners) 198 listener.lifeCycleStopped(this); 199 } 200 setFailed(Throwable th)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 { lifeCycleFailure(LifeCycle event, Throwable cause)211 public void lifeCycleFailure(LifeCycle event, Throwable cause) {} lifeCycleStarted(LifeCycle event)212 public void lifeCycleStarted(LifeCycle event) {} lifeCycleStarting(LifeCycle event)213 public void lifeCycleStarting(LifeCycle event) {} lifeCycleStopped(LifeCycle event)214 public void lifeCycleStopped(LifeCycle event) {} lifeCycleStopping(LifeCycle event)215 public void lifeCycleStopping(LifeCycle event) {} 216 } 217 } 218