Source Code Cross Referenced for Logger.java in  » 6.0-JDK-Core » Collections-Jar-Zip-Logging-regex » java » util » logging » Java Source Code / Java DocumentationJava Source Code and Java Documentation

Home
Java Source Code / Java Documentation
1.6.0 JDK Core
2.6.0 JDK Modules
3.6.0 JDK Modules com.sun
4.6.0 JDK Modules com.sun.java
5.6.0 JDK Modules sun
6.6.0 JDK Platform
7.Ajax
8.Apache Harmony Java SE
9.Aspect oriented
10.Authentication Authorization
11.Blogger System
12.Build
13.Byte Code
14.Cache
15.Chart
16.Chat
17.Code Analyzer
18.Collaboration
19.Content Management System
20.Database Client
21.Database DBMS
22.Database JDBC Connection Pool
23.Database ORM
24.Development
25.EJB Server
26.ERP CRM Financial
27.ESB
28.Forum
29.Game
30.GIS
31.Graphic 3D
32.Graphic Library
33.Groupware
34.HTML Parser
35.IDE
36.IDE Eclipse
37.IDE Netbeans
38.Installer
39.Internationalization Localization
40.Inversion of Control
41.Issue Tracking
42.J2EE
43.J2ME
44.JBoss
45.JMS
46.JMX
47.Library
48.Mail Clients
49.Music
50.Net
51.Parser
52.PDF
53.Portal
54.Profiler
55.Project Management
56.Report
57.RSS RDF
58.Rule Engine
59.Science
60.Scripting
61.Search Engine
62.Security
63.Sevlet Container
64.Source Control
65.Swing Library
66.Template Engine
67.Test Coverage
68.Testing
69.UML
70.Web Crawler
71.Web Framework
72.Web Mail
73.Web Server
74.Web Services
75.Web Services apache cxf 2.2.6
76.Web Services AXIS2
77.Wiki Engine
78.Workflow Engines
79.XML
80.XML UI
Java Source Code / Java Documentation » 6.0 JDK Core » Collections Jar Zip Logging regex » java.util.logging 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


