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 }