001/**
002 * Copyright (c) 2004-2019 QOS.ch
003 * All rights reserved.
004 *
005 * Permission is hereby granted, free  of charge, to any person obtaining
006 * a  copy  of this  software  and  associated  documentation files  (the
007 * "Software"), to  deal in  the Software without  restriction, including
008 * without limitation  the rights to  use, copy, modify,  merge, publish,
009 * distribute,  sublicense, and/or sell  copies of  the Software,  and to
010 * permit persons to whom the Software  is furnished to do so, subject to
011 * the following conditions:
012 *
013 * The  above  copyright  notice  and  this permission  notice  shall  be
014 * included in all copies or substantial portions of the Software.
015 *
016 * THE  SOFTWARE IS  PROVIDED  "AS  IS", WITHOUT  WARRANTY  OF ANY  KIND,
017 * EXPRESS OR  IMPLIED, INCLUDING  BUT NOT LIMITED  TO THE  WARRANTIES OF
018 * MERCHANTABILITY,    FITNESS    FOR    A   PARTICULAR    PURPOSE    AND
019 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
020 * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
021 * OF CONTRACT, TORT OR OTHERWISE,  ARISING FROM, OUT OF OR IN CONNECTION
022 * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
023 *
024 */
025package org.slf4j.helpers;
026
027import java.io.ObjectStreamException;
028import java.io.Serializable;
029
030import org.slf4j.Logger;
031import org.slf4j.LoggerFactory;
032import org.slf4j.Marker;
033import org.slf4j.event.Level;
034
035/**
036 * An abstract implementation which delegates actual logging work to the 
037 * {@link #handleNormalizedLoggingCall(Level, Marker, String, Object[], Throwable)} method.
038 * 
039 * @author Ceki Gülcü
040 * @since 2.0
041 */
042public abstract class AbstractLogger implements Logger, Serializable {
043
044    private static final long serialVersionUID = -2529255052481744503L;
045
046    protected String name;
047
048    public String getName() {
049        return name;
050    }
051
052    /**
053     * Replace this instance with a homonymous (same name) logger returned 
054     * by LoggerFactory. Note that this method is only called during 
055     * deserialization.
056     * 
057     * <p>
058     * This approach will work well if the desired ILoggerFactory is the one
059     * referenced by {@link org.slf4j.LoggerFactory} However, if the user manages its logger hierarchy
060     * through a different (non-static) mechanism, e.g. dependency injection, then
061     * this approach would be mostly counterproductive.
062     * 
063     * @return logger with same name as returned by LoggerFactory
064     * @throws ObjectStreamException
065     */
066    protected Object readResolve() throws ObjectStreamException {
067        // using getName() instead of this.name works even for
068        // NOPLogger
069        return LoggerFactory.getLogger(getName());
070    }
071
072    @Override
073    public void trace(String msg) {
074        if (isTraceEnabled()) {
075            handle_0ArgsCall(Level.TRACE, null, msg, null);
076        }
077    }
078
079    @Override
080    public void trace(String format, Object arg) {
081        if (isTraceEnabled()) {
082            handle_1ArgsCall(Level.TRACE, null, format, arg);
083        }
084    }
085
086    @Override
087    public void trace(String format, Object arg1, Object arg2) {
088        if (isTraceEnabled()) {
089            handle2ArgsCall(Level.TRACE, null, format, arg1, arg2);
090        }
091    }
092
093    @Override
094    public void trace(String format, Object... arguments) {
095        if (isTraceEnabled()) {
096            handleArgArrayCall(Level.TRACE, null, format, arguments);
097        }
098    }
099
100    @Override
101    public void trace(String msg, Throwable t) {
102        if (isTraceEnabled()) {
103            handle_0ArgsCall(Level.TRACE, null, msg, t);
104        }
105    }
106
107    @Override
108    public void trace(Marker marker, String msg) {
109        if (isTraceEnabled(marker)) {
110            handle_0ArgsCall(Level.TRACE, marker, msg, null);
111        }
112    }
113
114    @Override
115    public void trace(Marker marker, String format, Object arg) {
116        if (isTraceEnabled(marker)) {
117            handle_1ArgsCall(Level.TRACE, marker, format, arg);
118        }
119    }
120
121    @Override
122    public void trace(Marker marker, String format, Object arg1, Object arg2) {
123        if (isTraceEnabled(marker)) {
124            handle2ArgsCall(Level.TRACE, marker, format, arg1, arg2);
125        }
126    }
127
128    @Override
129    public void trace(Marker marker, String format, Object... argArray) {
130        if (isTraceEnabled(marker)) {
131            handleArgArrayCall(Level.TRACE, marker, format, argArray);
132        }
133    }
134
135    public void trace(Marker marker, String msg, Throwable t) {
136        if (isTraceEnabled(marker)) {
137            handle_0ArgsCall(Level.TRACE, marker, msg, t);
138        }
139    }
140
141    public void debug(String msg) {
142        if (isDebugEnabled()) {
143            handle_0ArgsCall(Level.DEBUG, null, msg, null);
144        }
145    }
146
147    public void debug(String format, Object arg) {
148        if (isDebugEnabled()) {
149            handle_1ArgsCall(Level.DEBUG, null, format, arg);
150        }
151    }
152
153    public void debug(String format, Object arg1, Object arg2) {
154        if (isDebugEnabled()) {
155            handle2ArgsCall(Level.DEBUG, null, format, arg1, arg2);
156        }
157    }
158
159    public void debug(String format, Object... arguments) {
160        if (isDebugEnabled()) {
161            handleArgArrayCall(Level.DEBUG, null, format, arguments);
162        }
163    }
164
165    public void debug(String msg, Throwable t) {
166        if (isDebugEnabled()) {
167            handle_0ArgsCall(Level.DEBUG, null, msg, t);
168        }
169    }
170
171    public void debug(Marker marker, String msg) {
172        if (isDebugEnabled(marker)) {
173            handle_0ArgsCall(Level.DEBUG, marker, msg, null);
174        }
175    }
176
177    public void debug(Marker marker, String format, Object arg) {
178        if (isDebugEnabled(marker)) {
179            handle_1ArgsCall(Level.DEBUG, marker, format, arg);
180        }
181    }
182
183    public void debug(Marker marker, String format, Object arg1, Object arg2) {
184        if (isDebugEnabled(marker)) {
185            handle2ArgsCall(Level.DEBUG, marker, format, arg1, arg2);
186        }
187    }
188
189    public void debug(Marker marker, String format, Object... arguments) {
190        if (isDebugEnabled(marker)) {
191            handleArgArrayCall(Level.DEBUG, marker, format, arguments);
192        }
193    }
194
195    public void debug(Marker marker, String msg, Throwable t) {
196        if (isDebugEnabled(marker)) {
197            handle_0ArgsCall(Level.DEBUG, marker, msg, t);
198        }
199    }
200
201    public void info(String msg) {
202        if (isInfoEnabled()) {
203            handle_0ArgsCall(Level.INFO, null, msg, null);
204        }
205    }
206
207    public void info(String format, Object arg) {
208        if (isInfoEnabled()) {
209            handle_1ArgsCall(Level.INFO, null, format, arg);
210        }
211    }
212
213    public void info(String format, Object arg1, Object arg2) {
214        if (isInfoEnabled()) {
215            handle2ArgsCall(Level.INFO, null, format, arg1, arg2);
216        }
217    }
218
219    public void info(String format, Object... arguments) {
220        if (isInfoEnabled()) {
221            handleArgArrayCall(Level.INFO, null, format, arguments);
222        }
223    }
224
225    public void info(String msg, Throwable t) {
226        if (isInfoEnabled()) {
227            handle_0ArgsCall(Level.INFO, null, msg, t);
228        }
229    }
230
231    public void info(Marker marker, String msg) {
232        if (isInfoEnabled(marker)) {
233            handle_0ArgsCall(Level.INFO, marker, msg, null);
234        }
235    }
236
237    public void info(Marker marker, String format, Object arg) {
238        if (isInfoEnabled(marker)) {
239            handle_1ArgsCall(Level.INFO, marker, format, arg);
240        }
241    }
242
243    public void info(Marker marker, String format, Object arg1, Object arg2) {
244        if (isInfoEnabled(marker)) {
245            handle2ArgsCall(Level.INFO, marker, format, arg1, arg2);
246        }
247    }
248
249    public void info(Marker marker, String format, Object... arguments) {
250        if (isInfoEnabled(marker)) {
251            handleArgArrayCall(Level.INFO, marker, format, arguments);
252        }
253    }
254
255    public void info(Marker marker, String msg, Throwable t) {
256        if (isInfoEnabled(marker)) {
257            handle_0ArgsCall(Level.INFO, marker, msg, t);
258        }
259    }
260
261    public void warn(String msg) {
262        if (isWarnEnabled()) {
263            handle_0ArgsCall(Level.WARN, null, msg, null);
264        }
265    }
266
267    public void warn(String format, Object arg) {
268        if (isWarnEnabled()) {
269            handle_1ArgsCall(Level.WARN, null, format, arg);
270        }
271    }
272
273    public void warn(String format, Object arg1, Object arg2) {
274        if (isWarnEnabled()) {
275            handle2ArgsCall(Level.WARN, null, format, arg1, arg2);
276        }
277    }
278
279    public void warn(String format, Object... arguments) {
280        if (isWarnEnabled()) {
281            handleArgArrayCall(Level.WARN, null, format, arguments);
282        }
283    }
284
285    public void warn(String msg, Throwable t) {
286        if (isWarnEnabled()) {
287            handle_0ArgsCall(Level.WARN, null, msg, t);
288        }
289    }
290
291    public void warn(Marker marker, String msg) {
292        if (isWarnEnabled(marker)) {
293            handle_0ArgsCall(Level.WARN, marker, msg, null);
294        }
295    }
296
297    public void warn(Marker marker, String format, Object arg) {
298        if (isWarnEnabled(marker)) {
299            handle_1ArgsCall(Level.WARN, marker, format, arg);
300        }
301    }
302
303    public void warn(Marker marker, String format, Object arg1, Object arg2) {
304        if (isWarnEnabled(marker)) {
305            handle2ArgsCall(Level.WARN, marker, format, arg1, arg2);
306        }
307    }
308
309    public void warn(Marker marker, String format, Object... arguments) {
310        if (isWarnEnabled(marker)) {
311            handleArgArrayCall(Level.WARN, marker, format, arguments);
312        }
313    }
314
315    public void warn(Marker marker, String msg, Throwable t) {
316        if (isWarnEnabled(marker)) {
317            handle_0ArgsCall(Level.WARN, marker, msg, t);
318        }
319    }
320
321    public void error(String msg) {
322        if (isErrorEnabled()) {
323            handle_0ArgsCall(Level.ERROR, null, msg, null);
324        }
325    }
326
327    public void error(String format, Object arg) {
328        if (isErrorEnabled()) {
329            handle_1ArgsCall(Level.ERROR, null, format, arg);
330        }
331    }
332
333    public void error(String format, Object arg1, Object arg2) {
334        if (isErrorEnabled()) {
335            handle2ArgsCall(Level.ERROR, null, format, arg1, arg2);
336        }
337    }
338
339    public void error(String format, Object... arguments) {
340        if (isErrorEnabled()) {
341            handleArgArrayCall(Level.ERROR, null, format, arguments);
342        }
343    }
344
345    public void error(String msg, Throwable t) {
346        if (isErrorEnabled()) {
347            handle_0ArgsCall(Level.ERROR, null, msg, t);
348        }
349    }
350
351    public void error(Marker marker, String msg) {
352        if (isErrorEnabled(marker)) {
353            handle_0ArgsCall(Level.ERROR, marker, msg, null);
354        }
355    }
356
357    public void error(Marker marker, String format, Object arg) {
358        if (isErrorEnabled(marker)) {
359            handle_1ArgsCall(Level.ERROR, marker, format, arg);
360        }
361    }
362
363    public void error(Marker marker, String format, Object arg1, Object arg2) {
364        if (isErrorEnabled(marker)) {
365            handle2ArgsCall(Level.ERROR, marker, format, arg1, arg2);
366        }
367    }
368
369    public void error(Marker marker, String format, Object... arguments) {
370        if (isErrorEnabled(marker)) {
371            handleArgArrayCall(Level.ERROR, marker, format, arguments);
372        }
373    }
374
375    public void error(Marker marker, String msg, Throwable t) {
376        if (isErrorEnabled(marker)) {
377            handle_0ArgsCall(Level.ERROR, marker, msg, t);
378        }
379    }
380
381    private void handle_0ArgsCall(Level level, Marker marker, String msg, Throwable t) {
382        handleNormalizedLoggingCall(level, marker, msg, null, t);
383    }
384
385    private void handle_1ArgsCall(Level level, Marker marker, String msg, Object arg1) {
386        handleNormalizedLoggingCall(level, marker, msg, new Object[] { arg1 }, null);
387    }
388
389    private void handle2ArgsCall(Level level, Marker marker, String msg, Object arg1, Object arg2) {
390        if (arg2 instanceof Throwable) {
391            handleNormalizedLoggingCall(level, marker, msg, new Object[] { arg1 }, (Throwable) arg2);
392        } else {
393            handleNormalizedLoggingCall(level, marker, msg, new Object[] { arg1, arg2 }, null);
394        }
395    }
396
397    private void handleArgArrayCall(Level level, Marker marker, String msg, Object[] args) {
398        Throwable throwableCandidate = MessageFormatter.getThrowableCandidate(args);
399        if (throwableCandidate != null) {
400            Object[] trimmedCopy = MessageFormatter.trimmedCopy(args);
401            handleNormalizedLoggingCall(level, marker, msg, trimmedCopy, throwableCandidate);
402        } else {
403            handleNormalizedLoggingCall(level, marker, msg, args, null);
404        }
405    }
406
407    abstract protected String getFullyQualifiedCallerName();
408
409    /**
410     * Given various arguments passed as parameters, perform actual logging.
411     * 
412     * <p>This method assumes that the separation of the args array into actual
413     * objects and a throwable has been already operated.
414     * 
415     * @param level the SLF4J level for this event
416     * @param marker  The marker to be used for this event, may be null.
417     * @param messagePattern The message pattern which will be parsed and formatted
418     * @param arguments  the array of arguments to be formatted, may be null
419     * @param throwable  The exception whose stack trace should be logged, may be null
420     */
421    abstract protected void handleNormalizedLoggingCall(Level level, Marker marker, String messagePattern, Object[] arguments, Throwable throwable);
422
423}