103928aee4356845252ac6b662d5c72c29903813eJake Slack// 203928aee4356845252ac6b662d5c72c29903813eJake Slack// ======================================================================== 303928aee4356845252ac6b662d5c72c29903813eJake Slack// Copyright (c) 1995-2014 Mort Bay Consulting Pty. Ltd. 403928aee4356845252ac6b662d5c72c29903813eJake Slack// ------------------------------------------------------------------------ 503928aee4356845252ac6b662d5c72c29903813eJake Slack// All rights reserved. This program and the accompanying materials 603928aee4356845252ac6b662d5c72c29903813eJake Slack// are made available under the terms of the Eclipse Public License v1.0 703928aee4356845252ac6b662d5c72c29903813eJake Slack// and Apache License v2.0 which accompanies this distribution. 803928aee4356845252ac6b662d5c72c29903813eJake Slack// 903928aee4356845252ac6b662d5c72c29903813eJake Slack// The Eclipse Public License is available at 1003928aee4356845252ac6b662d5c72c29903813eJake Slack// http://www.eclipse.org/legal/epl-v10.html 1103928aee4356845252ac6b662d5c72c29903813eJake Slack// 1203928aee4356845252ac6b662d5c72c29903813eJake Slack// The Apache License v2.0 is available at 1303928aee4356845252ac6b662d5c72c29903813eJake Slack// http://www.opensource.org/licenses/apache2.0.php 1403928aee4356845252ac6b662d5c72c29903813eJake Slack// 1503928aee4356845252ac6b662d5c72c29903813eJake Slack// You may elect to redistribute this code under either of these licenses. 1603928aee4356845252ac6b662d5c72c29903813eJake Slack// ======================================================================== 1703928aee4356845252ac6b662d5c72c29903813eJake Slack// 1803928aee4356845252ac6b662d5c72c29903813eJake Slack 1903928aee4356845252ac6b662d5c72c29903813eJake Slackpackage org.eclipse.jetty.util.component; 2003928aee4356845252ac6b662d5c72c29903813eJake Slack 2103928aee4356845252ac6b662d5c72c29903813eJake Slackimport java.util.concurrent.CopyOnWriteArrayList; 2203928aee4356845252ac6b662d5c72c29903813eJake Slack 2303928aee4356845252ac6b662d5c72c29903813eJake Slackimport org.eclipse.jetty.util.log.Log; 2403928aee4356845252ac6b662d5c72c29903813eJake Slackimport org.eclipse.jetty.util.log.Logger; 2503928aee4356845252ac6b662d5c72c29903813eJake Slack 2603928aee4356845252ac6b662d5c72c29903813eJake Slack/** 2703928aee4356845252ac6b662d5c72c29903813eJake Slack * Basic implementation of the life cycle interface for components. 2803928aee4356845252ac6b662d5c72c29903813eJake Slack * 2903928aee4356845252ac6b662d5c72c29903813eJake Slack * 3003928aee4356845252ac6b662d5c72c29903813eJake Slack */ 3103928aee4356845252ac6b662d5c72c29903813eJake Slackpublic abstract class AbstractLifeCycle implements LifeCycle 3203928aee4356845252ac6b662d5c72c29903813eJake Slack{ 3303928aee4356845252ac6b662d5c72c29903813eJake Slack private static final Logger LOG = Log.getLogger(AbstractLifeCycle.class); 3403928aee4356845252ac6b662d5c72c29903813eJake Slack public static final String STOPPED="STOPPED"; 3503928aee4356845252ac6b662d5c72c29903813eJake Slack public static final String FAILED="FAILED"; 3603928aee4356845252ac6b662d5c72c29903813eJake Slack public static final String STARTING="STARTING"; 3703928aee4356845252ac6b662d5c72c29903813eJake Slack public static final String STARTED="STARTED"; 3803928aee4356845252ac6b662d5c72c29903813eJake Slack public static final String STOPPING="STOPPING"; 3903928aee4356845252ac6b662d5c72c29903813eJake Slack public static final String RUNNING="RUNNING"; 4003928aee4356845252ac6b662d5c72c29903813eJake Slack 4103928aee4356845252ac6b662d5c72c29903813eJake Slack private final Object _lock = new Object(); 4203928aee4356845252ac6b662d5c72c29903813eJake Slack private final int __FAILED = -1, __STOPPED = 0, __STARTING = 1, __STARTED = 2, __STOPPING = 3; 4303928aee4356845252ac6b662d5c72c29903813eJake Slack private volatile int _state = __STOPPED; 4403928aee4356845252ac6b662d5c72c29903813eJake Slack 4503928aee4356845252ac6b662d5c72c29903813eJake Slack protected final CopyOnWriteArrayList<LifeCycle.Listener> _listeners=new CopyOnWriteArrayList<LifeCycle.Listener>(); 4603928aee4356845252ac6b662d5c72c29903813eJake Slack 4703928aee4356845252ac6b662d5c72c29903813eJake Slack protected void doStart() throws Exception 4803928aee4356845252ac6b662d5c72c29903813eJake Slack { 4903928aee4356845252ac6b662d5c72c29903813eJake Slack } 5003928aee4356845252ac6b662d5c72c29903813eJake Slack 5103928aee4356845252ac6b662d5c72c29903813eJake Slack protected void doStop() throws Exception 5203928aee4356845252ac6b662d5c72c29903813eJake Slack { 5303928aee4356845252ac6b662d5c72c29903813eJake Slack } 5403928aee4356845252ac6b662d5c72c29903813eJake Slack 5503928aee4356845252ac6b662d5c72c29903813eJake Slack public final void start() throws Exception 5603928aee4356845252ac6b662d5c72c29903813eJake Slack { 5703928aee4356845252ac6b662d5c72c29903813eJake Slack synchronized (_lock) 5803928aee4356845252ac6b662d5c72c29903813eJake Slack { 5903928aee4356845252ac6b662d5c72c29903813eJake Slack try 6003928aee4356845252ac6b662d5c72c29903813eJake Slack { 6103928aee4356845252ac6b662d5c72c29903813eJake Slack if (_state == __STARTED || _state == __STARTING) 6203928aee4356845252ac6b662d5c72c29903813eJake Slack return; 6303928aee4356845252ac6b662d5c72c29903813eJake Slack setStarting(); 6403928aee4356845252ac6b662d5c72c29903813eJake Slack doStart(); 6503928aee4356845252ac6b662d5c72c29903813eJake Slack setStarted(); 6603928aee4356845252ac6b662d5c72c29903813eJake Slack } 6703928aee4356845252ac6b662d5c72c29903813eJake Slack catch (Exception e) 6803928aee4356845252ac6b662d5c72c29903813eJake Slack { 6903928aee4356845252ac6b662d5c72c29903813eJake Slack setFailed(e); 7003928aee4356845252ac6b662d5c72c29903813eJake Slack throw e; 7103928aee4356845252ac6b662d5c72c29903813eJake Slack } 7203928aee4356845252ac6b662d5c72c29903813eJake Slack catch (Error e) 7303928aee4356845252ac6b662d5c72c29903813eJake Slack { 7403928aee4356845252ac6b662d5c72c29903813eJake Slack setFailed(e); 7503928aee4356845252ac6b662d5c72c29903813eJake Slack throw e; 7603928aee4356845252ac6b662d5c72c29903813eJake Slack } 7703928aee4356845252ac6b662d5c72c29903813eJake Slack } 7803928aee4356845252ac6b662d5c72c29903813eJake Slack } 7903928aee4356845252ac6b662d5c72c29903813eJake Slack 8003928aee4356845252ac6b662d5c72c29903813eJake Slack public final void stop() throws Exception 8103928aee4356845252ac6b662d5c72c29903813eJake Slack { 8203928aee4356845252ac6b662d5c72c29903813eJake Slack synchronized (_lock) 8303928aee4356845252ac6b662d5c72c29903813eJake Slack { 8403928aee4356845252ac6b662d5c72c29903813eJake Slack try 8503928aee4356845252ac6b662d5c72c29903813eJake Slack { 8603928aee4356845252ac6b662d5c72c29903813eJake Slack if (_state == __STOPPING || _state == __STOPPED) 8703928aee4356845252ac6b662d5c72c29903813eJake Slack return; 8803928aee4356845252ac6b662d5c72c29903813eJake Slack setStopping(); 8903928aee4356845252ac6b662d5c72c29903813eJake Slack doStop(); 9003928aee4356845252ac6b662d5c72c29903813eJake Slack setStopped(); 9103928aee4356845252ac6b662d5c72c29903813eJake Slack } 9203928aee4356845252ac6b662d5c72c29903813eJake Slack catch (Exception e) 9303928aee4356845252ac6b662d5c72c29903813eJake Slack { 9403928aee4356845252ac6b662d5c72c29903813eJake Slack setFailed(e); 9503928aee4356845252ac6b662d5c72c29903813eJake Slack throw e; 9603928aee4356845252ac6b662d5c72c29903813eJake Slack } 9703928aee4356845252ac6b662d5c72c29903813eJake Slack catch (Error e) 9803928aee4356845252ac6b662d5c72c29903813eJake Slack { 9903928aee4356845252ac6b662d5c72c29903813eJake Slack setFailed(e); 10003928aee4356845252ac6b662d5c72c29903813eJake Slack throw e; 10103928aee4356845252ac6b662d5c72c29903813eJake Slack } 10203928aee4356845252ac6b662d5c72c29903813eJake Slack } 10303928aee4356845252ac6b662d5c72c29903813eJake Slack } 10403928aee4356845252ac6b662d5c72c29903813eJake Slack 10503928aee4356845252ac6b662d5c72c29903813eJake Slack public boolean isRunning() 10603928aee4356845252ac6b662d5c72c29903813eJake Slack { 10703928aee4356845252ac6b662d5c72c29903813eJake Slack final int state = _state; 10803928aee4356845252ac6b662d5c72c29903813eJake Slack 10903928aee4356845252ac6b662d5c72c29903813eJake Slack return state == __STARTED || state == __STARTING; 11003928aee4356845252ac6b662d5c72c29903813eJake Slack } 11103928aee4356845252ac6b662d5c72c29903813eJake Slack 11203928aee4356845252ac6b662d5c72c29903813eJake Slack public boolean isStarted() 11303928aee4356845252ac6b662d5c72c29903813eJake Slack { 11403928aee4356845252ac6b662d5c72c29903813eJake Slack return _state == __STARTED; 11503928aee4356845252ac6b662d5c72c29903813eJake Slack } 11603928aee4356845252ac6b662d5c72c29903813eJake Slack 11703928aee4356845252ac6b662d5c72c29903813eJake Slack public boolean isStarting() 11803928aee4356845252ac6b662d5c72c29903813eJake Slack { 11903928aee4356845252ac6b662d5c72c29903813eJake Slack return _state == __STARTING; 12003928aee4356845252ac6b662d5c72c29903813eJake Slack } 12103928aee4356845252ac6b662d5c72c29903813eJake Slack 12203928aee4356845252ac6b662d5c72c29903813eJake Slack public boolean isStopping() 12303928aee4356845252ac6b662d5c72c29903813eJake Slack { 12403928aee4356845252ac6b662d5c72c29903813eJake Slack return _state == __STOPPING; 12503928aee4356845252ac6b662d5c72c29903813eJake Slack } 12603928aee4356845252ac6b662d5c72c29903813eJake Slack 12703928aee4356845252ac6b662d5c72c29903813eJake Slack public boolean isStopped() 12803928aee4356845252ac6b662d5c72c29903813eJake Slack { 12903928aee4356845252ac6b662d5c72c29903813eJake Slack return _state == __STOPPED; 13003928aee4356845252ac6b662d5c72c29903813eJake Slack } 13103928aee4356845252ac6b662d5c72c29903813eJake Slack 13203928aee4356845252ac6b662d5c72c29903813eJake Slack public boolean isFailed() 13303928aee4356845252ac6b662d5c72c29903813eJake Slack { 13403928aee4356845252ac6b662d5c72c29903813eJake Slack return _state == __FAILED; 13503928aee4356845252ac6b662d5c72c29903813eJake Slack } 13603928aee4356845252ac6b662d5c72c29903813eJake Slack 13703928aee4356845252ac6b662d5c72c29903813eJake Slack public void addLifeCycleListener(LifeCycle.Listener listener) 13803928aee4356845252ac6b662d5c72c29903813eJake Slack { 13903928aee4356845252ac6b662d5c72c29903813eJake Slack _listeners.add(listener); 14003928aee4356845252ac6b662d5c72c29903813eJake Slack } 14103928aee4356845252ac6b662d5c72c29903813eJake Slack 14203928aee4356845252ac6b662d5c72c29903813eJake Slack public void removeLifeCycleListener(LifeCycle.Listener listener) 14303928aee4356845252ac6b662d5c72c29903813eJake Slack { 14403928aee4356845252ac6b662d5c72c29903813eJake Slack _listeners.remove(listener); 14503928aee4356845252ac6b662d5c72c29903813eJake Slack } 14603928aee4356845252ac6b662d5c72c29903813eJake Slack 14703928aee4356845252ac6b662d5c72c29903813eJake Slack public String getState() 14803928aee4356845252ac6b662d5c72c29903813eJake Slack { 14903928aee4356845252ac6b662d5c72c29903813eJake Slack switch(_state) 15003928aee4356845252ac6b662d5c72c29903813eJake Slack { 15103928aee4356845252ac6b662d5c72c29903813eJake Slack case __FAILED: return FAILED; 15203928aee4356845252ac6b662d5c72c29903813eJake Slack case __STARTING: return STARTING; 15303928aee4356845252ac6b662d5c72c29903813eJake Slack case __STARTED: return STARTED; 15403928aee4356845252ac6b662d5c72c29903813eJake Slack case __STOPPING: return STOPPING; 15503928aee4356845252ac6b662d5c72c29903813eJake Slack case __STOPPED: return STOPPED; 15603928aee4356845252ac6b662d5c72c29903813eJake Slack } 15703928aee4356845252ac6b662d5c72c29903813eJake Slack return null; 15803928aee4356845252ac6b662d5c72c29903813eJake Slack } 15903928aee4356845252ac6b662d5c72c29903813eJake Slack 16003928aee4356845252ac6b662d5c72c29903813eJake Slack public static String getState(LifeCycle lc) 16103928aee4356845252ac6b662d5c72c29903813eJake Slack { 16203928aee4356845252ac6b662d5c72c29903813eJake Slack if (lc.isStarting()) return STARTING; 16303928aee4356845252ac6b662d5c72c29903813eJake Slack if (lc.isStarted()) return STARTED; 16403928aee4356845252ac6b662d5c72c29903813eJake Slack if (lc.isStopping()) return STOPPING; 16503928aee4356845252ac6b662d5c72c29903813eJake Slack if (lc.isStopped()) return STOPPED; 16603928aee4356845252ac6b662d5c72c29903813eJake Slack return FAILED; 16703928aee4356845252ac6b662d5c72c29903813eJake Slack } 16803928aee4356845252ac6b662d5c72c29903813eJake Slack 16903928aee4356845252ac6b662d5c72c29903813eJake Slack private void setStarted() 17003928aee4356845252ac6b662d5c72c29903813eJake Slack { 17103928aee4356845252ac6b662d5c72c29903813eJake Slack _state = __STARTED; 17203928aee4356845252ac6b662d5c72c29903813eJake Slack LOG.debug(STARTED+" {}",this); 17303928aee4356845252ac6b662d5c72c29903813eJake Slack for (Listener listener : _listeners) 17403928aee4356845252ac6b662d5c72c29903813eJake Slack listener.lifeCycleStarted(this); 17503928aee4356845252ac6b662d5c72c29903813eJake Slack } 17603928aee4356845252ac6b662d5c72c29903813eJake Slack 17703928aee4356845252ac6b662d5c72c29903813eJake Slack private void setStarting() 17803928aee4356845252ac6b662d5c72c29903813eJake Slack { 17903928aee4356845252ac6b662d5c72c29903813eJake Slack LOG.debug("starting {}",this); 18003928aee4356845252ac6b662d5c72c29903813eJake Slack _state = __STARTING; 18103928aee4356845252ac6b662d5c72c29903813eJake Slack for (Listener listener : _listeners) 18203928aee4356845252ac6b662d5c72c29903813eJake Slack listener.lifeCycleStarting(this); 18303928aee4356845252ac6b662d5c72c29903813eJake Slack } 18403928aee4356845252ac6b662d5c72c29903813eJake Slack 18503928aee4356845252ac6b662d5c72c29903813eJake Slack private void setStopping() 18603928aee4356845252ac6b662d5c72c29903813eJake Slack { 18703928aee4356845252ac6b662d5c72c29903813eJake Slack LOG.debug("stopping {}",this); 18803928aee4356845252ac6b662d5c72c29903813eJake Slack _state = __STOPPING; 18903928aee4356845252ac6b662d5c72c29903813eJake Slack for (Listener listener : _listeners) 19003928aee4356845252ac6b662d5c72c29903813eJake Slack listener.lifeCycleStopping(this); 19103928aee4356845252ac6b662d5c72c29903813eJake Slack } 19203928aee4356845252ac6b662d5c72c29903813eJake Slack 19303928aee4356845252ac6b662d5c72c29903813eJake Slack private void setStopped() 19403928aee4356845252ac6b662d5c72c29903813eJake Slack { 19503928aee4356845252ac6b662d5c72c29903813eJake Slack _state = __STOPPED; 19603928aee4356845252ac6b662d5c72c29903813eJake Slack LOG.debug("{} {}",STOPPED,this); 19703928aee4356845252ac6b662d5c72c29903813eJake Slack for (Listener listener : _listeners) 19803928aee4356845252ac6b662d5c72c29903813eJake Slack listener.lifeCycleStopped(this); 19903928aee4356845252ac6b662d5c72c29903813eJake Slack } 20003928aee4356845252ac6b662d5c72c29903813eJake Slack 20103928aee4356845252ac6b662d5c72c29903813eJake Slack private void setFailed(Throwable th) 20203928aee4356845252ac6b662d5c72c29903813eJake Slack { 20303928aee4356845252ac6b662d5c72c29903813eJake Slack _state = __FAILED; 20403928aee4356845252ac6b662d5c72c29903813eJake Slack LOG.warn(FAILED+" " + this+": "+th,th); 20503928aee4356845252ac6b662d5c72c29903813eJake Slack for (Listener listener : _listeners) 20603928aee4356845252ac6b662d5c72c29903813eJake Slack listener.lifeCycleFailure(this,th); 20703928aee4356845252ac6b662d5c72c29903813eJake Slack } 20803928aee4356845252ac6b662d5c72c29903813eJake Slack 20903928aee4356845252ac6b662d5c72c29903813eJake Slack public static abstract class AbstractLifeCycleListener implements LifeCycle.Listener 21003928aee4356845252ac6b662d5c72c29903813eJake Slack { 21103928aee4356845252ac6b662d5c72c29903813eJake Slack public void lifeCycleFailure(LifeCycle event, Throwable cause) {} 21203928aee4356845252ac6b662d5c72c29903813eJake Slack public void lifeCycleStarted(LifeCycle event) {} 21303928aee4356845252ac6b662d5c72c29903813eJake Slack public void lifeCycleStarting(LifeCycle event) {} 21403928aee4356845252ac6b662d5c72c29903813eJake Slack public void lifeCycleStopped(LifeCycle event) {} 21503928aee4356845252ac6b662d5c72c29903813eJake Slack public void lifeCycleStopping(LifeCycle event) {} 21603928aee4356845252ac6b662d5c72c29903813eJake Slack } 21703928aee4356845252ac6b662d5c72c29903813eJake Slack} 218