151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski/*
22c87ad3a45cecf9e344487cad1abfdebe79f2c7cNarayan Kamath * Copyright (C) 2014 The Android Open Source Project
34ff539dbc5a809ef3eacbe2d9f2b97f640b7e9cfPrzemyslaw Szczepaniak * Copyright (c) 2000, 2014, Oracle and/or its affiliates. All rights reserved.
451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski *
651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * This code is free software; you can redistribute it and/or modify it
751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * under the terms of the GNU General Public License version 2 only, as
851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * published by the Free Software Foundation.  Oracle designates this
951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * particular file as subject to the "Classpath" exception as provided
1051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * by Oracle in the LICENSE file that accompanied this code.
1151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski *
1251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * This code is distributed in the hope that it will be useful, but WITHOUT
1351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
1451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
1551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * version 2 for more details (a copy is included in the LICENSE file that
1651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * accompanied this code).
1751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski *
1851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * You should have received a copy of the GNU General Public License version
1951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * 2 along with this work; if not, write to the Free Software Foundation,
2051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
2151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski *
2251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
2351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * or visit www.oracle.com if you need additional information or have any
2451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * questions.
2551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */
2651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
2751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
2851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebskipackage java.util.logging;
2951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
3047f3c98d3c706c02c898cd15fbe6ee19d840c2c6Piotr Jastrzebskiimport dalvik.system.VMStack;
3151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebskiimport java.lang.ref.WeakReference;
3251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebskiimport java.security.AccessController;
3351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebskiimport java.security.PrivilegedAction;
3451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebskiimport java.util.ArrayList;
3551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebskiimport java.util.Iterator;
3651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebskiimport java.util.Locale;
3751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebskiimport java.util.MissingResourceException;
3851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebskiimport java.util.ResourceBundle;
3951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebskiimport java.util.concurrent.CopyOnWriteArrayList;
404ff539dbc5a809ef3eacbe2d9f2b97f640b7e9cfPrzemyslaw Szczepaniakimport java.util.function.Supplier;
4151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebskiimport sun.reflect.CallerSensitive;
4251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
4351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski/**
4451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * A Logger object is used to log messages for a specific
4551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * system or application component.  Loggers are normally named,
4651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * using a hierarchical dot-separated namespace.  Logger names
4751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * can be arbitrary strings, but they should normally be based on
4851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * the package name or class name of the logged component, such
4951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * as java.net or javax.swing.  In addition it is possible to create
5051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * "anonymous" Loggers that are not stored in the Logger namespace.
5151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * <p>
5251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Logger objects may be obtained by calls on one of the getLogger
5351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * factory methods.  These will either create a new Logger or
5451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * return a suitable existing Logger. It is important to note that
5551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * the Logger returned by one of the {@code getLogger} factory methods
5651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * may be garbage collected at any time if a strong reference to the
5751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Logger is not kept.
5851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * <p>
5951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Logging messages will be forwarded to registered Handler
6051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * objects, which can forward the messages to a variety of
6151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * destinations, including consoles, files, OS logs, etc.
6251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * <p>
6351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Each Logger keeps track of a "parent" Logger, which is its
6451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * nearest existing ancestor in the Logger namespace.
6551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * <p>
6651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Each Logger has a "Level" associated with it.  This reflects
6751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * a minimum Level that this logger cares about.  If a Logger's
6851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * level is set to <tt>null</tt>, then its effective level is inherited
6951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * from its parent, which may in turn obtain it recursively from its
7051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * parent, and so on up the tree.
7151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * <p>
7251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * The log level can be configured based on the properties from the
7351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * logging configuration file, as described in the description
7451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * of the LogManager class.  However it may also be dynamically changed
7551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * by calls on the Logger.setLevel method.  If a logger's level is
7651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * changed the change may also affect child loggers, since any child
7751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * logger that has <tt>null</tt> as its level will inherit its
7851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * effective level from its parent.
7951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * <p>
8051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * On each logging call the Logger initially performs a cheap
8151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * check of the request level (e.g., SEVERE or FINE) against the
8251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * effective log level of the logger.  If the request level is
8351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * lower than the log level, the logging call returns immediately.
8451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * <p>
8551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * After passing this initial (cheap) test, the Logger will allocate
8651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * a LogRecord to describe the logging message.  It will then call a
8751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Filter (if present) to do a more detailed check on whether the
8851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * record should be published.  If that passes it will then publish
8951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * the LogRecord to its output Handlers.  By default, loggers also
9051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * publish to their parent's Handlers, recursively up the tree.
9151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * <p>
924ff539dbc5a809ef3eacbe2d9f2b97f640b7e9cfPrzemyslaw Szczepaniak * Each Logger may have a {@code ResourceBundle} associated with it.
934ff539dbc5a809ef3eacbe2d9f2b97f640b7e9cfPrzemyslaw Szczepaniak * The {@code ResourceBundle} may be specified by name, using the
944ff539dbc5a809ef3eacbe2d9f2b97f640b7e9cfPrzemyslaw Szczepaniak * {@link #getLogger(java.lang.String, java.lang.String)} factory
954ff539dbc5a809ef3eacbe2d9f2b97f640b7e9cfPrzemyslaw Szczepaniak * method, or by value - using the {@link
964ff539dbc5a809ef3eacbe2d9f2b97f640b7e9cfPrzemyslaw Szczepaniak * #setResourceBundle(java.util.ResourceBundle) setResourceBundle} method.
974ff539dbc5a809ef3eacbe2d9f2b97f640b7e9cfPrzemyslaw Szczepaniak * This bundle will be used for localizing logging messages.
984ff539dbc5a809ef3eacbe2d9f2b97f640b7e9cfPrzemyslaw Szczepaniak * If a Logger does not have its own {@code ResourceBundle} or resource bundle
994ff539dbc5a809ef3eacbe2d9f2b97f640b7e9cfPrzemyslaw Szczepaniak * name, then it will inherit the {@code ResourceBundle} or resource bundle name
1004ff539dbc5a809ef3eacbe2d9f2b97f640b7e9cfPrzemyslaw Szczepaniak * from its parent, recursively up the tree.
10151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * <p>
10251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Most of the logger output methods take a "msg" argument.  This
10351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * msg argument may be either a raw value or a localization key.
10451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * During formatting, if the logger has (or inherits) a localization
1054ff539dbc5a809ef3eacbe2d9f2b97f640b7e9cfPrzemyslaw Szczepaniak * {@code ResourceBundle} and if the {@code ResourceBundle} has a mapping for
1064ff539dbc5a809ef3eacbe2d9f2b97f640b7e9cfPrzemyslaw Szczepaniak * the msg string, then the msg string is replaced by the localized value.
10751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Otherwise the original msg string is used.  Typically, formatters use
10851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * java.text.MessageFormat style formatting to format parameters, so
10951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * for example a format string "{0} {1}" would format two parameters
11051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * as strings.
11151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * <p>
1124ff539dbc5a809ef3eacbe2d9f2b97f640b7e9cfPrzemyslaw Szczepaniak * A set of methods alternatively take a "msgSupplier" instead of a "msg"
1134ff539dbc5a809ef3eacbe2d9f2b97f640b7e9cfPrzemyslaw Szczepaniak * argument.  These methods take a {@link Supplier}{@code <String>} function
1144ff539dbc5a809ef3eacbe2d9f2b97f640b7e9cfPrzemyslaw Szczepaniak * which is invoked to construct the desired log message only when the message
1154ff539dbc5a809ef3eacbe2d9f2b97f640b7e9cfPrzemyslaw Szczepaniak * actually is to be logged based on the effective log level thus eliminating
1164ff539dbc5a809ef3eacbe2d9f2b97f640b7e9cfPrzemyslaw Szczepaniak * unnecessary message construction. For example, if the developer wants to
1174ff539dbc5a809ef3eacbe2d9f2b97f640b7e9cfPrzemyslaw Szczepaniak * log system health status for diagnosis, with the String-accepting version,
1184ff539dbc5a809ef3eacbe2d9f2b97f640b7e9cfPrzemyslaw Szczepaniak * the code would look like:
1194ff539dbc5a809ef3eacbe2d9f2b97f640b7e9cfPrzemyslaw Szczepaniak <pre><code>
1204ff539dbc5a809ef3eacbe2d9f2b97f640b7e9cfPrzemyslaw Szczepaniak
1214ff539dbc5a809ef3eacbe2d9f2b97f640b7e9cfPrzemyslaw Szczepaniak   class DiagnosisMessages {
1224ff539dbc5a809ef3eacbe2d9f2b97f640b7e9cfPrzemyslaw Szczepaniak     static String systemHealthStatus() {
1234ff539dbc5a809ef3eacbe2d9f2b97f640b7e9cfPrzemyslaw Szczepaniak       // collect system health information
1244ff539dbc5a809ef3eacbe2d9f2b97f640b7e9cfPrzemyslaw Szczepaniak       ...
1254ff539dbc5a809ef3eacbe2d9f2b97f640b7e9cfPrzemyslaw Szczepaniak     }
1264ff539dbc5a809ef3eacbe2d9f2b97f640b7e9cfPrzemyslaw Szczepaniak   }
1274ff539dbc5a809ef3eacbe2d9f2b97f640b7e9cfPrzemyslaw Szczepaniak   ...
1284ff539dbc5a809ef3eacbe2d9f2b97f640b7e9cfPrzemyslaw Szczepaniak   logger.log(Level.FINER, DiagnosisMessages.systemHealthStatus());
1294ff539dbc5a809ef3eacbe2d9f2b97f640b7e9cfPrzemyslaw Szczepaniak</code></pre>
1304ff539dbc5a809ef3eacbe2d9f2b97f640b7e9cfPrzemyslaw Szczepaniak * With the above code, the health status is collected unnecessarily even when
1314ff539dbc5a809ef3eacbe2d9f2b97f640b7e9cfPrzemyslaw Szczepaniak * the log level FINER is disabled. With the Supplier-accepting version as
1324ff539dbc5a809ef3eacbe2d9f2b97f640b7e9cfPrzemyslaw Szczepaniak * below, the status will only be collected when the log level FINER is
1334ff539dbc5a809ef3eacbe2d9f2b97f640b7e9cfPrzemyslaw Szczepaniak * enabled.
1344ff539dbc5a809ef3eacbe2d9f2b97f640b7e9cfPrzemyslaw Szczepaniak <pre><code>
1354ff539dbc5a809ef3eacbe2d9f2b97f640b7e9cfPrzemyslaw Szczepaniak
1364ff539dbc5a809ef3eacbe2d9f2b97f640b7e9cfPrzemyslaw Szczepaniak   logger.log(Level.FINER, DiagnosisMessages::systemHealthStatus);
1374ff539dbc5a809ef3eacbe2d9f2b97f640b7e9cfPrzemyslaw Szczepaniak</code></pre>
1384ff539dbc5a809ef3eacbe2d9f2b97f640b7e9cfPrzemyslaw Szczepaniak * <p>
1394ff539dbc5a809ef3eacbe2d9f2b97f640b7e9cfPrzemyslaw Szczepaniak * When looking for a {@code ResourceBundle}, the logger will first look at
1404ff539dbc5a809ef3eacbe2d9f2b97f640b7e9cfPrzemyslaw Szczepaniak * whether a bundle was specified using {@link
1414ff539dbc5a809ef3eacbe2d9f2b97f640b7e9cfPrzemyslaw Szczepaniak * #setResourceBundle(java.util.ResourceBundle) setResourceBundle}, and then
1424ff539dbc5a809ef3eacbe2d9f2b97f640b7e9cfPrzemyslaw Szczepaniak * only whether a resource bundle name was specified through the {@link
1434ff539dbc5a809ef3eacbe2d9f2b97f640b7e9cfPrzemyslaw Szczepaniak * #getLogger(java.lang.String, java.lang.String) getLogger} factory method.
1444ff539dbc5a809ef3eacbe2d9f2b97f640b7e9cfPrzemyslaw Szczepaniak * If no {@code ResourceBundle} or no resource bundle name is found,
1454ff539dbc5a809ef3eacbe2d9f2b97f640b7e9cfPrzemyslaw Szczepaniak * then it will use the nearest {@code ResourceBundle} or resource bundle
1464ff539dbc5a809ef3eacbe2d9f2b97f640b7e9cfPrzemyslaw Szczepaniak * name inherited from its parent tree.<br>
1474ff539dbc5a809ef3eacbe2d9f2b97f640b7e9cfPrzemyslaw Szczepaniak * When a {@code ResourceBundle} was inherited or specified through the
1484ff539dbc5a809ef3eacbe2d9f2b97f640b7e9cfPrzemyslaw Szczepaniak * {@link
1494ff539dbc5a809ef3eacbe2d9f2b97f640b7e9cfPrzemyslaw Szczepaniak * #setResourceBundle(java.util.ResourceBundle) setResourceBundle} method, then
1504ff539dbc5a809ef3eacbe2d9f2b97f640b7e9cfPrzemyslaw Szczepaniak * that {@code ResourceBundle} will be used. Otherwise if the logger only
1514ff539dbc5a809ef3eacbe2d9f2b97f640b7e9cfPrzemyslaw Szczepaniak * has or inherited a resource bundle name, then that resource bundle name
1524ff539dbc5a809ef3eacbe2d9f2b97f640b7e9cfPrzemyslaw Szczepaniak * will be mapped to a {@code ResourceBundle} object, using the default Locale
1534ff539dbc5a809ef3eacbe2d9f2b97f640b7e9cfPrzemyslaw Szczepaniak * at the time of logging.
1544ff539dbc5a809ef3eacbe2d9f2b97f640b7e9cfPrzemyslaw Szczepaniak * <br id="ResourceBundleMapping">When mapping resource bundle names to
1554ff539dbc5a809ef3eacbe2d9f2b97f640b7e9cfPrzemyslaw Szczepaniak * {@code ResourceBundle} objects, the logger will first try to use the
1564ff539dbc5a809ef3eacbe2d9f2b97f640b7e9cfPrzemyslaw Szczepaniak * Thread's {@linkplain java.lang.Thread#getContextClassLoader() context class
1574ff539dbc5a809ef3eacbe2d9f2b97f640b7e9cfPrzemyslaw Szczepaniak * loader} to map the given resource bundle name to a {@code ResourceBundle}.
1584ff539dbc5a809ef3eacbe2d9f2b97f640b7e9cfPrzemyslaw Szczepaniak * If the thread context class loader is {@code null}, it will try the
1594ff539dbc5a809ef3eacbe2d9f2b97f640b7e9cfPrzemyslaw Szczepaniak * {@linkplain java.lang.ClassLoader#getSystemClassLoader() system class loader}
1604ff539dbc5a809ef3eacbe2d9f2b97f640b7e9cfPrzemyslaw Szczepaniak * instead.  If the {@code ResourceBundle} is still not found, it will use the
1614ff539dbc5a809ef3eacbe2d9f2b97f640b7e9cfPrzemyslaw Szczepaniak * class loader of the first caller of the {@link
1624ff539dbc5a809ef3eacbe2d9f2b97f640b7e9cfPrzemyslaw Szczepaniak * #getLogger(java.lang.String, java.lang.String) getLogger} factory method.
16351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * <p>
16451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Formatting (including localization) is the responsibility of
16551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * the output Handler, which will typically call a Formatter.
16651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * <p>
16751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Note that formatting need not occur synchronously.  It may be delayed
16851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * until a LogRecord is actually written to an external sink.
16951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * <p>
17051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * The logging methods are grouped in five main categories:
17151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * <ul>
17251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * <li><p>
17351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski *     There are a set of "log" methods that take a log level, a message
17451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski *     string, and optionally some parameters to the message string.
17551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * <li><p>
17651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski *     There are a set of "logp" methods (for "log precise") that are
17751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski *     like the "log" methods, but also take an explicit source class name
17851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski *     and method name.
17951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * <li><p>
18051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski *     There are a set of "logrb" method (for "log with resource bundle")
18151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski *     that are like the "logp" method, but also take an explicit resource
1824ff539dbc5a809ef3eacbe2d9f2b97f640b7e9cfPrzemyslaw Szczepaniak *     bundle object for use in localizing the log message.
18351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * <li><p>
18451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski *     There are convenience methods for tracing method entries (the
18551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski *     "entering" methods), method returns (the "exiting" methods) and
18651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski *     throwing exceptions (the "throwing" methods).
18751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * <li><p>
18851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski *     Finally, there are a set of convenience methods for use in the
18951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski *     very simplest cases, when a developer simply wants to log a
19051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski *     simple string at a given log level.  These methods are named
19151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski *     after the standard Level names ("severe", "warning", "info", etc.)
19251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski *     and take a single argument, a message string.
19351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * </ul>
19451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * <p>
19551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * For the methods that do not take an explicit source name and
19651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * method name, the Logging framework will make a "best effort"
19751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * to determine which class and method called into the logging method.
19851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * However, it is important to realize that this automatically inferred
19951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * information may only be approximate (or may even be quite wrong!).
20051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Virtual machines are allowed to do extensive optimizations when
20151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * JITing and may entirely remove stack frames, making it impossible
20251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * to reliably locate the calling class and method.
20351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * <P>
20451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * All methods on Logger are multi-thread safe.
20551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * <p>
20651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * <b>Subclassing Information:</b> Note that a LogManager class may
20751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * provide its own implementation of named Loggers for any point in
20851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * the namespace.  Therefore, any subclasses of Logger (unless they
20951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * are implemented in conjunction with a new LogManager class) should
21051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * take care to obtain a Logger instance from the LogManager class and
21151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * should delegate operations such as "isLoggable" and "log(LogRecord)"
21251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * to that instance.  Note that in order to intercept all logging
21351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * output, subclasses need only override the log(LogRecord) method.
21451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * All the other logging methods are implemented as calls on this
21551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * log(LogRecord) method.
21651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski *
21751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @since 1.4
21851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */
21951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebskipublic class Logger {
22051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    private static final Handler emptyHandlers[] = new Handler[0];
22151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    private static final int offValue = Level.OFF.intValue();
2224ff539dbc5a809ef3eacbe2d9f2b97f640b7e9cfPrzemyslaw Szczepaniak
2234ff539dbc5a809ef3eacbe2d9f2b97f640b7e9cfPrzemyslaw Szczepaniak    static final String SYSTEM_LOGGER_RB_NAME = "sun.util.logging.resources.logging";
2244ff539dbc5a809ef3eacbe2d9f2b97f640b7e9cfPrzemyslaw Szczepaniak
2254ff539dbc5a809ef3eacbe2d9f2b97f640b7e9cfPrzemyslaw Szczepaniak    // This class is immutable and it is important that it remains so.
2264ff539dbc5a809ef3eacbe2d9f2b97f640b7e9cfPrzemyslaw Szczepaniak    private static final class LoggerBundle {
2274ff539dbc5a809ef3eacbe2d9f2b97f640b7e9cfPrzemyslaw Szczepaniak        final String resourceBundleName; // Base name of the bundle.
2284ff539dbc5a809ef3eacbe2d9f2b97f640b7e9cfPrzemyslaw Szczepaniak        final ResourceBundle userBundle; // Bundle set through setResourceBundle.
2294ff539dbc5a809ef3eacbe2d9f2b97f640b7e9cfPrzemyslaw Szczepaniak        private LoggerBundle(String resourceBundleName, ResourceBundle bundle) {
2304ff539dbc5a809ef3eacbe2d9f2b97f640b7e9cfPrzemyslaw Szczepaniak            this.resourceBundleName = resourceBundleName;
2314ff539dbc5a809ef3eacbe2d9f2b97f640b7e9cfPrzemyslaw Szczepaniak            this.userBundle = bundle;
2324ff539dbc5a809ef3eacbe2d9f2b97f640b7e9cfPrzemyslaw Szczepaniak        }
2334ff539dbc5a809ef3eacbe2d9f2b97f640b7e9cfPrzemyslaw Szczepaniak        boolean isSystemBundle() {
2344ff539dbc5a809ef3eacbe2d9f2b97f640b7e9cfPrzemyslaw Szczepaniak            return SYSTEM_LOGGER_RB_NAME.equals(resourceBundleName);
2354ff539dbc5a809ef3eacbe2d9f2b97f640b7e9cfPrzemyslaw Szczepaniak        }
2364ff539dbc5a809ef3eacbe2d9f2b97f640b7e9cfPrzemyslaw Szczepaniak        static LoggerBundle get(String name, ResourceBundle bundle) {
2374ff539dbc5a809ef3eacbe2d9f2b97f640b7e9cfPrzemyslaw Szczepaniak            if (name == null && bundle == null) {
2384ff539dbc5a809ef3eacbe2d9f2b97f640b7e9cfPrzemyslaw Szczepaniak                return NO_RESOURCE_BUNDLE;
2394ff539dbc5a809ef3eacbe2d9f2b97f640b7e9cfPrzemyslaw Szczepaniak            } else if (SYSTEM_LOGGER_RB_NAME.equals(name) && bundle == null) {
2404ff539dbc5a809ef3eacbe2d9f2b97f640b7e9cfPrzemyslaw Szczepaniak                return SYSTEM_BUNDLE;
2414ff539dbc5a809ef3eacbe2d9f2b97f640b7e9cfPrzemyslaw Szczepaniak            } else {
2424ff539dbc5a809ef3eacbe2d9f2b97f640b7e9cfPrzemyslaw Szczepaniak                return new LoggerBundle(name, bundle);
2434ff539dbc5a809ef3eacbe2d9f2b97f640b7e9cfPrzemyslaw Szczepaniak            }
2444ff539dbc5a809ef3eacbe2d9f2b97f640b7e9cfPrzemyslaw Szczepaniak        }
2454ff539dbc5a809ef3eacbe2d9f2b97f640b7e9cfPrzemyslaw Szczepaniak    }
2464ff539dbc5a809ef3eacbe2d9f2b97f640b7e9cfPrzemyslaw Szczepaniak
2474ff539dbc5a809ef3eacbe2d9f2b97f640b7e9cfPrzemyslaw Szczepaniak    // This instance will be shared by all loggers created by the system
2484ff539dbc5a809ef3eacbe2d9f2b97f640b7e9cfPrzemyslaw Szczepaniak    // code
2494ff539dbc5a809ef3eacbe2d9f2b97f640b7e9cfPrzemyslaw Szczepaniak    private static final LoggerBundle SYSTEM_BUNDLE =
2504ff539dbc5a809ef3eacbe2d9f2b97f640b7e9cfPrzemyslaw Szczepaniak            new LoggerBundle(SYSTEM_LOGGER_RB_NAME, null);
2514ff539dbc5a809ef3eacbe2d9f2b97f640b7e9cfPrzemyslaw Szczepaniak
2524ff539dbc5a809ef3eacbe2d9f2b97f640b7e9cfPrzemyslaw Szczepaniak    // This instance indicates that no resource bundle has been specified yet,
2534ff539dbc5a809ef3eacbe2d9f2b97f640b7e9cfPrzemyslaw Szczepaniak    // and it will be shared by all loggers which have no resource bundle.
2544ff539dbc5a809ef3eacbe2d9f2b97f640b7e9cfPrzemyslaw Szczepaniak    private static final LoggerBundle NO_RESOURCE_BUNDLE =
2554ff539dbc5a809ef3eacbe2d9f2b97f640b7e9cfPrzemyslaw Szczepaniak            new LoggerBundle(null, null);
2564ff539dbc5a809ef3eacbe2d9f2b97f640b7e9cfPrzemyslaw Szczepaniak
2574ff539dbc5a809ef3eacbe2d9f2b97f640b7e9cfPrzemyslaw Szczepaniak    private volatile LogManager manager;
25851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    private String name;
25951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    private final CopyOnWriteArrayList<Handler> handlers =
26051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        new CopyOnWriteArrayList<>();
2614ff539dbc5a809ef3eacbe2d9f2b97f640b7e9cfPrzemyslaw Szczepaniak    private volatile LoggerBundle loggerBundle = NO_RESOURCE_BUNDLE;
26251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    private volatile boolean useParentHandlers = true;
26351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    private volatile Filter filter;
26451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    private boolean anonymous;
26551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
2664ff539dbc5a809ef3eacbe2d9f2b97f640b7e9cfPrzemyslaw Szczepaniak    // Cache to speed up behavior of findResourceBundle:
26751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    private ResourceBundle catalog;     // Cached resource bundle
26851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    private String catalogName;         // name associated with catalog
26951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    private Locale catalogLocale;       // locale associated with catalog
27051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
27151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    // The fields relating to parent-child relationships and levels
27251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    // are managed under a separate lock, the treeLock.
2734ff539dbc5a809ef3eacbe2d9f2b97f640b7e9cfPrzemyslaw Szczepaniak    private static final Object treeLock = new Object();
27451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    // We keep weak references from parents to children, but strong
27551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    // references from children to parents.
27651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    private volatile Logger parent;    // our nearest parent.
27751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    private ArrayList<LogManager.LoggerWeakRef> kids;   // WeakReferences to loggers that have us as parent
27851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    private volatile Level levelObject;
27951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    private volatile int levelValue;  // current effective level value
28051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    private WeakReference<ClassLoader> callersClassLoaderRef;
2814ff539dbc5a809ef3eacbe2d9f2b97f640b7e9cfPrzemyslaw Szczepaniak    private final boolean isSystemLogger;
28251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
28351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    /**
28451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * GLOBAL_LOGGER_NAME is a name for the global logger.
28551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     *
28651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * @since 1.6
28751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     */
28851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    public static final String GLOBAL_LOGGER_NAME = "global";
28951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
29051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    /**
29151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * Return global logger object with the name Logger.GLOBAL_LOGGER_NAME.
29251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     *
29351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * @return global logger object
29451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * @since 1.7
29551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     */
29651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    public static final Logger getGlobal() {
2974ff539dbc5a809ef3eacbe2d9f2b97f640b7e9cfPrzemyslaw Szczepaniak        // In order to break a cyclic dependence between the LogManager
2984ff539dbc5a809ef3eacbe2d9f2b97f640b7e9cfPrzemyslaw Szczepaniak        // and Logger static initializers causing deadlocks, the global
2994ff539dbc5a809ef3eacbe2d9f2b97f640b7e9cfPrzemyslaw Szczepaniak        // logger is created with a special constructor that does not
3004ff539dbc5a809ef3eacbe2d9f2b97f640b7e9cfPrzemyslaw Szczepaniak        // initialize its log manager.
3014ff539dbc5a809ef3eacbe2d9f2b97f640b7e9cfPrzemyslaw Szczepaniak        //
3024ff539dbc5a809ef3eacbe2d9f2b97f640b7e9cfPrzemyslaw Szczepaniak        // If an application calls Logger.getGlobal() before any logger
3034ff539dbc5a809ef3eacbe2d9f2b97f640b7e9cfPrzemyslaw Szczepaniak        // has been initialized, it is therefore possible that the
3044ff539dbc5a809ef3eacbe2d9f2b97f640b7e9cfPrzemyslaw Szczepaniak        // LogManager class has not been initialized yet, and therefore
3054ff539dbc5a809ef3eacbe2d9f2b97f640b7e9cfPrzemyslaw Szczepaniak        // Logger.global.manager will be null.
3064ff539dbc5a809ef3eacbe2d9f2b97f640b7e9cfPrzemyslaw Szczepaniak        //
3074ff539dbc5a809ef3eacbe2d9f2b97f640b7e9cfPrzemyslaw Szczepaniak        // In order to finish the initialization of the global logger, we
3084ff539dbc5a809ef3eacbe2d9f2b97f640b7e9cfPrzemyslaw Szczepaniak        // will therefore call LogManager.getLogManager() here.
3094ff539dbc5a809ef3eacbe2d9f2b97f640b7e9cfPrzemyslaw Szczepaniak        //
3104ff539dbc5a809ef3eacbe2d9f2b97f640b7e9cfPrzemyslaw Szczepaniak        // To prevent race conditions we also need to call
3114ff539dbc5a809ef3eacbe2d9f2b97f640b7e9cfPrzemyslaw Szczepaniak        // LogManager.getLogManager() unconditionally here.
3124ff539dbc5a809ef3eacbe2d9f2b97f640b7e9cfPrzemyslaw Szczepaniak        // Indeed we cannot rely on the observed value of global.manager,
3134ff539dbc5a809ef3eacbe2d9f2b97f640b7e9cfPrzemyslaw Szczepaniak        // because global.manager will become not null somewhere during
3144ff539dbc5a809ef3eacbe2d9f2b97f640b7e9cfPrzemyslaw Szczepaniak        // the initialization of LogManager.
3154ff539dbc5a809ef3eacbe2d9f2b97f640b7e9cfPrzemyslaw Szczepaniak        // If two threads are calling getGlobal() concurrently, one thread
3164ff539dbc5a809ef3eacbe2d9f2b97f640b7e9cfPrzemyslaw Szczepaniak        // will see global.manager null and call LogManager.getLogManager(),
3174ff539dbc5a809ef3eacbe2d9f2b97f640b7e9cfPrzemyslaw Szczepaniak        // but the other thread could come in at a time when global.manager
3184ff539dbc5a809ef3eacbe2d9f2b97f640b7e9cfPrzemyslaw Szczepaniak        // is already set although ensureLogManagerInitialized is not finished
3194ff539dbc5a809ef3eacbe2d9f2b97f640b7e9cfPrzemyslaw Szczepaniak        // yet...
3204ff539dbc5a809ef3eacbe2d9f2b97f640b7e9cfPrzemyslaw Szczepaniak        // Calling LogManager.getLogManager() unconditionally will fix that.
3214ff539dbc5a809ef3eacbe2d9f2b97f640b7e9cfPrzemyslaw Szczepaniak
3224ff539dbc5a809ef3eacbe2d9f2b97f640b7e9cfPrzemyslaw Szczepaniak        LogManager.getLogManager();
3234ff539dbc5a809ef3eacbe2d9f2b97f640b7e9cfPrzemyslaw Szczepaniak
3244ff539dbc5a809ef3eacbe2d9f2b97f640b7e9cfPrzemyslaw Szczepaniak        // Now the global LogManager should be initialized,
3254ff539dbc5a809ef3eacbe2d9f2b97f640b7e9cfPrzemyslaw Szczepaniak        // and the global logger should have been added to
3264ff539dbc5a809ef3eacbe2d9f2b97f640b7e9cfPrzemyslaw Szczepaniak        // it, unless we were called within the constructor of a LogManager
3274ff539dbc5a809ef3eacbe2d9f2b97f640b7e9cfPrzemyslaw Szczepaniak        // subclass installed as LogManager, in which case global.manager
3284ff539dbc5a809ef3eacbe2d9f2b97f640b7e9cfPrzemyslaw Szczepaniak        // would still be null, and global will be lazily initialized later on.
3294ff539dbc5a809ef3eacbe2d9f2b97f640b7e9cfPrzemyslaw Szczepaniak
33051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        return global;
33151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    }
33251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
33351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    /**
33451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * The "global" Logger object is provided as a convenience to developers
33551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * who are making casual use of the Logging package.  Developers
33651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * who are making serious use of the logging package (for example
33751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * in products) should create and use their own Logger objects,
33851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * with appropriate names, so that logging can be controlled on a
33951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * suitable per-Logger granularity. Developers also need to keep a
34051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * strong reference to their Logger objects to prevent them from
34151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * being garbage collected.
34251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * <p>
34351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * @deprecated Initialization of this field is prone to deadlocks.
34451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * The field must be initialized by the Logger class initialization
34551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * which may cause deadlocks with the LogManager class initialization.
34651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * In such cases two class initialization wait for each other to complete.
34751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * The preferred way to get the global logger object is via the call
34851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * <code>Logger.getGlobal()</code>.
34951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * For compatibility with old JDK versions where the
35051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * <code>Logger.getGlobal()</code> is not available use the call
35151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * <code>Logger.getLogger(Logger.GLOBAL_LOGGER_NAME)</code>
35251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * or <code>Logger.getLogger("global")</code>.
35351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     */
35451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    @Deprecated
35551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    public static final Logger global = new Logger(GLOBAL_LOGGER_NAME);
35651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
35751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    /**
35851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * Protected method to construct a logger for a named subsystem.
35951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * <p>
36051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * The logger will be initially configured with a null Level
36151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * and with useParentHandlers set to true.
36251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     *
36351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * @param   name    A name for the logger.  This should
36451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     *                          be a dot-separated name and should normally
36551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     *                          be based on the package name or class name
36651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     *                          of the subsystem, such as java.net
36751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     *                          or javax.swing.  It may be null for anonymous Loggers.
36851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * @param   resourceBundleName  name of ResourceBundle to be used for localizing
36951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     *                          messages for this logger.  May be null if none
37051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     *                          of the messages require localization.
37151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * @throws MissingResourceException if the resourceBundleName is non-null and
37251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     *             no corresponding resource can be found.
37351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     */
37451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    protected Logger(String name, String resourceBundleName) {
3754ff539dbc5a809ef3eacbe2d9f2b97f640b7e9cfPrzemyslaw Szczepaniak        this(name, resourceBundleName, null, LogManager.getLogManager(), false);
37651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    }
37751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
3784ff539dbc5a809ef3eacbe2d9f2b97f640b7e9cfPrzemyslaw Szczepaniak    Logger(String name, String resourceBundleName, Class<?> caller, LogManager manager, boolean isSystemLogger) {
3794ff539dbc5a809ef3eacbe2d9f2b97f640b7e9cfPrzemyslaw Szczepaniak        this.manager = manager;
3804ff539dbc5a809ef3eacbe2d9f2b97f640b7e9cfPrzemyslaw Szczepaniak        this.isSystemLogger = isSystemLogger;
38151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        setupResourceInfo(resourceBundleName, caller);
38251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        this.name = name;
38351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        levelValue = Level.INFO.intValue();
38451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    }
38551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
38651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    private void setCallersClassLoaderRef(Class<?> caller) {
38751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        ClassLoader callersClassLoader = ((caller != null)
38851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                                         ? caller.getClassLoader()
38951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                                         : null);
39051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        if (callersClassLoader != null) {
3914ff539dbc5a809ef3eacbe2d9f2b97f640b7e9cfPrzemyslaw Szczepaniak            this.callersClassLoaderRef = new WeakReference<>(callersClassLoader);
39251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        }
39351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    }
39451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
39551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    private ClassLoader getCallersClassLoader() {
39651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        return (callersClassLoaderRef != null)
39751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                ? callersClassLoaderRef.get()
39851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                : null;
39951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    }
40051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
40151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    // This constructor is used only to create the global Logger.
40251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    // It is needed to break a cyclic dependence between the LogManager
40351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    // and Logger static initializers causing deadlocks.
40451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    private Logger(String name) {
40551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        // The manager field is not initialized here.
40651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        this.name = name;
4074ff539dbc5a809ef3eacbe2d9f2b97f640b7e9cfPrzemyslaw Szczepaniak        this.isSystemLogger = true;
40851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        levelValue = Level.INFO.intValue();
40951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    }
41051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
4114ff539dbc5a809ef3eacbe2d9f2b97f640b7e9cfPrzemyslaw Szczepaniak    // It is called from LoggerContext.addLocalLogger() when the logger
4124ff539dbc5a809ef3eacbe2d9f2b97f640b7e9cfPrzemyslaw Szczepaniak    // is actually added to a LogManager.
41351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    void setLogManager(LogManager manager) {
41451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        this.manager = manager;
41551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    }
41651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
41751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    private void checkPermission() throws SecurityException {
41851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        if (!anonymous) {
41951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            if (manager == null) {
42051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                // Complete initialization of the global Logger.
42151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                manager = LogManager.getLogManager();
42251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            }
42351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            manager.checkPermission();
42451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        }
42551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    }
42651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
42751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    // Until all JDK code converted to call sun.util.logging.PlatformLogger
42851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    // (see 7054233), we need to determine if Logger.getLogger is to add
42951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    // a system logger or user logger.
43051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    //
43151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    // As an interim solution, if the immediate caller whose caller loader is
43251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    // null, we assume it's a system logger and add it to the system context.
43351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    // These system loggers only set the resource bundle to the given
43451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    // resource bundle name (rather than the default system resource bundle).
4354ff539dbc5a809ef3eacbe2d9f2b97f640b7e9cfPrzemyslaw Szczepaniak    private static class SystemLoggerHelper {
4364ff539dbc5a809ef3eacbe2d9f2b97f640b7e9cfPrzemyslaw Szczepaniak        static boolean disableCallerCheck = getBooleanProperty("sun.util.logging.disableCallerCheck");
43751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        private static boolean getBooleanProperty(final String key) {
43851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            String s = AccessController.doPrivileged(new PrivilegedAction<String>() {
4394ff539dbc5a809ef3eacbe2d9f2b97f640b7e9cfPrzemyslaw Szczepaniak                @Override
44051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                public String run() {
44151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    return System.getProperty(key);
44251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                }
44351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            });
444a5448c0d798644d549426f037ebc6676b1f4de3eTobias Thierer            return Boolean.parseBoolean(s);
44551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        }
44651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    }
44751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
44851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    private static Logger demandLogger(String name, String resourceBundleName, Class<?> caller) {
44951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        LogManager manager = LogManager.getLogManager();
45051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        SecurityManager sm = System.getSecurityManager();
4514ff539dbc5a809ef3eacbe2d9f2b97f640b7e9cfPrzemyslaw Szczepaniak        if (sm != null && !SystemLoggerHelper.disableCallerCheck) {
45251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            if (caller.getClassLoader() == null) {
45351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                return manager.demandSystemLogger(name, resourceBundleName);
45451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            }
45551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        }
45651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        return manager.demandLogger(name, resourceBundleName, caller);
45751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        // ends up calling new Logger(name, resourceBundleName, caller)
45851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        // iff the logger doesn't exist already
45951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    }
46051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
46151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    /**
46251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * Find or create a logger for a named subsystem.  If a logger has
46351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * already been created with the given name it is returned.  Otherwise
46451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * a new logger is created.
46551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * <p>
46651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * If a new logger is created its log level will be configured
46751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * based on the LogManager configuration and it will configured
46851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * to also send logging output to its parent's Handlers.  It will
46951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * be registered in the LogManager global namespace.
47051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * <p>
47151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * Note: The LogManager may only retain a weak reference to the newly
47251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * created Logger. It is important to understand that a previously
47351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * created Logger with the given name may be garbage collected at any
47451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * time if there is no strong reference to the Logger. In particular,
47551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * this means that two back-to-back calls like
47651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * {@code getLogger("MyLogger").log(...)} may use different Logger
47751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * objects named "MyLogger" if there is no strong reference to the
47851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * Logger named "MyLogger" elsewhere in the program.
47951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     *
48051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * @param   name            A name for the logger.  This should
48151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     *                          be a dot-separated name and should normally
48251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     *                          be based on the package name or class name
48351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     *                          of the subsystem, such as java.net
48451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     *                          or javax.swing
48551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * @return a suitable Logger
48651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * @throws NullPointerException if the name is null.
48751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     */
48851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
48951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    // Synchronization is not required here. All synchronization for
49051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    // adding a new Logger object is handled by LogManager.addLogger().
49151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    @CallerSensitive
49251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    public static Logger getLogger(String name) {
49351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        // This method is intentionally not a wrapper around a call
49451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        // to getLogger(name, resourceBundleName). If it were then
49551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        // this sequence:
49651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        //
49751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        //     getLogger("Foo", "resourceBundleForFoo");
49851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        //     getLogger("Foo");
49951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        //
50051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        // would throw an IllegalArgumentException in the second call
50151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        // because the wrapper would result in an attempt to replace
50251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        // the existing "resourceBundleForFoo" with null.
50347f3c98d3c706c02c898cd15fbe6ee19d840c2c6Piotr Jastrzebski        //
50447f3c98d3c706c02c898cd15fbe6ee19d840c2c6Piotr Jastrzebski        // Android-changed: Use VMStack.getStackClass1.
50547f3c98d3c706c02c898cd15fbe6ee19d840c2c6Piotr Jastrzebski        return demandLogger(name, null, VMStack.getStackClass1());
50651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    }
50751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
50851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    /**
50951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * Find or create a logger for a named subsystem.  If a logger has
51051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * already been created with the given name it is returned.  Otherwise
51151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * a new logger is created.
51251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * <p>
51351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * If a new logger is created its log level will be configured
51451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * based on the LogManager and it will configured to also send logging
51551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * output to its parent's Handlers.  It will be registered in
51651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * the LogManager global namespace.
51751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * <p>
51851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * Note: The LogManager may only retain a weak reference to the newly
51951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * created Logger. It is important to understand that a previously
52051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * created Logger with the given name may be garbage collected at any
52151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * time if there is no strong reference to the Logger. In particular,
52251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * this means that two back-to-back calls like
52351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * {@code getLogger("MyLogger", ...).log(...)} may use different Logger
52451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * objects named "MyLogger" if there is no strong reference to the
52551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * Logger named "MyLogger" elsewhere in the program.
52651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * <p>
52751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * If the named Logger already exists and does not yet have a
52851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * localization resource bundle then the given resource bundle
52951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * name is used.  If the named Logger already exists and has
53051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * a different resource bundle name then an IllegalArgumentException
53151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * is thrown.
53251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * <p>
53351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * @param   name    A name for the logger.  This should
53451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     *                          be a dot-separated name and should normally
53551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     *                          be based on the package name or class name
53651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     *                          of the subsystem, such as java.net
53751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     *                          or javax.swing
53851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * @param   resourceBundleName  name of ResourceBundle to be used for localizing
5394ff539dbc5a809ef3eacbe2d9f2b97f640b7e9cfPrzemyslaw Szczepaniak     *                          messages for this logger. May be {@code null}
5404ff539dbc5a809ef3eacbe2d9f2b97f640b7e9cfPrzemyslaw Szczepaniak     *                          if none of the messages require localization.
54151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * @return a suitable Logger
54251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * @throws MissingResourceException if the resourceBundleName is non-null and
54351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     *             no corresponding resource can be found.
54451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * @throws IllegalArgumentException if the Logger already exists and uses
5454ff539dbc5a809ef3eacbe2d9f2b97f640b7e9cfPrzemyslaw Szczepaniak     *             a different resource bundle name; or if
5464ff539dbc5a809ef3eacbe2d9f2b97f640b7e9cfPrzemyslaw Szczepaniak     *             {@code resourceBundleName} is {@code null} but the named
5474ff539dbc5a809ef3eacbe2d9f2b97f640b7e9cfPrzemyslaw Szczepaniak     *             logger has a resource bundle set.
54851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * @throws NullPointerException if the name is null.
54951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     */
55051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
55151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    // Synchronization is not required here. All synchronization for
55251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    // adding a new Logger object is handled by LogManager.addLogger().
55351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    @CallerSensitive
55451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    public static Logger getLogger(String name, String resourceBundleName) {
55547f3c98d3c706c02c898cd15fbe6ee19d840c2c6Piotr Jastrzebski        // Android-changed: Use VMStack.getStackClass1.
55647f3c98d3c706c02c898cd15fbe6ee19d840c2c6Piotr Jastrzebski        Class<?> callerClass = VMStack.getStackClass1();
55751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        Logger result = demandLogger(name, resourceBundleName, callerClass);
55851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
5594ff539dbc5a809ef3eacbe2d9f2b97f640b7e9cfPrzemyslaw Szczepaniak        // MissingResourceException or IllegalArgumentException can be
5604ff539dbc5a809ef3eacbe2d9f2b97f640b7e9cfPrzemyslaw Szczepaniak        // thrown by setupResourceInfo().
5614ff539dbc5a809ef3eacbe2d9f2b97f640b7e9cfPrzemyslaw Szczepaniak        // We have to set the callers ClassLoader here in case demandLogger
5624ff539dbc5a809ef3eacbe2d9f2b97f640b7e9cfPrzemyslaw Szczepaniak        // above found a previously created Logger.  This can happen, for
5634ff539dbc5a809ef3eacbe2d9f2b97f640b7e9cfPrzemyslaw Szczepaniak        // example, if Logger.getLogger(name) is called and subsequently
5644ff539dbc5a809ef3eacbe2d9f2b97f640b7e9cfPrzemyslaw Szczepaniak        // Logger.getLogger(name, resourceBundleName) is called.  In this case
5654ff539dbc5a809ef3eacbe2d9f2b97f640b7e9cfPrzemyslaw Szczepaniak        // we won't necessarily have the correct classloader saved away, so
5664ff539dbc5a809ef3eacbe2d9f2b97f640b7e9cfPrzemyslaw Szczepaniak        // we need to set it here, too.
5674ff539dbc5a809ef3eacbe2d9f2b97f640b7e9cfPrzemyslaw Szczepaniak
5684ff539dbc5a809ef3eacbe2d9f2b97f640b7e9cfPrzemyslaw Szczepaniak        result.setupResourceInfo(resourceBundleName, callerClass);
56951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        return result;
57051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    }
57151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
57251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    // package-private
57351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    // Add a platform logger to the system context.
57451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    // i.e. caller of sun.util.logging.PlatformLogger.getLogger
57551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    static Logger getPlatformLogger(String name) {
57651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        LogManager manager = LogManager.getLogManager();
57751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
57851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        // all loggers in the system context will default to
57951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        // the system logger's resource bundle
58051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        Logger result = manager.demandSystemLogger(name, SYSTEM_LOGGER_RB_NAME);
58151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        return result;
58251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    }
58351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
58451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    /**
58551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * Create an anonymous Logger.  The newly created Logger is not
58651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * registered in the LogManager namespace.  There will be no
58751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * access checks on updates to the logger.
58851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * <p>
58951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * This factory method is primarily intended for use from applets.
59051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * Because the resulting Logger is anonymous it can be kept private
59151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * by the creating class.  This removes the need for normal security
59251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * checks, which in turn allows untrusted applet code to update
59351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * the control state of the Logger.  For example an applet can do
59451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * a setLevel or an addHandler on an anonymous Logger.
59551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * <p>
59651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * Even although the new logger is anonymous, it is configured
59751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * to have the root logger ("") as its parent.  This means that
59851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * by default it inherits its effective level and handlers
5994ff539dbc5a809ef3eacbe2d9f2b97f640b7e9cfPrzemyslaw Szczepaniak     * from the root logger. Changing its parent via the
6004ff539dbc5a809ef3eacbe2d9f2b97f640b7e9cfPrzemyslaw Szczepaniak     * {@link #setParent(java.util.logging.Logger) setParent} method
6014ff539dbc5a809ef3eacbe2d9f2b97f640b7e9cfPrzemyslaw Szczepaniak     * will still require the security permission specified by that method.
60251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * <p>
60351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     *
60451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * @return a newly created private Logger
60551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     */
60651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    public static Logger getAnonymousLogger() {
60751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        return getAnonymousLogger(null);
60851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    }
60951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
61051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    /**
61151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * Create an anonymous Logger.  The newly created Logger is not
61251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * registered in the LogManager namespace.  There will be no
61351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * access checks on updates to the logger.
61451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * <p>
61551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * This factory method is primarily intended for use from applets.
61651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * Because the resulting Logger is anonymous it can be kept private
61751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * by the creating class.  This removes the need for normal security
61851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * checks, which in turn allows untrusted applet code to update
61951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * the control state of the Logger.  For example an applet can do
62051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * a setLevel or an addHandler on an anonymous Logger.
62151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * <p>
62251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * Even although the new logger is anonymous, it is configured
62351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * to have the root logger ("") as its parent.  This means that
62451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * by default it inherits its effective level and handlers
6254ff539dbc5a809ef3eacbe2d9f2b97f640b7e9cfPrzemyslaw Szczepaniak     * from the root logger.  Changing its parent via the
6264ff539dbc5a809ef3eacbe2d9f2b97f640b7e9cfPrzemyslaw Szczepaniak     * {@link #setParent(java.util.logging.Logger) setParent} method
6274ff539dbc5a809ef3eacbe2d9f2b97f640b7e9cfPrzemyslaw Szczepaniak     * will still require the security permission specified by that method.
62851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * <p>
62951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * @param   resourceBundleName  name of ResourceBundle to be used for localizing
63051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     *                          messages for this logger.
63151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     *          May be null if none of the messages require localization.
63251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * @return a newly created private Logger
63351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * @throws MissingResourceException if the resourceBundleName is non-null and
63451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     *             no corresponding resource can be found.
63551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     */
63651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
63751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    // Synchronization is not required here. All synchronization for
63851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    // adding a new anonymous Logger object is handled by doSetParent().
63951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    @CallerSensitive
64051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    public static Logger getAnonymousLogger(String resourceBundleName) {
64151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        LogManager manager = LogManager.getLogManager();
64251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        // cleanup some Loggers that have been GC'ed
64351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        manager.drainLoggerRefQueueBounded();
64447f3c98d3c706c02c898cd15fbe6ee19d840c2c6Piotr Jastrzebski        // Android-changed: Use VMStack.getStackClass1.
64551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        Logger result = new Logger(null, resourceBundleName,
6464ff539dbc5a809ef3eacbe2d9f2b97f640b7e9cfPrzemyslaw Szczepaniak                                   VMStack.getStackClass1(), manager, false);
64751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        result.anonymous = true;
64851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        Logger root = manager.getLogger("");
64951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        result.doSetParent(root);
65051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        return result;
65151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    }
65251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
65351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    /**
65451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * Retrieve the localization resource bundle for this
6554ff539dbc5a809ef3eacbe2d9f2b97f640b7e9cfPrzemyslaw Szczepaniak     * logger.
6564ff539dbc5a809ef3eacbe2d9f2b97f640b7e9cfPrzemyslaw Szczepaniak     * This method will return a {@code ResourceBundle} that was either
6574ff539dbc5a809ef3eacbe2d9f2b97f640b7e9cfPrzemyslaw Szczepaniak     * set by the {@link
6584ff539dbc5a809ef3eacbe2d9f2b97f640b7e9cfPrzemyslaw Szczepaniak     * #setResourceBundle(java.util.ResourceBundle) setResourceBundle} method or
6594ff539dbc5a809ef3eacbe2d9f2b97f640b7e9cfPrzemyslaw Szczepaniak     * <a href="#ResourceBundleMapping">mapped from the
6604ff539dbc5a809ef3eacbe2d9f2b97f640b7e9cfPrzemyslaw Szczepaniak     * the resource bundle name</a> set via the {@link
6614ff539dbc5a809ef3eacbe2d9f2b97f640b7e9cfPrzemyslaw Szczepaniak     * Logger#getLogger(java.lang.String, java.lang.String) getLogger} factory
6624ff539dbc5a809ef3eacbe2d9f2b97f640b7e9cfPrzemyslaw Szczepaniak     * method for the current default locale.
6634ff539dbc5a809ef3eacbe2d9f2b97f640b7e9cfPrzemyslaw Szczepaniak     * <br>Note that if the result is {@code null}, then the Logger will use a resource
6644ff539dbc5a809ef3eacbe2d9f2b97f640b7e9cfPrzemyslaw Szczepaniak     * bundle or resource bundle name inherited from its parent.
66551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     *
6664ff539dbc5a809ef3eacbe2d9f2b97f640b7e9cfPrzemyslaw Szczepaniak     * @return localization bundle (may be {@code null})
66751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     */
66851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    public ResourceBundle getResourceBundle() {
66951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        return findResourceBundle(getResourceBundleName(), true);
67051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    }
67151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
67251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    /**
67351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * Retrieve the localization resource bundle name for this
6744ff539dbc5a809ef3eacbe2d9f2b97f640b7e9cfPrzemyslaw Szczepaniak     * logger.
6754ff539dbc5a809ef3eacbe2d9f2b97f640b7e9cfPrzemyslaw Szczepaniak     * This is either the name specified through the {@link
6764ff539dbc5a809ef3eacbe2d9f2b97f640b7e9cfPrzemyslaw Szczepaniak     * #getLogger(java.lang.String, java.lang.String) getLogger} factory method,
6774ff539dbc5a809ef3eacbe2d9f2b97f640b7e9cfPrzemyslaw Szczepaniak     * or the {@linkplain ResourceBundle#getBaseBundleName() base name} of the
6784ff539dbc5a809ef3eacbe2d9f2b97f640b7e9cfPrzemyslaw Szczepaniak     * ResourceBundle set through {@link
6794ff539dbc5a809ef3eacbe2d9f2b97f640b7e9cfPrzemyslaw Szczepaniak     * #setResourceBundle(java.util.ResourceBundle) setResourceBundle} method.
6804ff539dbc5a809ef3eacbe2d9f2b97f640b7e9cfPrzemyslaw Szczepaniak     * <br>Note that if the result is {@code null}, then the Logger will use a resource
6814ff539dbc5a809ef3eacbe2d9f2b97f640b7e9cfPrzemyslaw Szczepaniak     * bundle or resource bundle name inherited from its parent.
68251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     *
6834ff539dbc5a809ef3eacbe2d9f2b97f640b7e9cfPrzemyslaw Szczepaniak     * @return localization bundle name (may be {@code null})
68451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     */
68551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    public String getResourceBundleName() {
6864ff539dbc5a809ef3eacbe2d9f2b97f640b7e9cfPrzemyslaw Szczepaniak        return loggerBundle.resourceBundleName;
68751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    }
68851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
68951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    /**
69051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * Set a filter to control output on this Logger.
69151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * <P>
69251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * After passing the initial "level" check, the Logger will
69351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * call this Filter to check if a log record should really
69451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * be published.
69551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     *
69651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * @param   newFilter  a filter object (may be null)
6974ff539dbc5a809ef3eacbe2d9f2b97f640b7e9cfPrzemyslaw Szczepaniak     * @throws  SecurityException if a security manager exists,
6984ff539dbc5a809ef3eacbe2d9f2b97f640b7e9cfPrzemyslaw Szczepaniak     *          this logger is not anonymous, and the caller
6994ff539dbc5a809ef3eacbe2d9f2b97f640b7e9cfPrzemyslaw Szczepaniak     *          does not have LoggingPermission("control").
70051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     */
70151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    public void setFilter(Filter newFilter) throws SecurityException {
70251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        checkPermission();
70351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        filter = newFilter;
70451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    }
70551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
70651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    /**
70751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * Get the current filter for this Logger.
70851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     *
70951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * @return  a filter object (may be null)
71051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     */
71151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    public Filter getFilter() {
71251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        return filter;
71351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    }
71451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
71551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    /**
71651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * Log a LogRecord.
71751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * <p>
71851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * All the other logging methods in this class call through
71951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * this method to actually perform any logging.  Subclasses can
72051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * override this single method to capture all log activity.
72151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     *
72251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * @param record the LogRecord to be published
72351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     */
72451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    public void log(LogRecord record) {
7254ff539dbc5a809ef3eacbe2d9f2b97f640b7e9cfPrzemyslaw Szczepaniak        if (!isLoggable(record.getLevel())) {
72651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            return;
72751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        }
72851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        Filter theFilter = filter;
72951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        if (theFilter != null && !theFilter.isLoggable(record)) {
73051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            return;
73151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        }
73251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
73351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        // Post the LogRecord to all our Handlers, and then to
73451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        // our parents' handlers, all the way up the tree.
73551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
73651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        Logger logger = this;
73751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        while (logger != null) {
7384ff539dbc5a809ef3eacbe2d9f2b97f640b7e9cfPrzemyslaw Szczepaniak            final Handler[] loggerHandlers = isSystemLogger
7394ff539dbc5a809ef3eacbe2d9f2b97f640b7e9cfPrzemyslaw Szczepaniak                ? logger.accessCheckedHandlers()
7404ff539dbc5a809ef3eacbe2d9f2b97f640b7e9cfPrzemyslaw Szczepaniak                : logger.getHandlers();
7414ff539dbc5a809ef3eacbe2d9f2b97f640b7e9cfPrzemyslaw Szczepaniak
7424ff539dbc5a809ef3eacbe2d9f2b97f640b7e9cfPrzemyslaw Szczepaniak            for (Handler handler : loggerHandlers) {
74351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                handler.publish(record);
74451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            }
74551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
7464ff539dbc5a809ef3eacbe2d9f2b97f640b7e9cfPrzemyslaw Szczepaniak            final boolean useParentHdls = isSystemLogger
7474ff539dbc5a809ef3eacbe2d9f2b97f640b7e9cfPrzemyslaw Szczepaniak                ? logger.useParentHandlers
7484ff539dbc5a809ef3eacbe2d9f2b97f640b7e9cfPrzemyslaw Szczepaniak                : logger.getUseParentHandlers();
7494ff539dbc5a809ef3eacbe2d9f2b97f640b7e9cfPrzemyslaw Szczepaniak
7504ff539dbc5a809ef3eacbe2d9f2b97f640b7e9cfPrzemyslaw Szczepaniak            if (!useParentHdls) {
75151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                break;
75251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            }
75351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
7544ff539dbc5a809ef3eacbe2d9f2b97f640b7e9cfPrzemyslaw Szczepaniak            logger = isSystemLogger ? logger.parent : logger.getParent();
75551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        }
75651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    }
75751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
75851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    // private support method for logging.
75951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    // We fill in the logger name, resource bundle name, and
76051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    // resource bundle and then call "void log(LogRecord)".
76151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    private void doLog(LogRecord lr) {
76251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        lr.setLoggerName(name);
7634ff539dbc5a809ef3eacbe2d9f2b97f640b7e9cfPrzemyslaw Szczepaniak        final LoggerBundle lb = getEffectiveLoggerBundle();
7644ff539dbc5a809ef3eacbe2d9f2b97f640b7e9cfPrzemyslaw Szczepaniak        final ResourceBundle  bundle = lb.userBundle;
7654ff539dbc5a809ef3eacbe2d9f2b97f640b7e9cfPrzemyslaw Szczepaniak        final String ebname = lb.resourceBundleName;
7664ff539dbc5a809ef3eacbe2d9f2b97f640b7e9cfPrzemyslaw Szczepaniak        if (ebname != null && bundle != null) {
76751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            lr.setResourceBundleName(ebname);
7684ff539dbc5a809ef3eacbe2d9f2b97f640b7e9cfPrzemyslaw Szczepaniak            lr.setResourceBundle(bundle);
76951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        }
77051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        log(lr);
77151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    }
77251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
77351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
77451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    //================================================================
77551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    // Start of convenience methods WITHOUT className and methodName
77651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    //================================================================
77751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
77851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    /**
77951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * Log a message, with no arguments.
78051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * <p>
78151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * If the logger is currently enabled for the given message
78251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * level then the given message is forwarded to all the
78351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * registered output Handler objects.
78451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * <p>
78551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * @param   level   One of the message level identifiers, e.g., SEVERE
78651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * @param   msg     The string message (or a key in the message catalog)
78751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     */
78851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    public void log(Level level, String msg) {
7894ff539dbc5a809ef3eacbe2d9f2b97f640b7e9cfPrzemyslaw Szczepaniak        if (!isLoggable(level)) {
79051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            return;
79151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        }
79251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        LogRecord lr = new LogRecord(level, msg);
79351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        doLog(lr);
79451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    }
79551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
79651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    /**
7974ff539dbc5a809ef3eacbe2d9f2b97f640b7e9cfPrzemyslaw Szczepaniak     * Log a message, which is only to be constructed if the logging level
7984ff539dbc5a809ef3eacbe2d9f2b97f640b7e9cfPrzemyslaw Szczepaniak     * is such that the message will actually be logged.
7994ff539dbc5a809ef3eacbe2d9f2b97f640b7e9cfPrzemyslaw Szczepaniak     * <p>
8004ff539dbc5a809ef3eacbe2d9f2b97f640b7e9cfPrzemyslaw Szczepaniak     * If the logger is currently enabled for the given message
8014ff539dbc5a809ef3eacbe2d9f2b97f640b7e9cfPrzemyslaw Szczepaniak     * level then the message is constructed by invoking the provided
8024ff539dbc5a809ef3eacbe2d9f2b97f640b7e9cfPrzemyslaw Szczepaniak     * supplier function and forwarded to all the registered output
8034ff539dbc5a809ef3eacbe2d9f2b97f640b7e9cfPrzemyslaw Szczepaniak     * Handler objects.
8044ff539dbc5a809ef3eacbe2d9f2b97f640b7e9cfPrzemyslaw Szczepaniak     * <p>
8054ff539dbc5a809ef3eacbe2d9f2b97f640b7e9cfPrzemyslaw Szczepaniak     * @param   level   One of the message level identifiers, e.g., SEVERE
8064ff539dbc5a809ef3eacbe2d9f2b97f640b7e9cfPrzemyslaw Szczepaniak     * @param   msgSupplier   A function, which when called, produces the
8074ff539dbc5a809ef3eacbe2d9f2b97f640b7e9cfPrzemyslaw Szczepaniak     *                        desired log message
8081d3a3b7676bc344c9daf25285d19f86b3b6c946aPrzemyslaw Szczepaniak     * @since 1.8
8094ff539dbc5a809ef3eacbe2d9f2b97f640b7e9cfPrzemyslaw Szczepaniak     */
8104ff539dbc5a809ef3eacbe2d9f2b97f640b7e9cfPrzemyslaw Szczepaniak    public void log(Level level, Supplier<String> msgSupplier) {
8114ff539dbc5a809ef3eacbe2d9f2b97f640b7e9cfPrzemyslaw Szczepaniak        if (!isLoggable(level)) {
8124ff539dbc5a809ef3eacbe2d9f2b97f640b7e9cfPrzemyslaw Szczepaniak            return;
8134ff539dbc5a809ef3eacbe2d9f2b97f640b7e9cfPrzemyslaw Szczepaniak        }
8144ff539dbc5a809ef3eacbe2d9f2b97f640b7e9cfPrzemyslaw Szczepaniak        LogRecord lr = new LogRecord(level, msgSupplier.get());
8154ff539dbc5a809ef3eacbe2d9f2b97f640b7e9cfPrzemyslaw Szczepaniak        doLog(lr);
8164ff539dbc5a809ef3eacbe2d9f2b97f640b7e9cfPrzemyslaw Szczepaniak    }
8174ff539dbc5a809ef3eacbe2d9f2b97f640b7e9cfPrzemyslaw Szczepaniak
8184ff539dbc5a809ef3eacbe2d9f2b97f640b7e9cfPrzemyslaw Szczepaniak    /**
81951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * Log a message, with one object parameter.
82051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * <p>
82151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * If the logger is currently enabled for the given message
82251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * level then a corresponding LogRecord is created and forwarded
82351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * to all the registered output Handler objects.
82451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * <p>
82551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * @param   level   One of the message level identifiers, e.g., SEVERE
82651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * @param   msg     The string message (or a key in the message catalog)
82751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * @param   param1  parameter to the message
82851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     */
82951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    public void log(Level level, String msg, Object param1) {
8304ff539dbc5a809ef3eacbe2d9f2b97f640b7e9cfPrzemyslaw Szczepaniak        if (!isLoggable(level)) {
83151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            return;
83251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        }
83351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        LogRecord lr = new LogRecord(level, msg);
83451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        Object params[] = { param1 };
83551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        lr.setParameters(params);
83651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        doLog(lr);
83751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    }
83851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
83951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    /**
84051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * Log a message, with an array of object arguments.
84151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * <p>
84251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * If the logger is currently enabled for the given message
84351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * level then a corresponding LogRecord is created and forwarded
84451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * to all the registered output Handler objects.
84551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * <p>
84651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * @param   level   One of the message level identifiers, e.g., SEVERE
84751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * @param   msg     The string message (or a key in the message catalog)
84851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * @param   params  array of parameters to the message
84951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     */
85051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    public void log(Level level, String msg, Object params[]) {
8514ff539dbc5a809ef3eacbe2d9f2b97f640b7e9cfPrzemyslaw Szczepaniak        if (!isLoggable(level)) {
85251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            return;
85351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        }
85451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        LogRecord lr = new LogRecord(level, msg);
85551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        lr.setParameters(params);
85651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        doLog(lr);
85751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    }
85851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
85951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    /**
86051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * Log a message, with associated Throwable information.
86151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * <p>
86251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * If the logger is currently enabled for the given message
86351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * level then the given arguments are stored in a LogRecord
86451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * which is forwarded to all registered output handlers.
86551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * <p>
86651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * Note that the thrown argument is stored in the LogRecord thrown
8674ff539dbc5a809ef3eacbe2d9f2b97f640b7e9cfPrzemyslaw Szczepaniak     * property, rather than the LogRecord parameters property.  Thus it is
86851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * processed specially by output Formatters and is not treated
86951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * as a formatting parameter to the LogRecord message property.
87051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * <p>
87151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * @param   level   One of the message level identifiers, e.g., SEVERE
87251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * @param   msg     The string message (or a key in the message catalog)
87351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * @param   thrown  Throwable associated with log message.
87451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     */
87551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    public void log(Level level, String msg, Throwable thrown) {
8764ff539dbc5a809ef3eacbe2d9f2b97f640b7e9cfPrzemyslaw Szczepaniak        if (!isLoggable(level)) {
87751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            return;
87851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        }
87951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        LogRecord lr = new LogRecord(level, msg);
88051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        lr.setThrown(thrown);
88151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        doLog(lr);
88251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    }
88351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
8844ff539dbc5a809ef3eacbe2d9f2b97f640b7e9cfPrzemyslaw Szczepaniak    /**
8854ff539dbc5a809ef3eacbe2d9f2b97f640b7e9cfPrzemyslaw Szczepaniak     * Log a lazily constructed message, with associated Throwable information.
8864ff539dbc5a809ef3eacbe2d9f2b97f640b7e9cfPrzemyslaw Szczepaniak     * <p>
8874ff539dbc5a809ef3eacbe2d9f2b97f640b7e9cfPrzemyslaw Szczepaniak     * If the logger is currently enabled for the given message level then the
8884ff539dbc5a809ef3eacbe2d9f2b97f640b7e9cfPrzemyslaw Szczepaniak     * message is constructed by invoking the provided supplier function. The
8894ff539dbc5a809ef3eacbe2d9f2b97f640b7e9cfPrzemyslaw Szczepaniak     * message and the given {@link Throwable} are then stored in a {@link
8904ff539dbc5a809ef3eacbe2d9f2b97f640b7e9cfPrzemyslaw Szczepaniak     * LogRecord} which is forwarded to all registered output handlers.
8914ff539dbc5a809ef3eacbe2d9f2b97f640b7e9cfPrzemyslaw Szczepaniak     * <p>
8924ff539dbc5a809ef3eacbe2d9f2b97f640b7e9cfPrzemyslaw Szczepaniak     * Note that the thrown argument is stored in the LogRecord thrown
8934ff539dbc5a809ef3eacbe2d9f2b97f640b7e9cfPrzemyslaw Szczepaniak     * property, rather than the LogRecord parameters property.  Thus it is
8944ff539dbc5a809ef3eacbe2d9f2b97f640b7e9cfPrzemyslaw Szczepaniak     * processed specially by output Formatters and is not treated
8954ff539dbc5a809ef3eacbe2d9f2b97f640b7e9cfPrzemyslaw Szczepaniak     * as a formatting parameter to the LogRecord message property.
8964ff539dbc5a809ef3eacbe2d9f2b97f640b7e9cfPrzemyslaw Szczepaniak     * <p>
8974ff539dbc5a809ef3eacbe2d9f2b97f640b7e9cfPrzemyslaw Szczepaniak     * @param   level   One of the message level identifiers, e.g., SEVERE
8984ff539dbc5a809ef3eacbe2d9f2b97f640b7e9cfPrzemyslaw Szczepaniak     * @param   thrown  Throwable associated with log message.
8994ff539dbc5a809ef3eacbe2d9f2b97f640b7e9cfPrzemyslaw Szczepaniak     * @param   msgSupplier   A function, which when called, produces the
9004ff539dbc5a809ef3eacbe2d9f2b97f640b7e9cfPrzemyslaw Szczepaniak     *                        desired log message
9014ff539dbc5a809ef3eacbe2d9f2b97f640b7e9cfPrzemyslaw Szczepaniak     * @since   1.8
9024ff539dbc5a809ef3eacbe2d9f2b97f640b7e9cfPrzemyslaw Szczepaniak     */
9034ff539dbc5a809ef3eacbe2d9f2b97f640b7e9cfPrzemyslaw Szczepaniak    public void log(Level level, Throwable thrown, Supplier<String> msgSupplier) {
9044ff539dbc5a809ef3eacbe2d9f2b97f640b7e9cfPrzemyslaw Szczepaniak        if (!isLoggable(level)) {
9054ff539dbc5a809ef3eacbe2d9f2b97f640b7e9cfPrzemyslaw Szczepaniak            return;
9064ff539dbc5a809ef3eacbe2d9f2b97f640b7e9cfPrzemyslaw Szczepaniak        }
9074ff539dbc5a809ef3eacbe2d9f2b97f640b7e9cfPrzemyslaw Szczepaniak        LogRecord lr = new LogRecord(level, msgSupplier.get());
9084ff539dbc5a809ef3eacbe2d9f2b97f640b7e9cfPrzemyslaw Szczepaniak        lr.setThrown(thrown);
9094ff539dbc5a809ef3eacbe2d9f2b97f640b7e9cfPrzemyslaw Szczepaniak        doLog(lr);
9104ff539dbc5a809ef3eacbe2d9f2b97f640b7e9cfPrzemyslaw Szczepaniak    }
9114ff539dbc5a809ef3eacbe2d9f2b97f640b7e9cfPrzemyslaw Szczepaniak
91251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    //================================================================
91351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    // Start of convenience methods WITH className and methodName
91451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    //================================================================
91551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
91651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    /**
91751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * Log a message, specifying source class and method,
91851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * with no arguments.
91951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * <p>
92051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * If the logger is currently enabled for the given message
92151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * level then the given message is forwarded to all the
92251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * registered output Handler objects.
92351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * <p>
92451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * @param   level   One of the message level identifiers, e.g., SEVERE
92551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * @param   sourceClass    name of class that issued the logging request
92651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * @param   sourceMethod   name of method that issued the logging request
92751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * @param   msg     The string message (or a key in the message catalog)
92851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     */
92951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    public void logp(Level level, String sourceClass, String sourceMethod, String msg) {
9304ff539dbc5a809ef3eacbe2d9f2b97f640b7e9cfPrzemyslaw Szczepaniak        if (!isLoggable(level)) {
93151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            return;
93251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        }
93351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        LogRecord lr = new LogRecord(level, msg);
93451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        lr.setSourceClassName(sourceClass);
93551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        lr.setSourceMethodName(sourceMethod);
93651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        doLog(lr);
93751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    }
93851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
93951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    /**
9404ff539dbc5a809ef3eacbe2d9f2b97f640b7e9cfPrzemyslaw Szczepaniak     * Log a lazily constructed message, specifying source class and method,
9414ff539dbc5a809ef3eacbe2d9f2b97f640b7e9cfPrzemyslaw Szczepaniak     * with no arguments.
9424ff539dbc5a809ef3eacbe2d9f2b97f640b7e9cfPrzemyslaw Szczepaniak     * <p>
9434ff539dbc5a809ef3eacbe2d9f2b97f640b7e9cfPrzemyslaw Szczepaniak     * If the logger is currently enabled for the given message
9444ff539dbc5a809ef3eacbe2d9f2b97f640b7e9cfPrzemyslaw Szczepaniak     * level then the message is constructed by invoking the provided
9454ff539dbc5a809ef3eacbe2d9f2b97f640b7e9cfPrzemyslaw Szczepaniak     * supplier function and forwarded to all the registered output
9464ff539dbc5a809ef3eacbe2d9f2b97f640b7e9cfPrzemyslaw Szczepaniak     * Handler objects.
9474ff539dbc5a809ef3eacbe2d9f2b97f640b7e9cfPrzemyslaw Szczepaniak     * <p>
9484ff539dbc5a809ef3eacbe2d9f2b97f640b7e9cfPrzemyslaw Szczepaniak     * @param   level   One of the message level identifiers, e.g., SEVERE
9494ff539dbc5a809ef3eacbe2d9f2b97f640b7e9cfPrzemyslaw Szczepaniak     * @param   sourceClass    name of class that issued the logging request
9504ff539dbc5a809ef3eacbe2d9f2b97f640b7e9cfPrzemyslaw Szczepaniak     * @param   sourceMethod   name of method that issued the logging request
9514ff539dbc5a809ef3eacbe2d9f2b97f640b7e9cfPrzemyslaw Szczepaniak     * @param   msgSupplier   A function, which when called, produces the
9524ff539dbc5a809ef3eacbe2d9f2b97f640b7e9cfPrzemyslaw Szczepaniak     *                        desired log message
9534ff539dbc5a809ef3eacbe2d9f2b97f640b7e9cfPrzemyslaw Szczepaniak     * @since   1.8
9544ff539dbc5a809ef3eacbe2d9f2b97f640b7e9cfPrzemyslaw Szczepaniak     */
9554ff539dbc5a809ef3eacbe2d9f2b97f640b7e9cfPrzemyslaw Szczepaniak    public void logp(Level level, String sourceClass, String sourceMethod,
9564ff539dbc5a809ef3eacbe2d9f2b97f640b7e9cfPrzemyslaw Szczepaniak                     Supplier<String> msgSupplier) {
9574ff539dbc5a809ef3eacbe2d9f2b97f640b7e9cfPrzemyslaw Szczepaniak        if (!isLoggable(level)) {
9584ff539dbc5a809ef3eacbe2d9f2b97f640b7e9cfPrzemyslaw Szczepaniak            return;
9594ff539dbc5a809ef3eacbe2d9f2b97f640b7e9cfPrzemyslaw Szczepaniak        }
9604ff539dbc5a809ef3eacbe2d9f2b97f640b7e9cfPrzemyslaw Szczepaniak        LogRecord lr = new LogRecord(level, msgSupplier.get());
9614ff539dbc5a809ef3eacbe2d9f2b97f640b7e9cfPrzemyslaw Szczepaniak        lr.setSourceClassName(sourceClass);
9624ff539dbc5a809ef3eacbe2d9f2b97f640b7e9cfPrzemyslaw Szczepaniak        lr.setSourceMethodName(sourceMethod);
9634ff539dbc5a809ef3eacbe2d9f2b97f640b7e9cfPrzemyslaw Szczepaniak        doLog(lr);
9644ff539dbc5a809ef3eacbe2d9f2b97f640b7e9cfPrzemyslaw Szczepaniak    }
9654ff539dbc5a809ef3eacbe2d9f2b97f640b7e9cfPrzemyslaw Szczepaniak
9664ff539dbc5a809ef3eacbe2d9f2b97f640b7e9cfPrzemyslaw Szczepaniak    /**
96751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * Log a message, specifying source class and method,
96851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * with a single object parameter to the log message.
96951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * <p>
97051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * If the logger is currently enabled for the given message
97151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * level then a corresponding LogRecord is created and forwarded
97251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * to all the registered output Handler objects.
97351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * <p>
97451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * @param   level   One of the message level identifiers, e.g., SEVERE
97551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * @param   sourceClass    name of class that issued the logging request
97651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * @param   sourceMethod   name of method that issued the logging request
97751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * @param   msg      The string message (or a key in the message catalog)
97851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * @param   param1    Parameter to the log message.
97951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     */
98051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    public void logp(Level level, String sourceClass, String sourceMethod,
98151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                                                String msg, Object param1) {
9824ff539dbc5a809ef3eacbe2d9f2b97f640b7e9cfPrzemyslaw Szczepaniak        if (!isLoggable(level)) {
98351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            return;
98451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        }
98551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        LogRecord lr = new LogRecord(level, msg);
98651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        lr.setSourceClassName(sourceClass);
98751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        lr.setSourceMethodName(sourceMethod);
98851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        Object params[] = { param1 };
98951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        lr.setParameters(params);
99051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        doLog(lr);
99151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    }
99251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
99351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    /**
99451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * Log a message, specifying source class and method,
99551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * with an array of object arguments.
99651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * <p>
99751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * If the logger is currently enabled for the given message
99851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * level then a corresponding LogRecord is created and forwarded
99951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * to all the registered output Handler objects.
100051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * <p>
100151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * @param   level   One of the message level identifiers, e.g., SEVERE
100251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * @param   sourceClass    name of class that issued the logging request
100351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * @param   sourceMethod   name of method that issued the logging request
100451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * @param   msg     The string message (or a key in the message catalog)
100551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * @param   params  Array of parameters to the message
100651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     */
100751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    public void logp(Level level, String sourceClass, String sourceMethod,
100851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                                                String msg, Object params[]) {
10094ff539dbc5a809ef3eacbe2d9f2b97f640b7e9cfPrzemyslaw Szczepaniak        if (!isLoggable(level)) {
101051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            return;
101151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        }
101251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        LogRecord lr = new LogRecord(level, msg);
101351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        lr.setSourceClassName(sourceClass);
101451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        lr.setSourceMethodName(sourceMethod);
101551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        lr.setParameters(params);
101651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        doLog(lr);
101751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    }
101851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
101951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    /**
102051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * Log a message, specifying source class and method,
102151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * with associated Throwable information.
102251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * <p>
102351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * If the logger is currently enabled for the given message
102451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * level then the given arguments are stored in a LogRecord
102551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * which is forwarded to all registered output handlers.
102651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * <p>
102751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * Note that the thrown argument is stored in the LogRecord thrown
10284ff539dbc5a809ef3eacbe2d9f2b97f640b7e9cfPrzemyslaw Szczepaniak     * property, rather than the LogRecord parameters property.  Thus it is
102951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * processed specially by output Formatters and is not treated
103051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * as a formatting parameter to the LogRecord message property.
103151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * <p>
103251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * @param   level   One of the message level identifiers, e.g., SEVERE
103351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * @param   sourceClass    name of class that issued the logging request
103451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * @param   sourceMethod   name of method that issued the logging request
103551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * @param   msg     The string message (or a key in the message catalog)
103651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * @param   thrown  Throwable associated with log message.
103751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     */
103851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    public void logp(Level level, String sourceClass, String sourceMethod,
10394ff539dbc5a809ef3eacbe2d9f2b97f640b7e9cfPrzemyslaw Szczepaniak                     String msg, Throwable thrown) {
10404ff539dbc5a809ef3eacbe2d9f2b97f640b7e9cfPrzemyslaw Szczepaniak        if (!isLoggable(level)) {
104151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            return;
104251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        }
104351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        LogRecord lr = new LogRecord(level, msg);
104451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        lr.setSourceClassName(sourceClass);
104551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        lr.setSourceMethodName(sourceMethod);
104651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        lr.setThrown(thrown);
104751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        doLog(lr);
104851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    }
104951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
10504ff539dbc5a809ef3eacbe2d9f2b97f640b7e9cfPrzemyslaw Szczepaniak    /**
10514ff539dbc5a809ef3eacbe2d9f2b97f640b7e9cfPrzemyslaw Szczepaniak     * Log a lazily constructed message, specifying source class and method,
10524ff539dbc5a809ef3eacbe2d9f2b97f640b7e9cfPrzemyslaw Szczepaniak     * with associated Throwable information.
10534ff539dbc5a809ef3eacbe2d9f2b97f640b7e9cfPrzemyslaw Szczepaniak     * <p>
10544ff539dbc5a809ef3eacbe2d9f2b97f640b7e9cfPrzemyslaw Szczepaniak     * If the logger is currently enabled for the given message level then the
10554ff539dbc5a809ef3eacbe2d9f2b97f640b7e9cfPrzemyslaw Szczepaniak     * message is constructed by invoking the provided supplier function. The
10564ff539dbc5a809ef3eacbe2d9f2b97f640b7e9cfPrzemyslaw Szczepaniak     * message and the given {@link Throwable} are then stored in a {@link
10574ff539dbc5a809ef3eacbe2d9f2b97f640b7e9cfPrzemyslaw Szczepaniak     * LogRecord} which is forwarded to all registered output handlers.
10584ff539dbc5a809ef3eacbe2d9f2b97f640b7e9cfPrzemyslaw Szczepaniak     * <p>
10594ff539dbc5a809ef3eacbe2d9f2b97f640b7e9cfPrzemyslaw Szczepaniak     * Note that the thrown argument is stored in the LogRecord thrown
10604ff539dbc5a809ef3eacbe2d9f2b97f640b7e9cfPrzemyslaw Szczepaniak     * property, rather than the LogRecord parameters property.  Thus it is
10614ff539dbc5a809ef3eacbe2d9f2b97f640b7e9cfPrzemyslaw Szczepaniak     * processed specially by output Formatters and is not treated
10624ff539dbc5a809ef3eacbe2d9f2b97f640b7e9cfPrzemyslaw Szczepaniak     * as a formatting parameter to the LogRecord message property.
10634ff539dbc5a809ef3eacbe2d9f2b97f640b7e9cfPrzemyslaw Szczepaniak     * <p>
10644ff539dbc5a809ef3eacbe2d9f2b97f640b7e9cfPrzemyslaw Szczepaniak     * @param   level   One of the message level identifiers, e.g., SEVERE
10654ff539dbc5a809ef3eacbe2d9f2b97f640b7e9cfPrzemyslaw Szczepaniak     * @param   sourceClass    name of class that issued the logging request
10664ff539dbc5a809ef3eacbe2d9f2b97f640b7e9cfPrzemyslaw Szczepaniak     * @param   sourceMethod   name of method that issued the logging request
10674ff539dbc5a809ef3eacbe2d9f2b97f640b7e9cfPrzemyslaw Szczepaniak     * @param   thrown  Throwable associated with log message.
10684ff539dbc5a809ef3eacbe2d9f2b97f640b7e9cfPrzemyslaw Szczepaniak     * @param   msgSupplier   A function, which when called, produces the
10694ff539dbc5a809ef3eacbe2d9f2b97f640b7e9cfPrzemyslaw Szczepaniak     *                        desired log message
10704ff539dbc5a809ef3eacbe2d9f2b97f640b7e9cfPrzemyslaw Szczepaniak     * @since   1.8
10714ff539dbc5a809ef3eacbe2d9f2b97f640b7e9cfPrzemyslaw Szczepaniak     */
10724ff539dbc5a809ef3eacbe2d9f2b97f640b7e9cfPrzemyslaw Szczepaniak    public void logp(Level level, String sourceClass, String sourceMethod,
10734ff539dbc5a809ef3eacbe2d9f2b97f640b7e9cfPrzemyslaw Szczepaniak                     Throwable thrown, Supplier<String> msgSupplier) {
10744ff539dbc5a809ef3eacbe2d9f2b97f640b7e9cfPrzemyslaw Szczepaniak        if (!isLoggable(level)) {
10754ff539dbc5a809ef3eacbe2d9f2b97f640b7e9cfPrzemyslaw Szczepaniak            return;
10764ff539dbc5a809ef3eacbe2d9f2b97f640b7e9cfPrzemyslaw Szczepaniak        }
10774ff539dbc5a809ef3eacbe2d9f2b97f640b7e9cfPrzemyslaw Szczepaniak        LogRecord lr = new LogRecord(level, msgSupplier.get());
10784ff539dbc5a809ef3eacbe2d9f2b97f640b7e9cfPrzemyslaw Szczepaniak        lr.setSourceClassName(sourceClass);
10794ff539dbc5a809ef3eacbe2d9f2b97f640b7e9cfPrzemyslaw Szczepaniak        lr.setSourceMethodName(sourceMethod);
10804ff539dbc5a809ef3eacbe2d9f2b97f640b7e9cfPrzemyslaw Szczepaniak        lr.setThrown(thrown);
10814ff539dbc5a809ef3eacbe2d9f2b97f640b7e9cfPrzemyslaw Szczepaniak        doLog(lr);
10824ff539dbc5a809ef3eacbe2d9f2b97f640b7e9cfPrzemyslaw Szczepaniak    }
10834ff539dbc5a809ef3eacbe2d9f2b97f640b7e9cfPrzemyslaw Szczepaniak
108451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
108551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    //=========================================================================
108651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    // Start of convenience methods WITH className, methodName and bundle name.
108751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    //=========================================================================
108851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
108951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    // Private support method for logging for "logrb" methods.
109051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    // We fill in the logger name, resource bundle name, and
109151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    // resource bundle and then call "void log(LogRecord)".
109251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    private void doLog(LogRecord lr, String rbname) {
109351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        lr.setLoggerName(name);
109451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        if (rbname != null) {
109551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            lr.setResourceBundleName(rbname);
109651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            lr.setResourceBundle(findResourceBundle(rbname, false));
109751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        }
109851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        log(lr);
109951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    }
110051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
11014ff539dbc5a809ef3eacbe2d9f2b97f640b7e9cfPrzemyslaw Szczepaniak    // Private support method for logging for "logrb" methods.
11024ff539dbc5a809ef3eacbe2d9f2b97f640b7e9cfPrzemyslaw Szczepaniak    private void doLog(LogRecord lr, ResourceBundle rb) {
11034ff539dbc5a809ef3eacbe2d9f2b97f640b7e9cfPrzemyslaw Szczepaniak        lr.setLoggerName(name);
11044ff539dbc5a809ef3eacbe2d9f2b97f640b7e9cfPrzemyslaw Szczepaniak        if (rb != null) {
11054ff539dbc5a809ef3eacbe2d9f2b97f640b7e9cfPrzemyslaw Szczepaniak            lr.setResourceBundleName(rb.getBaseBundleName());
11064ff539dbc5a809ef3eacbe2d9f2b97f640b7e9cfPrzemyslaw Szczepaniak            lr.setResourceBundle(rb);
11074ff539dbc5a809ef3eacbe2d9f2b97f640b7e9cfPrzemyslaw Szczepaniak        }
11084ff539dbc5a809ef3eacbe2d9f2b97f640b7e9cfPrzemyslaw Szczepaniak        log(lr);
11094ff539dbc5a809ef3eacbe2d9f2b97f640b7e9cfPrzemyslaw Szczepaniak    }
11104ff539dbc5a809ef3eacbe2d9f2b97f640b7e9cfPrzemyslaw Szczepaniak
111151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    /**
111251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * Log a message, specifying source class, method, and resource bundle name
111351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * with no arguments.
111451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * <p>
111551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * If the logger is currently enabled for the given message
111651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * level then the given message is forwarded to all the
111751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * registered output Handler objects.
111851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * <p>
111951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * The msg string is localized using the named resource bundle.  If the
112051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * resource bundle name is null, or an empty String or invalid
112151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * then the msg string is not localized.
112251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * <p>
112351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * @param   level   One of the message level identifiers, e.g., SEVERE
112451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * @param   sourceClass    name of class that issued the logging request
112551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * @param   sourceMethod   name of method that issued the logging request
112651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * @param   bundleName     name of resource bundle to localize msg,
112751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     *                         can be null
112851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * @param   msg     The string message (or a key in the message catalog)
11294ff539dbc5a809ef3eacbe2d9f2b97f640b7e9cfPrzemyslaw Szczepaniak     * @deprecated Use {@link #logrb(java.util.logging.Level, java.lang.String,
11304ff539dbc5a809ef3eacbe2d9f2b97f640b7e9cfPrzemyslaw Szczepaniak     * java.lang.String, java.util.ResourceBundle, java.lang.String,
11314ff539dbc5a809ef3eacbe2d9f2b97f640b7e9cfPrzemyslaw Szczepaniak     * java.lang.Object...)} instead.
113251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     */
11334ff539dbc5a809ef3eacbe2d9f2b97f640b7e9cfPrzemyslaw Szczepaniak    @Deprecated
113451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    public void logrb(Level level, String sourceClass, String sourceMethod,
113551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                                String bundleName, String msg) {
11364ff539dbc5a809ef3eacbe2d9f2b97f640b7e9cfPrzemyslaw Szczepaniak        if (!isLoggable(level)) {
113751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            return;
113851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        }
113951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        LogRecord lr = new LogRecord(level, msg);
114051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        lr.setSourceClassName(sourceClass);
114151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        lr.setSourceMethodName(sourceMethod);
114251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        doLog(lr, bundleName);
114351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    }
114451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
114551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    /**
114651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * Log a message, specifying source class, method, and resource bundle name,
114751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * with a single object parameter to the log message.
114851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * <p>
114951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * If the logger is currently enabled for the given message
115051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * level then a corresponding LogRecord is created and forwarded
115151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * to all the registered output Handler objects.
115251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * <p>
115351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * The msg string is localized using the named resource bundle.  If the
115451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * resource bundle name is null, or an empty String or invalid
115551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * then the msg string is not localized.
115651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * <p>
115751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * @param   level   One of the message level identifiers, e.g., SEVERE
115851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * @param   sourceClass    name of class that issued the logging request
115951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * @param   sourceMethod   name of method that issued the logging request
116051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * @param   bundleName     name of resource bundle to localize msg,
116151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     *                         can be null
116251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * @param   msg      The string message (or a key in the message catalog)
116351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * @param   param1    Parameter to the log message.
11644ff539dbc5a809ef3eacbe2d9f2b97f640b7e9cfPrzemyslaw Szczepaniak     * @deprecated Use {@link #logrb(java.util.logging.Level, java.lang.String,
11654ff539dbc5a809ef3eacbe2d9f2b97f640b7e9cfPrzemyslaw Szczepaniak     *   java.lang.String, java.util.ResourceBundle, java.lang.String,
11664ff539dbc5a809ef3eacbe2d9f2b97f640b7e9cfPrzemyslaw Szczepaniak     *   java.lang.Object...)} instead
116751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     */
11684ff539dbc5a809ef3eacbe2d9f2b97f640b7e9cfPrzemyslaw Szczepaniak    @Deprecated
116951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    public void logrb(Level level, String sourceClass, String sourceMethod,
117051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                                String bundleName, String msg, Object param1) {
11714ff539dbc5a809ef3eacbe2d9f2b97f640b7e9cfPrzemyslaw Szczepaniak        if (!isLoggable(level)) {
117251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            return;
117351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        }
117451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        LogRecord lr = new LogRecord(level, msg);
117551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        lr.setSourceClassName(sourceClass);
117651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        lr.setSourceMethodName(sourceMethod);
117751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        Object params[] = { param1 };
117851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        lr.setParameters(params);
117951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        doLog(lr, bundleName);
118051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    }
118151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
118251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    /**
118351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * Log a message, specifying source class, method, and resource bundle name,
118451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * with an array of object arguments.
118551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * <p>
118651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * If the logger is currently enabled for the given message
118751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * level then a corresponding LogRecord is created and forwarded
118851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * to all the registered output Handler objects.
118951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * <p>
119051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * The msg string is localized using the named resource bundle.  If the
119151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * resource bundle name is null, or an empty String or invalid
119251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * then the msg string is not localized.
119351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * <p>
119451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * @param   level   One of the message level identifiers, e.g., SEVERE
119551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * @param   sourceClass    name of class that issued the logging request
119651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * @param   sourceMethod   name of method that issued the logging request
119751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * @param   bundleName     name of resource bundle to localize msg,
119851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     *                         can be null.
119951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * @param   msg     The string message (or a key in the message catalog)
120051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * @param   params  Array of parameters to the message
12014ff539dbc5a809ef3eacbe2d9f2b97f640b7e9cfPrzemyslaw Szczepaniak     * @deprecated Use {@link #logrb(java.util.logging.Level, java.lang.String,
12024ff539dbc5a809ef3eacbe2d9f2b97f640b7e9cfPrzemyslaw Szczepaniak     *      java.lang.String, java.util.ResourceBundle, java.lang.String,
12034ff539dbc5a809ef3eacbe2d9f2b97f640b7e9cfPrzemyslaw Szczepaniak     *      java.lang.Object...)} instead.
120451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     */
12054ff539dbc5a809ef3eacbe2d9f2b97f640b7e9cfPrzemyslaw Szczepaniak    @Deprecated
120651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    public void logrb(Level level, String sourceClass, String sourceMethod,
120751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                                String bundleName, String msg, Object params[]) {
12084ff539dbc5a809ef3eacbe2d9f2b97f640b7e9cfPrzemyslaw Szczepaniak        if (!isLoggable(level)) {
120951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            return;
121051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        }
121151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        LogRecord lr = new LogRecord(level, msg);
121251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        lr.setSourceClassName(sourceClass);
121351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        lr.setSourceMethodName(sourceMethod);
121451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        lr.setParameters(params);
121551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        doLog(lr, bundleName);
121651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    }
121751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
121851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    /**
12194ff539dbc5a809ef3eacbe2d9f2b97f640b7e9cfPrzemyslaw Szczepaniak     * Log a message, specifying source class, method, and resource bundle,
12204ff539dbc5a809ef3eacbe2d9f2b97f640b7e9cfPrzemyslaw Szczepaniak     * with an optional list of message parameters.
12214ff539dbc5a809ef3eacbe2d9f2b97f640b7e9cfPrzemyslaw Szczepaniak     * <p>
12224ff539dbc5a809ef3eacbe2d9f2b97f640b7e9cfPrzemyslaw Szczepaniak     * If the logger is currently enabled for the given message
12234ff539dbc5a809ef3eacbe2d9f2b97f640b7e9cfPrzemyslaw Szczepaniak     * level then a corresponding LogRecord is created and forwarded
12244ff539dbc5a809ef3eacbe2d9f2b97f640b7e9cfPrzemyslaw Szczepaniak     * to all the registered output Handler objects.
12254ff539dbc5a809ef3eacbe2d9f2b97f640b7e9cfPrzemyslaw Szczepaniak     * <p>
12264ff539dbc5a809ef3eacbe2d9f2b97f640b7e9cfPrzemyslaw Szczepaniak     * The {@code msg} string is localized using the given resource bundle.
12274ff539dbc5a809ef3eacbe2d9f2b97f640b7e9cfPrzemyslaw Szczepaniak     * If the resource bundle is {@code null}, then the {@code msg} string is not
12284ff539dbc5a809ef3eacbe2d9f2b97f640b7e9cfPrzemyslaw Szczepaniak     * localized.
12294ff539dbc5a809ef3eacbe2d9f2b97f640b7e9cfPrzemyslaw Szczepaniak     * <p>
12304ff539dbc5a809ef3eacbe2d9f2b97f640b7e9cfPrzemyslaw Szczepaniak     * @param   level   One of the message level identifiers, e.g., SEVERE
12314ff539dbc5a809ef3eacbe2d9f2b97f640b7e9cfPrzemyslaw Szczepaniak     * @param   sourceClass    Name of the class that issued the logging request
12324ff539dbc5a809ef3eacbe2d9f2b97f640b7e9cfPrzemyslaw Szczepaniak     * @param   sourceMethod   Name of the method that issued the logging request
12334ff539dbc5a809ef3eacbe2d9f2b97f640b7e9cfPrzemyslaw Szczepaniak     * @param   bundle         Resource bundle to localize {@code msg},
12344ff539dbc5a809ef3eacbe2d9f2b97f640b7e9cfPrzemyslaw Szczepaniak     *                         can be {@code null}.
12354ff539dbc5a809ef3eacbe2d9f2b97f640b7e9cfPrzemyslaw Szczepaniak     * @param   msg     The string message (or a key in the message catalog)
12364ff539dbc5a809ef3eacbe2d9f2b97f640b7e9cfPrzemyslaw Szczepaniak     * @param   params  Parameters to the message (optional, may be none).
12374ff539dbc5a809ef3eacbe2d9f2b97f640b7e9cfPrzemyslaw Szczepaniak     * @since 1.8
12384ff539dbc5a809ef3eacbe2d9f2b97f640b7e9cfPrzemyslaw Szczepaniak     */
12394ff539dbc5a809ef3eacbe2d9f2b97f640b7e9cfPrzemyslaw Szczepaniak    public void logrb(Level level, String sourceClass, String sourceMethod,
12404ff539dbc5a809ef3eacbe2d9f2b97f640b7e9cfPrzemyslaw Szczepaniak                      ResourceBundle bundle, String msg, Object... params) {
12414ff539dbc5a809ef3eacbe2d9f2b97f640b7e9cfPrzemyslaw Szczepaniak        if (!isLoggable(level)) {
12424ff539dbc5a809ef3eacbe2d9f2b97f640b7e9cfPrzemyslaw Szczepaniak            return;
12434ff539dbc5a809ef3eacbe2d9f2b97f640b7e9cfPrzemyslaw Szczepaniak        }
12444ff539dbc5a809ef3eacbe2d9f2b97f640b7e9cfPrzemyslaw Szczepaniak        LogRecord lr = new LogRecord(level, msg);
12454ff539dbc5a809ef3eacbe2d9f2b97f640b7e9cfPrzemyslaw Szczepaniak        lr.setSourceClassName(sourceClass);
12464ff539dbc5a809ef3eacbe2d9f2b97f640b7e9cfPrzemyslaw Szczepaniak        lr.setSourceMethodName(sourceMethod);
12474ff539dbc5a809ef3eacbe2d9f2b97f640b7e9cfPrzemyslaw Szczepaniak        if (params != null && params.length != 0) {
12484ff539dbc5a809ef3eacbe2d9f2b97f640b7e9cfPrzemyslaw Szczepaniak            lr.setParameters(params);
12494ff539dbc5a809ef3eacbe2d9f2b97f640b7e9cfPrzemyslaw Szczepaniak        }
12504ff539dbc5a809ef3eacbe2d9f2b97f640b7e9cfPrzemyslaw Szczepaniak        doLog(lr, bundle);
12514ff539dbc5a809ef3eacbe2d9f2b97f640b7e9cfPrzemyslaw Szczepaniak    }
12524ff539dbc5a809ef3eacbe2d9f2b97f640b7e9cfPrzemyslaw Szczepaniak
12534ff539dbc5a809ef3eacbe2d9f2b97f640b7e9cfPrzemyslaw Szczepaniak    /**
125451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * Log a message, specifying source class, method, and resource bundle name,
125551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * with associated Throwable information.
125651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * <p>
125751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * If the logger is currently enabled for the given message
125851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * level then the given arguments are stored in a LogRecord
125951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * which is forwarded to all registered output handlers.
126051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * <p>
126151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * The msg string is localized using the named resource bundle.  If the
126251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * resource bundle name is null, or an empty String or invalid
126351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * then the msg string is not localized.
126451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * <p>
126551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * Note that the thrown argument is stored in the LogRecord thrown
12664ff539dbc5a809ef3eacbe2d9f2b97f640b7e9cfPrzemyslaw Szczepaniak     * property, rather than the LogRecord parameters property.  Thus it is
126751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * processed specially by output Formatters and is not treated
126851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * as a formatting parameter to the LogRecord message property.
126951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * <p>
127051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * @param   level   One of the message level identifiers, e.g., SEVERE
127151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * @param   sourceClass    name of class that issued the logging request
127251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * @param   sourceMethod   name of method that issued the logging request
127351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * @param   bundleName     name of resource bundle to localize msg,
127451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     *                         can be null
127551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * @param   msg     The string message (or a key in the message catalog)
127651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * @param   thrown  Throwable associated with log message.
12774ff539dbc5a809ef3eacbe2d9f2b97f640b7e9cfPrzemyslaw Szczepaniak     * @deprecated Use {@link #logrb(java.util.logging.Level, java.lang.String,
12784ff539dbc5a809ef3eacbe2d9f2b97f640b7e9cfPrzemyslaw Szczepaniak     *     java.lang.String, java.util.ResourceBundle, java.lang.String,
12794ff539dbc5a809ef3eacbe2d9f2b97f640b7e9cfPrzemyslaw Szczepaniak     *     java.lang.Throwable)} instead.
128051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     */
12814ff539dbc5a809ef3eacbe2d9f2b97f640b7e9cfPrzemyslaw Szczepaniak    @Deprecated
128251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    public void logrb(Level level, String sourceClass, String sourceMethod,
128351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                                        String bundleName, String msg, Throwable thrown) {
12844ff539dbc5a809ef3eacbe2d9f2b97f640b7e9cfPrzemyslaw Szczepaniak        if (!isLoggable(level)) {
128551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            return;
128651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        }
128751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        LogRecord lr = new LogRecord(level, msg);
128851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        lr.setSourceClassName(sourceClass);
128951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        lr.setSourceMethodName(sourceMethod);
129051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        lr.setThrown(thrown);
129151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        doLog(lr, bundleName);
129251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    }
129351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
12944ff539dbc5a809ef3eacbe2d9f2b97f640b7e9cfPrzemyslaw Szczepaniak    /**
12954ff539dbc5a809ef3eacbe2d9f2b97f640b7e9cfPrzemyslaw Szczepaniak     * Log a message, specifying source class, method, and resource bundle,
12964ff539dbc5a809ef3eacbe2d9f2b97f640b7e9cfPrzemyslaw Szczepaniak     * with associated Throwable information.
12974ff539dbc5a809ef3eacbe2d9f2b97f640b7e9cfPrzemyslaw Szczepaniak     * <p>
12984ff539dbc5a809ef3eacbe2d9f2b97f640b7e9cfPrzemyslaw Szczepaniak     * If the logger is currently enabled for the given message
12994ff539dbc5a809ef3eacbe2d9f2b97f640b7e9cfPrzemyslaw Szczepaniak     * level then the given arguments are stored in a LogRecord
13004ff539dbc5a809ef3eacbe2d9f2b97f640b7e9cfPrzemyslaw Szczepaniak     * which is forwarded to all registered output handlers.
13014ff539dbc5a809ef3eacbe2d9f2b97f640b7e9cfPrzemyslaw Szczepaniak     * <p>
13024ff539dbc5a809ef3eacbe2d9f2b97f640b7e9cfPrzemyslaw Szczepaniak     * The {@code msg} string is localized using the given resource bundle.
13034ff539dbc5a809ef3eacbe2d9f2b97f640b7e9cfPrzemyslaw Szczepaniak     * If the resource bundle is {@code null}, then the {@code msg} string is not
13044ff539dbc5a809ef3eacbe2d9f2b97f640b7e9cfPrzemyslaw Szczepaniak     * localized.
13054ff539dbc5a809ef3eacbe2d9f2b97f640b7e9cfPrzemyslaw Szczepaniak     * <p>
13064ff539dbc5a809ef3eacbe2d9f2b97f640b7e9cfPrzemyslaw Szczepaniak     * Note that the thrown argument is stored in the LogRecord thrown
13074ff539dbc5a809ef3eacbe2d9f2b97f640b7e9cfPrzemyslaw Szczepaniak     * property, rather than the LogRecord parameters property.  Thus it is
13084ff539dbc5a809ef3eacbe2d9f2b97f640b7e9cfPrzemyslaw Szczepaniak     * processed specially by output Formatters and is not treated
13094ff539dbc5a809ef3eacbe2d9f2b97f640b7e9cfPrzemyslaw Szczepaniak     * as a formatting parameter to the LogRecord message property.
13104ff539dbc5a809ef3eacbe2d9f2b97f640b7e9cfPrzemyslaw Szczepaniak     * <p>
13114ff539dbc5a809ef3eacbe2d9f2b97f640b7e9cfPrzemyslaw Szczepaniak     * @param   level   One of the message level identifiers, e.g., SEVERE
13124ff539dbc5a809ef3eacbe2d9f2b97f640b7e9cfPrzemyslaw Szczepaniak     * @param   sourceClass    Name of the class that issued the logging request
13134ff539dbc5a809ef3eacbe2d9f2b97f640b7e9cfPrzemyslaw Szczepaniak     * @param   sourceMethod   Name of the method that issued the logging request
13144ff539dbc5a809ef3eacbe2d9f2b97f640b7e9cfPrzemyslaw Szczepaniak     * @param   bundle         Resource bundle to localize {@code msg},
13154ff539dbc5a809ef3eacbe2d9f2b97f640b7e9cfPrzemyslaw Szczepaniak     *                         can be {@code null}
13164ff539dbc5a809ef3eacbe2d9f2b97f640b7e9cfPrzemyslaw Szczepaniak     * @param   msg     The string message (or a key in the message catalog)
13174ff539dbc5a809ef3eacbe2d9f2b97f640b7e9cfPrzemyslaw Szczepaniak     * @param   thrown  Throwable associated with the log message.
13184ff539dbc5a809ef3eacbe2d9f2b97f640b7e9cfPrzemyslaw Szczepaniak     * @since 1.8
13194ff539dbc5a809ef3eacbe2d9f2b97f640b7e9cfPrzemyslaw Szczepaniak     */
13204ff539dbc5a809ef3eacbe2d9f2b97f640b7e9cfPrzemyslaw Szczepaniak    public void logrb(Level level, String sourceClass, String sourceMethod,
13214ff539dbc5a809ef3eacbe2d9f2b97f640b7e9cfPrzemyslaw Szczepaniak                      ResourceBundle bundle, String msg, Throwable thrown) {
13224ff539dbc5a809ef3eacbe2d9f2b97f640b7e9cfPrzemyslaw Szczepaniak        if (!isLoggable(level)) {
13234ff539dbc5a809ef3eacbe2d9f2b97f640b7e9cfPrzemyslaw Szczepaniak            return;
13244ff539dbc5a809ef3eacbe2d9f2b97f640b7e9cfPrzemyslaw Szczepaniak        }
13254ff539dbc5a809ef3eacbe2d9f2b97f640b7e9cfPrzemyslaw Szczepaniak        LogRecord lr = new LogRecord(level, msg);
13264ff539dbc5a809ef3eacbe2d9f2b97f640b7e9cfPrzemyslaw Szczepaniak        lr.setSourceClassName(sourceClass);
13274ff539dbc5a809ef3eacbe2d9f2b97f640b7e9cfPrzemyslaw Szczepaniak        lr.setSourceMethodName(sourceMethod);
13284ff539dbc5a809ef3eacbe2d9f2b97f640b7e9cfPrzemyslaw Szczepaniak        lr.setThrown(thrown);
13294ff539dbc5a809ef3eacbe2d9f2b97f640b7e9cfPrzemyslaw Szczepaniak        doLog(lr, bundle);
13304ff539dbc5a809ef3eacbe2d9f2b97f640b7e9cfPrzemyslaw Szczepaniak    }
133151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
133251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    //======================================================================
133351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    // Start of convenience methods for logging method entries and returns.
133451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    //======================================================================
133551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
133651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    /**
133751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * Log a method entry.
133851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * <p>
133951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * This is a convenience method that can be used to log entry
134051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * to a method.  A LogRecord with message "ENTRY", log level
134151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * FINER, and the given sourceMethod and sourceClass is logged.
134251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * <p>
134351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * @param   sourceClass    name of class that issued the logging request
134451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * @param   sourceMethod   name of method that is being entered
134551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     */
134651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    public void entering(String sourceClass, String sourceMethod) {
134751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        logp(Level.FINER, sourceClass, sourceMethod, "ENTRY");
134851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    }
134951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
135051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    /**
135151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * Log a method entry, with one parameter.
135251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * <p>
135351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * This is a convenience method that can be used to log entry
135451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * to a method.  A LogRecord with message "ENTRY {0}", log level
135551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * FINER, and the given sourceMethod, sourceClass, and parameter
135651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * is logged.
135751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * <p>
135851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * @param   sourceClass    name of class that issued the logging request
135951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * @param   sourceMethod   name of method that is being entered
136051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * @param   param1         parameter to the method being entered
136151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     */
136251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    public void entering(String sourceClass, String sourceMethod, Object param1) {
13634ff539dbc5a809ef3eacbe2d9f2b97f640b7e9cfPrzemyslaw Szczepaniak        logp(Level.FINER, sourceClass, sourceMethod, "ENTRY {0}", param1);
136451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    }
136551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
136651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    /**
136751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * Log a method entry, with an array of parameters.
136851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * <p>
136951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * This is a convenience method that can be used to log entry
137051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * to a method.  A LogRecord with message "ENTRY" (followed by a
137151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * format {N} indicator for each entry in the parameter array),
137251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * log level FINER, and the given sourceMethod, sourceClass, and
137351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * parameters is logged.
137451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * <p>
137551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * @param   sourceClass    name of class that issued the logging request
137651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * @param   sourceMethod   name of method that is being entered
137751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * @param   params         array of parameters to the method being entered
137851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     */
137951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    public void entering(String sourceClass, String sourceMethod, Object params[]) {
138051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        String msg = "ENTRY";
138151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        if (params == null ) {
138251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski           logp(Level.FINER, sourceClass, sourceMethod, msg);
138351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski           return;
138451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        }
13854ff539dbc5a809ef3eacbe2d9f2b97f640b7e9cfPrzemyslaw Szczepaniak        if (!isLoggable(Level.FINER)) return;
138651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        for (int i = 0; i < params.length; i++) {
138751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            msg = msg + " {" + i + "}";
138851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        }
138951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        logp(Level.FINER, sourceClass, sourceMethod, msg, params);
139051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    }
139151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
139251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    /**
139351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * Log a method return.
139451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * <p>
139551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * This is a convenience method that can be used to log returning
139651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * from a method.  A LogRecord with message "RETURN", log level
139751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * FINER, and the given sourceMethod and sourceClass is logged.
139851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * <p>
139951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * @param   sourceClass    name of class that issued the logging request
140051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * @param   sourceMethod   name of the method
140151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     */
140251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    public void exiting(String sourceClass, String sourceMethod) {
140351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        logp(Level.FINER, sourceClass, sourceMethod, "RETURN");
140451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    }
140551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
140651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
140751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    /**
140851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * Log a method return, with result object.
140951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * <p>
141051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * This is a convenience method that can be used to log returning
141151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * from a method.  A LogRecord with message "RETURN {0}", log level
141251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * FINER, and the gives sourceMethod, sourceClass, and result
141351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * object is logged.
141451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * <p>
141551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * @param   sourceClass    name of class that issued the logging request
141651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * @param   sourceMethod   name of the method
141751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * @param   result  Object that is being returned
141851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     */
141951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    public void exiting(String sourceClass, String sourceMethod, Object result) {
142051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        logp(Level.FINER, sourceClass, sourceMethod, "RETURN {0}", result);
142151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    }
142251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
142351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    /**
142451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * Log throwing an exception.
142551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * <p>
142651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * This is a convenience method to log that a method is
142751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * terminating by throwing an exception.  The logging is done
142851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * using the FINER level.
142951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * <p>
143051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * If the logger is currently enabled for the given message
143151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * level then the given arguments are stored in a LogRecord
143251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * which is forwarded to all registered output handlers.  The
143351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * LogRecord's message is set to "THROW".
143451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * <p>
143551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * Note that the thrown argument is stored in the LogRecord thrown
14364ff539dbc5a809ef3eacbe2d9f2b97f640b7e9cfPrzemyslaw Szczepaniak     * property, rather than the LogRecord parameters property.  Thus it is
143751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * processed specially by output Formatters and is not treated
143851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * as a formatting parameter to the LogRecord message property.
143951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * <p>
144051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * @param   sourceClass    name of class that issued the logging request
144151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * @param   sourceMethod  name of the method.
144251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * @param   thrown  The Throwable that is being thrown.
144351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     */
144451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    public void throwing(String sourceClass, String sourceMethod, Throwable thrown) {
14454ff539dbc5a809ef3eacbe2d9f2b97f640b7e9cfPrzemyslaw Szczepaniak        if (!isLoggable(Level.FINER)) {
144651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            return;
144751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        }
144851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        LogRecord lr = new LogRecord(Level.FINER, "THROW");
144951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        lr.setSourceClassName(sourceClass);
145051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        lr.setSourceMethodName(sourceMethod);
145151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        lr.setThrown(thrown);
145251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        doLog(lr);
145351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    }
145451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
145551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    //=======================================================================
145651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    // Start of simple convenience methods using level names as method names
145751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    //=======================================================================
145851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
145951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    /**
146051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * Log a SEVERE message.
146151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * <p>
146251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * If the logger is currently enabled for the SEVERE message
146351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * level then the given message is forwarded to all the
146451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * registered output Handler objects.
146551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * <p>
146651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * @param   msg     The string message (or a key in the message catalog)
146751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     */
146851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    public void severe(String msg) {
146951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        log(Level.SEVERE, msg);
147051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    }
147151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
147251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    /**
147351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * Log a WARNING message.
147451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * <p>
147551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * If the logger is currently enabled for the WARNING message
147651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * level then the given message is forwarded to all the
147751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * registered output Handler objects.
147851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * <p>
147951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * @param   msg     The string message (or a key in the message catalog)
148051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     */
148151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    public void warning(String msg) {
148251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        log(Level.WARNING, msg);
148351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    }
148451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
148551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    /**
148651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * Log an INFO message.
148751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * <p>
148851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * If the logger is currently enabled for the INFO message
148951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * level then the given message is forwarded to all the
149051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * registered output Handler objects.
149151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * <p>
149251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * @param   msg     The string message (or a key in the message catalog)
149351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     */
149451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    public void info(String msg) {
149551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        log(Level.INFO, msg);
149651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    }
149751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
149851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    /**
149951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * Log a CONFIG message.
150051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * <p>
150151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * If the logger is currently enabled for the CONFIG message
150251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * level then the given message is forwarded to all the
150351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * registered output Handler objects.
150451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * <p>
150551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * @param   msg     The string message (or a key in the message catalog)
150651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     */
150751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    public void config(String msg) {
150851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        log(Level.CONFIG, msg);
150951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    }
151051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
151151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    /**
151251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * Log a FINE message.
151351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * <p>
151451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * If the logger is currently enabled for the FINE message
151551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * level then the given message is forwarded to all the
151651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * registered output Handler objects.
151751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * <p>
151851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * @param   msg     The string message (or a key in the message catalog)
151951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     */
152051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    public void fine(String msg) {
152151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        log(Level.FINE, msg);
152251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    }
152351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
152451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    /**
152551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * Log a FINER message.
152651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * <p>
152751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * If the logger is currently enabled for the FINER message
152851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * level then the given message is forwarded to all the
152951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * registered output Handler objects.
153051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * <p>
153151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * @param   msg     The string message (or a key in the message catalog)
153251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     */
153351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    public void finer(String msg) {
153451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        log(Level.FINER, msg);
153551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    }
153651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
153751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    /**
153851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * Log a FINEST message.
153951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * <p>
154051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * If the logger is currently enabled for the FINEST message
154151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * level then the given message is forwarded to all the
154251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * registered output Handler objects.
154351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * <p>
154451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * @param   msg     The string message (or a key in the message catalog)
154551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     */
154651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    public void finest(String msg) {
154751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        log(Level.FINEST, msg);
154851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    }
154951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
15504ff539dbc5a809ef3eacbe2d9f2b97f640b7e9cfPrzemyslaw Szczepaniak    //=======================================================================
15514ff539dbc5a809ef3eacbe2d9f2b97f640b7e9cfPrzemyslaw Szczepaniak    // Start of simple convenience methods using level names as method names
15524ff539dbc5a809ef3eacbe2d9f2b97f640b7e9cfPrzemyslaw Szczepaniak    // and use Supplier<String>
15534ff539dbc5a809ef3eacbe2d9f2b97f640b7e9cfPrzemyslaw Szczepaniak    //=======================================================================
15544ff539dbc5a809ef3eacbe2d9f2b97f640b7e9cfPrzemyslaw Szczepaniak
15554ff539dbc5a809ef3eacbe2d9f2b97f640b7e9cfPrzemyslaw Szczepaniak    /**
15564ff539dbc5a809ef3eacbe2d9f2b97f640b7e9cfPrzemyslaw Szczepaniak     * Log a SEVERE message, which is only to be constructed if the logging
15574ff539dbc5a809ef3eacbe2d9f2b97f640b7e9cfPrzemyslaw Szczepaniak     * level is such that the message will actually be logged.
15584ff539dbc5a809ef3eacbe2d9f2b97f640b7e9cfPrzemyslaw Szczepaniak     * <p>
15594ff539dbc5a809ef3eacbe2d9f2b97f640b7e9cfPrzemyslaw Szczepaniak     * If the logger is currently enabled for the SEVERE message
15604ff539dbc5a809ef3eacbe2d9f2b97f640b7e9cfPrzemyslaw Szczepaniak     * level then the message is constructed by invoking the provided
15614ff539dbc5a809ef3eacbe2d9f2b97f640b7e9cfPrzemyslaw Szczepaniak     * supplier function and forwarded to all the registered output
15624ff539dbc5a809ef3eacbe2d9f2b97f640b7e9cfPrzemyslaw Szczepaniak     * Handler objects.
15634ff539dbc5a809ef3eacbe2d9f2b97f640b7e9cfPrzemyslaw Szczepaniak     * <p>
15644ff539dbc5a809ef3eacbe2d9f2b97f640b7e9cfPrzemyslaw Szczepaniak     * @param   msgSupplier   A function, which when called, produces the
15654ff539dbc5a809ef3eacbe2d9f2b97f640b7e9cfPrzemyslaw Szczepaniak     *                        desired log message
15664ff539dbc5a809ef3eacbe2d9f2b97f640b7e9cfPrzemyslaw Szczepaniak     * @since   1.8
15674ff539dbc5a809ef3eacbe2d9f2b97f640b7e9cfPrzemyslaw Szczepaniak     */
15684ff539dbc5a809ef3eacbe2d9f2b97f640b7e9cfPrzemyslaw Szczepaniak    public void severe(Supplier<String> msgSupplier) {
15694ff539dbc5a809ef3eacbe2d9f2b97f640b7e9cfPrzemyslaw Szczepaniak        log(Level.SEVERE, msgSupplier);
15704ff539dbc5a809ef3eacbe2d9f2b97f640b7e9cfPrzemyslaw Szczepaniak    }
15714ff539dbc5a809ef3eacbe2d9f2b97f640b7e9cfPrzemyslaw Szczepaniak
15724ff539dbc5a809ef3eacbe2d9f2b97f640b7e9cfPrzemyslaw Szczepaniak    /**
15734ff539dbc5a809ef3eacbe2d9f2b97f640b7e9cfPrzemyslaw Szczepaniak     * Log a WARNING message, which is only to be constructed if the logging
15744ff539dbc5a809ef3eacbe2d9f2b97f640b7e9cfPrzemyslaw Szczepaniak     * level is such that the message will actually be logged.
15754ff539dbc5a809ef3eacbe2d9f2b97f640b7e9cfPrzemyslaw Szczepaniak     * <p>
15764ff539dbc5a809ef3eacbe2d9f2b97f640b7e9cfPrzemyslaw Szczepaniak     * If the logger is currently enabled for the WARNING message
15774ff539dbc5a809ef3eacbe2d9f2b97f640b7e9cfPrzemyslaw Szczepaniak     * level then the message is constructed by invoking the provided
15784ff539dbc5a809ef3eacbe2d9f2b97f640b7e9cfPrzemyslaw Szczepaniak     * supplier function and forwarded to all the registered output
15794ff539dbc5a809ef3eacbe2d9f2b97f640b7e9cfPrzemyslaw Szczepaniak     * Handler objects.
15804ff539dbc5a809ef3eacbe2d9f2b97f640b7e9cfPrzemyslaw Szczepaniak     * <p>
15814ff539dbc5a809ef3eacbe2d9f2b97f640b7e9cfPrzemyslaw Szczepaniak     * @param   msgSupplier   A function, which when called, produces the
15824ff539dbc5a809ef3eacbe2d9f2b97f640b7e9cfPrzemyslaw Szczepaniak     *                        desired log message
15834ff539dbc5a809ef3eacbe2d9f2b97f640b7e9cfPrzemyslaw Szczepaniak     * @since   1.8
15844ff539dbc5a809ef3eacbe2d9f2b97f640b7e9cfPrzemyslaw Szczepaniak     */
15854ff539dbc5a809ef3eacbe2d9f2b97f640b7e9cfPrzemyslaw Szczepaniak    public void warning(Supplier<String> msgSupplier) {
15864ff539dbc5a809ef3eacbe2d9f2b97f640b7e9cfPrzemyslaw Szczepaniak        log(Level.WARNING, msgSupplier);
15874ff539dbc5a809ef3eacbe2d9f2b97f640b7e9cfPrzemyslaw Szczepaniak    }
15884ff539dbc5a809ef3eacbe2d9f2b97f640b7e9cfPrzemyslaw Szczepaniak
15894ff539dbc5a809ef3eacbe2d9f2b97f640b7e9cfPrzemyslaw Szczepaniak    /**
15904ff539dbc5a809ef3eacbe2d9f2b97f640b7e9cfPrzemyslaw Szczepaniak     * Log a INFO message, which is only to be constructed if the logging
15914ff539dbc5a809ef3eacbe2d9f2b97f640b7e9cfPrzemyslaw Szczepaniak     * level is such that the message will actually be logged.
15924ff539dbc5a809ef3eacbe2d9f2b97f640b7e9cfPrzemyslaw Szczepaniak     * <p>
15934ff539dbc5a809ef3eacbe2d9f2b97f640b7e9cfPrzemyslaw Szczepaniak     * If the logger is currently enabled for the INFO message
15944ff539dbc5a809ef3eacbe2d9f2b97f640b7e9cfPrzemyslaw Szczepaniak     * level then the message is constructed by invoking the provided
15954ff539dbc5a809ef3eacbe2d9f2b97f640b7e9cfPrzemyslaw Szczepaniak     * supplier function and forwarded to all the registered output
15964ff539dbc5a809ef3eacbe2d9f2b97f640b7e9cfPrzemyslaw Szczepaniak     * Handler objects.
15974ff539dbc5a809ef3eacbe2d9f2b97f640b7e9cfPrzemyslaw Szczepaniak     * <p>
15984ff539dbc5a809ef3eacbe2d9f2b97f640b7e9cfPrzemyslaw Szczepaniak     * @param   msgSupplier   A function, which when called, produces the
15994ff539dbc5a809ef3eacbe2d9f2b97f640b7e9cfPrzemyslaw Szczepaniak     *                        desired log message
16004ff539dbc5a809ef3eacbe2d9f2b97f640b7e9cfPrzemyslaw Szczepaniak     * @since   1.8
16014ff539dbc5a809ef3eacbe2d9f2b97f640b7e9cfPrzemyslaw Szczepaniak     */
16024ff539dbc5a809ef3eacbe2d9f2b97f640b7e9cfPrzemyslaw Szczepaniak    public void info(Supplier<String> msgSupplier) {
16034ff539dbc5a809ef3eacbe2d9f2b97f640b7e9cfPrzemyslaw Szczepaniak        log(Level.INFO, msgSupplier);
16044ff539dbc5a809ef3eacbe2d9f2b97f640b7e9cfPrzemyslaw Szczepaniak    }
16054ff539dbc5a809ef3eacbe2d9f2b97f640b7e9cfPrzemyslaw Szczepaniak
16064ff539dbc5a809ef3eacbe2d9f2b97f640b7e9cfPrzemyslaw Szczepaniak    /**
16074ff539dbc5a809ef3eacbe2d9f2b97f640b7e9cfPrzemyslaw Szczepaniak     * Log a CONFIG message, which is only to be constructed if the logging
16084ff539dbc5a809ef3eacbe2d9f2b97f640b7e9cfPrzemyslaw Szczepaniak     * level is such that the message will actually be logged.
16094ff539dbc5a809ef3eacbe2d9f2b97f640b7e9cfPrzemyslaw Szczepaniak     * <p>
16104ff539dbc5a809ef3eacbe2d9f2b97f640b7e9cfPrzemyslaw Szczepaniak     * If the logger is currently enabled for the CONFIG message
16114ff539dbc5a809ef3eacbe2d9f2b97f640b7e9cfPrzemyslaw Szczepaniak     * level then the message is constructed by invoking the provided
16124ff539dbc5a809ef3eacbe2d9f2b97f640b7e9cfPrzemyslaw Szczepaniak     * supplier function and forwarded to all the registered output
16134ff539dbc5a809ef3eacbe2d9f2b97f640b7e9cfPrzemyslaw Szczepaniak     * Handler objects.
16144ff539dbc5a809ef3eacbe2d9f2b97f640b7e9cfPrzemyslaw Szczepaniak     * <p>
16154ff539dbc5a809ef3eacbe2d9f2b97f640b7e9cfPrzemyslaw Szczepaniak     * @param   msgSupplier   A function, which when called, produces the
16164ff539dbc5a809ef3eacbe2d9f2b97f640b7e9cfPrzemyslaw Szczepaniak     *                        desired log message
16174ff539dbc5a809ef3eacbe2d9f2b97f640b7e9cfPrzemyslaw Szczepaniak     * @since   1.8
16184ff539dbc5a809ef3eacbe2d9f2b97f640b7e9cfPrzemyslaw Szczepaniak     */
16194ff539dbc5a809ef3eacbe2d9f2b97f640b7e9cfPrzemyslaw Szczepaniak    public void config(Supplier<String> msgSupplier) {
16204ff539dbc5a809ef3eacbe2d9f2b97f640b7e9cfPrzemyslaw Szczepaniak        log(Level.CONFIG, msgSupplier);
16214ff539dbc5a809ef3eacbe2d9f2b97f640b7e9cfPrzemyslaw Szczepaniak    }
16224ff539dbc5a809ef3eacbe2d9f2b97f640b7e9cfPrzemyslaw Szczepaniak
16234ff539dbc5a809ef3eacbe2d9f2b97f640b7e9cfPrzemyslaw Szczepaniak    /**
16244ff539dbc5a809ef3eacbe2d9f2b97f640b7e9cfPrzemyslaw Szczepaniak     * Log a FINE message, which is only to be constructed if the logging
16254ff539dbc5a809ef3eacbe2d9f2b97f640b7e9cfPrzemyslaw Szczepaniak     * level is such that the message will actually be logged.
16264ff539dbc5a809ef3eacbe2d9f2b97f640b7e9cfPrzemyslaw Szczepaniak     * <p>
16274ff539dbc5a809ef3eacbe2d9f2b97f640b7e9cfPrzemyslaw Szczepaniak     * If the logger is currently enabled for the FINE message
16284ff539dbc5a809ef3eacbe2d9f2b97f640b7e9cfPrzemyslaw Szczepaniak     * level then the message is constructed by invoking the provided
16294ff539dbc5a809ef3eacbe2d9f2b97f640b7e9cfPrzemyslaw Szczepaniak     * supplier function and forwarded to all the registered output
16304ff539dbc5a809ef3eacbe2d9f2b97f640b7e9cfPrzemyslaw Szczepaniak     * Handler objects.
16314ff539dbc5a809ef3eacbe2d9f2b97f640b7e9cfPrzemyslaw Szczepaniak     * <p>
16324ff539dbc5a809ef3eacbe2d9f2b97f640b7e9cfPrzemyslaw Szczepaniak     * @param   msgSupplier   A function, which when called, produces the
16334ff539dbc5a809ef3eacbe2d9f2b97f640b7e9cfPrzemyslaw Szczepaniak     *                        desired log message
16344ff539dbc5a809ef3eacbe2d9f2b97f640b7e9cfPrzemyslaw Szczepaniak     * @since   1.8
16354ff539dbc5a809ef3eacbe2d9f2b97f640b7e9cfPrzemyslaw Szczepaniak     */
16364ff539dbc5a809ef3eacbe2d9f2b97f640b7e9cfPrzemyslaw Szczepaniak    public void fine(Supplier<String> msgSupplier) {
16374ff539dbc5a809ef3eacbe2d9f2b97f640b7e9cfPrzemyslaw Szczepaniak        log(Level.FINE, msgSupplier);
16384ff539dbc5a809ef3eacbe2d9f2b97f640b7e9cfPrzemyslaw Szczepaniak    }
16394ff539dbc5a809ef3eacbe2d9f2b97f640b7e9cfPrzemyslaw Szczepaniak
16404ff539dbc5a809ef3eacbe2d9f2b97f640b7e9cfPrzemyslaw Szczepaniak    /**
16414ff539dbc5a809ef3eacbe2d9f2b97f640b7e9cfPrzemyslaw Szczepaniak     * Log a FINER message, which is only to be constructed if the logging
16424ff539dbc5a809ef3eacbe2d9f2b97f640b7e9cfPrzemyslaw Szczepaniak     * level is such that the message will actually be logged.
16434ff539dbc5a809ef3eacbe2d9f2b97f640b7e9cfPrzemyslaw Szczepaniak     * <p>
16444ff539dbc5a809ef3eacbe2d9f2b97f640b7e9cfPrzemyslaw Szczepaniak     * If the logger is currently enabled for the FINER message
16454ff539dbc5a809ef3eacbe2d9f2b97f640b7e9cfPrzemyslaw Szczepaniak     * level then the message is constructed by invoking the provided
16464ff539dbc5a809ef3eacbe2d9f2b97f640b7e9cfPrzemyslaw Szczepaniak     * supplier function and forwarded to all the registered output
16474ff539dbc5a809ef3eacbe2d9f2b97f640b7e9cfPrzemyslaw Szczepaniak     * Handler objects.
16484ff539dbc5a809ef3eacbe2d9f2b97f640b7e9cfPrzemyslaw Szczepaniak     * <p>
16494ff539dbc5a809ef3eacbe2d9f2b97f640b7e9cfPrzemyslaw Szczepaniak     * @param   msgSupplier   A function, which when called, produces the
16504ff539dbc5a809ef3eacbe2d9f2b97f640b7e9cfPrzemyslaw Szczepaniak     *                        desired log message
16514ff539dbc5a809ef3eacbe2d9f2b97f640b7e9cfPrzemyslaw Szczepaniak     * @since   1.8
16524ff539dbc5a809ef3eacbe2d9f2b97f640b7e9cfPrzemyslaw Szczepaniak     */
16534ff539dbc5a809ef3eacbe2d9f2b97f640b7e9cfPrzemyslaw Szczepaniak    public void finer(Supplier<String> msgSupplier) {
16544ff539dbc5a809ef3eacbe2d9f2b97f640b7e9cfPrzemyslaw Szczepaniak        log(Level.FINER, msgSupplier);
16554ff539dbc5a809ef3eacbe2d9f2b97f640b7e9cfPrzemyslaw Szczepaniak    }
16564ff539dbc5a809ef3eacbe2d9f2b97f640b7e9cfPrzemyslaw Szczepaniak
16574ff539dbc5a809ef3eacbe2d9f2b97f640b7e9cfPrzemyslaw Szczepaniak    /**
16584ff539dbc5a809ef3eacbe2d9f2b97f640b7e9cfPrzemyslaw Szczepaniak     * Log a FINEST message, which is only to be constructed if the logging
16594ff539dbc5a809ef3eacbe2d9f2b97f640b7e9cfPrzemyslaw Szczepaniak     * level is such that the message will actually be logged.
16604ff539dbc5a809ef3eacbe2d9f2b97f640b7e9cfPrzemyslaw Szczepaniak     * <p>
16614ff539dbc5a809ef3eacbe2d9f2b97f640b7e9cfPrzemyslaw Szczepaniak     * If the logger is currently enabled for the FINEST message
16624ff539dbc5a809ef3eacbe2d9f2b97f640b7e9cfPrzemyslaw Szczepaniak     * level then the message is constructed by invoking the provided
16634ff539dbc5a809ef3eacbe2d9f2b97f640b7e9cfPrzemyslaw Szczepaniak     * supplier function and forwarded to all the registered output
16644ff539dbc5a809ef3eacbe2d9f2b97f640b7e9cfPrzemyslaw Szczepaniak     * Handler objects.
16654ff539dbc5a809ef3eacbe2d9f2b97f640b7e9cfPrzemyslaw Szczepaniak     * <p>
16664ff539dbc5a809ef3eacbe2d9f2b97f640b7e9cfPrzemyslaw Szczepaniak     * @param   msgSupplier   A function, which when called, produces the
16674ff539dbc5a809ef3eacbe2d9f2b97f640b7e9cfPrzemyslaw Szczepaniak     *                        desired log message
16684ff539dbc5a809ef3eacbe2d9f2b97f640b7e9cfPrzemyslaw Szczepaniak     * @since   1.8
16694ff539dbc5a809ef3eacbe2d9f2b97f640b7e9cfPrzemyslaw Szczepaniak     */
16704ff539dbc5a809ef3eacbe2d9f2b97f640b7e9cfPrzemyslaw Szczepaniak    public void finest(Supplier<String> msgSupplier) {
16714ff539dbc5a809ef3eacbe2d9f2b97f640b7e9cfPrzemyslaw Szczepaniak        log(Level.FINEST, msgSupplier);
16724ff539dbc5a809ef3eacbe2d9f2b97f640b7e9cfPrzemyslaw Szczepaniak    }
16734ff539dbc5a809ef3eacbe2d9f2b97f640b7e9cfPrzemyslaw Szczepaniak
167451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    //================================================================
167551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    // End of convenience methods
167651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    //================================================================
167751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
167851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    /**
167951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * Set the log level specifying which message levels will be
168051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * logged by this logger.  Message levels lower than this
168151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * value will be discarded.  The level value Level.OFF
168251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * can be used to turn off logging.
168351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * <p>
168451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * If the new level is null, it means that this node should
168551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * inherit its level from its nearest ancestor with a specific
168651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * (non-null) level value.
168751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     *
168851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * @param newLevel   the new value for the log level (may be null)
16894ff539dbc5a809ef3eacbe2d9f2b97f640b7e9cfPrzemyslaw Szczepaniak     * @throws  SecurityException if a security manager exists,
16904ff539dbc5a809ef3eacbe2d9f2b97f640b7e9cfPrzemyslaw Szczepaniak     *          this logger is not anonymous, and the caller
16914ff539dbc5a809ef3eacbe2d9f2b97f640b7e9cfPrzemyslaw Szczepaniak     *          does not have LoggingPermission("control").
169251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     */
169351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    public void setLevel(Level newLevel) throws SecurityException {
169451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        checkPermission();
169551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        synchronized (treeLock) {
169651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            levelObject = newLevel;
169751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            updateEffectiveLevel();
169851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        }
169951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    }
170051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
17014ff539dbc5a809ef3eacbe2d9f2b97f640b7e9cfPrzemyslaw Szczepaniak    final boolean isLevelInitialized() {
17024ff539dbc5a809ef3eacbe2d9f2b97f640b7e9cfPrzemyslaw Szczepaniak        return levelObject != null;
17034ff539dbc5a809ef3eacbe2d9f2b97f640b7e9cfPrzemyslaw Szczepaniak    }
17044ff539dbc5a809ef3eacbe2d9f2b97f640b7e9cfPrzemyslaw Szczepaniak
170551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    /**
170651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * Get the log Level that has been specified for this Logger.
170751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * The result may be null, which means that this logger's
170851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * effective level will be inherited from its parent.
170951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     *
171051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * @return  this Logger's level
171151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     */
171251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    public Level getLevel() {
171351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        return levelObject;
171451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    }
171551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
171651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    /**
171751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * Check if a message of the given level would actually be logged
171851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * by this logger.  This check is based on the Loggers effective level,
171951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * which may be inherited from its parent.
172051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     *
172151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * @param   level   a message logging level
172251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * @return  true if the given message level is currently being logged.
172351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     */
172451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    public boolean isLoggable(Level level) {
172551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        if (level.intValue() < levelValue || levelValue == offValue) {
172651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            return false;
172751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        }
172851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        return true;
172951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    }
173051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
173151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    /**
173251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * Get the name for this logger.
173351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * @return logger name.  Will be null for anonymous Loggers.
173451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     */
173551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    public String getName() {
173651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        return name;
173751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    }
173851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
173951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    /**
174051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * Add a log Handler to receive logging messages.
174151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * <p>
174251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * By default, Loggers also send their output to their parent logger.
174351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * Typically the root Logger is configured with a set of Handlers
174451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * that essentially act as default handlers for all loggers.
174551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     *
174651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * @param   handler a logging Handler
17474ff539dbc5a809ef3eacbe2d9f2b97f640b7e9cfPrzemyslaw Szczepaniak     * @throws  SecurityException if a security manager exists,
17484ff539dbc5a809ef3eacbe2d9f2b97f640b7e9cfPrzemyslaw Szczepaniak     *          this logger is not anonymous, and the caller
17494ff539dbc5a809ef3eacbe2d9f2b97f640b7e9cfPrzemyslaw Szczepaniak     *          does not have LoggingPermission("control").
175051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     */
175151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    public void addHandler(Handler handler) throws SecurityException {
175251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        // Check for null handler
175351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        handler.getClass();
175451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        checkPermission();
175551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        handlers.add(handler);
175651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    }
175751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
175851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    /**
175951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * Remove a log Handler.
176051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * <P>
176151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * Returns silently if the given Handler is not found or is null
176251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     *
176351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * @param   handler a logging Handler
17644ff539dbc5a809ef3eacbe2d9f2b97f640b7e9cfPrzemyslaw Szczepaniak     * @throws  SecurityException if a security manager exists,
17654ff539dbc5a809ef3eacbe2d9f2b97f640b7e9cfPrzemyslaw Szczepaniak     *          this logger is not anonymous, and the caller
17664ff539dbc5a809ef3eacbe2d9f2b97f640b7e9cfPrzemyslaw Szczepaniak     *          does not have LoggingPermission("control").
176751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     */
176851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    public void removeHandler(Handler handler) throws SecurityException {
176951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        checkPermission();
177051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        if (handler == null) {
177151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            return;
177251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        }
177351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        handlers.remove(handler);
177451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    }
177551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
177651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    /**
177751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * Get the Handlers associated with this logger.
177851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * <p>
177951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * @return  an array of all registered Handlers
178051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     */
178151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    public Handler[] getHandlers() {
17824ff539dbc5a809ef3eacbe2d9f2b97f640b7e9cfPrzemyslaw Szczepaniak        return accessCheckedHandlers();
17834ff539dbc5a809ef3eacbe2d9f2b97f640b7e9cfPrzemyslaw Szczepaniak    }
17844ff539dbc5a809ef3eacbe2d9f2b97f640b7e9cfPrzemyslaw Szczepaniak
17854ff539dbc5a809ef3eacbe2d9f2b97f640b7e9cfPrzemyslaw Szczepaniak    // This method should ideally be marked final - but unfortunately
17864ff539dbc5a809ef3eacbe2d9f2b97f640b7e9cfPrzemyslaw Szczepaniak    // it needs to be overridden by LogManager.RootLogger
17874ff539dbc5a809ef3eacbe2d9f2b97f640b7e9cfPrzemyslaw Szczepaniak    Handler[] accessCheckedHandlers() {
178851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        return handlers.toArray(emptyHandlers);
178951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    }
179051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
179151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    /**
179251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * Specify whether or not this logger should send its output
179351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * to its parent Logger.  This means that any LogRecords will
179451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * also be written to the parent's Handlers, and potentially
179551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * to its parent, recursively up the namespace.
179651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     *
179751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * @param useParentHandlers   true if output is to be sent to the
179851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     *          logger's parent.
17994ff539dbc5a809ef3eacbe2d9f2b97f640b7e9cfPrzemyslaw Szczepaniak     * @throws  SecurityException if a security manager exists,
18004ff539dbc5a809ef3eacbe2d9f2b97f640b7e9cfPrzemyslaw Szczepaniak     *          this logger is not anonymous, and the caller
18014ff539dbc5a809ef3eacbe2d9f2b97f640b7e9cfPrzemyslaw Szczepaniak     *          does not have LoggingPermission("control").
180251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     */
180351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    public void setUseParentHandlers(boolean useParentHandlers) {
180451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        checkPermission();
180551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        this.useParentHandlers = useParentHandlers;
180651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    }
180751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
180851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    /**
180951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * Discover whether or not this logger is sending its output
181051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * to its parent logger.
181151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     *
181251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * @return  true if output is to be sent to the logger's parent
181351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     */
181451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    public boolean getUseParentHandlers() {
181551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        return useParentHandlers;
181651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    }
181751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
181851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    private static ResourceBundle findSystemResourceBundle(final Locale locale) {
181951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        // the resource bundle is in a restricted package
182051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        return AccessController.doPrivileged(new PrivilegedAction<ResourceBundle>() {
18214ff539dbc5a809ef3eacbe2d9f2b97f640b7e9cfPrzemyslaw Szczepaniak            @Override
182251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            public ResourceBundle run() {
182351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                try {
182451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    return ResourceBundle.getBundle(SYSTEM_LOGGER_RB_NAME,
182551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                                                    locale,
182651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                                                    ClassLoader.getSystemClassLoader());
182751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                } catch (MissingResourceException e) {
182851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    throw new InternalError(e.toString());
182951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                }
183051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            }
183151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        });
183251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    }
183351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
183451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    /**
183551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * Private utility method to map a resource bundle name to an
183651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * actual resource bundle, using a simple one-entry cache.
183751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * Returns null for a null name.
183851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * May also return null if we can't find the resource bundle and
183951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * there is no suitable previous cached value.
184051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     *
184151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * @param name the ResourceBundle to locate
184251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * @param userCallersClassLoader if true search using the caller's ClassLoader
184351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * @return ResourceBundle specified by name or null if not found
184451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     */
184551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    private synchronized ResourceBundle findResourceBundle(String name,
184651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                                                           boolean useCallersClassLoader) {
184751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        // For all lookups, we first check the thread context class loader
184851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        // if it is set.  If not, we use the system classloader.  If we
184951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        // still haven't found it we use the callersClassLoaderRef if it
185051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        // is set and useCallersClassLoader is true.  We set
185151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        // callersClassLoaderRef initially upon creating the logger with a
185251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        // non-null resource bundle name.
185351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
185451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        // Return a null bundle for a null name.
185551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        if (name == null) {
185651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            return null;
185751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        }
185851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
185951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        Locale currentLocale = Locale.getDefault();
18604ff539dbc5a809ef3eacbe2d9f2b97f640b7e9cfPrzemyslaw Szczepaniak        final LoggerBundle lb = loggerBundle;
186151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
186251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        // Normally we should hit on our simple one entry cache.
18634ff539dbc5a809ef3eacbe2d9f2b97f640b7e9cfPrzemyslaw Szczepaniak        if (lb.userBundle != null &&
18644ff539dbc5a809ef3eacbe2d9f2b97f640b7e9cfPrzemyslaw Szczepaniak                name.equals(lb.resourceBundleName)) {
18654ff539dbc5a809ef3eacbe2d9f2b97f640b7e9cfPrzemyslaw Szczepaniak            return lb.userBundle;
18664ff539dbc5a809ef3eacbe2d9f2b97f640b7e9cfPrzemyslaw Szczepaniak        } else if (catalog != null && currentLocale.equals(catalogLocale)
186751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                && name.equals(catalogName)) {
186851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            return catalog;
186951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        }
187051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
187151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        if (name.equals(SYSTEM_LOGGER_RB_NAME)) {
187251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            catalog = findSystemResourceBundle(currentLocale);
187351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            catalogName = name;
187451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            catalogLocale = currentLocale;
187551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            return catalog;
187651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        }
187751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
187851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        // Use the thread's context ClassLoader.  If there isn't one, use the
187951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        // {@linkplain java.lang.ClassLoader#getSystemClassLoader() system ClassLoader}.
188051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        ClassLoader cl = Thread.currentThread().getContextClassLoader();
188151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        if (cl == null) {
188251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            cl = ClassLoader.getSystemClassLoader();
188351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        }
188451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        try {
188551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            catalog = ResourceBundle.getBundle(name, currentLocale, cl);
188651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            catalogName = name;
188751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            catalogLocale = currentLocale;
188851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            return catalog;
188951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        } catch (MissingResourceException ex) {
189051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            // We can't find the ResourceBundle in the default
189151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            // ClassLoader.  Drop through.
189251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        }
189351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
189451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        if (useCallersClassLoader) {
189551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            // Try with the caller's ClassLoader
189651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            ClassLoader callersClassLoader = getCallersClassLoader();
18974ff539dbc5a809ef3eacbe2d9f2b97f640b7e9cfPrzemyslaw Szczepaniak            if (callersClassLoader == null || callersClassLoader == cl) {
18984ff539dbc5a809ef3eacbe2d9f2b97f640b7e9cfPrzemyslaw Szczepaniak                return null;
189951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            }
190051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
190151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            try {
19024ff539dbc5a809ef3eacbe2d9f2b97f640b7e9cfPrzemyslaw Szczepaniak                catalog = ResourceBundle.getBundle(name, currentLocale,
19034ff539dbc5a809ef3eacbe2d9f2b97f640b7e9cfPrzemyslaw Szczepaniak                                                   callersClassLoader);
190451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                catalogName = name;
19054ff539dbc5a809ef3eacbe2d9f2b97f640b7e9cfPrzemyslaw Szczepaniak                catalogLocale = currentLocale;
190651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                return catalog;
190751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            } catch (MissingResourceException ex) {
19084ff539dbc5a809ef3eacbe2d9f2b97f640b7e9cfPrzemyslaw Szczepaniak                return null; // no luck
190951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            }
19104ff539dbc5a809ef3eacbe2d9f2b97f640b7e9cfPrzemyslaw Szczepaniak        } else {
19114ff539dbc5a809ef3eacbe2d9f2b97f640b7e9cfPrzemyslaw Szczepaniak            return null;
191251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        }
191351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    }
191451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
191551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    // Private utility method to initialize our one entry
191651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    // resource bundle name cache and the callers ClassLoader
191751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    // Note: for consistency reasons, we are careful to check
191851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    // that a suitable ResourceBundle exists before setting the
191951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    // resourceBundleName field.
192051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    // Synchronized to prevent races in setting the fields.
192151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    private synchronized void setupResourceInfo(String name,
192251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                                                Class<?> callersClass) {
19234ff539dbc5a809ef3eacbe2d9f2b97f640b7e9cfPrzemyslaw Szczepaniak        final LoggerBundle lb = loggerBundle;
19244ff539dbc5a809ef3eacbe2d9f2b97f640b7e9cfPrzemyslaw Szczepaniak        if (lb.resourceBundleName != null) {
19254ff539dbc5a809ef3eacbe2d9f2b97f640b7e9cfPrzemyslaw Szczepaniak            // this Logger already has a ResourceBundle
19264ff539dbc5a809ef3eacbe2d9f2b97f640b7e9cfPrzemyslaw Szczepaniak
19274ff539dbc5a809ef3eacbe2d9f2b97f640b7e9cfPrzemyslaw Szczepaniak            if (lb.resourceBundleName.equals(name)) {
19284ff539dbc5a809ef3eacbe2d9f2b97f640b7e9cfPrzemyslaw Szczepaniak                // the names match so there is nothing more to do
19294ff539dbc5a809ef3eacbe2d9f2b97f640b7e9cfPrzemyslaw Szczepaniak                return;
19304ff539dbc5a809ef3eacbe2d9f2b97f640b7e9cfPrzemyslaw Szczepaniak            }
19314ff539dbc5a809ef3eacbe2d9f2b97f640b7e9cfPrzemyslaw Szczepaniak
19324ff539dbc5a809ef3eacbe2d9f2b97f640b7e9cfPrzemyslaw Szczepaniak            // cannot change ResourceBundles once they are set
19334ff539dbc5a809ef3eacbe2d9f2b97f640b7e9cfPrzemyslaw Szczepaniak            throw new IllegalArgumentException(
19344ff539dbc5a809ef3eacbe2d9f2b97f640b7e9cfPrzemyslaw Szczepaniak                lb.resourceBundleName + " != " + name);
19354ff539dbc5a809ef3eacbe2d9f2b97f640b7e9cfPrzemyslaw Szczepaniak        }
19364ff539dbc5a809ef3eacbe2d9f2b97f640b7e9cfPrzemyslaw Szczepaniak
193751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        if (name == null) {
193851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            return;
193951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        }
194051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
194151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        setCallersClassLoaderRef(callersClass);
19424ff539dbc5a809ef3eacbe2d9f2b97f640b7e9cfPrzemyslaw Szczepaniak        if (isSystemLogger && getCallersClassLoader() != null) {
19434ff539dbc5a809ef3eacbe2d9f2b97f640b7e9cfPrzemyslaw Szczepaniak            checkPermission();
19444ff539dbc5a809ef3eacbe2d9f2b97f640b7e9cfPrzemyslaw Szczepaniak        }
194551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        if (findResourceBundle(name, true) == null) {
194651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            // We've failed to find an expected ResourceBundle.
194751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            // unset the caller's ClassLoader since we were unable to find the
194851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            // the bundle using it
194951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            this.callersClassLoaderRef = null;
195051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            throw new MissingResourceException("Can't find " + name + " bundle",
195151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                                                name, "");
195251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        }
19534ff539dbc5a809ef3eacbe2d9f2b97f640b7e9cfPrzemyslaw Szczepaniak
19544ff539dbc5a809ef3eacbe2d9f2b97f640b7e9cfPrzemyslaw Szczepaniak        // if lb.userBundle is not null we won't reach this line.
19554ff539dbc5a809ef3eacbe2d9f2b97f640b7e9cfPrzemyslaw Szczepaniak        assert lb.userBundle == null;
19564ff539dbc5a809ef3eacbe2d9f2b97f640b7e9cfPrzemyslaw Szczepaniak        loggerBundle = LoggerBundle.get(name, null);
19574ff539dbc5a809ef3eacbe2d9f2b97f640b7e9cfPrzemyslaw Szczepaniak    }
19584ff539dbc5a809ef3eacbe2d9f2b97f640b7e9cfPrzemyslaw Szczepaniak
19594ff539dbc5a809ef3eacbe2d9f2b97f640b7e9cfPrzemyslaw Szczepaniak    /**
19604ff539dbc5a809ef3eacbe2d9f2b97f640b7e9cfPrzemyslaw Szczepaniak     * Sets a resource bundle on this logger.
19614ff539dbc5a809ef3eacbe2d9f2b97f640b7e9cfPrzemyslaw Szczepaniak     * All messages will be logged using the given resource bundle for its
19624ff539dbc5a809ef3eacbe2d9f2b97f640b7e9cfPrzemyslaw Szczepaniak     * specific {@linkplain ResourceBundle#getLocale locale}.
19634ff539dbc5a809ef3eacbe2d9f2b97f640b7e9cfPrzemyslaw Szczepaniak     * @param bundle The resource bundle that this logger shall use.
19644ff539dbc5a809ef3eacbe2d9f2b97f640b7e9cfPrzemyslaw Szczepaniak     * @throws NullPointerException if the given bundle is {@code null}.
19654ff539dbc5a809ef3eacbe2d9f2b97f640b7e9cfPrzemyslaw Szczepaniak     * @throws IllegalArgumentException if the given bundle doesn't have a
19664ff539dbc5a809ef3eacbe2d9f2b97f640b7e9cfPrzemyslaw Szczepaniak     *         {@linkplain ResourceBundle#getBaseBundleName base name},
19674ff539dbc5a809ef3eacbe2d9f2b97f640b7e9cfPrzemyslaw Szczepaniak     *         or if this logger already has a resource bundle set but
19684ff539dbc5a809ef3eacbe2d9f2b97f640b7e9cfPrzemyslaw Szczepaniak     *         the given bundle has a different base name.
19694ff539dbc5a809ef3eacbe2d9f2b97f640b7e9cfPrzemyslaw Szczepaniak     * @throws SecurityException if a security manager exists,
19704ff539dbc5a809ef3eacbe2d9f2b97f640b7e9cfPrzemyslaw Szczepaniak     *         this logger is not anonymous, and the caller
19714ff539dbc5a809ef3eacbe2d9f2b97f640b7e9cfPrzemyslaw Szczepaniak     *         does not have LoggingPermission("control").
19724ff539dbc5a809ef3eacbe2d9f2b97f640b7e9cfPrzemyslaw Szczepaniak     * @since 1.8
19734ff539dbc5a809ef3eacbe2d9f2b97f640b7e9cfPrzemyslaw Szczepaniak     */
19744ff539dbc5a809ef3eacbe2d9f2b97f640b7e9cfPrzemyslaw Szczepaniak    public void setResourceBundle(ResourceBundle bundle) {
19754ff539dbc5a809ef3eacbe2d9f2b97f640b7e9cfPrzemyslaw Szczepaniak        checkPermission();
19764ff539dbc5a809ef3eacbe2d9f2b97f640b7e9cfPrzemyslaw Szczepaniak
19774ff539dbc5a809ef3eacbe2d9f2b97f640b7e9cfPrzemyslaw Szczepaniak        // Will throw NPE if bundle is null.
19784ff539dbc5a809ef3eacbe2d9f2b97f640b7e9cfPrzemyslaw Szczepaniak        final String baseName = bundle.getBaseBundleName();
19794ff539dbc5a809ef3eacbe2d9f2b97f640b7e9cfPrzemyslaw Szczepaniak
19804ff539dbc5a809ef3eacbe2d9f2b97f640b7e9cfPrzemyslaw Szczepaniak        // bundle must have a name
19814ff539dbc5a809ef3eacbe2d9f2b97f640b7e9cfPrzemyslaw Szczepaniak        if (baseName == null || baseName.isEmpty()) {
19824ff539dbc5a809ef3eacbe2d9f2b97f640b7e9cfPrzemyslaw Szczepaniak            throw new IllegalArgumentException("resource bundle must have a name");
19834ff539dbc5a809ef3eacbe2d9f2b97f640b7e9cfPrzemyslaw Szczepaniak        }
19844ff539dbc5a809ef3eacbe2d9f2b97f640b7e9cfPrzemyslaw Szczepaniak
19854ff539dbc5a809ef3eacbe2d9f2b97f640b7e9cfPrzemyslaw Szczepaniak        synchronized (this) {
19864ff539dbc5a809ef3eacbe2d9f2b97f640b7e9cfPrzemyslaw Szczepaniak            LoggerBundle lb = loggerBundle;
19874ff539dbc5a809ef3eacbe2d9f2b97f640b7e9cfPrzemyslaw Szczepaniak            final boolean canReplaceResourceBundle = lb.resourceBundleName == null
19884ff539dbc5a809ef3eacbe2d9f2b97f640b7e9cfPrzemyslaw Szczepaniak                    || lb.resourceBundleName.equals(baseName);
19894ff539dbc5a809ef3eacbe2d9f2b97f640b7e9cfPrzemyslaw Szczepaniak
19904ff539dbc5a809ef3eacbe2d9f2b97f640b7e9cfPrzemyslaw Szczepaniak            if (!canReplaceResourceBundle) {
19914ff539dbc5a809ef3eacbe2d9f2b97f640b7e9cfPrzemyslaw Szczepaniak                throw new IllegalArgumentException("can't replace resource bundle");
19924ff539dbc5a809ef3eacbe2d9f2b97f640b7e9cfPrzemyslaw Szczepaniak            }
19934ff539dbc5a809ef3eacbe2d9f2b97f640b7e9cfPrzemyslaw Szczepaniak
19944ff539dbc5a809ef3eacbe2d9f2b97f640b7e9cfPrzemyslaw Szczepaniak
19954ff539dbc5a809ef3eacbe2d9f2b97f640b7e9cfPrzemyslaw Szczepaniak            loggerBundle = LoggerBundle.get(baseName, bundle);
19964ff539dbc5a809ef3eacbe2d9f2b97f640b7e9cfPrzemyslaw Szczepaniak        }
199751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    }
199851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
199951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    /**
200051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * Return the parent for this Logger.
200151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * <p>
200251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * This method returns the nearest extant parent in the namespace.
200351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * Thus if a Logger is called "a.b.c.d", and a Logger called "a.b"
200451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * has been created but no logger "a.b.c" exists, then a call of
200551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * getParent on the Logger "a.b.c.d" will return the Logger "a.b".
200651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * <p>
200751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * The result will be null if it is called on the root Logger
200851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * in the namespace.
200951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     *
201051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * @return nearest existing parent Logger
201151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     */
201251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    public Logger getParent() {
201351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        // Note: this used to be synchronized on treeLock.  However, this only
201451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        // provided memory semantics, as there was no guarantee that the caller
201551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        // would synchronize on treeLock (in fact, there is no way for external
201651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        // callers to so synchronize).  Therefore, we have made parent volatile
201751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        // instead.
201851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        return parent;
201951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    }
202051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
202151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    /**
202251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * Set the parent for this Logger.  This method is used by
202351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * the LogManager to update a Logger when the namespace changes.
202451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * <p>
202551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * It should not be called from application code.
202651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * <p>
202751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * @param  parent   the new parent logger
20284ff539dbc5a809ef3eacbe2d9f2b97f640b7e9cfPrzemyslaw Szczepaniak     * @throws  SecurityException  if a security manager exists and if
20294ff539dbc5a809ef3eacbe2d9f2b97f640b7e9cfPrzemyslaw Szczepaniak     *          the caller does not have LoggingPermission("control").
203051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     */
203151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    public void setParent(Logger parent) {
203251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        if (parent == null) {
203351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            throw new NullPointerException();
203451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        }
20354ff539dbc5a809ef3eacbe2d9f2b97f640b7e9cfPrzemyslaw Szczepaniak
20364ff539dbc5a809ef3eacbe2d9f2b97f640b7e9cfPrzemyslaw Szczepaniak        // check permission for all loggers, including anonymous loggers
20374ff539dbc5a809ef3eacbe2d9f2b97f640b7e9cfPrzemyslaw Szczepaniak        if (manager == null) {
20384ff539dbc5a809ef3eacbe2d9f2b97f640b7e9cfPrzemyslaw Szczepaniak            manager = LogManager.getLogManager();
20394ff539dbc5a809ef3eacbe2d9f2b97f640b7e9cfPrzemyslaw Szczepaniak        }
204051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        manager.checkPermission();
20414ff539dbc5a809ef3eacbe2d9f2b97f640b7e9cfPrzemyslaw Szczepaniak
204251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        doSetParent(parent);
204351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    }
204451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
204551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    // Private method to do the work for parenting a child
204651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    // Logger onto a parent logger.
204751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    private void doSetParent(Logger newParent) {
204851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
204951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        // System.err.println("doSetParent \"" + getName() + "\" \""
205051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        //                              + newParent.getName() + "\"");
205151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
205251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        synchronized (treeLock) {
205351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
205451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            // Remove ourself from any previous parent.
205551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            LogManager.LoggerWeakRef ref = null;
205651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            if (parent != null) {
205751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                // assert parent.kids != null;
205851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                for (Iterator<LogManager.LoggerWeakRef> iter = parent.kids.iterator(); iter.hasNext(); ) {
205951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    ref = iter.next();
206051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    Logger kid =  ref.get();
206151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    if (kid == this) {
206251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                        // ref is used down below to complete the reparenting
206351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                        iter.remove();
206451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                        break;
206551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    } else {
206651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                        ref = null;
206751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    }
206851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                }
206951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                // We have now removed ourself from our parents' kids.
207051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            }
207151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
207251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            // Set our new parent.
207351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            parent = newParent;
207451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            if (parent.kids == null) {
207551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                parent.kids = new ArrayList<>(2);
207651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            }
207751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            if (ref == null) {
207851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                // we didn't have a previous parent
207951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                ref = manager.new LoggerWeakRef(this);
208051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            }
20814ff539dbc5a809ef3eacbe2d9f2b97f640b7e9cfPrzemyslaw Szczepaniak            ref.setParentRef(new WeakReference<>(parent));
208251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            parent.kids.add(ref);
208351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
208451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            // As a result of the reparenting, the effective level
208551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            // may have changed for us and our children.
208651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            updateEffectiveLevel();
208751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
208851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        }
208951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    }
209051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
209151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    // Package-level method.
209251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    // Remove the weak reference for the specified child Logger from the
209351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    // kid list. We should only be called from LoggerWeakRef.dispose().
209451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    final void removeChildLogger(LogManager.LoggerWeakRef child) {
209551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        synchronized (treeLock) {
209651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            for (Iterator<LogManager.LoggerWeakRef> iter = kids.iterator(); iter.hasNext(); ) {
209751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                LogManager.LoggerWeakRef ref = iter.next();
209851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                if (ref == child) {
209951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    iter.remove();
210051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    return;
210151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                }
210251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            }
210351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        }
210451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    }
210551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
210651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    // Recalculate the effective level for this node and
210751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    // recursively for our children.
210851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
210951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    private void updateEffectiveLevel() {
211051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        // assert Thread.holdsLock(treeLock);
211151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
211251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        // Figure out our current effective level.
211351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        int newLevelValue;
211451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        if (levelObject != null) {
211551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            newLevelValue = levelObject.intValue();
211651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        } else {
211751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            if (parent != null) {
211851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                newLevelValue = parent.levelValue;
211951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            } else {
212051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                // This may happen during initialization.
212151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                newLevelValue = Level.INFO.intValue();
212251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            }
212351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        }
212451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
212551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        // If our effective value hasn't changed, we're done.
212651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        if (levelValue == newLevelValue) {
212751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            return;
212851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        }
212951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
213051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        levelValue = newLevelValue;
213151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
213251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        // System.err.println("effective level: \"" + getName() + "\" := " + level);
213351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
213451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        // Recursively update the level on each of our kids.
213551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        if (kids != null) {
213651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            for (int i = 0; i < kids.size(); i++) {
213751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                LogManager.LoggerWeakRef ref = kids.get(i);
213851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                Logger kid =  ref.get();
213951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                if (kid != null) {
214051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    kid.updateEffectiveLevel();
214151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                }
214251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            }
214351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        }
214451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    }
214551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
214651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
214751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    // Private method to get the potentially inherited
21484ff539dbc5a809ef3eacbe2d9f2b97f640b7e9cfPrzemyslaw Szczepaniak    // resource bundle and resource bundle name for this Logger.
21494ff539dbc5a809ef3eacbe2d9f2b97f640b7e9cfPrzemyslaw Szczepaniak    // This method never returns null.
21504ff539dbc5a809ef3eacbe2d9f2b97f640b7e9cfPrzemyslaw Szczepaniak    private LoggerBundle getEffectiveLoggerBundle() {
21514ff539dbc5a809ef3eacbe2d9f2b97f640b7e9cfPrzemyslaw Szczepaniak        final LoggerBundle lb = loggerBundle;
21524ff539dbc5a809ef3eacbe2d9f2b97f640b7e9cfPrzemyslaw Szczepaniak        if (lb.isSystemBundle()) {
21534ff539dbc5a809ef3eacbe2d9f2b97f640b7e9cfPrzemyslaw Szczepaniak            return SYSTEM_BUNDLE;
21544ff539dbc5a809ef3eacbe2d9f2b97f640b7e9cfPrzemyslaw Szczepaniak        }
21554ff539dbc5a809ef3eacbe2d9f2b97f640b7e9cfPrzemyslaw Szczepaniak
21564ff539dbc5a809ef3eacbe2d9f2b97f640b7e9cfPrzemyslaw Szczepaniak        // first take care of this logger
21574ff539dbc5a809ef3eacbe2d9f2b97f640b7e9cfPrzemyslaw Szczepaniak        final ResourceBundle b = getResourceBundle();
21584ff539dbc5a809ef3eacbe2d9f2b97f640b7e9cfPrzemyslaw Szczepaniak        if (b != null && b == lb.userBundle) {
21594ff539dbc5a809ef3eacbe2d9f2b97f640b7e9cfPrzemyslaw Szczepaniak            return lb;
21604ff539dbc5a809ef3eacbe2d9f2b97f640b7e9cfPrzemyslaw Szczepaniak        } else if (b != null) {
21614ff539dbc5a809ef3eacbe2d9f2b97f640b7e9cfPrzemyslaw Szczepaniak            // either lb.userBundle is null or getResourceBundle() is
21624ff539dbc5a809ef3eacbe2d9f2b97f640b7e9cfPrzemyslaw Szczepaniak            // overriden
21634ff539dbc5a809ef3eacbe2d9f2b97f640b7e9cfPrzemyslaw Szczepaniak            final String rbName = getResourceBundleName();
21644ff539dbc5a809ef3eacbe2d9f2b97f640b7e9cfPrzemyslaw Szczepaniak            return LoggerBundle.get(rbName, b);
21654ff539dbc5a809ef3eacbe2d9f2b97f640b7e9cfPrzemyslaw Szczepaniak        }
21664ff539dbc5a809ef3eacbe2d9f2b97f640b7e9cfPrzemyslaw Szczepaniak
21674ff539dbc5a809ef3eacbe2d9f2b97f640b7e9cfPrzemyslaw Szczepaniak        // no resource bundle was specified on this logger, look up the
21684ff539dbc5a809ef3eacbe2d9f2b97f640b7e9cfPrzemyslaw Szczepaniak        // parent stack.
21694ff539dbc5a809ef3eacbe2d9f2b97f640b7e9cfPrzemyslaw Szczepaniak        Logger target = this.parent;
217051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        while (target != null) {
21714ff539dbc5a809ef3eacbe2d9f2b97f640b7e9cfPrzemyslaw Szczepaniak            final LoggerBundle trb = target.loggerBundle;
21724ff539dbc5a809ef3eacbe2d9f2b97f640b7e9cfPrzemyslaw Szczepaniak            if (trb.isSystemBundle()) {
21734ff539dbc5a809ef3eacbe2d9f2b97f640b7e9cfPrzemyslaw Szczepaniak                return SYSTEM_BUNDLE;
21744ff539dbc5a809ef3eacbe2d9f2b97f640b7e9cfPrzemyslaw Szczepaniak            }
21754ff539dbc5a809ef3eacbe2d9f2b97f640b7e9cfPrzemyslaw Szczepaniak            if (trb.userBundle != null) {
21764ff539dbc5a809ef3eacbe2d9f2b97f640b7e9cfPrzemyslaw Szczepaniak                return trb;
217751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            }
21784ff539dbc5a809ef3eacbe2d9f2b97f640b7e9cfPrzemyslaw Szczepaniak            final String rbName = isSystemLogger
21794ff539dbc5a809ef3eacbe2d9f2b97f640b7e9cfPrzemyslaw Szczepaniak                // ancestor of a system logger is expected to be a system logger.
21804ff539dbc5a809ef3eacbe2d9f2b97f640b7e9cfPrzemyslaw Szczepaniak                // ignore resource bundle name if it's not.
21814ff539dbc5a809ef3eacbe2d9f2b97f640b7e9cfPrzemyslaw Szczepaniak                ? (target.isSystemLogger ? trb.resourceBundleName : null)
21824ff539dbc5a809ef3eacbe2d9f2b97f640b7e9cfPrzemyslaw Szczepaniak                : target.getResourceBundleName();
21834ff539dbc5a809ef3eacbe2d9f2b97f640b7e9cfPrzemyslaw Szczepaniak            if (rbName != null) {
21844ff539dbc5a809ef3eacbe2d9f2b97f640b7e9cfPrzemyslaw Szczepaniak                return LoggerBundle.get(rbName,
21854ff539dbc5a809ef3eacbe2d9f2b97f640b7e9cfPrzemyslaw Szczepaniak                        findResourceBundle(rbName, true));
21864ff539dbc5a809ef3eacbe2d9f2b97f640b7e9cfPrzemyslaw Szczepaniak            }
21874ff539dbc5a809ef3eacbe2d9f2b97f640b7e9cfPrzemyslaw Szczepaniak            target = isSystemLogger ? target.parent : target.getParent();
218851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        }
21894ff539dbc5a809ef3eacbe2d9f2b97f640b7e9cfPrzemyslaw Szczepaniak        return NO_RESOURCE_BUNDLE;
219051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    }
219151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
219251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski}
2193