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 java.util.logging.Level;
022    import java.util.logging.Logger;
023    import java.util.logging.LogRecord;
024    import java.util.StringTokenizer;
025    import java.io.PrintWriter;
026    import java.io.StringWriter;
027    
028    import org.apache.commons.logging.Log;
029    
030    /**
031     * Implementation of the <code>org.apache.commons.logging.Log</code>
032     * interface that wraps the standard JDK logging mechanisms that are
033     * available in SourceForge's Lumberjack for JDKs prior to 1.4.
034     *
035     * @version $Id: Jdk13LumberjackLogger.html 862526 2013-05-20 17:07:42Z tn $
036     * @since 1.1
037     */
038    public class Jdk13LumberjackLogger implements Log, Serializable {
039    
040        /** Serializable version identifier. */
041        private static final long serialVersionUID = -8649807923527610591L;
042    
043        // ----------------------------------------------------- Instance Variables
044    
045        /**
046         * The underlying Logger implementation we are using.
047         */
048        protected transient Logger logger = null;
049        protected String name = null;
050        private String sourceClassName = "unknown";
051        private String sourceMethodName = "unknown";
052        private boolean classAndMethodFound = false;
053    
054        /**
055         * This member variable simply ensures that any attempt to initialise
056         * this class in a pre-1.4 JVM will result in an ExceptionInInitializerError.
057         * It must not be private, as an optimising compiler could detect that it
058         * is not used and optimise it away.
059         */
060        protected static final Level dummyLevel = Level.FINE;
061    
062        // ----------------------------------------------------------- Constructors
063    
064        /**
065         * Construct a named instance of this Logger.
066         *
067         * @param name Name of the logger to be constructed
068         */
069        public Jdk13LumberjackLogger(String name) {
070            this.name = name;
071            logger = getLogger();
072        }
073    
074        // --------------------------------------------------------- Public Methods
075    
076        private void log( Level level, String msg, Throwable ex ) {
077            if( getLogger().isLoggable(level) ) {
078                LogRecord record = new LogRecord(level, msg);
079                if( !classAndMethodFound ) {
080                    getClassAndMethod();
081                }
082                record.setSourceClassName(sourceClassName);
083                record.setSourceMethodName(sourceMethodName);
084                if( ex != null ) {
085                    record.setThrown(ex);
086                }
087                getLogger().log(record);
088            }
089        }
090    
091        /**
092         * Gets the class and method by looking at the stack trace for the
093         * first entry that is not this class.
094         */
095        private void getClassAndMethod() {
096            try {
097                Throwable throwable = new Throwable();
098                throwable.fillInStackTrace();
099                StringWriter stringWriter = new StringWriter();
100                PrintWriter printWriter = new PrintWriter( stringWriter );
101                throwable.printStackTrace( printWriter );
102                String traceString = stringWriter.getBuffer().toString();
103                StringTokenizer tokenizer =
104                    new StringTokenizer( traceString, "\n" );
105                tokenizer.nextToken();
106                String line = tokenizer.nextToken();
107                while ( line.indexOf( this.getClass().getName() )  == -1 ) {
108                    line = tokenizer.nextToken();
109                }
110                while ( line.indexOf( this.getClass().getName() ) >= 0 ) {
111                    line = tokenizer.nextToken();
112                }
113                int start = line.indexOf( "at " ) + 3;
114                int end = line.indexOf( '(' );
115                String temp = line.substring( start, end );
116                int lastPeriod = temp.lastIndexOf( '.' );
117                sourceClassName = temp.substring( 0, lastPeriod );
118                sourceMethodName = temp.substring( lastPeriod + 1 );
119            } catch ( Exception ex ) {
120                // ignore - leave class and methodname unknown
121            }
122            classAndMethodFound = true;
123        }
124    
125        /**
126         * Logs a message with <code>java.util.logging.Level.FINE</code>.
127         *
128         * @param message to log
129         * @see org.apache.commons.logging.Log#debug(Object)
130         */
131        public void debug(Object message) {
132            log(Level.FINE, String.valueOf(message), null);
133        }
134    
135        /**
136         * Logs a message with <code>java.util.logging.Level.FINE</code>.
137         *
138         * @param message to log
139         * @param exception log this cause
140         * @see org.apache.commons.logging.Log#debug(Object, Throwable)
141         */
142        public void debug(Object message, Throwable exception) {
143            log(Level.FINE, String.valueOf(message), exception);
144        }
145    
146        /**
147         * Logs a message with <code>java.util.logging.Level.SEVERE</code>.
148         *
149         * @param message to log
150         * @see org.apache.commons.logging.Log#error(Object)
151         */
152        public void error(Object message) {
153            log(Level.SEVERE, String.valueOf(message), null);
154        }
155    
156        /**
157         * Logs a message with <code>java.util.logging.Level.SEVERE</code>.
158         *
159         * @param message to log
160         * @param exception log this cause
161         * @see org.apache.commons.logging.Log#error(Object, Throwable)
162         */
163        public void error(Object message, Throwable exception) {
164            log(Level.SEVERE, String.valueOf(message), exception);
165        }
166    
167        /**
168         * Logs a message with <code>java.util.logging.Level.SEVERE</code>.
169         *
170         * @param message to log
171         * @see org.apache.commons.logging.Log#fatal(Object)
172         */
173        public void fatal(Object message) {
174            log(Level.SEVERE, String.valueOf(message), null);
175        }
176    
177        /**
178         * Logs a message with <code>java.util.logging.Level.SEVERE</code>.
179         *
180         * @param message to log
181         * @param exception log this cause
182         * @see org.apache.commons.logging.Log#fatal(Object, Throwable)
183         */
184        public void fatal(Object message, Throwable exception) {
185            log(Level.SEVERE, String.valueOf(message), exception);
186        }
187    
188        /**
189         * Return the native Logger instance we are using.
190         */
191        public Logger getLogger() {
192            if (logger == null) {
193                logger = Logger.getLogger(name);
194            }
195            return logger;
196        }
197    
198        /**
199         * Logs a message with <code>java.util.logging.Level.INFO</code>.
200         *
201         * @param message to log
202         * @see org.apache.commons.logging.Log#info(Object)
203         */
204        public void info(Object message) {
205            log(Level.INFO, String.valueOf(message), null);
206        }
207    
208        /**
209         * Logs a message with <code>java.util.logging.Level.INFO</code>.
210         *
211         * @param message to log
212         * @param exception log this cause
213         * @see org.apache.commons.logging.Log#info(Object, Throwable)
214         */
215        public void info(Object message, Throwable exception) {
216            log(Level.INFO, String.valueOf(message), exception);
217        }
218    
219        /**
220         * Is debug logging currently enabled?
221         */
222        public boolean isDebugEnabled() {
223            return getLogger().isLoggable(Level.FINE);
224        }
225    
226        /**
227         * Is error logging currently enabled?
228         */
229        public boolean isErrorEnabled() {
230            return getLogger().isLoggable(Level.SEVERE);
231        }
232    
233        /**
234         * Is fatal logging currently enabled?
235         */
236        public boolean isFatalEnabled() {
237            return getLogger().isLoggable(Level.SEVERE);
238        }
239    
240        /**
241         * Is info logging currently enabled?
242         */
243        public boolean isInfoEnabled() {
244            return getLogger().isLoggable(Level.INFO);
245        }
246    
247        /**
248         * Is trace logging currently enabled?
249         */
250        public boolean isTraceEnabled() {
251            return getLogger().isLoggable(Level.FINEST);
252        }
253    
254        /**
255         * Is warn logging currently enabled?
256         */
257        public boolean isWarnEnabled() {
258            return getLogger().isLoggable(Level.WARNING);
259        }
260    
261        /**
262         * Logs a message with <code>java.util.logging.Level.FINEST</code>.
263         *
264         * @param message to log
265         * @see org.apache.commons.logging.Log#trace(Object)
266         */
267        public void trace(Object message) {
268            log(Level.FINEST, String.valueOf(message), null);
269        }
270    
271        /**
272         * Logs a message with <code>java.util.logging.Level.FINEST</code>.
273         *
274         * @param message to log
275         * @param exception log this cause
276         * @see org.apache.commons.logging.Log#trace(Object, Throwable)
277         */
278        public void trace(Object message, Throwable exception) {
279            log(Level.FINEST, String.valueOf(message), exception);
280        }
281    
282        /**
283         * Logs a message with <code>java.util.logging.Level.WARNING</code>.
284         *
285         * @param message to log
286         * @see org.apache.commons.logging.Log#warn(Object)
287         */
288        public void warn(Object message) {
289            log(Level.WARNING, String.valueOf(message), null);
290        }
291    
292        /**
293         * Logs a message with <code>java.util.logging.Level.WARNING</code>.
294         *
295         * @param message to log
296         * @param exception log this cause
297         * @see org.apache.commons.logging.Log#warn(Object, Throwable)
298         */
299        public void warn(Object message, Throwable exception) {
300            log(Level.WARNING, String.valueOf(message), exception);
301        }
302    }