001    package org.picocontainer.monitors;
002    
003    import java.lang.reflect.Constructor;
004    import java.lang.reflect.Method;
005    import java.util.ArrayList;
006    import java.util.Collection;
007    import java.util.Iterator;
008    import java.util.List;
009    
010    import org.picocontainer.ComponentMonitor;
011    import org.picocontainer.PicoException;
012    
013    /**
014     * A {@link ComponentMonitor} which collects lifecycle failures
015     * and rethrows them on demand after the failures.
016     * 
017     * @author Paul Hammant
018     * @author Mauro Talevi
019     */
020    public class LifecycleComponentMonitor implements ComponentMonitor {
021    
022        private final ComponentMonitor delegate;
023        private final List lifecycleFailures = new ArrayList();
024    
025        public LifecycleComponentMonitor(ComponentMonitor delegate) {
026            this.delegate = delegate;
027        }
028    
029        public LifecycleComponentMonitor() {
030            delegate = new NullComponentMonitor();
031        }
032    
033        public void instantiating(Constructor constructor) {
034            delegate.instantiating(constructor);
035        }
036    
037        public void instantiated(Constructor constructor, long duration) {
038            delegate.instantiated(constructor, duration);
039        }
040    
041        public void instantiated(Constructor constructor, Object instantiated, Object[] parameters, long duration) {
042            delegate.instantiated(constructor, instantiated, parameters, duration);
043        }
044    
045        public void instantiationFailed(Constructor constructor, Exception cause) {
046            delegate.instantiationFailed(constructor, cause);
047        }
048    
049        public void invoking(Method method, Object instance) {
050            delegate.invoking(method, instance);
051        }
052    
053        public void invoked(Method method, Object instance, long duration) {
054            delegate.invoked(method, instance, duration);
055        }
056    
057        public void invocationFailed(Method method, Object instance, Exception cause) {
058            delegate.invocationFailed(method, instance, cause);
059        }
060    
061        public void lifecycleInvocationFailed(Method method, Object instance, RuntimeException cause) {
062            lifecycleFailures.add(cause);
063            delegate.lifecycleInvocationFailed(method, instance, cause);
064        }
065    
066    
067        public void rethrowLifecycleFailuresException() {
068            throw new LifecycleFailuresException(lifecycleFailures);
069        }
070    
071        /**
072         * Subclass of {@link PicoException} that is thrown when the collected
073         * lifecycle failures need to be be collectively rethrown.
074         * 
075         * @author Paul Hammant
076         * @author Mauro Talevi
077         */
078        public class LifecycleFailuresException extends PicoException {
079    
080            private List lifecycleFailures;
081    
082            public LifecycleFailuresException(List lifecycleFailures) {
083                this.lifecycleFailures = lifecycleFailures;
084            }
085    
086            public String getMessage() {
087                StringBuffer message = new StringBuffer();
088                for ( Iterator i = lifecycleFailures.iterator(); i.hasNext(); ) {
089                    Exception failure = (Exception)  i.next();
090                    message.append(failure.getMessage()).append(";  ");
091                }
092                return message.toString();
093            }
094    
095            public Collection getFailures() {
096                return lifecycleFailures;
097            }
098        }
099    }