001    /*****************************************************************************
002     * Copyright (C) PicoContainer Organization. All rights reserved.            *
003     * ------------------------------------------------------------------------- *
004     * The software in this package is published under the terms of the BSD      *
005     * style license a copy of which has been included with this distribution in *
006     * the LICENSE.txt file.                                                     *
007     *****************************************************************************/
008    package org.picocontainer.defaults;
009    
010    import org.picocontainer.ComponentMonitor;
011    import org.picocontainer.Disposable;
012    import org.picocontainer.Startable;
013    
014    import java.lang.reflect.Method;
015    
016    /**
017     * Default lifecycle strategy.  Starts and stops component if Startable,
018     * and disposes it if Disposable.
019     *
020     * @author Mauro Talevi
021     * @author Jörg Schaible
022     * @see Startable
023     * @see Disposable
024     */
025    public class DefaultLifecycleStrategy extends AbstractMonitoringLifecycleStrategy {
026    
027        private static Method start, stop, dispose;
028        {
029            try {
030                start = Startable.class.getMethod("start", (Class[])null);
031                stop = Startable.class.getMethod("stop", (Class[])null);
032                dispose = Disposable.class.getMethod("dispose", (Class[])null);
033            } catch (NoSuchMethodException e) {
034            }
035        }
036    
037        public DefaultLifecycleStrategy(ComponentMonitor monitor) {
038            super(monitor);
039        }
040    
041        public void start(Object component) {
042            if (component != null && component instanceof Startable) {
043                long str = System.currentTimeMillis();
044                currentMonitor().invoking(start, component);
045                try {
046                    ((Startable) component).start();
047                    currentMonitor().invoked(start, component, System.currentTimeMillis() - str);
048                } catch (RuntimeException cause) {
049                    currentMonitor().lifecycleInvocationFailed(start, component, cause); // may re-throw
050                }
051            }
052        }
053    
054        public void stop(Object component) {
055            if (component != null && component instanceof Startable) {
056                long str = System.currentTimeMillis();
057                currentMonitor().invoking(stop, component);
058                try {
059                    ((Startable) component).stop();
060                    currentMonitor().invoked(stop, component, System.currentTimeMillis() - str);
061                } catch (RuntimeException cause) {
062                    currentMonitor().lifecycleInvocationFailed(stop, component, cause); // may re-throw
063                }
064            }
065        }
066    
067        public void dispose(Object component) {
068            if (component != null && component instanceof Disposable) {
069                long str = System.currentTimeMillis();
070                currentMonitor().invoking(dispose, component);
071                try {
072                    ((Disposable) component).dispose();
073                    currentMonitor().invoked(dispose, component, System.currentTimeMillis() - str);
074                } catch (RuntimeException cause) {
075                    currentMonitor().lifecycleInvocationFailed(dispose, component, cause); // may re-throw
076                }
077            }
078        }
079    
080        public boolean hasLifecycle(Class type) {
081            return Startable.class.isAssignableFrom(type) || Disposable.class.isAssignableFrom(type);
082        }
083    }