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