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     * Original code by Mauro Talevi                                             *
009     *****************************************************************************/
010    
011    package org.picocontainer.monitors;
012    
013    import java.io.Serializable;
014    import java.lang.reflect.Constructor;
015    import java.lang.reflect.Member;
016    import java.lang.reflect.Method;
017    
018    import org.picocontainer.ComponentAdapter;
019    import org.picocontainer.ComponentMonitor;
020    import org.picocontainer.ComponentMonitorStrategy;
021    import org.picocontainer.MutablePicoContainer;
022    import org.picocontainer.PicoContainer;
023    import org.picocontainer.Injector;
024    import org.picocontainer.Behavior;
025    
026    /**
027     * <p>
028     * A {@link ComponentMonitor monitor} which delegates to another monitor.
029     * It provides a {@link NullComponentMonitor default ComponentMonitor},
030     * but does not allow to use <code>null</code> for the delegate.
031     * </p>
032     * <p>
033     * It also supports a {@link org.picocontainer.ComponentMonitorStrategy monitor strategy}
034     * that allows to change the delegate.
035     * </p>
036     * 
037     * @author Mauro Talevi
038     */
039    @SuppressWarnings("serial")
040    public class AbstractComponentMonitor implements ComponentMonitor, ComponentMonitorStrategy, Serializable {
041    
042            
043            /**
044             * Delegate monitor to allow for component monitor chaining.
045             */
046            private  ComponentMonitor delegate;
047        
048        /**
049         * Creates a AbstractComponentMonitor with a given delegate
050         * @param delegate the ComponentMonitor to which this monitor delegates
051         */
052        public AbstractComponentMonitor(ComponentMonitor delegate) {
053            checkMonitor(delegate);
054            this.delegate = delegate;
055        }
056    
057        /**
058         * Creates a AbstractComponentMonitor with an instance of
059         * {@link NullComponentMonitor}.
060         */
061        public AbstractComponentMonitor() {
062            this(new NullComponentMonitor());
063        }
064        
065        public <T> Constructor<T> instantiating(PicoContainer container, ComponentAdapter<T> componentAdapter,
066                                         Constructor<T> constructor) {
067            return delegate.instantiating(container, componentAdapter, constructor);
068        }
069    
070        public <T> void instantiated(PicoContainer container, ComponentAdapter<T> componentAdapter,
071                                 Constructor<T> constructor,
072                                 Object instantiated,
073                                 Object[] injected,
074                                 long duration) {
075            delegate.instantiated(container, componentAdapter, constructor, instantiated, injected, duration);
076        }
077    
078        public <T> void instantiationFailed(PicoContainer container,
079                                        ComponentAdapter<T> componentAdapter,
080                                        Constructor<T> constructor,
081                                        Exception e) {
082            delegate.instantiationFailed(container, componentAdapter, constructor, e);
083        }
084    
085        public Object invoking(PicoContainer container,
086                               ComponentAdapter<?> componentAdapter,
087                               Member member,
088                               Object instance, Object[] args) {
089            return delegate.invoking(container, componentAdapter, member, instance, args);
090        }
091    
092        public void invoked(PicoContainer container,
093                            ComponentAdapter<?> componentAdapter,
094                            Member member,
095                            Object instance,
096                            long duration, Object[] args, Object retVal) {
097            delegate.invoked(container, componentAdapter, member, instance, duration, args, retVal);
098        }
099    
100        public void invocationFailed(Member member, Object instance, Exception e) {
101            delegate.invocationFailed(member, instance, e);
102        }
103    
104        public void lifecycleInvocationFailed(MutablePicoContainer container,
105                                              ComponentAdapter<?> componentAdapter, Method method,
106                                              Object instance,
107                                              RuntimeException cause) {
108            delegate.lifecycleInvocationFailed(container, componentAdapter, method,instance, cause);
109        }
110    
111        public Object noComponentFound(MutablePicoContainer container, Object componentKey) {
112            return delegate.noComponentFound(container, componentKey);
113        }
114    
115        public Injector newInjector(Injector injector) {
116            return injector;
117        }
118    
119        public Behavior newBehavior(Behavior behavior) {
120            return behavior;
121        }
122    
123        /**
124         * If the delegate supports a {@link ComponentMonitorStrategy monitor strategy},
125         * this is used to changed the monitor while keeping the same delegate.
126         * Else the delegate is replaced by the new monitor.
127         * {@inheritDoc}
128         */
129        public void changeMonitor(ComponentMonitor monitor) {
130            checkMonitor(monitor);
131            if ( delegate instanceof ComponentMonitorStrategy ){
132                ((ComponentMonitorStrategy)delegate).changeMonitor(monitor);
133            } else {
134                delegate = monitor;
135            }
136        }
137    
138        public ComponentMonitor currentMonitor() {
139            if ( delegate instanceof ComponentMonitorStrategy ){
140                return ((ComponentMonitorStrategy)delegate).currentMonitor();
141            } else {
142                return delegate;
143            }
144        }
145        
146        private void checkMonitor(ComponentMonitor monitor) {
147            if ( monitor == null ){
148                throw new NullPointerException("monitor");
149            }
150        }
151    
152    }