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 Paul Hammaant                                            *
009 *****************************************************************************/
010
011package org.picocontainer.monitors;
012
013import static org.picocontainer.monitors.ComponentMonitorHelper.ctorToString;
014import static org.picocontainer.monitors.ComponentMonitorHelper.format;
015import static org.picocontainer.monitors.ComponentMonitorHelper.memberToString;
016import static org.picocontainer.monitors.ComponentMonitorHelper.methodToString;
017import static org.picocontainer.monitors.ComponentMonitorHelper.parmsToString;
018
019import java.io.OutputStream;
020import java.io.PrintStream;
021import java.io.Serializable;
022import java.lang.reflect.Constructor;
023import java.lang.reflect.Member;
024import java.lang.reflect.Method;
025
026import org.picocontainer.ComponentAdapter;
027import org.picocontainer.ComponentMonitor;
028import org.picocontainer.MutablePicoContainer;
029import org.picocontainer.PicoContainer;
030import org.picocontainer.Injector;
031import org.picocontainer.Behavior;
032
033/**
034 * A {@link ComponentMonitor} which writes to a {@link OutputStream}. 
035 * This is typically used to write to a console.
036 * (TODO  After serialization, the output printstream is null)  
037 *
038 * @author Paul Hammant
039 * @author Aslak Hellesøy
040 * @author Mauro Talevi
041 */
042@SuppressWarnings("serial")
043public class ConsoleComponentMonitor implements ComponentMonitor, Serializable {
044
045        /**
046         * The outgoing print stream.
047         */
048    private final transient PrintStream out;
049    
050    /**
051     * Delegate component monitor (for component monitor chains).
052     */
053    private final ComponentMonitor delegate;
054
055    /**
056     * Constructs a console component monitor that sends output to <tt>System.out</tt>.
057     */
058    public ConsoleComponentMonitor() {
059        this(System.out);
060    }
061
062    /**
063     * Constructs a console component monitor that sends output to the specified output stream.
064     * 
065     * @param out  the designated output stream.  Options include System.out, Socket streams, File streams,
066     * etc.
067     */
068    public ConsoleComponentMonitor(OutputStream out) {
069        this(out, new NullComponentMonitor());
070    }
071
072    /**
073     * Constructs a console component monitor chain that sends output to the specified output stream
074     * and then sends all events to the delegate component monitor.
075     * @param out the output stream of choice.
076     * @param delegate the next monitor in the component monitor chain to receive event information.
077     */
078    public ConsoleComponentMonitor(OutputStream out, ComponentMonitor delegate) {
079        this.out = new PrintStream(out);
080        this.delegate = delegate;
081    }
082
083    public <T> Constructor<T> instantiating(PicoContainer container, ComponentAdapter<T> componentAdapter,
084                                     Constructor<T> constructor
085    ) {
086        out.println(format(ComponentMonitorHelper.INSTANTIATING, ctorToString(constructor)));
087        return delegate.instantiating(container, componentAdapter, constructor);
088    }
089
090    public <T> void instantiated(PicoContainer container, ComponentAdapter<T> componentAdapter,
091                             Constructor<T> constructor,
092                             Object instantiated,
093                             Object[] parameters,
094                             long duration) {
095        out.println(format(ComponentMonitorHelper.INSTANTIATED, ctorToString(constructor), duration, instantiated.getClass().getName(), parmsToString(parameters)));
096        delegate.instantiated(container, componentAdapter, constructor, instantiated, parameters, duration);
097    }
098
099    public <T> void instantiationFailed(PicoContainer container,
100                                    ComponentAdapter<T> componentAdapter,
101                                    Constructor<T> constructor,
102                                    Exception cause) {
103        out.println(format(ComponentMonitorHelper.INSTANTIATION_FAILED, ctorToString(constructor), cause.getMessage()));
104        delegate.instantiationFailed(container, componentAdapter, constructor, cause);
105    }
106
107    public Object invoking(PicoContainer container,
108                           ComponentAdapter<?> componentAdapter,
109                           Member member,
110                           Object instance, Object[] args) {
111        out.println(format(ComponentMonitorHelper.INVOKING, memberToString(member), instance));
112        return delegate.invoking(container, componentAdapter, member, instance, args);
113    }
114
115    public void invoked(PicoContainer container,
116                        ComponentAdapter<?> componentAdapter,
117                        Member member,
118                        Object instance,
119                        long duration,
120                        Object[] args, Object retVal) {
121        out.println(format(ComponentMonitorHelper.INVOKED, methodToString(member), instance, duration));
122        delegate.invoked(container, componentAdapter, member, instance, duration, args, retVal);
123    }
124
125    public void invocationFailed(Member member, Object instance, Exception cause) {
126        out.println(format(ComponentMonitorHelper.INVOCATION_FAILED, memberToString(member), instance, cause.getMessage()));
127        delegate.invocationFailed(member, instance, cause);
128    }
129
130    public void lifecycleInvocationFailed(MutablePicoContainer container,
131                                          ComponentAdapter<?> componentAdapter, Method method,
132                                          Object instance,
133                                          RuntimeException cause) {
134        out.println(format(ComponentMonitorHelper.LIFECYCLE_INVOCATION_FAILED, methodToString(method), instance, cause.getMessage()));
135        delegate.lifecycleInvocationFailed(container, componentAdapter, method, instance, cause);
136    }
137
138    public Object noComponentFound(MutablePicoContainer container, Object componentKey) {
139        out.println(format(ComponentMonitorHelper.NO_COMPONENT, componentKey));
140        return delegate.noComponentFound(container, componentKey);
141    }
142
143    public Injector newInjector(Injector injector) {
144        return delegate.newInjector(injector);
145    }
146
147    /** {@inheritDoc} **/
148    public Behavior newBehavior(Behavior behavior) {
149        return delegate.newBehavior(behavior);
150    }
151
152}