001    /*
002     * Licensed to the Apache Software Foundation (ASF) under one or more
003     * contributor license agreements.  See the NOTICE file distributed with
004     * this work for additional information regarding copyright ownership.
005     * The ASF licenses this file to You under the Apache License, Version 2.0
006     * (the "License"); you may not use this file except in compliance with
007     * the License.  You may obtain a copy of the License at
008     *
009     *      http://www.apache.org/licenses/LICENSE-2.0
010     *
011     * Unless required by applicable law or agreed to in writing, software
012     * distributed under the License is distributed on an "AS IS" BASIS,
013     * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014     * See the License for the specific language governing permissions and
015     * limitations under the License.
016     */
017    
018    package org.apache.commons.logging.impl;
019    
020    import java.io.Serializable;
021    import org.apache.commons.logging.Log;
022    import org.apache.log4j.Logger;
023    import org.apache.log4j.Priority;
024    import org.apache.log4j.Level;
025    
026    /**
027     * Implementation of {@link Log} that maps directly to a
028     * <strong>Logger</strong> for log4J version 1.2.
029     * <p>
030     * Initial configuration of the corresponding Logger instances should be done
031     * in the usual manner, as outlined in the Log4J documentation.
032     * <p>
033     * The reason this logger is distinct from the 1.3 logger is that in version 1.2
034     * of Log4J:
035     * <ul>
036     * <li>class Logger takes Priority parameters not Level parameters.
037     * <li>class Level extends Priority
038     * </ul>
039     * Log4J1.3 is expected to change Level so it no longer extends Priority, which is
040     * a non-binary-compatible change. The class generated by compiling this code against
041     * log4j 1.2 will therefore not run against log4j 1.3.
042     *
043     * @version $Id: Log4JLogger.html 862526 2013-05-20 17:07:42Z tn $
044     */
045    public class Log4JLogger implements Log, Serializable {
046    
047        /** Serializable version identifier. */
048        private static final long serialVersionUID = 5160705895411730424L;
049    
050        // ------------------------------------------------------------- Attributes
051    
052        /** The fully qualified name of the Log4JLogger class. */
053        private static final String FQCN = Log4JLogger.class.getName();
054    
055        /** Log to this logger */
056        private transient volatile Logger logger = null;
057    
058        /** Logger name */
059        private final String name;
060    
061        private static final Priority traceLevel;
062    
063        // ------------------------------------------------------------
064        // Static Initializer.
065        //
066        // Note that this must come after the static variable declarations
067        // otherwise initialiser expressions associated with those variables
068        // will override any settings done here.
069        //
070        // Verify that log4j is available, and that it is version 1.2.
071        // If an ExceptionInInitializerError is generated, then LogFactoryImpl
072        // will treat that as meaning that the appropriate underlying logging
073        // library is just not present - if discovery is in progress then
074        // discovery will continue.
075        // ------------------------------------------------------------
076    
077        static {
078            if (!Priority.class.isAssignableFrom(Level.class)) {
079                // nope, this is log4j 1.3, so force an ExceptionInInitializerError
080                throw new InstantiationError("Log4J 1.2 not available");
081            }
082    
083            // Releases of log4j1.2 >= 1.2.12 have Priority.TRACE available, earlier
084            // versions do not. If TRACE is not available, then we have to map
085            // calls to Log.trace(...) onto the DEBUG level.
086    
087            Priority _traceLevel;
088            try {
089                _traceLevel = (Priority) Level.class.getDeclaredField("TRACE").get(null);
090            } catch(Exception ex) {
091                // ok, trace not available
092                _traceLevel = Level.DEBUG;
093            }
094            traceLevel = _traceLevel;
095        }
096    
097        // ------------------------------------------------------------ Constructor
098    
099        public Log4JLogger() {
100            name = null;
101        }
102    
103        /**
104         * Base constructor.
105         */
106        public Log4JLogger(String name) {
107            this.name = name;
108            this.logger = getLogger();
109        }
110    
111        /**
112         * For use with a log4j factory.
113         */
114        public Log4JLogger(Logger logger) {
115            if (logger == null) {
116                throw new IllegalArgumentException(
117                    "Warning - null logger in constructor; possible log4j misconfiguration.");
118            }
119            this.name = logger.getName();
120            this.logger = logger;
121        }
122    
123        /**
124         * Logs a message with <code>org.apache.log4j.Priority.TRACE</code>.
125         * When using a log4j version that does not support the <code>TRACE</code>
126         * level, the message will be logged at the <code>DEBUG</code> level.
127         *
128         * @param message to log
129         * @see org.apache.commons.logging.Log#trace(Object)
130         */
131        public void trace(Object message) {
132            getLogger().log(FQCN, traceLevel, message, null);
133        }
134    
135        /**
136         * Logs a message with <code>org.apache.log4j.Priority.TRACE</code>.
137         * When using a log4j version that does not support the <code>TRACE</code>
138         * level, the message will be logged at the <code>DEBUG</code> level.
139         *
140         * @param message to log
141         * @param t log this cause
142         * @see org.apache.commons.logging.Log#trace(Object, Throwable)
143         */
144        public void trace(Object message, Throwable t) {
145            getLogger().log(FQCN, traceLevel, message, t);
146        }
147    
148        /**
149         * Logs a message with <code>org.apache.log4j.Priority.DEBUG</code>.
150         *
151         * @param message to log
152         * @see org.apache.commons.logging.Log#debug(Object)
153         */
154        public void debug(Object message) {
155            getLogger().log(FQCN, Level.DEBUG, message, null);
156        }
157    
158        /**
159         * Logs a message with <code>org.apache.log4j.Priority.DEBUG</code>.
160         *
161         * @param message to log
162         * @param t log this cause
163         * @see org.apache.commons.logging.Log#debug(Object, Throwable)
164         */
165        public void debug(Object message, Throwable t) {
166            getLogger().log(FQCN, Level.DEBUG, message, t);
167        }
168    
169        /**
170         * Logs a message with <code>org.apache.log4j.Priority.INFO</code>.
171         *
172         * @param message to log
173         * @see org.apache.commons.logging.Log#info(Object)
174         */
175        public void info(Object message) {
176            getLogger().log(FQCN, Level.INFO, message, null);
177        }
178    
179        /**
180         * Logs a message with <code>org.apache.log4j.Priority.INFO</code>.
181         *
182         * @param message to log
183         * @param t log this cause
184         * @see org.apache.commons.logging.Log#info(Object, Throwable)
185         */
186        public void info(Object message, Throwable t) {
187            getLogger().log(FQCN, Level.INFO, message, t);
188        }
189    
190        /**
191         * Logs a message with <code>org.apache.log4j.Priority.WARN</code>.
192         *
193         * @param message to log
194         * @see org.apache.commons.logging.Log#warn(Object)
195         */
196        public void warn(Object message) {
197            getLogger().log(FQCN, Level.WARN, message, null);
198        }
199    
200        /**
201         * Logs a message with <code>org.apache.log4j.Priority.WARN</code>.
202         *
203         * @param message to log
204         * @param t log this cause
205         * @see org.apache.commons.logging.Log#warn(Object, Throwable)
206         */
207        public void warn(Object message, Throwable t) {
208            getLogger().log(FQCN, Level.WARN, message, t);
209        }
210    
211        /**
212         * Logs a message with <code>org.apache.log4j.Priority.ERROR</code>.
213         *
214         * @param message to log
215         * @see org.apache.commons.logging.Log#error(Object)
216         */
217        public void error(Object message) {
218            getLogger().log(FQCN, Level.ERROR, message, null);
219        }
220    
221        /**
222         * Logs a message with <code>org.apache.log4j.Priority.ERROR</code>.
223         *
224         * @param message to log
225         * @param t log this cause
226         * @see org.apache.commons.logging.Log#error(Object, Throwable)
227         */
228        public void error(Object message, Throwable t) {
229            getLogger().log(FQCN, Level.ERROR, message, t);
230        }
231    
232        /**
233         * Logs a message with <code>org.apache.log4j.Priority.FATAL</code>.
234         *
235         * @param message to log
236         * @see org.apache.commons.logging.Log#fatal(Object)
237         */
238        public void fatal(Object message) {
239            getLogger().log(FQCN, Level.FATAL, message, null);
240        }
241    
242        /**
243         * Logs a message with <code>org.apache.log4j.Priority.FATAL</code>.
244         *
245         * @param message to log
246         * @param t log this cause
247         * @see org.apache.commons.logging.Log#fatal(Object, Throwable)
248         */
249        public void fatal(Object message, Throwable t) {
250            getLogger().log(FQCN, Level.FATAL, message, t);
251        }
252    
253        /**
254         * Return the native Logger instance we are using.
255         */
256        public Logger getLogger() {
257            Logger result = logger;
258            if (result == null) {
259                synchronized(this) {
260                    result = logger;
261                    if (result == null) {
262                        logger = result = Logger.getLogger(name);
263                    }
264                }
265            }
266            return result;
267        }
268    
269        /**
270         * Check whether the Log4j Logger used is enabled for <code>DEBUG</code> priority.
271         */
272        public boolean isDebugEnabled() {
273            return getLogger().isDebugEnabled();
274        }
275    
276        /**
277         * Check whether the Log4j Logger used is enabled for <code>ERROR</code> priority.
278         */
279        public boolean isErrorEnabled() {
280            return getLogger().isEnabledFor(Level.ERROR);
281        }
282    
283        /**
284         * Check whether the Log4j Logger used is enabled for <code>FATAL</code> priority.
285         */
286        public boolean isFatalEnabled() {
287            return getLogger().isEnabledFor(Level.FATAL);
288        }
289    
290        /**
291         * Check whether the Log4j Logger used is enabled for <code>INFO</code> priority.
292         */
293        public boolean isInfoEnabled() {
294            return getLogger().isInfoEnabled();
295        }
296    
297        /**
298         * Check whether the Log4j Logger used is enabled for <code>TRACE</code> priority.
299         * When using a log4j version that does not support the TRACE level, this call
300         * will report whether <code>DEBUG</code> is enabled or not.
301         */
302        public boolean isTraceEnabled() {
303            return getLogger().isEnabledFor(traceLevel);
304        }
305    
306        /**
307         * Check whether the Log4j Logger used is enabled for <code>WARN</code> priority.
308         */
309        public boolean isWarnEnabled() {
310            return getLogger().isEnabledFor(Level.WARN);
311        }
312    }