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.injectors.AbstractInjector;
024    
025    /**
026     * <p>
027     * A {@link ComponentMonitor monitor} which delegates to another monitor.
028     * It provides a {@link NullComponentMonitor default ComponentMonitor},
029     * but does not allow to use <code>null</code> for the delegate.
030     * </p>
031     * <p>
032     * It also supports a {@link org.picocontainer.ComponentMonitorStrategy monitor strategy}
033     * that allows to change the delegate.
034     * </p>
035     * 
036     * @author Mauro Talevi
037     */
038    @SuppressWarnings("serial")
039    public class AbstractComponentMonitor implements ComponentMonitor, ComponentMonitorStrategy, Serializable {
040    
041            
042            /**
043             * Delegate monitor to allow for component monitor chaining.
044             */
045            private  ComponentMonitor delegate;
046        
047        /**
048         * Creates a AbstractComponentMonitor with a given delegate
049         * @param delegate the ComponentMonitor to which this monitor delegates
050         */
051        public AbstractComponentMonitor(ComponentMonitor delegate) {
052            checkMonitor(delegate);
053            this.delegate = delegate;
054        }
055    
056        /**
057         * Creates a AbstractComponentMonitor with an instance of
058         * {@link NullComponentMonitor}.
059         */
060        public AbstractComponentMonitor() {
061            this(new NullComponentMonitor());
062        }
063        
064        public <T> Constructor<T> instantiating(PicoContainer container, ComponentAdapter<T> componentAdapter,
065                                         Constructor<T> constructor
066        ) {
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 void invoking(PicoContainer container,
086                             ComponentAdapter<?> componentAdapter,
087                             Member member,
088                             Object instance) {
089            delegate.invoking(container, componentAdapter, member, instance);
090        }
091    
092        public void invoked(PicoContainer container,
093                            ComponentAdapter<?> componentAdapter,
094                            Method method,
095                            Object instance,
096                            long duration) {
097            delegate.invoked(container, componentAdapter, method, instance, duration);
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 AbstractInjector newInjectionFactory(AbstractInjector abstractInjector) {
116            return abstractInjector;
117        }
118    
119        /**
120         * If the delegate supports a {@link ComponentMonitorStrategy monitor strategy},
121         * this is used to changed the monitor while keeping the same delegate.
122         * Else the delegate is replaced by the new monitor.
123         * {@inheritDoc}
124         */
125        public void changeMonitor(ComponentMonitor monitor) {
126            checkMonitor(monitor);
127            if ( delegate instanceof ComponentMonitorStrategy ){
128                ((ComponentMonitorStrategy)delegate).changeMonitor(monitor);
129            } else {
130                delegate = monitor;
131            }
132        }
133    
134        public ComponentMonitor currentMonitor() {
135            if ( delegate instanceof ComponentMonitorStrategy ){
136                return ((ComponentMonitorStrategy)delegate).currentMonitor();
137            } else {
138                return delegate;
139            }
140        }
141        
142        private void checkMonitor(ComponentMonitor monitor) {
143            if ( monitor == null ){
144                throw new NullPointerException("monitor");
145            }
146        }
147    
148    }