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 Hammant                                             *
009     *****************************************************************************/
010    
011    package org.picocontainer.gems.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.apache.log4j.LogManager;
019    import org.apache.log4j.Logger;
020    import org.apache.log4j.Priority;
021    import org.picocontainer.monitors.AbstractComponentMonitor;
022    import org.picocontainer.monitors.DefaultComponentMonitor;
023    import org.picocontainer.ComponentMonitor;
024    
025    
026    /**
027     * A {@link org.picocontainer.ComponentMonitor} which writes to a Log4J {@link org.apache.log4j.Logger} instance.
028     * The Logger instance can either be injected or, if not set, the {@link LogManager LogManager}
029     * will be used to retrieve it at every invocation of the monitor.
030     *
031     * @author Paul Hammant
032     * @author Mauro Talevi
033     * @version $Revision: $
034     */
035    public class Log4JComponentMonitor extends AbstractComponentMonitor implements Serializable {
036    
037        private Logger logger;
038        private final ComponentMonitor delegate;
039    
040        /**
041         * Creates a Log4JComponentMonitor with no Logger instance set.
042         * The {@link LogManager LogManager} will be used to retrieve the Logger instance
043         * at every invocation of the monitor.
044         */
045        public Log4JComponentMonitor() {
046            delegate = new DefaultComponentMonitor();
047        }
048        
049        /**
050         * Creates a Log4JComponentMonitor with a given Logger instance class.
051         * The class name is used to retrieve the Logger instance.
052         *
053         * @param loggerClass the class of the Logger
054         */
055        public Log4JComponentMonitor(Class loggerClass) {
056            this(loggerClass.getName());
057        }
058    
059        /**
060         * Creates a Log4JComponentMonitor with a given Logger instance name. It uses the
061         * {@link org.apache.log4j.LogManager LogManager} to create the Logger instance.
062         *
063         * @param loggerName the name of the Log
064         */
065        public Log4JComponentMonitor(String loggerName) {
066            this(LogManager.getLogger(loggerName));
067        }
068    
069        /**
070         * Creates a Log4JComponentMonitor with a given Logger instance
071         *
072         * @param logger the Logger to write to
073         */
074        public Log4JComponentMonitor(Logger logger) {
075            this();
076            this.logger = logger;
077        }
078    
079        /**
080         * Creates a Log4JComponentMonitor with a given Logger instance class.
081         * The class name is used to retrieve the Logger instance.
082         *
083         * @param loggerClass the class of the Logger
084         */
085        public Log4JComponentMonitor(Class loggerClass, ComponentMonitor delegate) {
086            this(loggerClass.getName(), delegate);
087        }
088    
089        /**
090         * Creates a Log4JComponentMonitor with a given Logger instance name. It uses the
091         * {@link org.apache.log4j.LogManager LogManager} to create the Logger instance.
092         *
093         * @param loggerName the name of the Log
094         */
095        public Log4JComponentMonitor(String loggerName, ComponentMonitor delegate) {
096            this(LogManager.getLogger(loggerName), delegate);
097        }
098    
099        /**
100         * Creates a Log4JComponentMonitor with a given Logger instance
101         *
102         * @param logger the Logger to write to
103         */
104        public Log4JComponentMonitor(Logger logger, ComponentMonitor delegate) {
105            this(delegate);
106            this.logger = logger;
107        }
108    
109        public Log4JComponentMonitor(ComponentMonitor delegate) {
110            this.delegate = delegate;
111        }
112    
113        public void instantiating(Constructor constructor) {
114            Logger logger = getLogger(constructor);
115            if (logger.isDebugEnabled()) {
116                logger.debug(format(INSTANTIATING, new Object[]{toString(constructor)}));
117            }
118            delegate.instantiating(constructor);
119        }
120    
121        public void instantiated(Constructor constructor, long duration) {
122            Logger logger = getLogger(constructor);
123            if (logger.isDebugEnabled()) {
124                logger.debug(format(INSTANTIATED, new Object[]{toString(constructor), new Long(duration)}));
125            }
126            delegate.instantiated(constructor, duration);
127        }
128    
129        public void instantiated(Constructor constructor, Object instantiated, Object[] parameters, long duration) {
130            Logger logger = getLogger(constructor);
131            if (logger.isDebugEnabled()) {
132                logger.debug(format(INSTANTIATED2, new Object[]{toString(constructor), new Long(duration), instantiated.getClass().getName(), toString(parameters)}));
133            }
134            delegate.instantiated(constructor, instantiated, parameters, duration);
135        }
136    
137        public void instantiationFailed(Constructor constructor, Exception cause) {
138            Logger logger = getLogger(constructor);
139            if (logger.isEnabledFor(Priority.WARN)) {
140                logger.warn(format(INSTANTIATION_FAILED, new Object[]{toString(constructor), cause.getMessage()}), cause);
141            }
142            delegate.instantiationFailed(constructor, cause);
143        }
144    
145        public void invoking(Method method, Object instance) {
146            Logger logger = getLogger(method);
147            if (logger.isDebugEnabled()) {
148                logger.debug(format(INVOKING, new Object[]{toString(method), instance}));
149            }
150            delegate.invoking(method, instance);
151        }
152    
153        public void invoked(Method method, Object instance, long duration) {
154            Logger logger = getLogger(method);
155            if (logger.isDebugEnabled()) {
156                logger.debug(format(INVOKED, new Object[]{toString(method), instance, new Long(duration)}));
157            }
158            delegate.invoked(method, instance, duration);
159        }
160    
161        public void invocationFailed(Method method, Object instance, Exception cause) {
162            Logger logger = getLogger(method);
163            if (logger.isEnabledFor(Priority.WARN)) {
164                logger.warn(format(INVOCATION_FAILED, new Object[]{toString(method), instance, cause.getMessage()}), cause);
165            }
166            delegate.invocationFailed(method, instance, cause);
167        }
168    
169        public void lifecycleInvocationFailed(Method method, Object instance, RuntimeException cause) {
170            Logger logger = getLogger(method);
171            if (logger.isEnabledFor(Priority.WARN)) {
172                logger.warn(format(LIFECYCLE_INVOCATION_FAILED, new Object[]{toString(method), instance, cause.getMessage()}), cause);
173            }
174            delegate.lifecycleInvocationFailed(method, instance, cause);
175        }
176    
177        protected Logger getLogger(Member member) {
178            if ( logger != null ){
179                return logger;
180            } 
181            return LogManager.getLogger(member.getDeclaringClass());
182        }
183    
184    }