View Javadoc

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 it.imolinfo.jbi4corba.logger;
35  
36  import it.imolinfo.jbi4corba.jbi.Messages;
37  import java.text.MessageFormat;
38  import java.util.logging.Level;
39  import java.util.logging.LogRecord;
40  import java.util.logging.Logger;
41  
42  
43  //import org.slf4j.Marker;
44  //import org.slf4j.helpers.MarkerIgnoringBase;
45  //import org.slf4j.spi.LocationAwareLogger;
46  
47  /**
48   * A wrapper over {@link java.util.logging.Logger} in conformity with the
49   * {@link org.slf4j.Logger} interface. Note that the logging levels mentioned in
50   * this class refer to those defined in the <code>java.util.logging</code>
51   * package.
52   * <p>
53   *
54   * @author Ceki G&uuml;lc&uuml;
55   * @author Peter Royal
56   * @author <a href="mailto:acannone@imolinfo.it">Amedeo Cannone</a>
57   * @author <a href="mailto:mcimatti@imolinfo.it">Marco Cimatti</a>
58   */
59  final class JDK14LoggerAdapter  implements  it.imolinfo.jbi4corba.Logger {
60  
61      /**
62       * This class name.
63       */
64      private static final String SELF = JDK14LoggerAdapter.class.getName();
65  
66      /**
67       * The super-class name of this class.
68       */
69      //private static final String SUPER = MarkerIgnoringBase.class.getName();
70  
71      /**
72       * The logger adapted by this instance.
73       */
74      private final Logger logger;
75  
76      /**
77       * The optional <code>Messages</code> available to apply I18N to logged
78       * messages.
79       */
80      private final Messages messages;
81  
82      /**
83       * Creates a new adapter for the specificed logger.
84       *
85       * @param   logger                the logger.
86       * @param   messages              the optional <code>Messages</code>
87       *                                instance, responsible to apply I18N to
88       *                                messages logged by <code>logger</code>. It
89       *                                may be <code>null</code>, so there isn't
90       *                                I18N on logged messages.
91       */
92      JDK14LoggerAdapter(final Logger logger, final Messages messages) {
93          if (logger == null) {
94              throw new NullPointerException("Log4j logger null");
95          }
96  
97          this.logger   = logger;
98          this.messages = messages;
99      }
100 
101     /**
102      * Gets the name of this <code>Logger</code>.
103      *
104      * @return the name of this <code>Logger</code> instance.
105      */
106     public String getName() {
107         return logger.getName();
108     }
109 
110     /**
111      * Indicates if this <code>Logger</code> is applying internationalization
112      * to logged messages.
113      *
114      * @return  <code>true</code> if and only if this instance is applying I18N
115      *          to logged messages.
116      */
117     private boolean isI18N() {
118         return (messages != null);
119     }
120 
121     /**
122      * Formats the specified message, applying I18N if it is available for this
123      * logger.
124      *
125      * @param   format  the format string.
126      * @param   args    the optional arguments.
127      * @return  the formatted message, eventually internationalized.
128      */
129     private String formatMessage(final String format, final Object... args) {
130         String msg;
131 
132         if (isI18N()) {
133             if (args.length == 0) {
134                 msg = messages.getString(format);
135             } else {
136                 msg = messages.getString(format, args);
137             }
138         } else {
139             if (args.length == 0) {
140                 msg = format;
141             } else {
142                 try {
143                     msg = MessageFormat.format(format, args);
144                 } catch (IllegalArgumentException e) {
145                     msg = format;
146                 }
147             }
148         }
149         return msg;
150     }
151 
152     /**
153      * Is this logger instance enabled for the DEBUG level?
154      *
155      * @return  <code>true</code> if and only if this
156      *          <code>org.slf4j.Logger</code> is enabled for level DEBUG.
157      */
158     public boolean isDebugEnabled() {
159         return logger.isLoggable(Level.FINE);
160     }
161 
162     /**
163      * Log a message object at level DEBUG.
164      *
165      * @param  msg  the message string to be logged.
166      */
167     public void debug(final String msg) {
168         log(SELF, Level.FINE, msg, null);
169     }
170 
171     /**
172      * Log a message at level DEBUG according to the specified format and
173      * argument.
174      * <p>
175      * This form avoids superfluous object creation when the logger is disabled
176      * for level DEBUG.
177      * </p>
178      *
179      * @param  format  the format string.
180      * @param  arg     the argument.
181      */
182     public void debug(final String format, final Object arg) {
183         if (isDebugEnabled()) {
184             String msgStr = MessageFormat.format(format, arg);
185 
186             log(SELF, Level.FINE, msgStr, null);
187         }
188     }
189 
190     /**
191      * Log a message at level DEBUG according to the specified format and
192      * arguments.
193      * <p>
194      * This form avoids superfluous object creation when the logger is disabled
195      * for the DEBUG level.
196      * </p>
197      *
198      * @param  format  the format string.
199      * @param  arg1    the first argument
200      * @param  arg2    the second argument.
201      */
202     public void debug(
203             final String format, final Object arg1, final Object arg2) {
204         if (isDebugEnabled()) {
205             String msgStr = MessageFormat.format(format, arg1, arg2);
206 
207             log(SELF, Level.FINE, msgStr, null);
208         }
209     }
210 
211     /**
212      * Log a message at level DEBUG according to the specified format and
213      * arguments.
214      * <p>
215      * This form avoids superfluous object creation when the logger is disabled
216      * for the DEBUG level.
217      * </p>
218      *
219      * @param  format  the format string.
220      * @param  args    the arguments.
221      */
222     public void debug(final String format, final Object[] args) {
223         if (isDebugEnabled()) {
224             String msgStr = MessageFormat.format(format, args);
225 
226             log(SELF, Level.FINE, msgStr, null);
227         }
228     }
229 
230     /**
231      * Log an exception (throwable) at level DEBUG with an accompanying message.
232      *
233      * @param  msg  the message accompanying the exception.
234      * @param  t    the exception (throwable) to log.
235      */
236     public void debug(final String msg, final Throwable t) {
237         log(SELF, Level.FINE, msg, t);
238     }
239 
240     /**
241      * Is this logger instance enabled for the INFO level?
242      *
243      * @return  <code>true</code> if and only if this
244      *          <code>org.slf4j.Logger</code> is enabled for the INFO level.
245      */
246     public boolean isInfoEnabled() {
247         return logger.isLoggable(Level.INFO);
248     }
249 
250     /**
251      * Log a message object at the INFO level.
252      *
253      * @param  msg  the message string to be logged.
254      */
255     public void info(final String msg) {
256         if (isInfoEnabled()) {
257             log(SELF, Level.INFO, formatMessage(msg), null);
258         }
259     }
260 
261     /**
262      * Log a message at level INFO according to the specified format and
263      * argument.
264      * <p>
265      * This form avoids superfluous object creation when the logger is disabled
266      * for the INFO level.
267      * </p>
268      *
269      * @param  format  the format string.
270      * @param  arg     the argument.
271      */
272     public void info(final String format, final Object arg) {
273         if (isInfoEnabled()) {
274             log(SELF, Level.INFO, formatMessage(format, arg), null);
275         }
276     }
277 
278     /**
279      * Log a message at the INFO level according to the specified format and
280      * arguments.
281      * <p>
282      * This form avoids superfluous object creation when the logger is disabled
283      * for the INFO level.
284      * </p>
285      *
286      * @param  format  the format string.
287      * @param  arg1    the first argument.
288      * @param  arg2    the second argument.
289      */
290     public void info(
291             final String format, final Object arg1, final Object arg2) {
292         if (isInfoEnabled()) {
293             log(SELF, Level.INFO, formatMessage(format, arg1, arg2), null);
294         }
295     }
296 
297     /**
298      * Log a message at level INFO according to the specified format and
299      * arguments.
300      * <p>
301      * This form avoids superfluous object creation when the logger is disabled
302      * for the INFO level.
303      * </p>
304      *
305      * @param  format  the format string.
306      * @param  args    the arguments.
307      */
308     public void info(final String format, final Object[] args) {
309         if (isInfoEnabled()) {
310             log(SELF, Level.INFO, formatMessage(format, args), null);
311         }
312     }
313 
314     /**
315      * Log an exception (throwable) at the INFO level with an accompanying
316      * message.
317      *
318      * @param  msg  the message accompanying the exception
319      * @param  t    the exception (throwable) to log.
320      */
321     public void info(final String msg, final Throwable t) {
322         if (isInfoEnabled()) {
323             log(SELF, Level.INFO, formatMessage(msg), t);
324         }
325     }
326 
327     /**
328      * Is this logger instance enabled for the WARN level?
329      *
330      * @return  <code>true</code> if and only if this
331      *          <code>org.slf4j.Logger</code> is enabled for the WARN level.
332      */
333     public boolean isWarnEnabled() {
334         return logger.isLoggable(Level.WARNING);
335     }
336 
337     /**
338      * Log a message object at the WARN level.
339      *
340      * @param  msg  the message string to be logged.
341      */
342     public void warn(final String msg) {
343         if (isWarnEnabled()) {
344             log(SELF, Level.WARNING, formatMessage(msg), null);
345         }
346     }
347 
348     /**
349      * Log a message at the WARN level according to the specified format and
350      * argument.
351      * <p>
352      * This form avoids superfluous object creation when the logger is disabled
353      * for the WARN level.
354      * </p>
355      *
356      * @param  format  the format string.
357      * @param  arg     the argument.
358      */
359     public void warn(final String format, final Object arg) {
360         if (isWarnEnabled()) {
361             log(SELF, Level.WARNING, formatMessage(format, arg), null);
362         }
363     }
364 
365     /**
366      * Log a message at the WARN level according to the specified format and
367      * arguments.
368      * <p>
369      * This form avoids superfluous object creation when the logger is disabled
370      * for the WARN level.
371      * </p>
372      *
373      * @param  format  the format string.
374      * @param  arg1    the first argument.
375      * @param  arg2    the second argument.
376      */
377     public void warn(
378             final String format, final Object arg1, final Object arg2) {
379         if (isWarnEnabled()) {
380             log(SELF, Level.WARNING, formatMessage(format, arg1, arg2), null);
381         }
382     }
383 
384     /**
385      * Log a message at level WARN according to the specified format and
386      * arguments.
387      * <p>
388      * This form avoids superfluous object creation when the logger is disabled
389      * for the WARN level.
390      * </p>
391      *
392      * @param  format  the format string.
393      * @param  args    the arguments.
394      */
395     public void warn(final String format, final Object[] args) {
396         if (isWarnEnabled()) {
397             log(SELF, Level.WARNING, formatMessage(format, args), null);
398         }
399     }
400 
401     /**
402      * Log an exception (throwable) at the WARN level with an accompanying
403      * message.
404      *
405      * @param  msg  the message accompanying the exception.
406      * @param  t    the exception (throwable) to log.
407      */
408     public void warn(final String msg, final Throwable t) {
409         if (isWarnEnabled()) {
410             log(SELF, Level.WARNING, formatMessage(msg), t);
411         }
412     }
413 
414     /**
415      * Is this logger instance enabled for level ERROR?
416      *
417      * @return  <code>true</code> if and only if this
418      *          <code>org.slf4j.Logger</code> is enabled for level ERROR.
419      */
420     public boolean isErrorEnabled() {
421         return logger.isLoggable(Level.SEVERE);
422     }
423 
424     /**
425      * Log a message object at the ERROR level.
426      *
427      * @param  msg  the message string to be logged.
428      */
429     public void error(final String msg) {
430         if (isErrorEnabled()) {
431             log(SELF, Level.SEVERE, formatMessage(msg), null);
432         }
433     }
434 
435     /**
436      * Log a message at the ERROR level according to the specified format
437      * and argument.
438      * <p>
439      * This form avoids superfluous object creation when the logger is disabled
440      * for the ERROR level.
441      * </p>
442      *
443      * @param  format  the format string.
444      * @param  arg     the argument.
445      */
446     public void error(final String format, final Object arg) {
447         if (isErrorEnabled()) {
448             log(SELF, Level.SEVERE, formatMessage(format, arg), null);
449         }
450     }
451 
452     /**
453      * Log a message at the ERROR level according to the specified format and
454      * arguments.
455      * <p>
456      * This form avoids superfluous object creation when the logger is disabled
457      * for the ERROR level.
458      * </p>
459      *
460      * @param  format  the format string.
461      * @param  arg1    the first argument.
462      * @param  arg2    the second argument.
463      */
464     public void error(
465             final String format, final Object arg1, final Object arg2) {
466         if (isErrorEnabled()) {
467             log(SELF, Level.SEVERE, formatMessage(format, arg1, arg2), null);
468         }
469     }
470 
471     /**
472      * Log a message at level ERROR according to the specified format and
473      * arguments.
474      * <p>
475      * This form avoids superfluous object creation when the logger is disabled
476      * for the ERROR level.
477      * </p>
478      *
479      * @param  format  the format string.
480      * @param  args    the arguments.
481      */
482     public void error(final String format, final Object[] args) {
483         if (isErrorEnabled()) {
484             log(SELF, Level.SEVERE, formatMessage(format, args), null);
485         }
486     }
487 
488     /**
489      * Log an exception (throwable) at the ERROR level with an accompanying
490      * message.
491      *
492      * @param  msg  the message accompanying the exception.
493      * @param  t    the exception (throwable) to log.
494      */
495     public void error(final String msg, final Throwable t) {
496         if (isErrorEnabled()) {
497             log(SELF, Level.SEVERE, formatMessage(msg), t);
498         }
499     }
500 
501     /**
502      * Log the message at the specified level with the specified throwable if
503      * any. This method creates a <code>java.util.logging.LogRecord</code> and
504      * fills in caller date before calling this instance's JDK14 logger.
505      * <p>
506      * See bug report #13 for more details.
507      *
508      * @param  callerFQCN  the fully qualified class name of the <b>caller</b>.
509      * @param  level       the level.
510      * @param  msg         the message.
511      * @param  t           the exception (throwable).
512      */
513     private void log(final String callerFQCN, final Level level,
514                      final String msg, final Throwable t) {
515 
516         // Millis and thread are filled by the constructor
517         LogRecord record = new LogRecord(level, msg);
518 
519         record.setLoggerName(getName());
520         record.setThrown(t);
521         fillCallerData(callerFQCN, record);
522         logger.log(record);
523     }
524 
525     /**
526      * Fill in caller data if possible.
527      *
528      * @param  callerFQCN  the fully qualified class name of the <b>caller</b>.
529      * @param  record      the record to update.
530      */
531     private static void fillCallerData(final String callerFQCN,
532                                        final LogRecord record) {
533         StackTraceElement[] steArray = new Throwable().getStackTrace();
534         int length = steArray.length;
535         int selfIndex = -1;
536 
537         for (int i = 0; i < length; i++) {
538             final String className = steArray[i].getClassName();
539 
540             if (className.equals(callerFQCN) ) {
541                 selfIndex = i;
542                 break;
543             }
544         }
545         for (int i = selfIndex + 1; i < length; i++) {
546             final String className = steArray[i].getClassName();
547 
548             if (!(className.equals(callerFQCN) )) {
549                 StackTraceElement ste = steArray[i];
550 
551                 /*
552                  * Setting the class name has the side effect of setting the
553                  * needToInferCaller variable to false
554                  */
555                 record.setSourceClassName(ste.getClassName());
556                 record.setSourceMethodName(ste.getMethodName());
557                 break;
558             }
559         }
560     }
561 
562    
563 
564 
565     // New methods added to those provided by SLF4J: we want to log a formatted
566     // string and a Throwable
567 
568 
569     /**
570      * Log an exception (throwable) at level DEBUG with an accompanying message
571      * according to the specified format and arguments.
572      * <p>
573      * This form avoids superfluous object creation when the logger is disabled
574      * for the DEBUG level.
575      * </p>
576      *
577      * @param  format  the format string.
578      * @param  args    the arguments.
579      * @param  t       the exception (throwable) to log.
580      */
581     public void debug(
582             final String format, final Object[] args, final Throwable t) {
583         if (isDebugEnabled()) {
584             String msgStr = MessageFormat.format(format, args);
585 
586             log(SELF, Level.FINE, msgStr, t);
587         }
588     }
589 
590     /**
591      * Log an exception (throwable) at level INFO with an accompanying message
592      * according to the specified format and arguments.
593      * <p>
594      * This form avoids superfluous object creation when the logger is disabled
595      * for the INFO level.
596      * </p>
597      *
598      * @param  format  the format string.
599      * @param  args    the arguments.
600      * @param  t       the exception (throwable) to log.
601      */
602     public void info(
603             final String format, final Object[] args, final Throwable t) {
604         if (isInfoEnabled()) {
605             log(SELF, Level.INFO, formatMessage(format, args), t);
606         }
607     }
608 
609     /**
610      * Log an exception (throwable) at level WARN with an accompanying message
611      * according to the specified format and arguments.
612      * <p>
613      * This form avoids superfluous object creation when the logger is disabled
614      * for the WARN level.
615      * </p>
616      *
617      * @param  format  the format string.
618      * @param  args    the arguments.
619      * @param  t       the exception (throwable) to log.
620      */
621     public void warn(
622             final String format, final Object[] args, final Throwable t) {
623         if (isWarnEnabled()) {
624             log(SELF, Level.WARNING, formatMessage(format, args), t);
625         }
626     }
627 
628     /**
629      * Log an exception (throwable) at level ERROR with an accompanying message
630      * according to the specified format and arguments.
631      * <p>
632      * This form avoids superfluous object creation when the logger is disabled
633      * for the ERROR level.
634      * </p>
635      *
636      * @param  format  the format string.
637      * @param  args    the arguments.
638      * @param  t       the exception (throwable) to log.
639      */
640     public void error(
641             final String format, final Object[] args, final Throwable t) {
642         if (isErrorEnabled()) {
643             log(SELF, Level.SEVERE, formatMessage(format, args), t);
644         }
645     }
646 
647 }