1 /*
2 * Copyright (c) 2004-2005 SLF4J.ORG
3 * Copyright (c) 2004-2005 QOS.ch
4 *
5 * All rights reserved.
6 *
7 * Permission is hereby granted, free of charge, to any person obtaining
8 * a copy of this software and associated documentation files (the
9 * "Software"), to deal in the Software without restriction, including
10 * without limitation the rights to use, copy, modify, merge, publish,
11 * distribute, and/or sell copies of the Software, and to permit persons
12 * to whom the Software is furnished to do so, provided that the above
13 * copyright notice(s) and this permission notice appear in all copies of
14 * the Software and that both the above copyright notice(s) and this
15 * permission notice appear in supporting documentation.
16 *
17 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
18 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
19 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT
20 * OF THIRD PARTY RIGHTS. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
21 * HOLDERS INCLUDED IN THIS NOTICE BE LIABLE FOR ANY CLAIM, OR ANY
22 * SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER
23 * RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF
24 * CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
25 * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
26 *
27 * Except as contained in this notice, the name of a copyright holder
28 * shall not be used in advertising or otherwise to promote the sale, use
29 * or other dealings in this Software without prior written authorization
30 * of the copyright holder.
31 */
32
33
34 package org.slf4j.impl;
35
36 import it.imolinfo.jbi4ejb.jbi.Messages;
37
38 import java.text.MessageFormat;
39
40 import org.apache.log4j.Level;
41 import org.apache.log4j.Logger;
42 import org.slf4j.Marker;
43 import org.slf4j.helpers.MarkerIgnoringBase;
44 import org.slf4j.spi.LocationAwareLogger;
45
46 /**
47 * A wrapper over <code>org.apache.log4j.Logger</code> in conformance with the
48 * <code>org.slf4j.Logger</code> interface. Note that the logging levels
49 * mentioned in this class refer to those defined in the <a
50 * href="http://logging.apache.org/log4j/docs/api/org/apache/log4j/Level.html">
51 * <code>org.apache.log4j.Level</code></a> class.
52 * <p>
53 * This adapter is capable to translate (I18N) messages logged with level >=
54 * <i>INFO</i>, while <i>DEBUG</i> messages are leaved as they are.
55 * <p>
56 *
57 * @author Ceki Gülcü
58 * @author <a href="mailto:acannone@imolinfo.it">Amedeo Cannone</a>
59 * @author <a href="mailto:mcimatti@imolinfo.it">Marco Cimatti</a>
60 */
61 final class Log4jLoggerAdapter extends MarkerIgnoringBase
62 implements LocationAwareLogger, it.imolinfo.jbi4ejb.Logger {
63
64 /**
65 * Following the pattern discussed in pages 162 through 168 of "The
66 * complete log4j manual".
67 */
68 private static final String FQCN = Log4jLoggerAdapter.class.getName();
69
70 /**
71 * The Log4j logger adapted by this instance.
72 */
73 private final Logger logger;
74
75 /**
76 * The optional <code>Messages</code> available to apply I18N to logged
77 * messages.
78 */
79 private final Messages messages;
80
81 /**
82 * Creates a new adapter for the specificed Log4j logger.
83 *
84 * @param logger the Log4j logger.
85 * @param messages the optional <code>Messages</code>
86 * instance, responsible to apply I18N to
87 * messages logged by <code>logger</code>. It
88 * may be <code>null</code>, so there isn't
89 * I18N on logged messages.
90 * @throws NullPointerException if <code>logger</code> is
91 * <code>null</code>.
92 */
93 Log4jLoggerAdapter(final Logger logger, final Messages messages) {
94 if (logger == null) {
95 throw new NullPointerException("Log4j logger null");
96 }
97
98 this.logger = logger;
99 this.messages = messages;
100 }
101
102 /**
103 * Indicates if this <code>Logger</code> is applying internationalization
104 * to logged messages.
105 *
106 * @return <code>true</code> if and only if this instance is applying I18N
107 * to logged messages.
108 */
109 private boolean isI18N() {
110 return messages != null;
111 }
112
113 /**
114 * Formats the specified message, applying I18N if it is available for this
115 * logger.
116 *
117 * @param format the format string.
118 * @param args the optional arguments.
119 * @return the formatted message, eventually internationalized.
120 */
121 private String formatMessage(final String format, final Object ... args) {
122 String msg;
123
124 if (isI18N()) {
125 if (args.length == 0) {
126 msg = messages.getString(format);
127 } else {
128 msg = messages.getString(format, args);
129 }
130 } else {
131 if (args.length == 0) {
132 msg = format;
133 } else {
134 try {
135 msg = MessageFormat.format(format, args);
136 } catch (IllegalArgumentException e) {
137 msg = format;
138 }
139 }
140 }
141 return msg;
142 }
143
144 /**
145 * Gets the name of this <code>Logger</code>.
146 *
147 * @return the name of this <code>Logger</code> instance.
148 */
149 public String getName() {
150 return logger.getName();
151 }
152
153 /**
154 * Is this logger instance enabled for the DEBUG level?
155 *
156 * @return <code>true</code> if and only if this
157 * <code>org.slf4j.Logger</code> is enabled for level DEBUG.
158 */
159 public boolean isDebugEnabled() {
160 return logger.isDebugEnabled();
161 }
162
163 /**
164 * Log a message object at level DEBUG.
165 *
166 * @param msg the message string to be logged.
167 */
168 public void debug(final String msg) {
169 logger.log(FQCN, Level.DEBUG, msg, null);
170 }
171
172 /**
173 * Log a message at level DEBUG according to the specified format and
174 * argument.
175 * <p>
176 * This form avoids superfluous object creation when the logger is disabled
177 * for level DEBUG.
178 * </p>
179 *
180 * @param format the format string.
181 * @param arg the argument.
182 */
183 public void debug(final String format, final Object arg) {
184 if (isDebugEnabled()) {
185
186 // Debug level -> no I18N, argument formatting only
187 String msg = MessageFormat.format(format, arg);
188
189 logger.log(FQCN, Level.DEBUG, msg, null);
190 }
191 }
192
193 /**
194 * Log a message at level DEBUG according to the specified format and
195 * arguments.
196 * <p>
197 * This form avoids superfluous object creation when the logger is disabled
198 * for the DEBUG level.
199 * </p>
200 *
201 * @param format the format string.
202 * @param arg1 the first argument
203 * @param arg2 the second argument.
204 */
205 public void debug(
206 final String format, final Object arg1, final Object arg2) {
207 if (isDebugEnabled()) {
208
209 // Debug level -> no I18N, argument formatting only
210 String msg = MessageFormat.format(format, arg1, arg2);
211
212 logger.log(FQCN, Level.DEBUG, msg, null);
213 }
214 }
215
216 /**
217 * Log a message at level DEBUG according to the specified format and
218 * arguments.
219 * <p>
220 * This form avoids superfluous object creation when the logger is disabled
221 * for the DEBUG level.
222 * </p>
223 *
224 * @param format the format string.
225 * @param args the arguments.
226 */
227 public void debug(final String format, final Object[] args) {
228 if (isDebugEnabled()) {
229
230 // Debug level -> no I18N, argument formatting only
231 String msg = MessageFormat.format(format, args);
232
233 logger.log(FQCN, Level.DEBUG, msg, null);
234 }
235 }
236
237 /**
238 * Log an exception (throwable) at level DEBUG with an accompanying message.
239 *
240 * @param msg the message accompanying the exception.
241 * @param t the exception (throwable) to log.
242 */
243 public void debug(final String msg, final Throwable t) {
244
245 // Debug level -> no I18N
246 logger.log(FQCN, Level.DEBUG, msg, t);
247 }
248
249 /**
250 * Is this logger instance enabled for the INFO level?
251 *
252 * @return <code>true</code> if and only if this
253 * <code>org.slf4j.Logger</code> is enabled for the INFO level.
254 */
255 public boolean isInfoEnabled() {
256 return logger.isInfoEnabled();
257 }
258
259 /**
260 * Log a message object at the INFO level.
261 *
262 * @param msg the message string to be logged.
263 */
264 public void info(final String msg) {
265 if (isInfoEnabled()) {
266 logger.log(FQCN, Level.INFO, formatMessage(msg), null);
267 }
268 }
269
270 /**
271 * Log a message at level INFO according to the specified format and
272 * argument.
273 * <p>
274 * This form avoids superfluous object creation when the logger is disabled
275 * for the INFO level.
276 * </p>
277 *
278 * @param format the format string.
279 * @param arg the argument.
280 */
281 public void info(final String format, final Object arg) {
282 if (isInfoEnabled()) {
283 logger.log(FQCN, Level.INFO, formatMessage(format, arg), null);
284 }
285 }
286
287 /**
288 * Log a message at the INFO level according to the specified format and
289 * arguments.
290 * <p>
291 * This form avoids superfluous object creation when the logger is disabled
292 * for the INFO level.
293 * </p>
294 *
295 * @param format the format string.
296 * @param arg1 the first argument.
297 * @param arg2 the second argument.
298 */
299 public void info(
300 final String format, final Object arg1, final Object arg2) {
301 if (isInfoEnabled()) {
302 String msg = formatMessage(format, arg1, arg2);
303
304 logger.log(FQCN, Level.INFO, msg, null);
305 }
306 }
307
308 /**
309 * Log a message at level INFO according to the specified format and
310 * arguments.
311 * <p>
312 * This form avoids superfluous object creation when the logger is disabled
313 * for the INFO level.
314 * </p>
315 *
316 * @param format the format string.
317 * @param args the arguments.
318 */
319 public void info(final String format, final Object[] args) {
320 if (isInfoEnabled()) {
321 logger.log(FQCN, Level.INFO, formatMessage(format, args), null);
322 }
323 }
324
325 /**
326 * Log an exception (throwable) at the INFO level with an accompanying
327 * message.
328 *
329 * @param msg the message accompanying the exception
330 * @param t the exception (throwable) to log.
331 */
332 public void info(final String msg, final Throwable t) {
333 if (isInfoEnabled()) {
334 logger.log(FQCN, Level.INFO, formatMessage(msg), t);
335 }
336 }
337
338 /**
339 * Is this logger instance enabled for the WARN level?
340 *
341 * @return <code>true</code> if and only if this
342 * <code>org.slf4j.Logger</code> is enabled for the WARN level.
343 */
344 public boolean isWarnEnabled() {
345 return logger.isEnabledFor(Level.WARN);
346 }
347
348 /**
349 * Log a message object at the WARN level.
350 *
351 * @param msg the message string to be logged.
352 */
353 public void warn(final String msg) {
354 if (isWarnEnabled()) {
355 logger.log(FQCN, Level.WARN, formatMessage(msg), null);
356 }
357 }
358
359 /**
360 * Log a message at the WARN level according to the specified format and
361 * argument.
362 * <p>
363 * This form avoids superfluous object creation when the logger is disabled
364 * for the WARN level.
365 * </p>
366 *
367 * @param format the format string.
368 * @param arg the argument.
369 */
370 public void warn(final String format, final Object arg) {
371 if (isWarnEnabled()) {
372 logger.log(FQCN, Level.WARN, formatMessage(format, arg), null);
373 }
374 }
375
376 /**
377 * Log a message at the WARN level according to the specified format and
378 * arguments.
379 * <p>
380 * This form avoids superfluous object creation when the logger is disabled
381 * for the WARN level.
382 * </p>
383 *
384 * @param format the format string.
385 * @param arg1 the first argument.
386 * @param arg2 the second argument.
387 */
388 public void warn(
389 final String format, final Object arg1, final Object arg2) {
390 if (isWarnEnabled()) {
391 String msg = formatMessage(format, arg1, arg2);
392
393 logger.log(FQCN, Level.WARN, msg, null);
394 }
395 }
396
397 /**
398 * Log a message at level WARN according to the specified format and
399 * arguments.
400 * <p>
401 * This form avoids superfluous object creation when the logger is disabled
402 * for the WARN level.
403 * </p>
404 *
405 * @param format the format string.
406 * @param args the arguments.
407 */
408 public void warn(final String format, final Object[] args) {
409 if (isWarnEnabled()) {
410 logger.log(FQCN, Level.WARN, formatMessage(format, args), null);
411 }
412 }
413
414 /**
415 * Log an exception (throwable) at the WARN level with an accompanying
416 * message.
417 *
418 * @param msg the message accompanying the exception.
419 * @param t the exception (throwable) to log.
420 */
421 public void warn(final String msg, final Throwable t) {
422 if (isWarnEnabled()) {
423 logger.log(FQCN, Level.WARN, formatMessage(msg), t);
424 }
425 }
426
427 /**
428 * Is this logger instance enabled for level ERROR?
429 *
430 * @return <code>true</code> if and only if this
431 * <code>org.slf4j.Logger</code> is enabled for level ERROR.
432 */
433 public boolean isErrorEnabled() {
434 return logger.isEnabledFor(Level.ERROR);
435 }
436
437 /**
438 * Log a message object at the ERROR level.
439 *
440 * @param msg the message string to be logged.
441 */
442 public void error(final String msg) {
443 if (isErrorEnabled()) {
444 logger.log(FQCN, Level.ERROR, formatMessage(msg), null);
445 }
446 }
447
448 /**
449 * Log a message at the ERROR level according to the specified format
450 * and argument.
451 * <p>
452 * This form avoids superfluous object creation when the logger is disabled
453 * for the ERROR level.
454 * </p>
455 *
456 * @param format the format string.
457 * @param arg the argument.
458 */
459 public void error(final String format, final Object arg) {
460 if (isErrorEnabled()) {
461 String msg = formatMessage(format, arg);
462
463 logger.log(FQCN, Level.ERROR, msg, null);
464 }
465 }
466
467 /**
468 * Log a message at the ERROR level according to the specified format and
469 * arguments.
470 * <p>
471 * This form avoids superfluous object creation when the logger is disabled
472 * for the ERROR level.
473 * </p>
474 *
475 * @param format the format string.
476 * @param arg1 the first argument.
477 * @param arg2 the second argument.
478 */
479 public void error(
480 final String format, final Object arg1, final Object arg2) {
481 if (isErrorEnabled()) {
482 String msg = formatMessage(format, arg1, arg2);
483
484 logger.log(FQCN, Level.ERROR, msg, null);
485 }
486 }
487
488 /**
489 * Log a message at level ERROR according to the specified format and
490 * arguments.
491 * <p>
492 * This form avoids superfluous object creation when the logger is disabled
493 * for the ERROR level.
494 * </p>
495 *
496 * @param format the format string.
497 * @param args the arguments.
498 */
499 public void error(final String format, final Object[] args) {
500 if (isErrorEnabled()) {
501 logger.log(FQCN, Level.ERROR, formatMessage(format, args), null);
502 }
503 }
504
505 /**
506 * Log an exception (throwable) at the ERROR level with an accompanying
507 * message.
508 *
509 * @param msg the message accompanying the exception.
510 * @param t the exception (throwable) to log.
511 */
512 public void error(final String msg, final Throwable t) {
513 if (isErrorEnabled()) {
514 logger.log(FQCN, Level.ERROR, formatMessage(msg), t);
515 }
516 }
517
518 /**
519 * Printing method which support for location information.
520 *
521 * @param marker the marker.
522 * @param callerFQCN the fully qualified class name of the <b>caller</b>.
523 * @param level the level.
524 * @param msg the message.
525 * @param t the exception (throwable).
526 */
527 public void log(final Marker marker, final String callerFQCN,
528 final int level, final String msg, final Throwable t) {
529 Level log4jLevel;
530
531 switch (level) {
532 case LocationAwareLogger.DEBUG_INT:
533 log4jLevel = Level.DEBUG;
534 break;
535
536 case LocationAwareLogger.INFO_INT:
537 log4jLevel = Level.INFO;
538 break;
539
540 case LocationAwareLogger.WARN_INT:
541 log4jLevel = Level.WARN;
542 break;
543
544 case LocationAwareLogger.ERROR_INT:
545 log4jLevel = Level.ERROR;
546 break;
547
548 default:
549 throw new IllegalArgumentException(
550 "Level number " + level + " is not recognized.");
551 }
552 logger.log(callerFQCN, log4jLevel, msg, t);
553 }
554
555
556 // New methods added to those provided by SLF4J: we want to log a formatted
557 // string and a Throwable
558
559
560 /**
561 * Log an exception (throwable) at level DEBUG with an accompanying message
562 * according to the specified format and arguments.
563 * <p>
564 * This form avoids superfluous object creation when the logger is disabled
565 * for the DEBUG level.
566 * </p>
567 *
568 * @param format the format string.
569 * @param args the arguments.
570 * @param t the exception (throwable) to log.
571 */
572 public void debug(
573 final String format, final Object[] args, final Throwable t) {
574 if (isDebugEnabled()) {
575
576 // Debug level -> no I18N, argument formatting only
577 String msg = MessageFormat.format(format, args);
578
579 logger.log(FQCN, Level.DEBUG, msg, null);
580 }
581 }
582
583 /**
584 * Log an exception (throwable) at level INFO with an accompanying message
585 * according to the specified format and arguments.
586 * <p>
587 * This form avoids superfluous object creation when the logger is disabled
588 * for the INFO level.
589 * </p>
590 *
591 * @param format the format string.
592 * @param args the arguments.
593 * @param t the exception (throwable) to log.
594 */
595 public void info(
596 final String format, final Object[] args, final Throwable t) {
597 if (isInfoEnabled()) {
598 logger.log(FQCN, Level.INFO, formatMessage(format, args), t);
599 }
600 }
601
602 /**
603 * Log an exception (throwable) at level WARN with an accompanying message
604 * according to the specified format and arguments.
605 * <p>
606 * This form avoids superfluous object creation when the logger is disabled
607 * for the WARN level.
608 * </p>
609 *
610 * @param format the format string.
611 * @param args the arguments.
612 * @param t the exception (throwable) to log.
613 */
614 public void warn(
615 final String format, final Object[] args, final Throwable t) {
616 if (isWarnEnabled()) {
617 logger.log(FQCN, Level.WARN, formatMessage(format, args), t);
618 }
619 }
620
621 /**
622 * Log an exception (throwable) at level ERROR with an accompanying message
623 * according to the specified format and arguments.
624 * <p>
625 * This form avoids superfluous object creation when the logger is disabled
626 * for the ERROR level.
627 * </p>
628 *
629 * @param format the format string.
630 * @param args the arguments.
631 * @param t the exception (throwable) to log.
632 */
633 public void error(
634 final String format, final Object[] args, final Throwable t) {
635 if (isErrorEnabled()) {
636 logger.log(FQCN, Level.ERROR, formatMessage(format, args), t);
637 }
638 }
639 }