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 java.lang.reflect.Method;
011    
012    import org.picocontainer.ComponentMonitor;
013    import org.picocontainer.Disposable;
014    import org.picocontainer.LifecycleManager;
015    import org.picocontainer.PicoIntrospectionException;
016    import org.picocontainer.Startable;
017    import org.picocontainer.monitors.DefaultComponentMonitor;
018    
019    
020    /**
021     * A PicoVisitor for the lifecycle methods of the components.
022     * 
023     * @author Aslak Hellesøy
024     * @author Jörg Schaible
025     * @since 1.1
026     * @deprecated since 1.2 in favour of {@link LifecycleManager}
027     */
028    public class LifecycleVisitor extends MethodCallingVisitor {
029        private static final Method START;
030        private static final Method STOP;
031        private static final Method DISPOSE;
032        static {
033            try {
034                START = Startable.class.getMethod("start", (Class[])null);
035                STOP = Startable.class.getMethod("stop", (Class[])null);
036                DISPOSE = Disposable.class.getMethod("dispose", (Class[])null);
037            } catch (NoSuchMethodException e) {
038                // /CLOVER:OFF
039                throw new InternalError(e.getMessage());
040                // /CLOVER:ON
041            }
042        }
043    
044        private final ComponentMonitor componentMonitor;
045    
046        /**
047         * Construct a LifecycleVisitor.
048         * 
049         * @param method the method to call
050         * @param ofType the component type
051         * @param visitInInstantiationOrder flag for the visiting order
052         * @param monitor the {@link ComponentMonitor} to use
053         * @deprecated since 1.2 in favour of {@link LifecycleManager}
054         */
055        protected LifecycleVisitor(Method method, Class ofType, boolean visitInInstantiationOrder, ComponentMonitor monitor) {
056            super(method, ofType, null, visitInInstantiationOrder);
057            if (monitor == null) {
058                throw new NullPointerException();
059            }
060            this.componentMonitor = monitor;
061        }
062    
063        /**
064         * Construct a LifecycleVisitor.
065         * 
066         * @param method the method to call
067         * @param ofType the component type
068         * @param visitInInstantiationOrder flag for the visiting order
069         * @deprecated since 1.2 in favour of {@link org.picocontainer.LifecycleManager}
070         */
071        public LifecycleVisitor(Method method, Class ofType, boolean visitInInstantiationOrder) {
072            this(method, ofType, visitInInstantiationOrder, new DefaultComponentMonitor());
073        }
074    
075        /**
076         * Invoke the standard PicoContainer lifecycle for {@link Startable#start()}.
077         * 
078         * @param node The node to start the traversal.
079         * @deprecated since 1.2 in favour of {@link org.picocontainer.LifecycleManager}
080         */
081        public static void start(Object node) {
082            new LifecycleVisitor(START, Startable.class, true).traverse(node);
083        }
084    
085        /**
086         * Invoke the standard PicoContainer lifecycle for {@link Startable#stop()}.
087         * 
088         * @param node The node to start the traversal.
089         * @deprecated since 1.2 in favour of {@link LifecycleManager}
090         */
091        public static void stop(Object node) {
092            new LifecycleVisitor(STOP, Startable.class, false).traverse(node);
093        }
094    
095        /**
096         * Invoke the standard PicoContainer lifecycle for {@link Disposable#dispose()}.
097         * 
098         * @param node The node to start the traversal.
099         * @deprecated since 1.2 in favour of {@link LifecycleManager}
100         */
101        public static void dispose(Object node) {
102            new LifecycleVisitor(DISPOSE, Disposable.class, false).traverse(node);
103        }
104    
105        protected Object invoke(final Object target) {
106            final Method method = getMethod();
107            try {
108                componentMonitor.invoking(method, target);
109                final long startTime = System.currentTimeMillis();
110                super.invoke(target);
111                componentMonitor.invoked(method, target, System.currentTimeMillis() - startTime);
112            } catch (final PicoIntrospectionException e) {
113                componentMonitor.invocationFailed(method, target, (Exception)e.getCause());
114                throw e;
115            }
116            return Void.TYPE;
117        }
118    
119    }