View Javadoc

1   /*
2    * Licensed to the Apache Software Foundation (ASF) under one
3    * or more contributor license agreements.  See the NOTICE file
4    * distributed with this work for additional information
5    * regarding copyright ownership.  The ASF licenses this file
6    * to you under the Apache License, Version 2.0 (the
7    * "License"); you may not use this file except in compliance
8    * with the License.  You may obtain a copy of the License at
9    *
10   *   http://www.apache.org/licenses/LICENSE-2.0
11   *
12   * Unless required by applicable law or agreed to in writing,
13   * software distributed under the License is distributed on an
14   * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15   * KIND, either express or implied.  See the License for the
16   * specific language governing permissions and limitations
17   * under the License.
18   */
19  package org.apache.myfaces.logging;
20  
21  import java.text.MessageFormat;
22  import java.util.Locale;
23  import java.util.MissingResourceException;
24  import java.util.ResourceBundle;
25  import java.util.logging.Handler;
26  import java.util.logging.Level;
27  import java.util.logging.LogRecord;
28  import java.util.logging.Logger;
29  
30  
31  /**
32   * MyfacesLogger wraps JDK 1.4 logging to provided a large number of 
33   * extra convenience methods.  MyfacesLoggers are created off of
34   * Packages or Classes (not arbitrary names) to force
35   * proper logging hierarchies.
36   * 
37   * Has predefined Logger for javax.faces related packages, like
38   * {@link MyfacesLogger#APPLICATION_LOGGER} for javax.faces.application and related
39   * 
40   * Original code copied from TrinidadLogger
41   * 
42   */
43  public class MyfacesLogger
44  {
45  
46      private static final String LOGGER_NAME_PREFIX = "org.apache.myfaces.";
47  
48      /** for javax.faces.application and related  */
49      public static final MyfacesLogger APPLICATION_LOGGER
50              = MyfacesLogger.createMyfacesLogger(LOGGER_NAME_PREFIX + "application");
51  
52      /** for javax.faces.component and related  */
53      public static final MyfacesLogger COMPONENT_LOGGER
54              = MyfacesLogger.createMyfacesLogger(LOGGER_NAME_PREFIX + "component");
55  
56      /** for javax.faces.component.html and related  */
57      public static final MyfacesLogger COMPONENT_HTML_LOGGER
58              = MyfacesLogger.createMyfacesLogger(LOGGER_NAME_PREFIX + "component.html");
59  
60      /** for javax.faces.component.behavior and related  */
61      public static final MyfacesLogger COMPONENT_BEHAVIOR_LOGGER
62              = MyfacesLogger.createMyfacesLogger(LOGGER_NAME_PREFIX + "component.behavior");
63  
64      /** for javax.faces.component.visit and related  */
65      public static final MyfacesLogger COMPONENT_VISIT_LOGGER
66              = MyfacesLogger.createMyfacesLogger(LOGGER_NAME_PREFIX + "component.visit");
67  
68      /** for javax.faces.context and related  */
69      public static final MyfacesLogger CONTEXT_LOGGER
70              = MyfacesLogger.createMyfacesLogger(LOGGER_NAME_PREFIX + "context");
71  
72      /** for javax.faces.convert and related  */
73      public static final MyfacesLogger CONVERT_LOGGER
74              = MyfacesLogger.createMyfacesLogger(LOGGER_NAME_PREFIX + "convert");
75  
76      /** for javax.faces.event and related  */
77      public static final MyfacesLogger EVENT_LOGGER
78              = MyfacesLogger.createMyfacesLogger(LOGGER_NAME_PREFIX + "event");
79  
80      /** for javax.faces.lifecycle and related  */
81      public static final MyfacesLogger LIFECYCLE_LOGGER
82              = MyfacesLogger.createMyfacesLogger(LOGGER_NAME_PREFIX + "lifecycle");
83  
84      /** for javax.faces.model and related  */
85      public static final MyfacesLogger MODEL_LOGGER
86              = MyfacesLogger.createMyfacesLogger(LOGGER_NAME_PREFIX + "model");
87  
88      /** for javax.faces.render and related  */
89      public static final MyfacesLogger RENDER_LOGGER
90              = MyfacesLogger.createMyfacesLogger(LOGGER_NAME_PREFIX + "render");
91  
92      /** for javax.faces.validator and related  */
93      public static final MyfacesLogger VALIDATOR_LOGGER
94              = MyfacesLogger.createMyfacesLogger(LOGGER_NAME_PREFIX + "validator");
95  
96      /** for javax.faces.view and related  */
97      public static final MyfacesLogger VIEW_LOGGER
98              = MyfacesLogger.createMyfacesLogger(LOGGER_NAME_PREFIX + "view");
99  
100     /** for javax.faces.view.facelets and related  */
101     public static final MyfacesLogger VIEW_FACELETS_LOGGER
102             = MyfacesLogger.createMyfacesLogger(LOGGER_NAME_PREFIX + "view.facelets");
103 
104     /** for {@link javax.faces.application.Resource} and related  (does not have own javax.faces. package) */
105     public static final MyfacesLogger RESOURCE_LOGGER
106             = MyfacesLogger.createMyfacesLogger(LOGGER_NAME_PREFIX + "resource");
107 
108     /** for myfaces config */ 
109     public static final MyfacesLogger CONFIG_LOGGER
110             = MyfacesLogger.createMyfacesLogger(LOGGER_NAME_PREFIX + "config");
111 
112 
113     private MyfacesLogger(Logger log)
114     {
115         _log = log;
116     }
117 
118     /**
119      * Get the Java logger from an Myfaces Logger.
120      * 
121      * @return a java Logger instance
122      */
123     public Logger getLogger()
124     {
125         return _log;
126     }
127 
128     /**
129      * Find or create a logger for a named subsystem.  If a logger has
130      * already been created with the given name it is returned.  Otherwise
131      * a new logger is created.
132      * <p>
133      * If a new logger is created its log level will be configured
134      * based on the LogManager configuration and it will configured
135      * to also send logging output to its parent's handlers.  It will
136      * be registered in the LogManager global namespace.
137      * 
138      * @param name        A name for the logger.  This should
139      *                be a dot-separated name and should normally
140      *                be based on the package name or class name
141      *                of the subsystem, such as java.net
142      *                or javax.swing
143      * @return a suitable Logger
144      */
145     private static MyfacesLogger createMyfacesLogger(String name) 
146     {
147         if (name == null)
148         {
149             throw new IllegalArgumentException(_LOG.getMessage(
150                     "LOGGER_NAME_REQUIRED"));
151         }
152 
153         Logger log;
154 
155         if (name.startsWith("javax.faces"))
156         {
157             log = Logger.getLogger(name, _API_LOGGER_BUNDLE);
158         }
159         else if (name.startsWith("org.apache.myfaces."))
160         {
161             log = Logger.getLogger(name, _IMPL_LOGGER_BUNDLE);
162         }
163         else
164         {
165             log = Logger.getLogger(name);
166         }
167 
168         return new MyfacesLogger(log);
169     }
170 
171     /**
172      * Find or create a logger for a named subsystem.  If a logger has 
173      * already been created with the given name it is returned.  Otherwise
174      * a new logger is created.
175      * <p>
176      * If a new logger is created its log level will be configured
177      * based on the LogManager and it will configured to also send logging
178      * output to its parent loggers Handlers.  It will be registered in
179      * the LogManager global namespace.
180      * <p>
181      * If the named Logger already exists and does not yet have a
182      * localization resource bundle then the given resource bundle 
183      * name is used.  If the named Logger already exists and has
184      * a different resource bundle name then an IllegalArgumentException
185      * is thrown.
186      * <p>
187      * @param name    A name for the logger.  This should
188      *                be a dot-separated name and should normally
189      *                be based on the package name or class name
190      *                of the subsystem, such as java.net
191      *                or javax.swing
192      * @param     resourceBundleName  name of ResourceBundle to be used for localizing
193      *                messages for this logger.
194      * @return a suitable Logger
195      * @throws MissingResourceException if the named ResourceBundle cannot be found.
196      * @throws IllegalArgumentException if the Logger already exists and uses
197      *           a different resource bundle name.
198      */
199     private static MyfacesLogger createMyfacesLogger(String name, String resourceBundleName) 
200     {
201         if (name == null)
202         {
203             throw new IllegalArgumentException(_LOG.getMessage(
204                     "LOGGER_NAME_REQUIRED"));
205         }
206 
207         Logger log = Logger.getLogger(name, resourceBundleName);
208 
209         return new MyfacesLogger(log);
210     }
211 
212 
213     /**
214      * Find or create a logger for a named subsystem.  If a logger has
215      * already been created with the given name it is returned.  Otherwise
216      * a new logger is created.
217      * <p>
218      * If a new logger is created its log level will be configured
219      * based on the LogManager configuration and it will configured
220      * to also send logging output to its parent's handlers.  It will
221      * be registered in the LogManager global namespace.
222      * 
223      * @param c       A class instance for the logger.  
224      * @return a suitable Logger
225      */
226     public static MyfacesLogger createMyfacesLogger(Class<?> c) 
227     {
228         if (c == null)
229         {
230             throw new IllegalArgumentException(_LOG.getMessage(
231                     "CLASS_REQUIRED"));
232         }
233         String name = c.getName();
234         return createMyfacesLogger(name);
235     }
236 
237     /**
238      * Find or create a logger for a named subsystem.  If a logger has
239      * already been created with the given name it is returned.  Otherwise
240      * a new logger is created.
241      * <p>
242      * If a new logger is created its log level will be configured
243      * based on the LogManager configuration and it will configured
244      * to also send logging output to its parent's handlers.  It will
245      * be registered in the LogManager global namespace.
246      * 
247      * @param c       A class instance for the logger.  
248      * @param     resourceBundleName  name of ResourceBundle to be used for localizing
249      *                messages for this logger.
250      *        
251      * @return a suitable Logger
252      */
253     public static MyfacesLogger createMyfacesLogger(Class<?> c, String resourceBundleName) 
254     {
255         if (c == null)
256         {
257             throw new IllegalArgumentException(_LOG.getMessage(
258                     "CLASS_REQUIRED"));
259         }
260         String name = c.getName();
261         return createMyfacesLogger(name, resourceBundleName);
262     }
263 
264     /**
265      * Find or create a logger for a named subsystem.  If a logger has
266      * already been created with the given name it is returned.  Otherwise
267      * a new logger is created.
268      * <p>
269      * If a new logger is created its log level will be configured
270      * based on the LogManager configuration and it will configured
271      * to also send logging output to its parent's handlers.  It will
272      * be registered in the LogManager global namespace.
273      * 
274      * @param p       A Package instance for the logger.  
275      * @return a suitable Logger
276      */
277 
278     public static MyfacesLogger createMyfacesLogger(Package p)
279     {
280         if (p == null)
281         {
282             throw new IllegalArgumentException(_LOG.getMessage(
283                     "PACKAGE_REQUIRED"));
284         }
285         String name = p.getName();
286         return createMyfacesLogger(name);
287     }
288 
289     /**
290      * Find or create a logger for a named subsystem.  If a logger has
291      * already been created with the given name it is returned.  Otherwise
292      * a new logger is created.
293      * <p>
294      * If a new logger is created its log level will be configured
295      * based on the LogManager configuration and it will configured
296      * to also send logging output to its parent's handlers.  It will
297      * be registered in the LogManager global namespace.
298      * 
299      * @param p       A Package instance for the logger.  
300      * @param     resourceBundleName  name of ResourceBundle to be used for localizing
301      *                messages for this logger.
302      *        
303      * @return a suitable Logger
304      */
305 
306     public static MyfacesLogger createMyfacesLogger(Package p, String resourceBundleName)
307     {
308         if (p == null)
309         {
310             throw new IllegalArgumentException(_LOG.getMessage(
311                     "PACKAGE_REQUIRED"));
312         }
313         String name = p.getName();
314         return createMyfacesLogger(name, resourceBundleName);
315     }
316 
317     /**
318      * Log a LogRecord.
319      * <p>
320      * All the other logging methods in this class call through
321      * this method to actually perform any logging.  Subclasses can
322      * override this single method to capture all log activity.
323      *
324      * @param record the LogRecord to be published
325      */
326     public void log(LogRecord record) 
327     {
328         _log.log(record);
329     }
330 
331 
332     //================================================================
333     // Start of convenience methods WITHOUT className and methodName
334     //================================================================
335 
336     /**
337      * Log a message, with no arguments.
338      * <p>
339      * If the logger is currently enabled for the given message 
340      * level then the given message is forwarded to all the
341      * registered output Handler objects.
342      * <p>
343      * @param   msg   The string message (or a key in the message catalog)
344      */
345     public void log(String msg) 
346     {
347         log(Level.FINE, msg);
348     }
349 
350     /**
351      * Log a message, with no arguments.
352      * <p>
353      * If the logger is currently enabled for the given message 
354      * level then the given message is forwarded to all the
355      * registered output Handler objects.
356      * <p>
357      * @param level   One of the message level identifiers, e.g. SEVERE
358      * @param   msg   The string message (or a key in the message catalog)
359      */
360     public void log(Level level, String msg) 
361     {
362         if (isLoggable(level))
363         {
364             MyfacesLogRecord lr = new MyfacesLogRecord(level, msg);
365             doLog(lr);  
366         }
367     }
368 
369     /**
370      * Log a message, with one object parameter.
371      * <p>
372      * If the logger is currently enabled for the given message 
373      * level then a corresponding LogRecord is created and forwarded 
374      * to all the registered output Handler objects.
375      * <p>
376      * @param level   One of the message level identifiers, e.g. SEVERE
377      * @param   msg   The string message (or a key in the message catalog)
378      * @param   param1    parameter to the message
379      */
380     public void log(Level level, String msg, Object param1) 
381     {
382         if (isLoggable(level))
383         {
384             MyfacesLogRecord lr = new MyfacesLogRecord(level, msg);
385             Object params[] = { param1};
386             lr.setParameters(params);
387             doLog(lr);  
388         }
389     }
390 
391     /**
392      * Log a message, with an array of object arguments.
393      * <p>
394      * If the logger is currently enabled for the given message 
395      * level then a corresponding LogRecord is created and forwarded 
396      * to all the registered output Handler objects.
397      * <p>
398      * @param level   One of the message level identifiers, e.g. SEVERE
399      * @param   msg   The string message (or a key in the message catalog)
400      * @param   params    array of parameters to the message
401      */
402     public void log(Level level, String msg, Object params[]) 
403     {
404         if (isLoggable(level))
405         {
406             MyfacesLogRecord lr = new MyfacesLogRecord(level, msg);
407             lr.setParameters(params);
408             doLog(lr);  
409         }
410     }
411 
412     /**
413      * Log a message, with associated Throwable information.
414      * <p>
415      * If the logger is currently enabled for the given message 
416      * level then the given arguments are stored in a LogRecord
417      * which is forwarded to all registered output handlers.
418      * <p>
419      * Note that the thrown argument is stored in the LogRecord thrown
420      * property, rather than the LogRecord parameters property.  Thus is it
421      * processed specially by output Formatters and is not treated
422      * as a formatting parameter to the LogRecord message property.
423      * <p>
424      * @param level   One of the message level identifiers, e.g. SEVERE
425      * @param   msg   The string message (or a key in the message catalog)
426      * @param   thrown  Throwable associated with log message.
427      */
428     public void log(Level level, String msg, Throwable thrown) 
429     {
430         if (isLoggable(level))
431         {
432             MyfacesLogRecord lr = new MyfacesLogRecord(level, msg);
433             lr.setThrown(thrown);
434             doLog(lr);  
435         }
436     }
437 
438     //================================================================
439     // Start of convenience methods WITH className and methodName
440     //================================================================
441 
442     /**
443      * Log a message, specifying source class and method,
444      * with no arguments.
445      * <p>
446      * If the logger is currently enabled for the given message 
447      * level then the given message is forwarded to all the
448      * registered output Handler objects.
449      * <p>
450      * @param level   One of the message level identifiers, e.g. SEVERE
451      * @param   sourceClass    name of class that issued the logging request
452      * @param   sourceMethod   name of method that issued the logging request
453      * @param   msg   The string message (or a key in the message catalog)
454      */
455     public void logp(Level level, String sourceClass, String sourceMethod, String msg) 
456     {
457         if (isLoggable(level))
458         {
459             MyfacesLogRecord lr = new MyfacesLogRecord(level, msg);
460             lr.setSourceClassName(sourceClass);
461             lr.setSourceMethodName(sourceMethod);
462             doLog(lr);  
463         }
464     }
465 
466     /**
467      * Log a message, specifying source class and method,
468      * with a single object parameter to the log message.
469      * <p>
470      * If the logger is currently enabled for the given message 
471      * level then a corresponding LogRecord is created and forwarded 
472      * to all the registered output Handler objects.
473      * <p>
474      * @param level   One of the message level identifiers, e.g. SEVERE
475      * @param   sourceClass    name of class that issued the logging request
476      * @param   sourceMethod   name of method that issued the logging request
477      * @param   msg    The string message (or a key in the message catalog)
478      * @param   param1    Parameter to the log message.
479      */
480     public void logp(Level level, String sourceClass, String sourceMethod,
481             String msg, Object param1) 
482     {
483         if (isLoggable(level))
484         {
485             MyfacesLogRecord lr = new MyfacesLogRecord(level, msg);
486             lr.setSourceClassName(sourceClass);
487             lr.setSourceMethodName(sourceMethod);
488             Object params[] = { param1};
489             lr.setParameters(params);
490             doLog(lr);  
491         }
492     }
493 
494     /**
495      * Log a message, specifying source class and method,
496      * with an array of object arguments.
497      * <p>
498      * If the logger is currently enabled for the given message 
499      * level then a corresponding LogRecord is created and forwarded 
500      * to all the registered output Handler objects.
501      * <p>
502      * @param level   One of the message level identifiers, e.g. SEVERE
503      * @param   sourceClass    name of class that issued the logging request
504      * @param   sourceMethod   name of method that issued the logging request
505      * @param   msg   The string message (or a key in the message catalog)
506      * @param   params    Array of parameters to the message
507      */
508     public void logp(Level level, String sourceClass, String sourceMethod,
509             String msg, Object params[]) 
510     {
511         if (isLoggable(level))
512         {
513             MyfacesLogRecord lr = new MyfacesLogRecord(level, msg);
514             lr.setSourceClassName(sourceClass);
515             lr.setSourceMethodName(sourceMethod);
516             lr.setParameters(params);
517             doLog(lr);  
518         }
519     }
520 
521     /**
522      * Log a message, specifying source class and method,
523      * with associated Throwable information.
524      * <p>
525      * If the logger is currently enabled for the given message 
526      * level then the given arguments are stored in a LogRecord
527      * which is forwarded to all registered output handlers.
528      * <p>
529      * Note that the thrown argument is stored in the LogRecord thrown
530      * property, rather than the LogRecord parameters property.  Thus is it
531      * processed specially by output Formatters and is not treated
532      * as a formatting parameter to the LogRecord message property.
533      * <p>
534      * @param level   One of the message level identifiers, e.g. SEVERE
535      * @param   sourceClass    name of class that issued the logging request
536      * @param   sourceMethod   name of method that issued the logging request
537      * @param   msg   The string message (or a key in the message catalog)
538      * @param   thrown  Throwable associated with log message.
539      */
540     public void logp(Level level, String sourceClass, String sourceMethod,
541             String msg, Throwable thrown) 
542     {
543         if (isLoggable(level))
544         {
545             MyfacesLogRecord lr = new MyfacesLogRecord(level, msg);
546             lr.setSourceClassName(sourceClass);
547             lr.setSourceMethodName(sourceMethod);
548             lr.setThrown(thrown);
549             doLog(lr);  
550         }
551     }
552 
553 
554     /**
555      * Log a message, specifying source class, method, and resource bundle name
556      * with no arguments.
557      * <p>
558      * If the logger is currently enabled for the given message 
559      * level then the given message is forwarded to all the
560      * registered output Handler objects.
561      * <p>
562      * The msg string is localized using the named resource bundle.  If the
563      * resource bundle name is null, then the msg string is not localized.
564      * <p>
565      * @param level   One of the message level identifiers, e.g. SEVERE
566      * @param   sourceClass    name of class that issued the logging request
567      * @param   sourceMethod   name of method that issued the logging request
568      * @param   bundleName     name of resource bundle to localize msg
569      * @param   msg   The string message (or a key in the message catalog)
570      * @throws  MissingResourceException if no suitable ResourceBundle can
571      *        be found.
572      */
573 
574     public void logrb(Level level, String sourceClass, String sourceMethod, 
575             String bundleName, String msg) 
576     {
577         if (isLoggable(level))
578         {
579             MyfacesLogRecord lr = new MyfacesLogRecord(level, msg);
580             lr.setSourceClassName(sourceClass);
581             lr.setSourceMethodName(sourceMethod);
582             doLog(lr,bundleName);  
583         }
584     }
585 
586     /**
587      * Log a message, specifying source class, method, and resource bundle name,
588      * with a single object parameter to the log message.
589      * <p>
590      * If the logger is currently enabled for the given message 
591      * level then a corresponding LogRecord is created and forwarded 
592      * to all the registered output Handler objects.
593      * <p>
594      * The msg string is localized using the named resource bundle.  If the
595      * resource bundle name is null, then the msg string is not localized.
596      * <p>
597      * @param level   One of the message level identifiers, e.g. SEVERE
598      * @param   sourceClass    name of class that issued the logging request
599      * @param   sourceMethod   name of method that issued the logging request
600      * @param   bundleName     name of resource bundle to localize msg
601      * @param   msg    The string message (or a key in the message catalog)
602      * @param   param1    Parameter to the log message.
603      * @throws  MissingResourceException if no suitable ResourceBundle can
604      *        be found.
605      */
606     public void logrb(Level level, String sourceClass, String sourceMethod,
607             String bundleName, String msg, Object param1) 
608     {
609         if (isLoggable(level))
610         {
611             MyfacesLogRecord lr = new MyfacesLogRecord(level, msg);
612             lr.setSourceClassName(sourceClass);
613             lr.setSourceMethodName(sourceMethod);
614             Object params[] = { param1};
615             lr.setParameters(params);
616             doLog(lr,bundleName);  
617         }
618     }
619 
620     /**
621      * Log a message, specifying source class, method, and resource bundle name,
622      * with an array of object arguments.
623      * <p>
624      * If the logger is currently enabled for the given message 
625      * level then a corresponding LogRecord is created and forwarded 
626      * to all the registered output Handler objects.
627      * <p>
628      * The msg string is localized using the named resource bundle.  If the
629      * resource bundle name is null, then the msg string is not localized.
630      * <p>
631      * @param level   One of the message level identifiers, e.g. SEVERE
632      * @param   sourceClass    name of class that issued the logging request
633      * @param   sourceMethod   name of method that issued the logging request
634      * @param   bundleName     name of resource bundle to localize msg
635      * @param   msg   The string message (or a key in the message catalog)
636      * @param   params    Array of parameters to the message
637      * @throws  MissingResourceException if no suitable ResourceBundle can
638      *        be found.
639      */
640     public void logrb(Level level, String sourceClass, String sourceMethod,
641             String bundleName, String msg, Object params[]) 
642     {
643         if (isLoggable(level))
644         {
645             MyfacesLogRecord lr = new MyfacesLogRecord(level, msg);
646             lr.setSourceClassName(sourceClass);
647             lr.setSourceMethodName(sourceMethod);
648             lr.setParameters(params);
649             doLog(lr,bundleName);  
650         }
651     }
652 
653     /**
654      * Log a message, specifying source class, method, and resource bundle name,
655      * with associated Throwable information.
656      * <p>
657      * If the logger is currently enabled for the given message 
658      * level then the given arguments are stored in a LogRecord
659      * which is forwarded to all registered output handlers.
660      * <p>
661      * The msg string is localized using the named resource bundle.  If the
662      * resource bundle name is null, then the msg string is not localized.
663      * <p>
664      * Note that the thrown argument is stored in the LogRecord thrown
665      * property, rather than the LogRecord parameters property.  Thus is it
666      * processed specially by output Formatters and is not treated
667      * as a formatting parameter to the LogRecord message property.
668      * <p>
669      * @param level   One of the message level identifiers, e.g. SEVERE
670      * @param   sourceClass    name of class that issued the logging request
671      * @param   sourceMethod   name of method that issued the logging request
672      * @param   bundleName     name of resource bundle to localize msg
673      * @param   msg   The string message (or a key in the message catalog)
674      * @param   thrown  Throwable associated with log message.
675      * @throws  MissingResourceException if no suitable ResourceBundle can
676      *        be found.
677      */
678     public void logrb(Level level, String sourceClass, String sourceMethod,
679             String bundleName, String msg, Throwable thrown) 
680     {
681         if (isLoggable(level))
682         {
683             MyfacesLogRecord lr = new MyfacesLogRecord(level, msg);
684             lr.setSourceClassName(sourceClass);
685             lr.setSourceMethodName(sourceMethod);
686             lr.setThrown(thrown);
687             doLog(lr,bundleName);  
688         }
689     }
690 
691 
692     //======================================================================
693     // Start of convenience methods for logging method entries and returns.
694     //======================================================================
695 
696     /**
697      * Log a method entry.
698      * <p>
699      * This is a convenience method that can be used to log entry
700      * to a method.  A LogRecord with message "ENTRY", log level
701      * FINER, and the given sourceMethod and sourceClass is logged.
702      * <p>
703      * @param   sourceClass    name of class that issued the logging request
704      * @param   sourceMethod   name of method that is being entered
705      */
706     public void entering(String sourceClass, String sourceMethod) 
707     {
708         _log.entering(sourceClass, sourceMethod);
709     }
710 
711     /**
712      * Log a method entry, with one parameter.
713      * <p>
714      * This is a convenience method that can be used to log entry
715      * to a method.  A LogRecord with message "ENTRY {0}", log level
716      * FINER, and the given sourceMethod, sourceClass, and parameter
717      * is logged.
718      * <p>
719      * @param   sourceClass    name of class that issued the logging request
720      * @param   sourceMethod   name of method that is being entered
721      * @param   param1           parameter to the method being entered
722      */
723     public void entering(String sourceClass, String sourceMethod, Object param1) 
724     {
725         _log.entering(sourceClass, sourceMethod, param1);
726     }
727 
728     /**
729      * Log a method entry, with an array of parameters.
730      * <p>
731      * This is a convenience method that can be used to log entry
732      * to a method.  A LogRecord with message "ENTRY" (followed by a 
733      * format {N} indicator for each entry in the parameter array), 
734      * log level FINER, and the given sourceMethod, sourceClass, and 
735      * parameters is logged.
736      * <p>
737      * @param   sourceClass    name of class that issued the logging request
738      * @param   sourceMethod   name of method that is being entered
739      * @param   params           array of parameters to the method being entered
740      */
741     public void entering(String sourceClass, String sourceMethod, Object params[]) 
742     {
743         _log.entering(sourceClass, sourceMethod, params);
744     }
745 
746     /**
747      * Log a method return.
748      * <p>
749      * This is a convenience method that can be used to log returning
750      * from a method.  A LogRecord with message "RETURN", log level
751      * FINER, and the given sourceMethod and sourceClass is logged.
752      * <p>
753      * @param   sourceClass    name of class that issued the logging request
754      * @param   sourceMethod   name of the method 
755      */
756     public void exiting(String sourceClass, String sourceMethod) 
757     {
758         _log.exiting(sourceClass, sourceMethod);
759     }
760 
761 
762     /**
763      * Log a method return, with result object.
764      * <p>
765      * This is a convenience method that can be used to log returning
766      * from a method.  A LogRecord with message "RETURN {0}", log level
767      * FINER, and the gives sourceMethod, sourceClass, and result
768      * object is logged.
769      * <p>
770      * @param   sourceClass    name of class that issued the logging request
771      * @param   sourceMethod   name of the method 
772      * @param   result  Object that is being returned
773      */
774     public void exiting(String sourceClass, String sourceMethod, Object result) 
775     {
776         _log.exiting(sourceClass, sourceMethod, result);
777     }
778 
779     /**
780      * Log throwing an exception.
781      * <p>
782      * This is a convenience method to log that a method is
783      * terminating by throwing an exception.  The logging is done 
784      * using the FINER level.
785      * <p>
786      * If the logger is currently enabled for the given message 
787      * level then the given arguments are stored in a LogRecord
788      * which is forwarded to all registered output handlers.  The
789      * LogRecord's message is set to "THROW".
790      * <p>
791      * Note that the thrown argument is stored in the LogRecord thrown
792      * property, rather than the LogRecord parameters property.  Thus is it
793      * processed specially by output Formatters and is not treated
794      * as a formatting parameter to the LogRecord message property.
795      * <p>
796      * @param   sourceClass    name of class that issued the logging request
797      * @param   sourceMethod  name of the method.
798      * @param   thrown  The Throwable that is being thrown.
799      */
800     public void throwing(String sourceClass, String sourceMethod, Throwable thrown) 
801     {
802         _log.throwing(sourceClass, sourceMethod, thrown);
803     }
804 
805     //=======================================================================
806     // Start of simple convenience methods using level names as method names
807     //=======================================================================
808 
809     /**
810      * Log a SEVERE message.
811      * <p>
812      * If the logger is currently enabled for the SEVERE message 
813      * level then the given message is forwarded to all the
814      * registered output Handler objects.
815      * <p>
816      * @param   msg   The string message (or a key in the message catalog)
817      */
818     public void severe(String msg) 
819     {
820         //_log.severe(msg);
821         log(Level.SEVERE,msg);
822     }
823 
824     /**
825      * Log a WARNING message.
826      * <p>
827      * If the logger is currently enabled for the WARNING message 
828      * level then the given message is forwarded to all the
829      * registered output Handler objects.
830      * <p>
831      * @param   msg   The string message (or a key in the message catalog)
832      */
833     public void warning(String msg) 
834     {
835         //_log.warning(msg);
836         log(Level.WARNING,msg);
837     }
838 
839     /**
840      * Log an INFO message.
841      * <p>
842      * If the logger is currently enabled for the INFO message 
843      * level then the given message is forwarded to all the
844      * registered output Handler objects.
845      * <p>
846      * @param   msg   The string message (or a key in the message catalog)
847      */
848     public void info(String msg) 
849     {
850         //_log.info(msg);
851         log(Level.INFO,msg);
852     }
853 
854     /**
855      * Log a CONFIG message.
856      * <p>
857      * If the logger is currently enabled for the CONFIG message 
858      * level then the given message is forwarded to all the
859      * registered output Handler objects.
860      * <p>
861      * @param   msg   The string message (or a key in the message catalog)
862      */
863     public void config(String msg) 
864     {
865         //_log.config(msg);
866         log(Level.CONFIG,msg);
867     }
868 
869     /**
870      * Log a FINE message.
871      * <p>
872      * If the logger is currently enabled for the FINE message 
873      * level then the given message is forwarded to all the
874      * registered output Handler objects.
875      * <p>
876      * @param   msg   The string message (or a key in the message catalog)
877      */
878     public void fine(String msg) 
879     {
880         //_log.fine(msg);
881         log(Level.FINE,msg);
882     }
883 
884     /**
885      * Log a FINER message.
886      * <p>
887      * If the logger is currently enabled for the FINER message 
888      * level then the given message is forwarded to all the
889      * registered output Handler objects.
890      * <p>
891      * @param   msg   The string message (or a key in the message catalog)
892      */
893     public void finer(String msg) 
894     {
895         //_log.finer(msg);
896         log(Level.FINER,msg);
897     }
898 
899     /**
900      * Log a FINEST message.
901      * <p>
902      * If the logger is currently enabled for the FINEST message 
903      * level then the given message is forwarded to all the
904      * registered output Handler objects.
905      * <p>
906      * @param   msg   The string message (or a key in the message catalog)
907      */
908     public void finest(String msg) 
909     {
910         //_log.finest(msg);
911         log(Level.FINEST,msg);
912     }
913 
914     /**
915      * Log throwing an exception.
916      * 
917      * Comparing to Java Logging function
918      * 
919      *     Logger.throwing(sourceClass, sourceMethod, thrown) 
920      * 
921      * this function takes one more parameter "level" so that developers can 
922      * specify the logging level of an exception. Developers should pass value
923      * for the "level" parameter using following convention,
924      * <p>
925      * Level.SEVERE -- Serious exceptions or error conditions such that an 
926      * application can no longer run.
927      * <p>
928      * Level.WARNING -- Exceptions or errors that are not fatal, but an 
929      * application will run with some problems.
930      * <p>
931      * 
932      * @param level Java Logging level
933      * @param sourceClass name of class that issued the logging request
934      * @param sourceMethod name of the method
935      * @param thrown The Throwable that is being thrown
936      */
937     public void throwing(
938             Level  level,
939             String sourceClass,
940             String sourceMethod,
941             Throwable thrown
942             )
943     {
944         logp(level, sourceClass, sourceMethod, null, thrown);
945     }
946 
947     /**
948      * Log a SEVERE message, with no arguments.
949      * <p>
950      * The message is forwarded to appropriate Java Logger objects. 
951      * <p>
952      * @param sourceClass  the name of the class that issued the logging request 
953      * @param sourceMethod the name of the method that issued the logging request 
954      * @param msg          the string message (or a key in the resource bundle)
955      */
956     public void severe(
957             String sourceClass,
958             String sourceMethod,
959             String msg
960             )
961     {
962         logp(Level.SEVERE, sourceClass, sourceMethod, msg);
963     }
964 
965     /**
966      * Log a SEVERE message, with one object parameter.
967      * <p>
968      * The message is forwarded to appropriate Java Logger objects. 
969      * <p>
970      * @param sourceClass  the name of the class that issued the logging request 
971      * @param sourceMethod the name of the method that issued the logging request 
972      * @param msg          the string message (or a key in the resource bundle)
973      * @param param1       a parameter to the message
974      */
975     public void severe(
976             String sourceClass,
977             String sourceMethod,
978             String msg,
979             Object param1
980             )
981     {
982         logp(Level.SEVERE, sourceClass, sourceMethod, msg, param1);
983     }
984 
985     /**
986      * Log a SEVERE message, with an array of object arguments.
987      * <p>
988      * The message is forwarded to appropriate Java Logger objects. 
989      * <p>
990      * @param sourceClass  the name of the class that issued the logging request 
991      * @param sourceMethod the name of the method that issued the logging request 
992      * @param msg          the string message (or a key in the resource bundle)
993      * @param params       an array of parameters to the message
994      */
995     public void severe(
996             String sourceClass,
997             String sourceMethod,
998             String msg,
999             Object[] params
1000             )
1001     {
1002         logp(Level.SEVERE, sourceClass, sourceMethod, msg, params);
1003     }
1004 
1005     /**
1006      * Log a WARNING message, with no arguments.
1007      * <p>
1008      * The message is forwarded to appropriate Java Logger objects. 
1009      * <p>
1010      * @param sourceClass  the name of the class that issued the logging request 
1011      * @param sourceMethod the name of the method that issued the logging request 
1012      * @param msg          the string message (or a key in the resource bundle)
1013      */
1014     public void warning(
1015             String sourceClass,
1016             String sourceMethod,
1017             String msg
1018             )
1019     {
1020         logp(Level.WARNING, sourceClass, sourceMethod, msg);
1021     }
1022 
1023     /**
1024      * Log a WARNING message, with one object parameter.
1025      * <p>
1026      * The message is forwarded to appropriate Java Logger objects. 
1027      * <p>
1028      * @param sourceClass  the name of the class that issued the logging request 
1029      * @param sourceMethod the name of the method that issued the logging request 
1030      * @param msg          the string message (or a key in the resource bundle)
1031      * @param param1       a parameter to the message
1032      */
1033     public void warning(
1034             String sourceClass,
1035             String sourceMethod,
1036             String msg,
1037             Object param1
1038             )
1039     {
1040         logp(Level.WARNING, sourceClass, sourceMethod, msg, param1);
1041     }
1042 
1043     /**
1044      * Log a WARNING message, with an array of object arguments.
1045      * <p>
1046      * The message is forwarded to appropriate Java Logger objects. 
1047      * <p>
1048      * @param sourceClass  the name of the class that issued the logging request 
1049      * @param sourceMethod the name of the method that issued the logging request 
1050      * @param msg          the string message (or a key in the resource bundle)
1051      * @param params       an array of parameters to the message
1052      */
1053     public void warning(
1054             String sourceClass,
1055             String sourceMethod,
1056             String msg,
1057             Object[] params
1058             )
1059     {
1060         logp(Level.WARNING, sourceClass, sourceMethod, msg, params);
1061     }
1062 
1063     /**
1064      * Log a INFO message, with no arguments.
1065      * <p>
1066      * The message is forwarded to appropriate Java Logger objects. 
1067      * <p>
1068      * @param sourceClass  the name of the class that issued the logging request 
1069      * @param sourceMethod the name of the method that issued the logging request 
1070      * @param msg          the string message (or a key in the resource bundle)
1071      */
1072     public void info(
1073             String sourceClass,
1074             String sourceMethod,
1075             String msg
1076             )
1077     {
1078         logp(Level.INFO, sourceClass, sourceMethod, msg);
1079     }
1080 
1081     /**
1082      * Log a INFO message, with one object parameter.
1083      * <p>
1084      * The message is forwarded to appropriate Java Logger objects. 
1085      * <p>
1086      * @param sourceClass  the name of the class that issued the logging request 
1087      * @param sourceMethod the name of the method that issued the logging request 
1088      * @param msg          the string message (or a key in the resource bundle)
1089      * @param param1       a parameter to the message
1090      */
1091     public void info(
1092             String sourceClass,
1093             String sourceMethod,
1094             String msg,
1095             Object param1
1096             )
1097     {
1098         logp(Level.INFO, sourceClass, sourceMethod, msg, param1);
1099     }
1100 
1101     /**
1102      * Log a INFO message, with an array of object arguments.
1103      * <p>
1104      * The message is forwarded to appropriate Java Logger objects. 
1105      * <p>
1106      * @param sourceClass  the name of the class that issued the logging request 
1107      * @param sourceMethod the name of the method that issued the logging request 
1108      * @param msg          the string message (or a key in the resource bundle)
1109      * @param params       an array of parameters to the message
1110      */
1111     public void info(
1112             String sourceClass,
1113             String sourceMethod,
1114             String msg,
1115             Object[] params
1116             )
1117     {
1118         logp(Level.INFO, sourceClass, sourceMethod, msg, params);
1119     }
1120 
1121     /**
1122      * Log a CONFIG message, with no arguments.
1123      * <p>
1124      * The message is forwarded to appropriate Java Logger objects. 
1125      * <p>
1126      * @param sourceClass  the name of the class that issued the logging request 
1127      * @param sourceMethod the name of the method that issued the logging request 
1128      * @param msg          the string message (or a key in the resource bundle)
1129      */
1130     public void config(
1131             String sourceClass,
1132             String sourceMethod,
1133             String msg
1134             )
1135     {
1136         logp(Level.CONFIG, sourceClass, sourceMethod, msg);
1137     }
1138 
1139     /**
1140      * Log a CONFIG message, with one object parameter.
1141      * <p>
1142      * The message is forwarded to appropriate Java Logger objects. 
1143      * <p>
1144      * @param sourceClass  the name of the class that issued the logging request 
1145      * @param sourceMethod the name of the method that issued the logging request 
1146      * @param msg          the string message (or a key in the resource bundle)
1147      * @param param1       a parameter to the message
1148      */
1149     public void config(
1150             String sourceClass,
1151             String sourceMethod,
1152             String msg,
1153             Object param1
1154             )
1155     {
1156         _log.logp(Level.CONFIG, sourceClass, sourceMethod, msg, param1);
1157     }
1158 
1159     /**
1160      * Log a CONFIG message, with an array of object arguments.
1161      * <p>
1162      * The message is forwarded to appropriate Java Logger objects. 
1163      * <p>
1164      * @param sourceClass  the name of the class that issued the logging request 
1165      * @param sourceMethod the name of the method that issued the logging request 
1166      * @param msg          the string message (or a key in the resource bundle)
1167      * @param params       an array of parameters to the message
1168      */
1169     public void config(
1170             String sourceClass,
1171             String sourceMethod,
1172             String msg,
1173             Object[] params
1174             )
1175     {
1176         logp(Level.CONFIG, sourceClass, sourceMethod, msg, params);
1177     }
1178 
1179     /**
1180      * Log a FINE message, with no arguments.
1181      * <p>
1182      * The message is forwarded to appropriate Java Logger objects. 
1183      * <p>
1184      * @param sourceClass  the name of the class that issued the logging request 
1185      * @param sourceMethod the name of the method that issued the logging request 
1186      * @param msg          the string message (or a key in the resource bundle)
1187      */
1188     public void fine(
1189             String sourceClass,
1190             String sourceMethod,
1191             String msg
1192             )
1193     {
1194         logp(Level.FINE, sourceClass, sourceMethod, msg);
1195     }
1196 
1197     /**
1198      * Log a FINE message, with one object parameter.
1199      * <p>
1200      * The message is forwarded to appropriate Java Logger objects. 
1201      * <p>
1202      * @param sourceClass  the name of the class that issued the logging request 
1203      * @param sourceMethod the name of the method that issued the logging request 
1204      * @param msg          the string message (or a key in the resource bundle)
1205      * @param param1       a parameter to the message
1206      */
1207     public void fine(
1208             String sourceClass,
1209             String sourceMethod,
1210             String msg,
1211             Object param1
1212             )
1213     {
1214         logp(Level.FINE, sourceClass, sourceMethod, msg, param1);
1215     }
1216 
1217     /**
1218      * Log a FINE message, with an array of object arguments.
1219      * <p>
1220      * The message is forwarded to appropriate Java Logger objects. 
1221      * <p>
1222      * @param sourceClass  the name of the class that issued the logging request 
1223      * @param sourceMethod the name of the method that issued the logging request 
1224      * @param msg          the string message (or a key in the resource bundle)
1225      * @param params       an array of parameters to the message
1226      */
1227     public void fine(
1228             String sourceClass,
1229             String sourceMethod,
1230             String msg,
1231             Object[] params
1232             )
1233     {
1234         logp(Level.FINE, sourceClass, sourceMethod, msg, params);
1235     }
1236 
1237     /**
1238      * Log a FINER message, with no arguments.
1239      * <p>
1240      * The message is forwarded to appropriate Java Logger objects. 
1241      * <p>
1242      * @param sourceClass  the name of the class that issued the logging request 
1243      * @param sourceMethod the name of the method that issued the logging request 
1244      * @param msg          the string message (or a key in the resource bundle)
1245      */
1246     public void finer(
1247             String sourceClass,
1248             String sourceMethod,
1249             String msg
1250             )
1251     {
1252         logp(Level.FINER, sourceClass, sourceMethod, msg);
1253     }
1254 
1255     /**
1256      * Log a FINER message, with one object parameter.
1257      * <p>
1258      * The message is forwarded to appropriate Java Logger objects. 
1259      * <p>
1260      * @param sourceClass  the name of the class that issued the logging request 
1261      * @param sourceMethod the name of the method that issued the logging request 
1262      * @param msg          the string message (or a key in the resource bundle)
1263      * @param param1       a parameter to the message
1264      */
1265     public void finer(
1266             String sourceClass,
1267             String sourceMethod,
1268             String msg,
1269             Object param1
1270             )
1271     {
1272         logp(Level.FINER, sourceClass, sourceMethod, msg, param1);
1273     }
1274 
1275     /**
1276      * Log a FINER message, with an array of object arguments.
1277      * <p>
1278      * The message is forwarded to appropriate Java Logger objects. 
1279      * <p>
1280      * @param sourceClass  the name of the class that issued the logging request 
1281      * @param sourceMethod the name of the method that issued the logging request 
1282      * @param msg          the string message (or a key in the resource bundle)
1283      * @param params       an array of parameters to the message
1284      */
1285     public void finer(
1286             String sourceClass,
1287             String sourceMethod,
1288             String msg,
1289             Object[] params
1290             )
1291     {
1292         logp(Level.FINER, sourceClass, sourceMethod, msg, params);
1293     }
1294 
1295     /**
1296      * Log a FINEST message, with no arguments.
1297      * <p>
1298      * The message is forwarded to appropriate Java Logger objects. 
1299      * <p>
1300      * @param sourceClass  the name of the class that issued the logging request 
1301      * @param sourceMethod the name of the method that issued the logging request 
1302      * @param msg          the string message (or a key in the resource bundle)
1303      */
1304     public void finest(
1305             String sourceClass,
1306             String sourceMethod,
1307             String msg
1308             )
1309     {
1310         logp(Level.FINEST, sourceClass, sourceMethod, msg);
1311     }
1312 
1313     /**
1314      * Log a FINEST message, with one object parameter.
1315      * <p>
1316      * The message is forwarded to appropriate Java Logger objects. 
1317      * <p>
1318      * @param sourceClass  the name of the class that issued the logging request 
1319      * @param sourceMethod the name of the method that issued the logging request 
1320      * @param msg          the string message (or a key in the resource bundle)
1321      * @param param1       a parameter to the message
1322      */
1323     public void finest(
1324             String sourceClass,
1325             String sourceMethod,
1326             String msg,
1327             Object param1
1328             )
1329     {
1330         logp(Level.FINEST, sourceClass, sourceMethod, msg, param1);
1331     }
1332 
1333     /**
1334      * Log a FINEST message, with an array of object arguments.
1335      * <p>
1336      * The message is forwarded to appropriate Java Logger objects. 
1337      * <p>
1338      * @param sourceClass  the name of the class that issued the logging request 
1339      * @param sourceMethod the name of the method that issued the logging request 
1340      * @param msg          the string message (or a key in the resource bundle)
1341      * @param params       an array of parameters to the message
1342      */
1343     public void finest(
1344             String sourceClass,
1345             String sourceMethod,
1346             String msg,
1347             Object[] params
1348             )
1349     {
1350         logp(Level.FINEST, sourceClass, sourceMethod, msg, params);
1351     }
1352 
1353     /**
1354      * Log a message, with an list of object arguments.
1355      * <p>
1356      * The message is forwarded to appropriate Java Logger objects. 
1357      * <p>
1358      * @param sourceClass  the name of the class that issued the logging request 
1359      * @param sourceMethod the name of the method that issued the logging request 
1360      * @param msg          the string message (or a key in the resource bundle)
1361      * @param params1      Parameter 1 to the log message
1362      * @param params2      Parameter 2 to the log message
1363      * @param params3      Parameter 3 to the log message
1364      */
1365     public void logp(Level level,
1366             String sourceClass,
1367             String sourceMethod,
1368             String msg,
1369             Object params1,
1370             Object params2,
1371             Object params3
1372             )
1373     {
1374         logp(level,sourceClass, sourceMethod, msg, new Object[] {params1, params2, params3});
1375     }
1376 
1377     //================================================================
1378     // End of convenience methods 
1379     //================================================================
1380 
1381     /**
1382      * Set the log level specifying which message levels will be
1383      * logged by this logger.  Message levels lower than this
1384      * value will be discarded.  The level value Level.OFF
1385      * can be used to turn off logging.
1386      * <p>
1387      * If the new level is null, it means that this node should
1388      * inherit its level from its nearest ancestor with a specific
1389      * (non-null) level value.
1390      * 
1391      * @param newLevel   the new value for the log level (may be null)
1392      * @exception  SecurityException  if a security manager exists and if
1393      *             the caller does not have LoggingPermission("control").
1394      */
1395     public void setLevel(Level newLevel) throws SecurityException 
1396     {
1397         _log.setLevel(newLevel);
1398     }
1399 
1400     /**
1401      * Get the log Level that has been specified for this Logger.
1402      * The result may be null, which means that this logger's
1403      * effective level will be inherited from its parent.
1404      *
1405      * @return    this Logger's level
1406      */
1407     public Level getLevel() 
1408     {
1409         return _log.getLevel();
1410     }
1411 
1412     /**
1413      * Check if a message of the given level would actually be logged
1414      * by this logger.  This check is based on the Loggers effective level,
1415      * which may be inherited from its parent.
1416      *
1417      * @param level   a message logging level
1418      * @return    true if the given message level is currently being logged.
1419      */
1420     public boolean isLoggable(Level level) 
1421     {
1422         return _log.isLoggable(level);
1423     }
1424 
1425     /**
1426      * Get the name for this logger.
1427      * @return logger name.  Will be null for anonymous Loggers.
1428      */
1429     public String getName() 
1430     {
1431         return _log.getName();  
1432     }
1433 
1434     /**
1435      * Add a log Handler to receive logging messages.
1436      * <p>
1437      * By default, Loggers also send their output to their parent logger.
1438      * Typically the root Logger is configured with a set of Handlers
1439      * that essentially act as default handlers for all loggers.
1440      *
1441      * @param handler a logging Handler
1442      * @exception  SecurityException  if a security manager exists and if
1443      *             the caller does not have LoggingPermission("control").
1444      */
1445     public void addHandler(Handler handler) throws SecurityException 
1446     {
1447         _log.addHandler(handler);
1448     }
1449 
1450     /**
1451      * Remove a log Handler.
1452      * <P>
1453      * Returns silently if the given Handler is not found.
1454      * 
1455      * @param handler a logging Handler
1456      * @exception  SecurityException  if a security manager exists and if
1457      *             the caller does not have LoggingPermission("control").
1458      */
1459     public void removeHandler(Handler handler) throws SecurityException 
1460     {
1461         _log.removeHandler(handler);
1462     }
1463 
1464     /**
1465      * Get the Handlers associated with this logger.
1466      * <p>
1467      * @return  an array of all registered Handlers
1468      */
1469     public Handler[] getHandlers() 
1470     {
1471         return _log.getHandlers();
1472     }
1473 
1474     /**
1475      * Specify whether or not this logger should send its output
1476      * to it's parent Logger.  This means that any LogRecords will
1477      * also be written to the parent's Handlers, and potentially
1478      * to its parent, recursively up the namespace.
1479      *
1480      * @param useParentHandlers   true if output is to be sent to the
1481      *        logger's parent.
1482      * @exception  SecurityException  if a security manager exists and if
1483      *             the caller does not have LoggingPermission("control").
1484      */
1485     public void setUseParentHandlers(boolean useParentHandlers) 
1486     {
1487         _log.setUseParentHandlers(useParentHandlers);
1488     }
1489 
1490     /**
1491      * Discover whether or not this logger is sending its output
1492      * to its parent logger.
1493      *
1494      * @return  true if output is to be sent to the logger's parent
1495      */
1496     public boolean getUseParentHandlers() 
1497     {
1498         return _log.getUseParentHandlers();
1499     }
1500 
1501     /**
1502      * Return the parent for this Logger.
1503      * <p>
1504      * This method returns the nearest extant parent in the namespace.
1505      * Thus if a Logger is called "a.b.c.d", and a Logger called "a.b"
1506      * has been created but no logger "a.b.c" exists, then a call of
1507      * getParent on the Logger "a.b.c.d" will return the Logger "a.b".
1508      * <p>
1509      * The result will be null if it is called on the root Logger
1510      * in the namespace.
1511      * 
1512      * @return nearest existing parent Logger 
1513      */
1514     public Logger getParent() 
1515     {
1516         return _log.getParent();
1517     }
1518 
1519     /**
1520      * Set the parent for this Logger.  This method is used by
1521      * the LogManager to update a Logger when the namespace changes.
1522      * <p>
1523      * It should not be called from application code.
1524      * <p>
1525      * @param  parent   the new parent logger
1526      * @exception  SecurityException  if a security manager exists and if
1527      *             the caller does not have LoggingPermission("control").
1528      */
1529     public void setParent(Logger parent) 
1530     {
1531         _log.setParent(parent);
1532     }
1533 
1534 
1535     private ResourceBundle findResourceBundle(String name) 
1536     {
1537         // Return a null bundle for a null name.
1538         if (name == null)
1539         {
1540             return null;
1541         }
1542 
1543         Locale currentLocale = Locale.getDefault();
1544         return ResourceBundle.getBundle(name, currentLocale);
1545 
1546     }
1547 
1548 
1549     private void doLog(LogRecord lr, String rbname) 
1550     {
1551         lr.setLoggerName(_log.getName());
1552         if (rbname != null)
1553         {
1554             lr.setResourceBundleName(rbname);
1555             lr.setResourceBundle(findResourceBundle(rbname));
1556         }
1557         log(lr);
1558     }
1559 
1560     private void doLog(LogRecord lr) 
1561     {
1562         lr.setLoggerName(_log.getName());
1563         String ebname = _log.getResourceBundleName();
1564         if (ebname != null)
1565         {
1566             lr.setResourceBundleName(ebname);
1567             lr.setResourceBundle(_log.getResourceBundle());
1568         }
1569         _log.log(lr);
1570     }
1571 
1572     public void severe(Throwable t)
1573     {
1574         severe(null, t);
1575     }
1576 
1577     public void severe(String message, Throwable t)
1578     {
1579         log(Level.SEVERE, message, t);
1580     }
1581 
1582     public void severe(String message, Object param)
1583     {
1584         log(Level.SEVERE, message, param);
1585     }
1586 
1587     public void severe(String message, Object[] params)
1588     {
1589         log(Level.SEVERE, message, params);
1590     }
1591 
1592 
1593     public void warning(Throwable t)
1594     {
1595         warning(null, t);
1596     }
1597 
1598     public void warning(String message, Throwable t)
1599     {
1600         log(Level.WARNING, message, t);
1601     }
1602 
1603     public void warning(String message, Object param)
1604     {
1605         log(Level.WARNING, message, param);
1606     }
1607 
1608     public void warning(String message, Object[] params)
1609     {
1610         log(Level.WARNING, message, params);
1611     }
1612 
1613     public void info(Throwable t)
1614     {
1615         info(null, t);
1616     }
1617 
1618     public void info(String message, Throwable t)
1619     {
1620         log(Level.INFO, message, t);
1621     }
1622 
1623     public void info(String message, Object param)
1624     {
1625         log(Level.INFO, message, param);
1626     }
1627 
1628     public void info(String message, Object[] params)
1629     {
1630         log(Level.INFO, message, params);
1631     }
1632 
1633     public void fine(Throwable t)
1634     {
1635         fine(null, t);
1636     }
1637 
1638     public void fine(String message, Throwable t)
1639     {
1640         log(Level.FINE, message, t);
1641     }
1642 
1643     public void fine(String message, Object param)
1644     {
1645         log(Level.FINE, message, param);
1646     }
1647 
1648     public void fine(String message, Object[] params)
1649     {
1650         log(Level.FINE, message, params);
1651     }
1652 
1653     public void finer(Throwable t)
1654     {
1655         finer(null, t);
1656     }
1657 
1658     public void finer(String message, Throwable t)
1659     {
1660         log(Level.FINER, message, t);
1661     }
1662 
1663     public void finer(String message, Object param)
1664     {
1665         log(Level.FINER, message, param);
1666     }
1667 
1668     public void finer(String message, Object[] params)
1669     {
1670         log(Level.FINER, message, params);
1671     }
1672 
1673 
1674     public void finest(Throwable t)
1675     {
1676         finest(null, t);
1677     }
1678 
1679     public void finest(String message, Throwable t)
1680     {
1681         log(Level.FINEST, message, t);
1682     }
1683 
1684     public void finest(String message, Object param)
1685     {
1686         log(Level.FINEST, message, param);
1687     }
1688 
1689     public void finest(String message, Object[] params)
1690     {
1691         log(Level.FINEST, message, params);
1692     }
1693 
1694     /**
1695      * Returns true if severe messages should be logged.
1696      */
1697     public boolean isSevere()
1698     {
1699         return isLoggable(Level.SEVERE);
1700     }
1701 
1702     /**
1703      * Returns true if warning messages should be logged.
1704      */
1705     public boolean isWarning()
1706     {
1707         return isLoggable(Level.WARNING);
1708     }
1709 
1710 
1711     /**
1712      * Returns true if info messages should be logged.
1713      */
1714     public boolean isInfo()
1715     {
1716         return isLoggable(Level.INFO);
1717     }
1718 
1719 
1720     /**
1721      * Returns true if config messages should be logged.
1722      */
1723     public boolean isConfig()
1724     {
1725         return isLoggable(Level.CONFIG);
1726     }
1727 
1728 
1729     /**
1730      * Returns true if fine messages should be logged.
1731      */
1732     public boolean isFine()
1733     {
1734         return isLoggable(Level.FINE);
1735     }
1736 
1737 
1738     /**
1739      * Returns true if finer messages should be logged.
1740      */
1741     public boolean isFiner()
1742     {
1743         return isLoggable(Level.FINER);
1744     }
1745 
1746     /**
1747      * Returns true if finest messages should be logged.
1748      */
1749     public boolean isFinest()
1750     {
1751         return isLoggable(Level.FINEST);
1752     }
1753 
1754     /**
1755      * Returns message string in default locale
1756      */
1757     public String getMessage(String key)
1758     {
1759         try
1760         {
1761             return _log.getResourceBundle().getString(key);
1762         }
1763         catch (MissingResourceException mre)
1764         {
1765             return key;
1766         }
1767     }
1768 
1769     /**
1770      * Returns message string in default locale
1771      */
1772     public String getMessage(MyfacesLogKey key)
1773     {
1774         try
1775         {
1776             String name = key.name();
1777             return _log.getResourceBundle().getString(name);
1778         }
1779         catch (MissingResourceException mre)
1780         {
1781             return key.name();
1782         }
1783     }
1784 
1785     /**
1786      * Returns message string in default locale
1787      */
1788     public MyfacesLogMessage getMyfacesMessage(MyfacesLogKey key)
1789     {
1790         MyfacesLogMessage facesMessage = new MyfacesLogMessage();
1791         try
1792         {
1793 
1794             String name = key.name();
1795             String summary = _log.getResourceBundle().getString(name);
1796             facesMessage.setSummary(summary);
1797             try
1798             {
1799                 String detail = _log.getResourceBundle().getString(name +"_detail");
1800                 facesMessage.setDetail(detail);
1801             }
1802             catch (MissingResourceException e)
1803             {
1804                 facesMessage.setDetail(name);
1805             }
1806 
1807             try
1808             {
1809                 String related = _log.getResourceBundle().getString(name +"_related");
1810                 facesMessage.setRelated(related);
1811             }
1812             catch (MissingResourceException e)
1813             {
1814                 /// ignore
1815             }
1816             return facesMessage;
1817         }
1818         catch (MissingResourceException mre)
1819         {
1820             facesMessage.setSummary(key.name());
1821             return facesMessage;
1822         }
1823     }
1824 
1825     /**
1826      * Returns formated string in default locale
1827      */
1828     public String getMessage(String key, Object... params)
1829     {
1830         String message = getMessage(key);
1831         MessageFormat fmt = new MessageFormat(message);  
1832         return fmt.format(params);  
1833     }
1834 
1835     /**
1836      * Returns formated string in default locale
1837      */
1838     public String getMessage(String key, Object param)
1839     {
1840         return getMessage(key, new Object[]{param});
1841     }
1842 
1843     private Logger _log;
1844 
1845     /** Currenly this logger is used only in myfaces-impl:  therefore LoggerBundle is same for both api and impl*/
1846     private static final String _API_LOGGER_BUNDLE = "org.apache.myfaces.resource.LoggerBundle";
1847 
1848     private static final String _IMPL_LOGGER_BUNDLE = "org.apache.myfaces.resource.LoggerBundle";
1849 
1850     private static final MyfacesLogger _LOG = MyfacesLogger.createMyfacesLogger(
1851             MyfacesLogger.class);
1852 }