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