0001        /*
0002         * Copyright 2000-2006 Sun Microsystems, Inc.  All Rights Reserved.
0003         * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
0004         *
0005         * This code is free software; you can redistribute it and/or modify it
0006         * under the terms of the GNU General Public License version 2 only, as
0007         * published by the Free Software Foundation.  Sun designates this
0008         * particular file as subject to the "Classpath" exception as provided
0009         * by Sun in the LICENSE file that accompanied this code.
0010         *
0011         * This code is distributed in the hope that it will be useful, but WITHOUT
0012         * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
0013         * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
0014         * version 2 for more details (a copy is included in the LICENSE file that
0015         * accompanied this code).
0016         *
0017         * You should have received a copy of the GNU General Public License version
0018         * 2 along with this work; if not, write to the Free Software Foundation,
0019         * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
0020         *
0021         * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
0022         * CA 95054 USA or visit www.sun.com if you need additional information or
0023         * have any questions.
0024         */
0025
0026        package java.util.logging;
0027
0028        import java.util.*;
0029        import java.security.*;
0030        import java.lang.ref.WeakReference;
0031
0032        /**
0033         * A Logger object is used to log messages for a specific
0034         * system or application component.  Loggers are normally named,
0035         * using a hierarchical dot-separated namespace.  Logger names
0036         * can be arbitrary strings, but they should normally be based on
0037         * the package name or class name of the logged component, such
0038         * as java.net or javax.swing.  In addition it is possible to create
0039         * "anonymous" Loggers that are not stored in the Logger namespace.
0040         * <p>
0041         * Logger objects may be obtained by calls on one of the getLogger
0042         * factory methods.  These will either create a new Logger or
0043         * return a suitable existing Logger.
0044         * <p>
0045         * Logging messages will be forwarded to registered Handler
0046         * objects, which can forward the messages to a variety of
0047         * destinations, including consoles, files, OS logs, etc.
0048         * <p>
0049         * Each Logger keeps track of a "parent" Logger, which is its
0050         * nearest existing ancestor in the Logger namespace.
0051         * <p>
0052         * Each Logger has a "Level" associated with it.  This reflects
0053         * a minimum Level that this logger cares about.  If a Logger's
0054         * level is set to <tt>null</tt>, then its effective level is inherited
0055         * from its parent, which may in turn obtain it recursively from its
0056         * parent, and so on up the tree.
0057         * <p>
0058         * The log level can be configured based on the properties from the
0059         * logging configuration file, as described in the description
0060         * of the LogManager class.  However it may also be dynamically changed
0061         * by calls on the Logger.setLevel method.  If a logger's level is
0062         * changed the change may also affect child loggers, since any child
0063         * logger that has <tt>null</tt> as its level will inherit its
0064         * effective level from its parent.
0065         * <p>
0066         * On each logging call the Logger initially performs a cheap
0067         * check of the request level (e.g. SEVERE or FINE) against the
0068         * effective log level of the logger.  If the request level is
0069         * lower than the log level, the logging call returns immediately.
0070         * <p>
0071         * After passing this initial (cheap) test, the Logger will allocate
0072         * a LogRecord to describe the logging message.  It will then call a 
0073         * Filter (if present) to do a more detailed check on whether the
0074         * record should be published.  If that passes it will then publish
0075         * the LogRecord to its output Handlers.  By default, loggers also
0076         * publish to their parent's Handlers, recursively up the tree.
0077         * <p>
0078         * Each Logger may have a ResourceBundle name associated with it.
0079         * The named bundle will be used for localizing logging messages.
0080         * If a Logger does not have its own ResourceBundle name, then
0081         * it will inherit the ResourceBundle name from its parent,
0082         * recursively up the tree.
0083         * <p>
0084         * Most of the logger output methods take a "msg" argument.  This
0085         * msg argument may be either a raw value or a localization key.
0086         * During formatting, if the logger has (or inherits) a localization
0087         * ResourceBundle and if the ResourceBundle has a mapping for the msg
0088         * string, then the msg string is replaced by the localized value.
0089         * Otherwise the original msg string is used.  Typically, formatters use
0090         * java.text.MessageFormat style formatting to format parameters, so
0091         * for example a format string "{0} {1}" would format two parameters
0092         * as strings.
0093         * <p>
0094         * When mapping ResourceBundle names to ResourceBundles, the Logger
0095         * will first try to use the Thread's ContextClassLoader.  If that
0096         * is null it will try the SystemClassLoader instead.  As a temporary
0097         * transition feature in the initial implementation, if the Logger is
0098         * unable to locate a ResourceBundle from the ContextClassLoader or
0099         * SystemClassLoader the Logger will also search up the class stack
0100         * and use successive calling ClassLoaders to try to locate a ResourceBundle.
0101         * (This call stack search is to allow containers to transition to
0102         * using ContextClassLoaders and is likely to be removed in future
0103         * versions.)
0104         * <p>
0105         * Formatting (including localization) is the responsibility of
0106         * the output Handler, which will typically call a Formatter.
0107         * <p>
0108         * Note that formatting need not occur synchronously.  It may be delayed
0109         * until a LogRecord is actually written to an external sink.
0110         * <p>
0111         * The logging methods are grouped in five main categories:
0112         * <ul>
0113         * <li><p>
0114         *     There are a set of "log" methods that take a log level, a message
0115         *     string, and optionally some parameters to the message string.
0116         * <li><p>
0117         *     There are a set of "logp" methods (for "log precise") that are
0118         *     like the "log" methods, but also take an explicit source class name
0119         *     and method name.
0120         * <li><p>
0121         *     There are a set of "logrb" method (for "log with resource bundle")
0122         *     that are like the "logp" method, but also take an explicit resource
0123         *     bundle name for use in localizing the log message.
0124         * <li><p>
0125         *     There are convenience methods for tracing method entries (the
0126         *     "entering" methods), method returns (the "exiting" methods) and
0127         *     throwing exceptions (the "throwing" methods).
0128         * <li><p>
0129         *     Finally, there are a set of convenience methods for use in the
0130         *     very simplest cases, when a developer simply wants to log a
0131         *     simple string at a given log level.  These methods are named
0132         *     after the standard Level names ("severe", "warning", "info", etc.)
0133         *     and take a single argument, a message string.
0134         * </ul>
0135         * <p>
0136         * For the methods that do not take an explicit source name and
0137         * method name, the Logging framework will make a "best effort"
0138         * to determine which class and method called into the logging method.
0139         * However, it is important to realize that this automatically inferred
0140         * information may only be approximate (or may even be quite wrong!).
0141         * Virtual machines are allowed to do extensive optimizations when
0142         * JITing and may entirely remove stack frames, making it impossible
0143         * to reliably locate the calling class and method.
0144         * <P>
0145         * All methods on Logger are multi-thread safe.
0146         * <p>
0147         * <b>Subclassing Information:</b> Note that a LogManager class may
0148         * provide its own implementation of named Loggers for any point in
0149         * the namespace.  Therefore, any subclasses of Logger (unless they
0150         * are implemented in conjunction with a new LogManager class) should
0151         * take care to obtain a Logger instance from the LogManager class and
0152         * should delegate operations such as "isLoggable" and "log(LogRecord)"
0153         * to that instance.  Note that in order to intercept all logging
0154         * output, subclasses need only override the log(LogRecord) method.
0155         * All the other logging methods are implemented as calls on this
0156         * log(LogRecord) method.
0157         *
0158         * @version 1.59, 06/06/07
0159         * @since 1.4
0160         */
0161
0162        public class Logger {
0163            private static final Handler emptyHandlers[] = new Handler[0];
0164            private static final int offValue = Level.OFF.intValue();
0165            private LogManager manager;
0166            private String name;
0167            private ArrayList<Handler> handlers;
0168            private String resourceBundleName;
0169            private boolean useParentHandlers = true;
0170            private Filter filter;
0171            private boolean anonymous;
0172
0173            private ResourceBundle catalog; // Cached resource bundle
0174            private String catalogName; // name associated with catalog
0175            private Locale catalogLocale; // locale associated with catalog
0176
0177            // The fields relating to parent-child relationships and levels
0178            // are managed under a separate lock, the treeLock.
0179            private static Object treeLock = new Object();
0180            // We keep weak references from parents to children, but strong
0181            // references from children to parents.
0182            private Logger parent; // our nearest parent.
0183            private ArrayList<WeakReference<Logger>> kids; // WeakReferences to loggers that have us as parent
0184            private Level levelObject;
0185            private volatile int levelValue; // current effective level value
0186
0187            /**
0188             * GLOBAL_LOGGER_NAME is a name for the global logger.
0189             * 
0190             * @since 1.6
0191             */
0192            public static final String GLOBAL_LOGGER_NAME = "global";
0193
0194            /**
0195             * Return global logger object with the name Logger.GLOBAL_LOGGER_NAME.
0196             * 
0197             * @return global logger object
0198             * @since 1.7
0199             */
0200            public static final Logger getGlobal() {
0201                return global;
0202            }
0203
0204            /**
0205             * The "global" Logger object is provided as a convenience to developers
0206             * who are making casual use of the Logging package.  Developers
0207             * who are making serious use of the logging package (for example
0208             * in products) should create and use their own Logger objects,
0209             * with appropriate names, so that logging can be controlled on a
0210             * suitable per-Logger granularity.
0211             * <p>
0212             * @deprecated Initialization of this field is prone to deadlocks.
0213             * The field must be initialized by the Logger class initialization
0214             * which may cause deadlocks with the LogManager class initialization.
0215             * In such cases two class initialization wait for each other to complete.
0216             * The preferred way to get the global logger object is via the call
0217             * <code>Logger.getGlobal()</code>.
0218             * For compatibility with old JDK versions where the
0219             * <code>Logger.getGlobal()</code> is not available use the call
0220             * <code>Logger.getLogger(Logger.GLOBAL_LOGGER_NAME)</code>
0221             * or <code>Logger.getLogger("global")</code>.
0222             */
0223            @Deprecated
0224            public static final Logger global = new Logger(GLOBAL_LOGGER_NAME);
0225
0226            /**
0227             * Protected method to construct a logger for a named subsystem.
0228             * <p>
0229             * The logger will be initially configured with a null Level
0230             * and with useParentHandlers true.
0231             *
0232             * @param	name	A name for the logger.  This should
0233             *				be a dot-separated name and should normally
0234             *				be based on the package name or class name
0235             *				of the subsystem, such as java.net
0236             *				or javax.swing.  It may be null for anonymous Loggers.
0237             * @param 	resourceBundleName  name of ResourceBundle to be used for localizing
0238             *				messages for this logger.  May be null if none
0239             *				of the messages require localization.
0240             * @throws MissingResourceException if the ResourceBundleName is non-null and
0241             *		   no corresponding resource can be found.
0242             */
0243            protected Logger(String name, String resourceBundleName) {
0244                this .manager = LogManager.getLogManager();
0245                if (resourceBundleName != null) {
0246                    // Note: we may get a MissingResourceException here.
0247                    setupResourceInfo(resourceBundleName);
0248                }
0249                this .name = name;
0250                levelValue = Level.INFO.intValue();
0251            }
0252
0253            // This constructor is used only to create the global Logger.
0254            // It is needed to break a cyclic dependence between the LogManager
0255            // and Logger static initializers causing deadlocks.
0256            private Logger(String name) {
0257                // The manager field is not initialized here.
0258                this .name = name;
0259                levelValue = Level.INFO.intValue();
0260            }
0261
0262            // It is called from the LogManager.<clinit> to complete
0263            // initialization of the global Logger.
0264            void setLogManager(LogManager manager) {
0265                this .manager = manager;
0266            }
0267
0268            private void checkAccess() throws SecurityException {
0269                if (!anonymous) {
0270                    if (manager == null) {
0271                        // Complete initialization of the global Logger.
0272                        manager = LogManager.getLogManager();
0273                    }
0274                    manager.checkAccess();
0275                }
0276            }
0277
0278            /**
0279             * Find or create a logger for a named subsystem.  If a logger has
0280             * already been created with the given name it is returned.  Otherwise
0281             * a new logger is created.
0282             * <p>
0283             * If a new logger is created its log level will be configured
0284             * based on the LogManager configuration and it will configured
0285             * to also send logging output to its parent's handlers.  It will
0286             * be registered in the LogManager global namespace.
0287             * 
0288             * @param	name		A name for the logger.  This should
0289             *				be a dot-separated name and should normally
0290             *				be based on the package name or class name
0291             *				of the subsystem, such as java.net
0292             *				or javax.swing
0293             * @return a suitable Logger
0294             * @throws NullPointerException if the name is null.
0295             */
0296            public static synchronized Logger getLogger(String name) {
0297                LogManager manager = LogManager.getLogManager();
0298                return manager.demandLogger(name);
0299            }
0300
0301            /**
0302             * Find or create a logger for a named subsystem.  If a logger has 
0303             * already been created with the given name it is returned.  Otherwise
0304             * a new logger is created.
0305             * <p>
0306             * If a new logger is created its log level will be configured
0307             * based on the LogManager and it will configured to also send logging
0308             * output to its parent loggers Handlers.  It will be registered in
0309             * the LogManager global namespace.
0310             * <p>
0311             * If the named Logger already exists and does not yet have a
0312             * localization resource bundle then the given resource bundle 
0313             * name is used.  If the named Logger already exists and has
0314             * a different resource bundle name then an IllegalArgumentException
0315             * is thrown.
0316             * <p>
0317             * @param	name	A name for the logger.  This should
0318             *				be a dot-separated name and should normally
0319             *				be based on the package name or class name
0320             *				of the subsystem, such as java.net
0321             *				or javax.swing
0322             * @param 	resourceBundleName  name of ResourceBundle to be used for localizing
0323             *				messages for this logger. May be <CODE>null</CODE> if none of 
0324             *				the messages require localization.
0325             * @return a suitable Logger
0326             * @throws MissingResourceException if the named ResourceBundle cannot be found.
0327             * @throws IllegalArgumentException if the Logger already exists and uses
0328             *		   a different resource bundle name.
0329             * @throws NullPointerException if the name is null.
0330             */
0331            public static synchronized Logger getLogger(String name,
0332                    String resourceBundleName) {
0333                LogManager manager = LogManager.getLogManager();
0334                Logger result = manager.demandLogger(name);
0335                if (result.resourceBundleName == null) {
0336                    // Note: we may get a MissingResourceException here.
0337                    result.setupResourceInfo(resourceBundleName);
0338                } else if (!result.resourceBundleName
0339                        .equals(resourceBundleName)) {
0340                    throw new IllegalArgumentException(
0341                            result.resourceBundleName + " != "
0342                                    + resourceBundleName);
0343                }
0344                return result;
0345            }
0346
0347            /**
0348             * Create an anonymous Logger.  The newly created Logger is not
0349             * registered in the LogManager namespace.  There will be no
0350             * access checks on updates to the logger.
0351             * <p>
0352             * This factory method is primarily intended for use from applets.
0353             * Because the resulting Logger is anonymous it can be kept private
0354             * by the creating class.  This removes the need for normal security
0355             * checks, which in turn allows untrusted applet code to update
0356             * the control state of the Logger.  For example an applet can do
0357             * a setLevel or an addHandler on an anonymous Logger.
0358             * <p>
0359             * Even although the new logger is anonymous, it is configured
0360             * to have the root logger ("") as its parent.  This means that
0361             * by default it inherits its effective level and handlers
0362             * from the root logger.
0363             * <p>
0364             *
0365             * @return a newly created private Logger
0366             */
0367            public static synchronized Logger getAnonymousLogger() {
0368                LogManager manager = LogManager.getLogManager();
0369                Logger result = new Logger(null, null);
0370                result.anonymous = true;
0371                Logger root = manager.getLogger("");
0372                result.doSetParent(root);
0373                return result;
0374            }
0375
0376            /**
0377             * Create an anonymous Logger.  The newly created Logger is not
0378             * registered in the LogManager namespace.  There will be no
0379             * access checks on updates to the logger.
0380             * <p>
0381             * This factory method is primarily intended for use from applets.
0382             * Because the resulting Logger is anonymous it can be kept private
0383             * by the creating class.  This removes the need for normal security
0384             * checks, which in turn allows untrusted applet code to update
0385             * the control state of the Logger.  For example an applet can do
0386             * a setLevel or an addHandler on an anonymous Logger.
0387             * <p>
0388             * Even although the new logger is anonymous, it is configured
0389             * to have the root logger ("") as its parent.  This means that
0390             * by default it inherits its effective level and handlers
0391             * from the root logger.
0392             * <p>
0393             * @param 	resourceBundleName  name of ResourceBundle to be used for localizing
0394             *				messages for this logger.
0395             *          May be null if none of the messages require localization.
0396             * @return a newly created private Logger
0397             * @throws MissingResourceException if the named ResourceBundle cannot be found.
0398             */
0399            public static synchronized Logger getAnonymousLogger(
0400                    String resourceBundleName) {
0401                LogManager manager = LogManager.getLogManager();
0402                Logger result = new Logger(null, resourceBundleName);
0403                result.anonymous = true;
0404                Logger root = manager.getLogger("");
0405                result.doSetParent(root);
0406                return result;
0407            }
0408
0409            /**
0410             * Retrieve the localization resource bundle for this
0411             * logger for the current default locale.  Note that if
0412             * the result is null, then the Logger will use a resource 
0413             * bundle inherited from its parent.
0414             *
0415             * @return localization bundle (may be null)
0416             */
0417            public ResourceBundle getResourceBundle() {
0418                return findResourceBundle(getResourceBundleName());
0419            }
0420
0421            /**
0422             * Retrieve the localization resource bundle name for this
0423             * logger.  Note that if the result is null, then the Logger
0424             * will use a resource bundle name inherited from its parent.
0425             *
0426             * @return localization bundle name (may be null)
0427             */
0428            public String getResourceBundleName() {
0429                return resourceBundleName;
0430            }
0431
0432            /**
0433             * Set a filter to control output on this Logger.
0434             * <P>
0435             * After passing the initial "level" check, the Logger will
0436             * call this Filter to check if a log record should really
0437             * be published.
0438             *
0439             * @param   newFilter  a filter object (may be null)
0440             * @exception  SecurityException  if a security manager exists and if
0441             *             the caller does not have LoggingPermission("control").
0442             */
0443            public synchronized void setFilter(Filter newFilter)
0444                    throws SecurityException {
0445                checkAccess();
0446                filter = newFilter;
0447            }
0448
0449            /**
0450             * Get the current filter for this Logger.
0451             *
0452             * @return  a filter object (may be null)
0453             */
0454            public synchronized Filter getFilter() {
0455                return filter;
0456            }
0457
0458            /**
0459             * Log a LogRecord.
0460             * <p>
0461             * All the other logging methods in this class call through
0462             * this method to actually perform any logging.  Subclasses can
0463             * override this single method to capture all log activity.
0464             *
0465             * @param record the LogRecord to be published
0466             */
0467            public void log(LogRecord record) {
0468                if (record.getLevel().intValue() < levelValue
0469                        || levelValue == offValue) {
0470                    return;
0471                }
0472                synchronized (this ) {
0473                    if (filter != null && !filter.isLoggable(record)) {
0474                        return;
0475                    }
0476                }
0477
0478                // Post the LogRecord to all our Handlers, and then to
0479                // our parents' handlers, all the way up the tree.
0480
0481                Logger logger = this ;
0482                while (logger != null) {
0483                    Handler targets[] = logger.getHandlers();
0484
0485                    if (targets != null) {
0486                        for (int i = 0; i < targets.length; i++) {
0487                            targets[i].publish(record);
0488                        }
0489                    }
0490
0491                    if (!logger.getUseParentHandlers()) {
0492                        break;
0493                    }
0494
0495                    logger = logger.getParent();
0496                }
0497            }
0498
0499            // private support method for logging.
0500            // We fill in the logger name, resource bundle name, and
0501            // resource bundle and then call "void log(LogRecord)".
0502            private void doLog(LogRecord lr) {
0503                lr.setLoggerName(name);
0504                String ebname = getEffectiveResourceBundleName();
0505                if (ebname != null) {
0506                    lr.setResourceBundleName(ebname);
0507                    lr.setResourceBundle(findResourceBundle(ebname));
0508                }
0509                log(lr);
0510            }
0511
0512            //================================================================
0513            // Start of convenience methods WITHOUT className and methodName
0514            //================================================================
0515
0516            /**
0517             * Log a message, with no arguments.
0518             * <p>
0519             * If the logger is currently enabled for the given message 
0520             * level then the given message is forwarded to all the
0521             * registered output Handler objects.
0522             * <p>
0523             * @param	level	One of the message level identifiers, e.g. SEVERE
0524             * @param   msg	The string message (or a key in the message catalog)
0525             */
0526            public void log(Level level, String msg) {
0527                if (level.intValue() < levelValue || levelValue == offValue) {
0528                    return;
0529                }
0530                LogRecord lr = new LogRecord(level, msg);
0531                doLog(lr);
0532            }
0533
0534            /**
0535             * Log a message, with one object parameter.
0536             * <p>
0537             * If the logger is currently enabled for the given message 
0538             * level then a corresponding LogRecord is created and forwarded 
0539             * to all the registered output Handler objects.
0540             * <p>
0541             * @param	level   One of the message level identifiers, e.g. SEVERE
0542             * @param   msg	The string message (or a key in the message catalog)
0543             * @param   param1	parameter to the message
0544             */
0545            public void log(Level level, String msg, Object param1) {
0546                if (level.intValue() < levelValue || levelValue == offValue) {
0547                    return;
0548                }
0549                LogRecord lr = new LogRecord(level, msg);
0550                Object params[] = { param1 };
0551                lr.setParameters(params);
0552                doLog(lr);
0553            }
0554
0555            /**
0556             * Log a message, with an array of object arguments.
0557             * <p>
0558             * If the logger is currently enabled for the given message 
0559             * level then a corresponding LogRecord is created and forwarded 
0560             * to all the registered output Handler objects.
0561             * <p>
0562             * @param	level   One of the message level identifiers, e.g. SEVERE
0563             * @param   msg	The string message (or a key in the message catalog)
0564             * @param   params	array of parameters to the message
0565             */
0566            public void log(Level level, String msg, Object params[]) {
0567                if (level.intValue() < levelValue || levelValue == offValue) {
0568                    return;
0569                }
0570                LogRecord lr = new LogRecord(level, msg);
0571                lr.setParameters(params);
0572                doLog(lr);
0573            }
0574
0575            /**
0576             * Log a message, with associated Throwable information.
0577             * <p>
0578             * If the logger is currently enabled for the given message 
0579             * level then the given arguments are stored in a LogRecord
0580             * which is forwarded to all registered output handlers.
0581             * <p>
0582             * Note that the thrown argument is stored in the LogRecord thrown
0583             * property, rather than the LogRecord parameters property.  Thus is it
0584             * processed specially by output Formatters and is not treated
0585             * as a formatting parameter to the LogRecord message property.
0586             * <p>
0587             * @param	level   One of the message level identifiers, e.g. SEVERE
0588             * @param   msg	The string message (or a key in the message catalog)
0589             * @param   thrown  Throwable associated with log message.
0590             */
0591            public void log(Level level, String msg, Throwable thrown) {
0592                if (level.intValue() < levelValue || levelValue == offValue) {
0593                    return;
0594                }
0595                LogRecord lr = new LogRecord(level, msg);
0596                lr.setThrown(thrown);
0597                doLog(lr);
0598            }
0599
0600            //================================================================
0601            // Start of convenience methods WITH className and methodName
0602            //================================================================
0603
0604            /**
0605             * Log a message, specifying source class and method,
0606             * with no arguments.
0607             * <p>
0608             * If the logger is currently enabled for the given message 
0609             * level then the given message is forwarded to all the
0610             * registered output Handler objects.
0611             * <p>
0612             * @param	level	One of the message level identifiers, e.g. SEVERE
0613             * @param   sourceClass    name of class that issued the logging request
0614             * @param   sourceMethod   name of method that issued the logging request
0615             * @param   msg	The string message (or a key in the message catalog)
0616             */
0617            public void logp(Level level, String sourceClass,
0618                    String sourceMethod, String msg) {
0619                if (level.intValue() < levelValue || levelValue == offValue) {
0620                    return;
0621                }
0622                LogRecord lr = new LogRecord(level, msg);
0623                lr.setSourceClassName(sourceClass);
0624                lr.setSourceMethodName(sourceMethod);
0625                doLog(lr);
0626            }
0627
0628            /**
0629             * Log a message, specifying source class and method,
0630             * with a single object parameter to the log message.
0631             * <p>
0632             * If the logger is currently enabled for the given message 
0633             * level then a corresponding LogRecord is created and forwarded 
0634             * to all the registered output Handler objects.
0635             * <p>
0636             * @param	level   One of the message level identifiers, e.g. SEVERE
0637             * @param   sourceClass    name of class that issued the logging request
0638             * @param   sourceMethod   name of method that issued the logging request
0639             * @param   msg	 The string message (or a key in the message catalog)
0640             * @param   param1    Parameter to the log message.
0641             */
0642            public void logp(Level level, String sourceClass,
0643                    String sourceMethod, String msg, Object param1) {
0644                if (level.intValue() < levelValue || levelValue == offValue) {
0645                    return;
0646                }
0647                LogRecord lr = new LogRecord(level, msg);
0648                lr.setSourceClassName(sourceClass);
0649                lr.setSourceMethodName(sourceMethod);
0650                Object params[] = { param1 };
0651                lr.setParameters(params);
0652                doLog(lr);
0653            }
0654
0655            /**
0656             * Log a message, specifying source class and method,
0657             * with an array of object arguments.
0658             * <p>
0659             * If the logger is currently enabled for the given message 
0660             * level then a corresponding LogRecord is created and forwarded 
0661             * to all the registered output Handler objects.
0662             * <p>
0663             * @param	level   One of the message level identifiers, e.g. SEVERE
0664             * @param   sourceClass    name of class that issued the logging request
0665             * @param   sourceMethod   name of method that issued the logging request
0666             * @param   msg	The string message (or a key in the message catalog)
0667             * @param   params	Array of parameters to the message
0668             */
0669            public void logp(Level level, String sourceClass,
0670                    String sourceMethod, String msg, Object params[]) {
0671                if (level.intValue() < levelValue || levelValue == offValue) {
0672                    return;
0673                }
0674                LogRecord lr = new LogRecord(level, msg);
0675                lr.setSourceClassName(sourceClass);
0676                lr.setSourceMethodName(sourceMethod);
0677                lr.setParameters(params);
0678                doLog(lr);
0679            }
0680
0681            /**
0682             * Log a message, specifying source class and method,
0683             * with associated Throwable information.
0684             * <p>
0685             * If the logger is currently enabled for the given message 
0686             * level then the given arguments are stored in a LogRecord
0687             * which is forwarded to all registered output handlers.
0688             * <p>
0689             * Note that the thrown argument is stored in the LogRecord thrown
0690             * property, rather than the LogRecord parameters property.  Thus is it
0691             * processed specially by output Formatters and is not treated
0692             * as a formatting parameter to the LogRecord message property.
0693             * <p>
0694             * @param	level   One of the message level identifiers, e.g. SEVERE
0695             * @param   sourceClass    name of class that issued the logging request
0696             * @param   sourceMethod   name of method that issued the logging request
0697             * @param   msg	The string message (or a key in the message catalog)
0698             * @param   thrown  Throwable associated with log message.
0699             */
0700            public void logp(Level level, String sourceClass,
0701                    String sourceMethod, String msg, Throwable thrown) {
0702                if (level.intValue() < levelValue || levelValue == offValue) {
0703                    return;
0704                }
0705                LogRecord lr = new LogRecord(level, msg);
0706                lr.setSourceClassName(sourceClass);
0707                lr.setSourceMethodName(sourceMethod);
0708                lr.setThrown(thrown);
0709                doLog(lr);
0710            }
0711
0712            //=========================================================================
0713            // Start of convenience methods WITH className, methodName and bundle name.
0714            //=========================================================================
0715
0716            // Private support method for logging for "logrb" methods.
0717            // We fill in the logger name, resource bundle name, and
0718            // resource bundle and then call "void log(LogRecord)".
0719            private void doLog(LogRecord lr, String rbname) {
0720                lr.setLoggerName(name);
0721                if (rbname != null) {
0722                    lr.setResourceBundleName(rbname);
0723                    lr.setResourceBundle(findResourceBundle(rbname));
0724                }
0725                log(lr);
0726            }
0727
0728            /**
0729             * Log a message, specifying source class, method, and resource bundle name
0730             * with no arguments.
0731             * <p>
0732             * If the logger is currently enabled for the given message 
0733             * level then the given message is forwarded to all the
0734             * registered output Handler objects.
0735             * <p>
0736             * The msg string is localized using the named resource bundle.  If the
0737             * resource bundle name is null, or an empty String or invalid
0738             * then the msg string is not localized.
0739             * <p>
0740             * @param	level	One of the message level identifiers, e.g. SEVERE
0741             * @param   sourceClass    name of class that issued the logging request
0742             * @param   sourceMethod   name of method that issued the logging request
0743             * @param   bundleName     name of resource bundle to localize msg, 
0744             *                         can be null
0745             * @param   msg	The string message (or a key in the message catalog)
0746             */
0747
0748            public void logrb(Level level, String sourceClass,
0749                    String sourceMethod, String bundleName, String msg) {
0750                if (level.intValue() < levelValue || levelValue == offValue) {
0751                    return;
0752                }
0753                LogRecord lr = new LogRecord(level, msg);
0754                lr.setSourceClassName(sourceClass);
0755                lr.setSourceMethodName(sourceMethod);
0756                doLog(lr, bundleName);
0757            }
0758
0759            /**
0760             * Log a message, specifying source class, method, and resource bundle name,
0761             * with a single object parameter to the log message.
0762             * <p>
0763             * If the logger is currently enabled for the given message 
0764             * level then a corresponding LogRecord is created and forwarded 
0765             * to all the registered output Handler objects.
0766             * <p>
0767             * The msg string is localized using the named resource bundle.  If the
0768             * resource bundle name is null, or an empty String or invalid
0769             * then the msg string is not localized.
0770             * <p>
0771             * @param	level   One of the message level identifiers, e.g. SEVERE
0772             * @param   sourceClass    name of class that issued the logging request
0773             * @param   sourceMethod   name of method that issued the logging request
0774             * @param   bundleName     name of resource bundle to localize msg,
0775             *                         can be null
0776             * @param   msg	 The string message (or a key in the message catalog)
0777             * @param   param1    Parameter to the log message.
0778             */
0779            public void logrb(Level level, String sourceClass,
0780                    String sourceMethod, String bundleName, String msg,
0781                    Object param1) {
0782                if (level.intValue() < levelValue || levelValue == offValue) {
0783                    return;
0784                }
0785                LogRecord lr = new LogRecord(level, msg);
0786                lr.setSourceClassName(sourceClass);
0787                lr.setSourceMethodName(sourceMethod);
0788                Object params[] = { param1 };
0789                lr.setParameters(params);
0790                doLog(lr, bundleName);
0791            }
0792
0793            /**
0794             * Log a message, specifying source class, method, and resource bundle name,
0795             * with an array of object arguments.
0796             * <p>
0797             * If the logger is currently enabled for the given message 
0798             * level then a corresponding LogRecord is created and forwarded 
0799             * to all the registered output Handler objects.
0800             * <p>
0801             * The msg string is localized using the named resource bundle.  If the
0802             * resource bundle name is null, or an empty String or invalid
0803             * then the msg string is not localized.
0804             * <p>
0805             * @param	level   One of the message level identifiers, e.g. SEVERE
0806             * @param   sourceClass    name of class that issued the logging request
0807             * @param   sourceMethod   name of method that issued the logging request
0808             * @param   bundleName     name of resource bundle to localize msg,
0809             *                         can be null.
0810             * @param   msg	The string message (or a key in the message catalog)
0811             * @param   params	Array of parameters to the message
0812             */
0813            public void logrb(Level level, String sourceClass,
0814                    String sourceMethod, String bundleName, String msg,
0815                    Object params[]) {
0816                if (level.intValue() < levelValue || levelValue == offValue) {
0817                    return;
0818                }
0819                LogRecord lr = new LogRecord(level, msg);
0820                lr.setSourceClassName(sourceClass);
0821                lr.setSourceMethodName(sourceMethod);
0822                lr.setParameters(params);
0823                doLog(lr, bundleName);
0824            }
0825
0826            /**
0827             * Log a message, specifying source class, method, and resource bundle name,
0828             * with associated Throwable information.
0829             * <p>
0830             * If the logger is currently enabled for the given message 
0831             * level then the given arguments are stored in a LogRecord
0832             * which is forwarded to all registered output handlers.
0833             * <p>
0834             * The msg string is localized using the named resource bundle.  If the
0835             * resource bundle name is null, or an empty String or invalid
0836             * then the msg string is not localized.
0837             * <p>
0838             * Note that the thrown argument is stored in the LogRecord thrown
0839             * property, rather than the LogRecord parameters property.  Thus is it
0840             * processed specially by output Formatters and is not treated
0841             * as a formatting parameter to the LogRecord message property.
0842             * <p>
0843             * @param	level   One of the message level identifiers, e.g. SEVERE
0844             * @param   sourceClass    name of class that issued the logging request
0845             * @param   sourceMethod   name of method that issued the logging request
0846             * @param   bundleName     name of resource bundle to localize msg,
0847             *                         can be null
0848             * @param   msg	The string message (or a key in the message catalog)
0849             * @param   thrown  Throwable associated with log message.
0850             */
0851            public void logrb(Level level, String sourceClass,
0852                    String sourceMethod, String bundleName, String msg,
0853                    Throwable thrown) {
0854                if (level.intValue() < levelValue || levelValue == offValue) {
0855                    return;
0856                }
0857                LogRecord lr = new LogRecord(level, msg);
0858                lr.setSourceClassName(sourceClass);
0859                lr.setSourceMethodName(sourceMethod);
0860                lr.setThrown(thrown);
0861                doLog(lr, bundleName);
0862            }
0863
0864            //======================================================================
0865            // Start of convenience methods for logging method entries and returns.
0866            //======================================================================
0867
0868            /**
0869             * Log a method entry.
0870             * <p>
0871             * This is a convenience method that can be used to log entry
0872             * to a method.  A LogRecord with message "ENTRY", log level
0873             * FINER, and the given sourceMethod and sourceClass is logged.
0874             * <p>
0875             * @param   sourceClass    name of class that issued the logging request
0876             * @param   sourceMethod   name of method that is being entered
0877             */
0878            public void entering(String sourceClass, String sourceMethod) {
0879                if (Level.FINER.intValue() < levelValue) {
0880                    return;
0881                }
0882                logp(Level.FINER, sourceClass, sourceMethod, "ENTRY");
0883            }
0884
0885            /**
0886             * Log a method entry, with one parameter.
0887             * <p>
0888             * This is a convenience method that can be used to log entry
0889             * to a method.  A LogRecord with message "ENTRY {0}", log level
0890             * FINER, and the given sourceMethod, sourceClass, and parameter
0891             * is logged.
0892             * <p>
0893             * @param   sourceClass    name of class that issued the logging request
0894             * @param   sourceMethod   name of method that is being entered
0895             * @param   param1	       parameter to the method being entered
0896             */
0897            public void entering(String sourceClass, String sourceMethod,
0898                    Object param1) {
0899                if (Level.FINER.intValue() < levelValue) {
0900                    return;
0901                }
0902                Object params[] = { param1 };
0903                logp(Level.FINER, sourceClass, sourceMethod, "ENTRY {0}",
0904                        params);
0905            }
0906
0907            /**
0908             * Log a method entry, with an array of parameters.
0909             * <p>
0910             * This is a convenience method that can be used to log entry
0911             * to a method.  A LogRecord with message "ENTRY" (followed by a 
0912             * format {N} indicator for each entry in the parameter array), 
0913             * log level FINER, and the given sourceMethod, sourceClass, and 
0914             * parameters is logged.
0915             * <p>
0916             * @param   sourceClass    name of class that issued the logging request
0917             * @param   sourceMethod   name of method that is being entered
0918             * @param   params	       array of parameters to the method being entered
0919             */
0920            public void entering(String sourceClass, String sourceMethod,
0921                    Object params[]) {
0922                if (Level.FINER.intValue() < levelValue) {
0923                    return;
0924                }
0925                String msg = "ENTRY";
0926                if (params == null) {
0927                    logp(Level.FINER, sourceClass, sourceMethod, msg);
0928                    return;
0929                }
0930                for (int i = 0; i < params.length; i++) {
0931                    msg = msg + " {" + i + "}";
0932                }
0933                logp(Level.FINER, sourceClass, sourceMethod, msg, params);
0934            }
0935
0936            /**
0937             * Log a method return.
0938             * <p>
0939             * This is a convenience method that can be used to log returning
0940             * from a method.  A LogRecord with message "RETURN", log level
0941             * FINER, and the given sourceMethod and sourceClass is logged.
0942             * <p>
0943             * @param   sourceClass    name of class that issued the logging request
0944             * @param   sourceMethod   name of the method 
0945             */
0946            public void exiting(String sourceClass, String sourceMethod) {
0947                if (Level.FINER.intValue() < levelValue) {
0948                    return;
0949                }
0950                logp(Level.FINER, sourceClass, sourceMethod, "RETURN");
0951            }
0952
0953            /**
0954             * Log a method return, with result object.
0955             * <p>
0956             * This is a convenience method that can be used to log returning
0957             * from a method.  A LogRecord with message "RETURN {0}", log level
0958             * FINER, and the gives sourceMethod, sourceClass, and result
0959             * object is logged.
0960             * <p>
0961             * @param   sourceClass    name of class that issued the logging request
0962             * @param   sourceMethod   name of the method 
0963             * @param   result  Object that is being returned
0964             */
0965            public void exiting(String sourceClass, String sourceMethod,
0966                    Object result) {
0967                if (Level.FINER.intValue() < levelValue) {
0968                    return;
0969                }
0970                Object params[] = { result };
0971                logp(Level.FINER, sourceClass, sourceMethod, "RETURN {0}",
0972                        result);
0973            }
0974
0975            /**
0976             * Log throwing an exception.
0977             * <p>
0978             * This is a convenience method to log that a method is
0979             * terminating by throwing an exception.  The logging is done 
0980             * using the FINER level.
0981             * <p>
0982             * If the logger is currently enabled for the given message 
0983             * level then the given arguments are stored in a LogRecord
0984             * which is forwarded to all registered output handlers.  The
0985             * LogRecord's message is set to "THROW".
0986             * <p>
0987             * Note that the thrown argument is stored in the LogRecord thrown
0988             * property, rather than the LogRecord parameters property.  Thus is it
0989             * processed specially by output Formatters and is not treated
0990             * as a formatting parameter to the LogRecord message property.
0991             * <p>
0992             * @param   sourceClass    name of class that issued the logging request
0993             * @param   sourceMethod  name of the method.
0994             * @param   thrown  The Throwable that is being thrown.
0995             */
0996            public void throwing(String sourceClass, String sourceMethod,
0997                    Throwable thrown) {
0998                if (Level.FINER.intValue() < levelValue
0999                        || levelValue == offValue) {
1000                    return;
1001                }
1002                LogRecord lr = new LogRecord(Level.FINER, "THROW");
1003                lr.setSourceClassName(sourceClass);
1004                lr.setSourceMethodName(sourceMethod);
1005                lr.setThrown(thrown);
1006                doLog(lr);
1007            }
1008
1009            //=======================================================================
1010            // Start of simple convenience methods using level names as method names
1011            //=======================================================================
1012
1013            /**
1014             * Log a SEVERE message.
1015             * <p>
1016             * If the logger is currently enabled for the SEVERE message 
1017             * level then the given message is forwarded to all the
1018             * registered output Handler objects.
1019             * <p>
1020             * @param   msg	The string message (or a key in the message catalog)
1021             */
1022            public void severe(String msg) {
1023                if (Level.SEVERE.intValue() < levelValue) {
1024                    return;
1025                }
1026                log(Level.SEVERE, msg);
1027            }
1028
1029            /**
1030             * Log a WARNING message.
1031             * <p>
1032             * If the logger is currently enabled for the WARNING message 
1033             * level then the given message is forwarded to all the
1034             * registered output Handler objects.
1035             * <p>
1036             * @param   msg	The string message (or a key in the message catalog)
1037             */
1038            public void warning(String msg) {
1039                if (Level.WARNING.intValue() < levelValue) {
1040                    return;
1041                }
1042                log(Level.WARNING, msg);
1043            }
1044
1045            /**
1046             * Log an INFO message.
1047             * <p>
1048             * If the logger is currently enabled for the INFO message 
1049             * level then the given message is forwarded to all the
1050             * registered output Handler objects.
1051             * <p>
1052             * @param   msg	The string message (or a key in the message catalog)
1053             */
1054            public void info(String msg) {
1055                if (Level.INFO.intValue() < levelValue) {
1056                    return;
1057                }
1058                log(Level.INFO, msg);
1059            }
1060
1061            /**
1062             * Log a CONFIG message.
1063             * <p>
1064             * If the logger is currently enabled for the CONFIG message 
1065             * level then the given message is forwarded to all the
1066             * registered output Handler objects.
1067             * <p>
1068             * @param   msg	The string message (or a key in the message catalog)
1069             */
1070            public void config(String msg) {
1071                if (Level.CONFIG.intValue() < levelValue) {
1072                    return;
1073                }
1074                log(Level.CONFIG, msg);
1075            }
1076
1077            /**
1078             * Log a FINE message.
1079             * <p>
1080             * If the logger is currently enabled for the FINE message 
1081             * level then the given message is forwarded to all the
1082             * registered output Handler objects.
1083             * <p>
1084             * @param   msg	The string message (or a key in the message catalog)
1085             */
1086            public void fine(String msg) {
1087                if (Level.FINE.intValue() < levelValue) {
1088                    return;
1089                }
1090                log(Level.FINE, msg);
1091            }
1092
1093            /**
1094             * Log a FINER message.
1095             * <p>
1096             * If the logger is currently enabled for the FINER message 
1097             * level then the given message is forwarded to all the
1098             * registered output Handler objects.
1099             * <p>
1100             * @param   msg	The string message (or a key in the message catalog)
1101             */
1102            public void finer(String msg) {
1103                if (Level.FINER.intValue() < levelValue) {
1104                    return;
1105                }
1106                log(Level.FINER, msg);
1107            }
1108
1109            /**
1110             * Log a FINEST message.
1111             * <p>
1112             * If the logger is currently enabled for the FINEST message 
1113             * level then the given message is forwarded to all the
1114             * registered output Handler objects.
1115             * <p>
1116             * @param   msg	The string message (or a key in the message catalog)
1117             */
1118            public void finest(String msg) {
1119                if (Level.FINEST.intValue() < levelValue) {
1120                    return;
1121                }
1122                log(Level.FINEST, msg);
1123            }
1124
1125            //================================================================
1126            // End of convenience methods 
1127            //================================================================
1128
1129            /**
1130             * Set the log level specifying which message levels will be
1131             * logged by this logger.  Message levels lower than this
1132             * value will be discarded.  The level value Level.OFF
1133             * can be used to turn off logging.
1134             * <p>
1135             * If the new level is null, it means that this node should
1136             * inherit its level from its nearest ancestor with a specific
1137             * (non-null) level value.
1138             * 
1139             * @param newLevel   the new value for the log level (may be null)
1140             * @exception  SecurityException  if a security manager exists and if
1141             *             the caller does not have LoggingPermission("control").
1142             */
1143            public void setLevel(Level newLevel) throws SecurityException {
1144                checkAccess();
1145                synchronized (treeLock) {
1146                    levelObject = newLevel;
1147                    updateEffectiveLevel();
1148                }
1149            }
1150
1151            /**
1152             * Get the log Level that has been specified for this Logger.
1153             * The result may be null, which means that this logger's
1154             * effective level will be inherited from its parent.
1155             *
1156             * @return	this Logger's level
1157             */
1158            public Level getLevel() {
1159                return levelObject;
1160            }
1161
1162            /**
1163             * Check if a message of the given level would actually be logged
1164             * by this logger.  This check is based on the Loggers effective level,
1165             * which may be inherited from its parent.
1166             *
1167             * @param	level	a message logging level
1168             * @return	true if the given message level is currently being logged.
1169             */
1170            public boolean isLoggable(Level level) {
1171                if (level.intValue() < levelValue || levelValue == offValue) {
1172                    return false;
1173                }
1174                return true;
1175            }
1176
1177            /**
1178             * Get the name for this logger.
1179             * @return logger name.  Will be null for anonymous Loggers.
1180             */
1181            public String getName() {
1182                return name;
1183            }
1184
1185            /**
1186             * Add a log Handler to receive logging messages.
1187             * <p>
1188             * By default, Loggers also send their output to their parent logger.
1189             * Typically the root Logger is configured with a set of Handlers
1190             * that essentially act as default handlers for all loggers.
1191             *
1192             * @param	handler	a logging Handler
1193             * @exception  SecurityException  if a security manager exists and if
1194             *             the caller does not have LoggingPermission("control").
1195             */
1196            public synchronized void addHandler(Handler handler)
1197                    throws SecurityException {
1198                // Check for null handler
1199                handler.getClass();
1200                checkAccess();
1201                if (handlers == null) {
1202                    handlers = new ArrayList<Handler>();
1203                }
1204                handlers.add(handler);
1205            }
1206
1207            /**
1208             * Remove a log Handler.
1209             * <P>
1210             * Returns silently if the given Handler is not found or is null
1211             * 
1212             * @param	handler	a logging Handler
1213             * @exception  SecurityException  if a security manager exists and if
1214             *             the caller does not have LoggingPermission("control").
1215             */
1216            public synchronized void removeHandler(Handler handler)
1217                    throws SecurityException {
1218                checkAccess();
1219                if (handler == null) {
1220                    return;
1221                }
1222                if (handlers == null) {
1223                    return;
1224                }
1225                handlers.remove(handler);
1226            }
1227
1228            /**
1229             * Get the Handlers associated with this logger.
1230             * <p>
1231             * @return  an array of all registered Handlers
1232             */
1233            public synchronized Handler[] getHandlers() {
1234                if (handlers == null) {
1235                    return emptyHandlers;
1236                }
1237                Handler result[] = new Handler[handlers.size()];
1238                result = (Handler[]) handlers.toArray(result);
1239                return result;
1240            }
1241
1242            /**
1243             * Specify whether or not this logger should send its output
1244             * to it's parent Logger.  This means that any LogRecords will
1245             * also be written to the parent's Handlers, and potentially
1246             * to its parent, recursively up the namespace.
1247             *
1248             * @param useParentHandlers   true if output is to be sent to the
1249             *		logger's parent.
1250             * @exception  SecurityException  if a security manager exists and if
1251             *             the caller does not have LoggingPermission("control").
1252             */
1253            public synchronized void setUseParentHandlers(
1254                    boolean useParentHandlers) {
1255                checkAccess();
1256                this .useParentHandlers = useParentHandlers;
1257            }
1258
1259            /**
1260             * Discover whether or not this logger is sending its output
1261             * to its parent logger.
1262             *
1263             * @return  true if output is to be sent to the logger's parent
1264             */
1265            public synchronized boolean getUseParentHandlers() {
1266                return useParentHandlers;
1267            }
1268
1269            // Private utility method to map a resource bundle name to an
1270            // actual resource bundle, using a simple one-entry cache.
1271            // Returns null for a null name.
1272            // May also return null if we can't find the resource bundle and
1273            // there is no suitable previous cached value.
1274
1275            private synchronized ResourceBundle findResourceBundle(String name) {
1276                // Return a null bundle for a null name.
1277                if (name == null) {
1278                    return null;
1279                }
1280
1281                Locale currentLocale = Locale.getDefault();
1282
1283                // Normally we should hit on our simple one entry cache.
1284                if (catalog != null && currentLocale == catalogLocale
1285                        && name == catalogName) {
1286                    return catalog;
1287                }
1288
1289                // Use the thread's context ClassLoader.  If there isn't one,
1290                // use the SystemClassloader.
1291                ClassLoader cl = Thread.currentThread().getContextClassLoader();
1292                if (cl == null) {
1293                    cl = ClassLoader.getSystemClassLoader();
1294                }
1295                try {
1296                    catalog = ResourceBundle.getBundle(name, currentLocale, cl);
1297                    catalogName = name;
1298                    catalogLocale = currentLocale;
1299                    return catalog;
1300                } catch (MissingResourceException ex) {
1301                    // Woops.  We can't find the ResourceBundle in the default
1302                    // ClassLoader.  Drop through.
1303                }
1304
1305                // Fall back to searching up the call stack and trying each
1306                // calling ClassLoader.
1307                for (int ix = 0;; ix++) {
1308                    Class clz = sun.reflect.Reflection.getCallerClass(ix);
1309                    if (clz == null) {
1310                        break;
1311                    }
1312                    ClassLoader cl2 = clz.getClassLoader();
1313                    if (cl2 == null) {
1314                        cl2 = ClassLoader.getSystemClassLoader();
1315                    }
1316                    if (cl == cl2) {
1317                        // We've already checked this classloader.
1318                        continue;
1319                    }
1320                    cl = cl2;
1321                    try {
1322                        catalog = ResourceBundle.getBundle(name, currentLocale,
1323                                cl);
1324                        catalogName = name;
1325                        catalogLocale = currentLocale;
1326                        return catalog;
1327                    } catch (MissingResourceException ex) {
1328                        // Ok, this one didn't work either.
1329                        // Drop through, and try the next one.
1330                    }
1331                }
1332
1333                if (name.equals(catalogName)) {
1334                    // Return the previous cached value for that name.
1335                    // This may be null.
1336                    return catalog;
1337                }
1338                // Sorry, we're out of luck.
1339                return null;
1340            }
1341
1342            // Private utility method to initialize our one entry
1343            // resource bundle cache.
1344            // Note: for consistency reasons, we are careful to check
1345            // that a suitable ResourceBundle exists before setting the
1346            // ResourceBundleName.
1347            private synchronized void setupResourceInfo(String name) {
1348                if (name == null) {
1349                    return;
1350                }
1351                ResourceBundle rb = findResourceBundle(name);
1352                if (rb == null) {
1353                    // We've failed to find an expected ResourceBundle.
1354                    throw new MissingResourceException("Can't find " + name
1355                            + " bundle", name, "");
1356                }
1357                resourceBundleName = name;
1358            }
1359
1360            /**
1361             * Return the parent for this Logger.
1362             * <p>
1363             * This method returns the nearest extant parent in the namespace.
1364             * Thus if a Logger is called "a.b.c.d", and a Logger called "a.b"
1365             * has been created but no logger "a.b.c" exists, then a call of
1366             * getParent on the Logger "a.b.c.d" will return the Logger "a.b".
1367             * <p>
1368             * The result will be null if it is called on the root Logger
1369             * in the namespace.
1370             * 
1371             * @return nearest existing parent Logger 
1372             */
1373            public Logger getParent() {
1374                synchronized (treeLock) {
1375                    return parent;
1376                }
1377            }
1378
1379            /**
1380             * Set the parent for this Logger.  This method is used by
1381             * the LogManager to update a Logger when the namespace changes.
1382             * <p>
1383             * It should not be called from application code.
1384             * <p>
1385             * @param  parent   the new parent logger
1386             * @exception  SecurityException  if a security manager exists and if
1387             *             the caller does not have LoggingPermission("control").
1388             */
1389            public void setParent(Logger parent) {
1390                if (parent == null) {
1391                    throw new NullPointerException();
1392                }
1393                manager.checkAccess();
1394                doSetParent(parent);
1395            }
1396
1397            // Private method to do the work for parenting a child
1398            // Logger onto a parent logger.
1399            private void doSetParent(Logger newParent) {
1400
1401                // System.err.println("doSetParent \"" + getName() + "\" \"" 
1402                //				+ newParent.getName() + "\"");
1403
1404                synchronized (treeLock) {
1405
1406                    // Remove ourself from any previous parent.
1407                    if (parent != null) {
1408                        // assert parent.kids != null;
1409                        for (Iterator<WeakReference<Logger>> iter = parent.kids
1410                                .iterator(); iter.hasNext();) {
1411                            WeakReference<Logger> ref = iter.next();
1412                            Logger kid = ref.get();
1413                            if (kid == this ) {
1414                                iter.remove();
1415                                break;
1416                            }
1417                        }
1418                        // We have now removed ourself from our parents' kids.
1419                    }
1420
1421                    // Set our new parent.
1422                    parent = newParent;
1423                    if (parent.kids == null) {
1424                        parent.kids = new ArrayList<WeakReference<Logger>>(2);
1425                    }
1426                    parent.kids.add(new WeakReference<Logger>(this ));
1427
1428                    // As a result of the reparenting, the effective level
1429                    // may have changed for us and our children.
1430                    updateEffectiveLevel();
1431
1432                }
1433            }
1434
1435            // Recalculate the effective level for this node and
1436            // recursively for our children.
1437
1438            private void updateEffectiveLevel() {
1439                // assert Thread.holdsLock(treeLock);
1440
1441                // Figure out our current effective level.
1442                int newLevelValue;
1443                if (levelObject != null) {
1444                    newLevelValue = levelObject.intValue();
1445                } else {
1446                    if (parent != null) {
1447                        newLevelValue = parent.levelValue;
1448                    } else {
1449                        // This may happen during initialization.
1450                        newLevelValue = Level.INFO.intValue();
1451                    }
1452                }
1453
1454                // If our effective value hasn't changed, we're done.
1455                if (levelValue == newLevelValue) {
1456                    return;
1457                }
1458
1459                levelValue = newLevelValue;
1460
1461                // System.err.println("effective level: \"" + getName() + "\" := " + level);
1462
1463                // Recursively update the level on each of our kids.
1464                if (kids != null) {
1465                    for (int i = 0; i < kids.size(); i++) {
1466                        WeakReference<Logger> ref = kids.get(i);
1467                        Logger kid = ref.get();
1468                        if (kid != null) {
1469                            kid.updateEffectiveLevel();
1470                        }
1471                    }
1472                }
1473            }
1474
1475            // Private method to get the potentially inherited
1476            // resource bundle name for this Logger.
1477            // May return null
1478            private String getEffectiveResourceBundleName() {
1479                Logger target = this ;
1480                while (target != null) {
1481                    String rbn = target.getResourceBundleName();
1482                    if (rbn != null) {
1483                        return rbn;
1484                    }
1485                    target = target.getParent();
1486                }
1487                return null;
1488            }
1489
1490        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.