src/java.logging/share/classes/java/util/logging/Level.java
author egahlin
Thu, 30 May 2019 23:04:50 +0200
branchJEP-349-branch
changeset 57380 6a7e7743b82f
parent 52427 3c6aa484536c
permissions -rw-r--r--
setOrdered and setReuse implemented for file stream, incl. unit tests
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
     1
/*
51532
5f40be158613 8209987: Minor cleanup in Level.java
dfuchs
parents: 48226
diff changeset
     2
 * Copyright (c) 2000, 2018, Oracle and/or its affiliates. All rights reserved.
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
     3
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
90ce3da70b43 Initial load
duke
parents:
diff changeset
     4
 *
90ce3da70b43 Initial load
duke
parents:
diff changeset
     5
 * This code is free software; you can redistribute it and/or modify it
90ce3da70b43 Initial load
duke
parents:
diff changeset
     6
 * under the terms of the GNU General Public License version 2 only, as
5506
202f599c92aa 6943119: Rebrand source copyright notices
ohair
parents: 3853
diff changeset
     7
 * published by the Free Software Foundation.  Oracle designates this
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
     8
 * particular file as subject to the "Classpath" exception as provided
5506
202f599c92aa 6943119: Rebrand source copyright notices
ohair
parents: 3853
diff changeset
     9
 * by Oracle in the LICENSE file that accompanied this code.
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
    10
 *
90ce3da70b43 Initial load
duke
parents:
diff changeset
    11
 * This code is distributed in the hope that it will be useful, but WITHOUT
90ce3da70b43 Initial load
duke
parents:
diff changeset
    12
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
90ce3da70b43 Initial load
duke
parents:
diff changeset
    13
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
90ce3da70b43 Initial load
duke
parents:
diff changeset
    14
 * version 2 for more details (a copy is included in the LICENSE file that
90ce3da70b43 Initial load
duke
parents:
diff changeset
    15
 * accompanied this code).
90ce3da70b43 Initial load
duke
parents:
diff changeset
    16
 *
90ce3da70b43 Initial load
duke
parents:
diff changeset
    17
 * You should have received a copy of the GNU General Public License version
90ce3da70b43 Initial load
duke
parents:
diff changeset
    18
 * 2 along with this work; if not, write to the Free Software Foundation,
90ce3da70b43 Initial load
duke
parents:
diff changeset
    19
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
90ce3da70b43 Initial load
duke
parents:
diff changeset
    20
 *
5506
202f599c92aa 6943119: Rebrand source copyright notices
ohair
parents: 3853
diff changeset
    21
 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
202f599c92aa 6943119: Rebrand source copyright notices
ohair
parents: 3853
diff changeset
    22
 * or visit www.oracle.com if you need additional information or have any
202f599c92aa 6943119: Rebrand source copyright notices
ohair
parents: 3853
diff changeset
    23
 * questions.
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
    24
 */
90ce3da70b43 Initial load
duke
parents:
diff changeset
    25
90ce3da70b43 Initial load
duke
parents:
diff changeset
    26
package java.util.logging;
44545
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents: 43197
diff changeset
    27
40944
dba53de83476 6543126: Level.known can leak memory
dfuchs
parents: 36511
diff changeset
    28
import java.lang.ref.Reference;
dba53de83476 6543126: Level.known can leak memory
dfuchs
parents: 36511
diff changeset
    29
import java.lang.ref.ReferenceQueue;
dba53de83476 6543126: Level.known can leak memory
dfuchs
parents: 36511
diff changeset
    30
import java.lang.ref.WeakReference;
dba53de83476 6543126: Level.known can leak memory
dfuchs
parents: 36511
diff changeset
    31
import java.security.AccessController;
dba53de83476 6543126: Level.known can leak memory
dfuchs
parents: 36511
diff changeset
    32
import java.security.PrivilegedAction;
16098
9001e536ab4e 6664509: Add logging context
mchung
parents: 9035
diff changeset
    33
import java.util.ArrayList;
40944
dba53de83476 6543126: Level.known can leak memory
dfuchs
parents: 36511
diff changeset
    34
import java.util.Collections;
16098
9001e536ab4e 6664509: Add logging context
mchung
parents: 9035
diff changeset
    35
import java.util.HashMap;
9001e536ab4e 6664509: Add logging context
mchung
parents: 9035
diff changeset
    36
import java.util.List;
19795
6c628e165476 8016127: NLS: logging.properties translatability recommendation
dfuchs
parents: 16098
diff changeset
    37
import java.util.Locale;
16098
9001e536ab4e 6664509: Add logging context
mchung
parents: 9035
diff changeset
    38
import java.util.Map;
40944
dba53de83476 6543126: Level.known can leak memory
dfuchs
parents: 36511
diff changeset
    39
import java.util.Optional;
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
    40
import java.util.ResourceBundle;
40944
dba53de83476 6543126: Level.known can leak memory
dfuchs
parents: 36511
diff changeset
    41
import java.util.function.Function;
dba53de83476 6543126: Level.known can leak memory
dfuchs
parents: 36511
diff changeset
    42
import jdk.internal.loader.ClassLoaderValue;
52427
3c6aa484536c 8211122: Reduce the number of internal classes made accessible to jdk.unsupported
mchung
parents: 51532
diff changeset
    43
import jdk.internal.access.JavaUtilResourceBundleAccess;
3c6aa484536c 8211122: Reduce the number of internal classes made accessible to jdk.unsupported
mchung
parents: 51532
diff changeset
    44
import jdk.internal.access.SharedSecrets;
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
    45
90ce3da70b43 Initial load
duke
parents:
diff changeset
    46
/**
90ce3da70b43 Initial load
duke
parents:
diff changeset
    47
 * The Level class defines a set of standard logging levels that
90ce3da70b43 Initial load
duke
parents:
diff changeset
    48
 * can be used to control logging output.  The logging Level objects
90ce3da70b43 Initial load
duke
parents:
diff changeset
    49
 * are ordered and are specified by ordered integers.  Enabling logging
90ce3da70b43 Initial load
duke
parents:
diff changeset
    50
 * at a given level also enables logging at all higher levels.
90ce3da70b43 Initial load
duke
parents:
diff changeset
    51
 * <p>
90ce3da70b43 Initial load
duke
parents:
diff changeset
    52
 * Clients should normally use the predefined Level constants such
90ce3da70b43 Initial load
duke
parents:
diff changeset
    53
 * as Level.SEVERE.
90ce3da70b43 Initial load
duke
parents:
diff changeset
    54
 * <p>
90ce3da70b43 Initial load
duke
parents:
diff changeset
    55
 * The levels in descending order are:
90ce3da70b43 Initial load
duke
parents:
diff changeset
    56
 * <ul>
90ce3da70b43 Initial load
duke
parents:
diff changeset
    57
 * <li>SEVERE (highest value)
90ce3da70b43 Initial load
duke
parents:
diff changeset
    58
 * <li>WARNING
90ce3da70b43 Initial load
duke
parents:
diff changeset
    59
 * <li>INFO
90ce3da70b43 Initial load
duke
parents:
diff changeset
    60
 * <li>CONFIG
90ce3da70b43 Initial load
duke
parents:
diff changeset
    61
 * <li>FINE
90ce3da70b43 Initial load
duke
parents:
diff changeset
    62
 * <li>FINER
90ce3da70b43 Initial load
duke
parents:
diff changeset
    63
 * <li>FINEST  (lowest value)
90ce3da70b43 Initial load
duke
parents:
diff changeset
    64
 * </ul>
90ce3da70b43 Initial load
duke
parents:
diff changeset
    65
 * In addition there is a level OFF that can be used to turn
90ce3da70b43 Initial load
duke
parents:
diff changeset
    66
 * off logging, and a level ALL that can be used to enable
90ce3da70b43 Initial load
duke
parents:
diff changeset
    67
 * logging of all messages.
90ce3da70b43 Initial load
duke
parents:
diff changeset
    68
 * <p>
90ce3da70b43 Initial load
duke
parents:
diff changeset
    69
 * It is possible for third parties to define additional logging
90ce3da70b43 Initial load
duke
parents:
diff changeset
    70
 * levels by subclassing Level.  In such cases subclasses should
90ce3da70b43 Initial load
duke
parents:
diff changeset
    71
 * take care to chose unique integer level values and to ensure that
90ce3da70b43 Initial load
duke
parents:
diff changeset
    72
 * they maintain the Object uniqueness property across serialization
90ce3da70b43 Initial load
duke
parents:
diff changeset
    73
 * by defining a suitable readResolve method.
90ce3da70b43 Initial load
duke
parents:
diff changeset
    74
 *
90ce3da70b43 Initial load
duke
parents:
diff changeset
    75
 * @since 1.4
90ce3da70b43 Initial load
duke
parents:
diff changeset
    76
 */
90ce3da70b43 Initial load
duke
parents:
diff changeset
    77
90ce3da70b43 Initial load
duke
parents:
diff changeset
    78
public class Level implements java.io.Serializable {
42338
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 40944
diff changeset
    79
    private static final String defaultBundle =
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 40944
diff changeset
    80
        "sun.util.logging.resources.logging";
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 40944
diff changeset
    81
42462
c12ae7eefac0 8170984: java.util.logging might force the initialization of ResourceBundle class too early.
dfuchs
parents: 42338
diff changeset
    82
    // Calling SharedSecrets.getJavaUtilResourceBundleAccess()
c12ae7eefac0 8170984: java.util.logging might force the initialization of ResourceBundle class too early.
dfuchs
parents: 42338
diff changeset
    83
    // forces the initialization of ResourceBundle.class, which
c12ae7eefac0 8170984: java.util.logging might force the initialization of ResourceBundle class too early.
dfuchs
parents: 42338
diff changeset
    84
    // can be too early if the VM has not finished booting yet.
c12ae7eefac0 8170984: java.util.logging might force the initialization of ResourceBundle class too early.
dfuchs
parents: 42338
diff changeset
    85
    private static final class RbAccess {
c12ae7eefac0 8170984: java.util.logging might force the initialization of ResourceBundle class too early.
dfuchs
parents: 42338
diff changeset
    86
        static final JavaUtilResourceBundleAccess RB_ACCESS =
c12ae7eefac0 8170984: java.util.logging might force the initialization of ResourceBundle class too early.
dfuchs
parents: 42338
diff changeset
    87
            SharedSecrets.getJavaUtilResourceBundleAccess();
c12ae7eefac0 8170984: java.util.logging might force the initialization of ResourceBundle class too early.
dfuchs
parents: 42338
diff changeset
    88
    }
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
    89
90ce3da70b43 Initial load
duke
parents:
diff changeset
    90
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
    91
     * @serial  The non-localized name of the level.
90ce3da70b43 Initial load
duke
parents:
diff changeset
    92
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
    93
    private final String name;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    94
90ce3da70b43 Initial load
duke
parents:
diff changeset
    95
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
    96
     * @serial  The integer value of the level.
90ce3da70b43 Initial load
duke
parents:
diff changeset
    97
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
    98
    private final int value;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    99
90ce3da70b43 Initial load
duke
parents:
diff changeset
   100
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   101
     * @serial The resource bundle name to be used in localizing the level name.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   102
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   103
    private final String resourceBundleName;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   104
16098
9001e536ab4e 6664509: Add logging context
mchung
parents: 9035
diff changeset
   105
    // localized level name
19795
6c628e165476 8016127: NLS: logging.properties translatability recommendation
dfuchs
parents: 16098
diff changeset
   106
    private transient String localizedLevelName;
6c628e165476 8016127: NLS: logging.properties translatability recommendation
dfuchs
parents: 16098
diff changeset
   107
    private transient Locale cachedLocale;
16098
9001e536ab4e 6664509: Add logging context
mchung
parents: 9035
diff changeset
   108
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   109
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   110
     * OFF is a special level that can be used to turn off logging.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   111
     * This level is initialized to <CODE>Integer.MAX_VALUE</CODE>.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   112
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   113
    public static final Level OFF = new Level("OFF",Integer.MAX_VALUE, defaultBundle);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   114
90ce3da70b43 Initial load
duke
parents:
diff changeset
   115
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   116
     * SEVERE is a message level indicating a serious failure.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   117
     * <p>
90ce3da70b43 Initial load
duke
parents:
diff changeset
   118
     * In general SEVERE messages should describe events that are
90ce3da70b43 Initial load
duke
parents:
diff changeset
   119
     * of considerable importance and which will prevent normal
90ce3da70b43 Initial load
duke
parents:
diff changeset
   120
     * program execution.   They should be reasonably intelligible
90ce3da70b43 Initial load
duke
parents:
diff changeset
   121
     * to end users and to system administrators.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   122
     * This level is initialized to <CODE>1000</CODE>.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   123
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   124
    public static final Level SEVERE = new Level("SEVERE",1000, defaultBundle);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   125
90ce3da70b43 Initial load
duke
parents:
diff changeset
   126
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   127
     * WARNING is a message level indicating a potential problem.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   128
     * <p>
90ce3da70b43 Initial load
duke
parents:
diff changeset
   129
     * In general WARNING messages should describe events that will
90ce3da70b43 Initial load
duke
parents:
diff changeset
   130
     * be of interest to end users or system managers, or which
90ce3da70b43 Initial load
duke
parents:
diff changeset
   131
     * indicate potential problems.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   132
     * This level is initialized to <CODE>900</CODE>.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   133
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   134
    public static final Level WARNING = new Level("WARNING", 900, defaultBundle);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   135
90ce3da70b43 Initial load
duke
parents:
diff changeset
   136
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   137
     * INFO is a message level for informational messages.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   138
     * <p>
90ce3da70b43 Initial load
duke
parents:
diff changeset
   139
     * Typically INFO messages will be written to the console
90ce3da70b43 Initial load
duke
parents:
diff changeset
   140
     * or its equivalent.  So the INFO level should only be
90ce3da70b43 Initial load
duke
parents:
diff changeset
   141
     * used for reasonably significant messages that will
3853
9d2382b74894 6882363: 4/4 typos in java.util.logging javadocs
dcubed
parents: 2
diff changeset
   142
     * make sense to end users and system administrators.
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   143
     * This level is initialized to <CODE>800</CODE>.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   144
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   145
    public static final Level INFO = new Level("INFO", 800, defaultBundle);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   146
90ce3da70b43 Initial load
duke
parents:
diff changeset
   147
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   148
     * CONFIG is a message level for static configuration messages.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   149
     * <p>
90ce3da70b43 Initial load
duke
parents:
diff changeset
   150
     * CONFIG messages are intended to provide a variety of static
90ce3da70b43 Initial load
duke
parents:
diff changeset
   151
     * configuration information, to assist in debugging problems
90ce3da70b43 Initial load
duke
parents:
diff changeset
   152
     * that may be associated with particular configurations.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   153
     * For example, CONFIG message might include the CPU type,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   154
     * the graphics depth, the GUI look-and-feel, etc.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   155
     * This level is initialized to <CODE>700</CODE>.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   156
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   157
    public static final Level CONFIG = new Level("CONFIG", 700, defaultBundle);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   158
90ce3da70b43 Initial load
duke
parents:
diff changeset
   159
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   160
     * FINE is a message level providing tracing information.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   161
     * <p>
90ce3da70b43 Initial load
duke
parents:
diff changeset
   162
     * All of FINE, FINER, and FINEST are intended for relatively
90ce3da70b43 Initial load
duke
parents:
diff changeset
   163
     * detailed tracing.  The exact meaning of the three levels will
90ce3da70b43 Initial load
duke
parents:
diff changeset
   164
     * vary between subsystems, but in general, FINEST should be used
90ce3da70b43 Initial load
duke
parents:
diff changeset
   165
     * for the most voluminous detailed output, FINER for somewhat
90ce3da70b43 Initial load
duke
parents:
diff changeset
   166
     * less detailed output, and FINE for the  lowest volume (and
90ce3da70b43 Initial load
duke
parents:
diff changeset
   167
     * most important) messages.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   168
     * <p>
90ce3da70b43 Initial load
duke
parents:
diff changeset
   169
     * In general the FINE level should be used for information
90ce3da70b43 Initial load
duke
parents:
diff changeset
   170
     * that will be broadly interesting to developers who do not have
90ce3da70b43 Initial load
duke
parents:
diff changeset
   171
     * a specialized interest in the specific subsystem.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   172
     * <p>
90ce3da70b43 Initial load
duke
parents:
diff changeset
   173
     * FINE messages might include things like minor (recoverable)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   174
     * failures.  Issues indicating potential performance problems
90ce3da70b43 Initial load
duke
parents:
diff changeset
   175
     * are also worth logging as FINE.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   176
     * This level is initialized to <CODE>500</CODE>.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   177
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   178
    public static final Level FINE = new Level("FINE", 500, defaultBundle);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   179
90ce3da70b43 Initial load
duke
parents:
diff changeset
   180
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   181
     * FINER indicates a fairly detailed tracing message.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   182
     * By default logging calls for entering, returning, or throwing
90ce3da70b43 Initial load
duke
parents:
diff changeset
   183
     * an exception are traced at this level.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   184
     * This level is initialized to <CODE>400</CODE>.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   185
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   186
    public static final Level FINER = new Level("FINER", 400, defaultBundle);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   187
90ce3da70b43 Initial load
duke
parents:
diff changeset
   188
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   189
     * FINEST indicates a highly detailed tracing message.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   190
     * This level is initialized to <CODE>300</CODE>.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   191
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   192
    public static final Level FINEST = new Level("FINEST", 300, defaultBundle);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   193
90ce3da70b43 Initial load
duke
parents:
diff changeset
   194
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   195
     * ALL indicates that all messages should be logged.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   196
     * This level is initialized to <CODE>Integer.MIN_VALUE</CODE>.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   197
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   198
    public static final Level ALL = new Level("ALL", Integer.MIN_VALUE, defaultBundle);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   199
40944
dba53de83476 6543126: Level.known can leak memory
dfuchs
parents: 36511
diff changeset
   200
    private static final Level[] standardLevels = {
dba53de83476 6543126: Level.known can leak memory
dfuchs
parents: 36511
diff changeset
   201
        OFF, SEVERE, WARNING, INFO, CONFIG, FINE, FINER, FINEST, ALL
dba53de83476 6543126: Level.known can leak memory
dfuchs
parents: 36511
diff changeset
   202
    };
dba53de83476 6543126: Level.known can leak memory
dfuchs
parents: 36511
diff changeset
   203
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   204
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   205
     * Create a named Level with a given integer value.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   206
     * <p>
90ce3da70b43 Initial load
duke
parents:
diff changeset
   207
     * Note that this constructor is "protected" to allow subclassing.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   208
     * In general clients of logging should use one of the constant Level
90ce3da70b43 Initial load
duke
parents:
diff changeset
   209
     * objects such as SEVERE or FINEST.  However, if clients need to
90ce3da70b43 Initial load
duke
parents:
diff changeset
   210
     * add new logging levels, they may subclass Level and define new
90ce3da70b43 Initial load
duke
parents:
diff changeset
   211
     * constants.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   212
     * @param name  the name of the Level, for example "SEVERE".
90ce3da70b43 Initial load
duke
parents:
diff changeset
   213
     * @param value an integer value for the level.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   214
     * @throws NullPointerException if the name is null
90ce3da70b43 Initial load
duke
parents:
diff changeset
   215
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   216
    protected Level(String name, int value) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   217
        this(name, value, null);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   218
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   219
90ce3da70b43 Initial load
duke
parents:
diff changeset
   220
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   221
     * Create a named Level with a given integer value and a
90ce3da70b43 Initial load
duke
parents:
diff changeset
   222
     * given localization resource name.
24196
61c9885d76e2 8029451: Tidy warnings cleanup for java.util package; minor changes in java.nio, java.sql
yan
parents: 23010
diff changeset
   223
     *
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   224
     * @param name  the name of the Level, for example "SEVERE".
90ce3da70b43 Initial load
duke
parents:
diff changeset
   225
     * @param value an integer value for the level.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   226
     * @param resourceBundleName name of a resource bundle to use in
90ce3da70b43 Initial load
duke
parents:
diff changeset
   227
     *    localizing the given name. If the resourceBundleName is null
90ce3da70b43 Initial load
duke
parents:
diff changeset
   228
     *    or an empty string, it is ignored.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   229
     * @throws NullPointerException if the name is null
90ce3da70b43 Initial load
duke
parents:
diff changeset
   230
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   231
    protected Level(String name, int value, String resourceBundleName) {
20745
3d2e35965c56 8026027: Level.parse should return the custom Level instance instead of the mirrored Level
mchung
parents: 19795
diff changeset
   232
        this(name, value, resourceBundleName, true);
3d2e35965c56 8026027: Level.parse should return the custom Level instance instead of the mirrored Level
mchung
parents: 19795
diff changeset
   233
    }
3d2e35965c56 8026027: Level.parse should return the custom Level instance instead of the mirrored Level
mchung
parents: 19795
diff changeset
   234
3d2e35965c56 8026027: Level.parse should return the custom Level instance instead of the mirrored Level
mchung
parents: 19795
diff changeset
   235
    // private constructor to specify whether this instance should be added
3d2e35965c56 8026027: Level.parse should return the custom Level instance instead of the mirrored Level
mchung
parents: 19795
diff changeset
   236
    // to the KnownLevel list from which Level.parse method does its look up
3d2e35965c56 8026027: Level.parse should return the custom Level instance instead of the mirrored Level
mchung
parents: 19795
diff changeset
   237
    private Level(String name, int value, String resourceBundleName, boolean visible) {
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   238
        if (name == null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   239
            throw new NullPointerException();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   240
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   241
        this.name = name;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   242
        this.value = value;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   243
        this.resourceBundleName = resourceBundleName;
16098
9001e536ab4e 6664509: Add logging context
mchung
parents: 9035
diff changeset
   244
        this.localizedLevelName = resourceBundleName == null ? name : null;
19795
6c628e165476 8016127: NLS: logging.properties translatability recommendation
dfuchs
parents: 16098
diff changeset
   245
        this.cachedLocale = null;
20745
3d2e35965c56 8026027: Level.parse should return the custom Level instance instead of the mirrored Level
mchung
parents: 19795
diff changeset
   246
        if (visible) {
3d2e35965c56 8026027: Level.parse should return the custom Level instance instead of the mirrored Level
mchung
parents: 19795
diff changeset
   247
            KnownLevel.add(this);
3d2e35965c56 8026027: Level.parse should return the custom Level instance instead of the mirrored Level
mchung
parents: 19795
diff changeset
   248
        }
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   249
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   250
90ce3da70b43 Initial load
duke
parents:
diff changeset
   251
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   252
     * Return the level's localization resource bundle name, or
90ce3da70b43 Initial load
duke
parents:
diff changeset
   253
     * null if no localization bundle is defined.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   254
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   255
     * @return localization resource bundle name
90ce3da70b43 Initial load
duke
parents:
diff changeset
   256
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   257
    public String getResourceBundleName() {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   258
        return resourceBundleName;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   259
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   260
90ce3da70b43 Initial load
duke
parents:
diff changeset
   261
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   262
     * Return the non-localized string name of the Level.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   263
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   264
     * @return non-localized name
90ce3da70b43 Initial load
duke
parents:
diff changeset
   265
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   266
    public String getName() {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   267
        return name;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   268
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   269
90ce3da70b43 Initial load
duke
parents:
diff changeset
   270
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   271
     * Return the localized string name of the Level, for
90ce3da70b43 Initial load
duke
parents:
diff changeset
   272
     * the current default locale.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   273
     * <p>
90ce3da70b43 Initial load
duke
parents:
diff changeset
   274
     * If no localization information is available, the
90ce3da70b43 Initial load
duke
parents:
diff changeset
   275
     * non-localized name is returned.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   276
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   277
     * @return localized name
90ce3da70b43 Initial load
duke
parents:
diff changeset
   278
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   279
    public String getLocalizedName() {
16098
9001e536ab4e 6664509: Add logging context
mchung
parents: 9035
diff changeset
   280
        return getLocalizedLevelName();
9001e536ab4e 6664509: Add logging context
mchung
parents: 9035
diff changeset
   281
    }
9001e536ab4e 6664509: Add logging context
mchung
parents: 9035
diff changeset
   282
9001e536ab4e 6664509: Add logging context
mchung
parents: 9035
diff changeset
   283
    // package-private getLevelName() is used by the implementation
9001e536ab4e 6664509: Add logging context
mchung
parents: 9035
diff changeset
   284
    // instead of getName() to avoid calling the subclass's version
9001e536ab4e 6664509: Add logging context
mchung
parents: 9035
diff changeset
   285
    final String getLevelName() {
9001e536ab4e 6664509: Add logging context
mchung
parents: 9035
diff changeset
   286
        return this.name;
9001e536ab4e 6664509: Add logging context
mchung
parents: 9035
diff changeset
   287
    }
9001e536ab4e 6664509: Add logging context
mchung
parents: 9035
diff changeset
   288
19795
6c628e165476 8016127: NLS: logging.properties translatability recommendation
dfuchs
parents: 16098
diff changeset
   289
    private String computeLocalizedLevelName(Locale newLocale) {
36511
9d0388c6b336 8142968: Module System implementation
alanb
parents: 25859
diff changeset
   290
        // Resource bundle should be loaded from the defining module
9d0388c6b336 8142968: Module System implementation
alanb
parents: 25859
diff changeset
   291
        // or its defining class loader, if it's unnamed module,
9d0388c6b336 8142968: Module System implementation
alanb
parents: 25859
diff changeset
   292
        // of this Level instance that can be a custom Level subclass;
9d0388c6b336 8142968: Module System implementation
alanb
parents: 25859
diff changeset
   293
        Module module = this.getClass().getModule();
42462
c12ae7eefac0 8170984: java.util.logging might force the initialization of ResourceBundle class too early.
dfuchs
parents: 42338
diff changeset
   294
        ResourceBundle rb = RbAccess.RB_ACCESS.getBundle(resourceBundleName,
40944
dba53de83476 6543126: Level.known can leak memory
dfuchs
parents: 36511
diff changeset
   295
                newLocale, module);
36511
9d0388c6b336 8142968: Module System implementation
alanb
parents: 25859
diff changeset
   296
19795
6c628e165476 8016127: NLS: logging.properties translatability recommendation
dfuchs
parents: 16098
diff changeset
   297
        final String localizedName = rb.getString(name);
6c628e165476 8016127: NLS: logging.properties translatability recommendation
dfuchs
parents: 16098
diff changeset
   298
        final boolean isDefaultBundle = defaultBundle.equals(resourceBundleName);
6c628e165476 8016127: NLS: logging.properties translatability recommendation
dfuchs
parents: 16098
diff changeset
   299
        if (!isDefaultBundle) return localizedName;
6c628e165476 8016127: NLS: logging.properties translatability recommendation
dfuchs
parents: 16098
diff changeset
   300
6c628e165476 8016127: NLS: logging.properties translatability recommendation
dfuchs
parents: 16098
diff changeset
   301
        // This is a trick to determine whether the name has been translated
6c628e165476 8016127: NLS: logging.properties translatability recommendation
dfuchs
parents: 16098
diff changeset
   302
        // or not. If it has not been translated, we need to use Locale.ROOT
6c628e165476 8016127: NLS: logging.properties translatability recommendation
dfuchs
parents: 16098
diff changeset
   303
        // when calling toUpperCase().
6c628e165476 8016127: NLS: logging.properties translatability recommendation
dfuchs
parents: 16098
diff changeset
   304
        final Locale rbLocale = rb.getLocale();
6c628e165476 8016127: NLS: logging.properties translatability recommendation
dfuchs
parents: 16098
diff changeset
   305
        final Locale locale =
6c628e165476 8016127: NLS: logging.properties translatability recommendation
dfuchs
parents: 16098
diff changeset
   306
                Locale.ROOT.equals(rbLocale)
6c628e165476 8016127: NLS: logging.properties translatability recommendation
dfuchs
parents: 16098
diff changeset
   307
                || name.equals(localizedName.toUpperCase(Locale.ROOT))
6c628e165476 8016127: NLS: logging.properties translatability recommendation
dfuchs
parents: 16098
diff changeset
   308
                ? Locale.ROOT : rbLocale;
6c628e165476 8016127: NLS: logging.properties translatability recommendation
dfuchs
parents: 16098
diff changeset
   309
6c628e165476 8016127: NLS: logging.properties translatability recommendation
dfuchs
parents: 16098
diff changeset
   310
        // ALL CAPS in a resource bundle's message indicates no translation
6c628e165476 8016127: NLS: logging.properties translatability recommendation
dfuchs
parents: 16098
diff changeset
   311
        // needed per Oracle translation guideline.  To workaround this
6c628e165476 8016127: NLS: logging.properties translatability recommendation
dfuchs
parents: 16098
diff changeset
   312
        // in Oracle JDK implementation, convert the localized level name
6c628e165476 8016127: NLS: logging.properties translatability recommendation
dfuchs
parents: 16098
diff changeset
   313
        // to uppercase for compatibility reason.
6c628e165476 8016127: NLS: logging.properties translatability recommendation
dfuchs
parents: 16098
diff changeset
   314
        return Locale.ROOT.equals(locale) ? name : localizedName.toUpperCase(locale);
6c628e165476 8016127: NLS: logging.properties translatability recommendation
dfuchs
parents: 16098
diff changeset
   315
    }
6c628e165476 8016127: NLS: logging.properties translatability recommendation
dfuchs
parents: 16098
diff changeset
   316
6c628e165476 8016127: NLS: logging.properties translatability recommendation
dfuchs
parents: 16098
diff changeset
   317
    // Avoid looking up the localizedLevelName twice if we already
6c628e165476 8016127: NLS: logging.properties translatability recommendation
dfuchs
parents: 16098
diff changeset
   318
    // have it.
6c628e165476 8016127: NLS: logging.properties translatability recommendation
dfuchs
parents: 16098
diff changeset
   319
    final String getCachedLocalizedLevelName() {
6c628e165476 8016127: NLS: logging.properties translatability recommendation
dfuchs
parents: 16098
diff changeset
   320
16098
9001e536ab4e 6664509: Add logging context
mchung
parents: 9035
diff changeset
   321
        if (localizedLevelName != null) {
19795
6c628e165476 8016127: NLS: logging.properties translatability recommendation
dfuchs
parents: 16098
diff changeset
   322
            if (cachedLocale != null) {
6c628e165476 8016127: NLS: logging.properties translatability recommendation
dfuchs
parents: 16098
diff changeset
   323
                if (cachedLocale.equals(Locale.getDefault())) {
6c628e165476 8016127: NLS: logging.properties translatability recommendation
dfuchs
parents: 16098
diff changeset
   324
                    // OK: our cached value was looked up with the same
6c628e165476 8016127: NLS: logging.properties translatability recommendation
dfuchs
parents: 16098
diff changeset
   325
                    //     locale. We can use it.
6c628e165476 8016127: NLS: logging.properties translatability recommendation
dfuchs
parents: 16098
diff changeset
   326
                    return localizedLevelName;
6c628e165476 8016127: NLS: logging.properties translatability recommendation
dfuchs
parents: 16098
diff changeset
   327
                }
6c628e165476 8016127: NLS: logging.properties translatability recommendation
dfuchs
parents: 16098
diff changeset
   328
            }
16098
9001e536ab4e 6664509: Add logging context
mchung
parents: 9035
diff changeset
   329
        }
9001e536ab4e 6664509: Add logging context
mchung
parents: 9035
diff changeset
   330
19795
6c628e165476 8016127: NLS: logging.properties translatability recommendation
dfuchs
parents: 16098
diff changeset
   331
        if (resourceBundleName == null) {
6c628e165476 8016127: NLS: logging.properties translatability recommendation
dfuchs
parents: 16098
diff changeset
   332
            // No resource bundle: just use the name.
6c628e165476 8016127: NLS: logging.properties translatability recommendation
dfuchs
parents: 16098
diff changeset
   333
            return name;
6c628e165476 8016127: NLS: logging.properties translatability recommendation
dfuchs
parents: 16098
diff changeset
   334
        }
6c628e165476 8016127: NLS: logging.properties translatability recommendation
dfuchs
parents: 16098
diff changeset
   335
6c628e165476 8016127: NLS: logging.properties translatability recommendation
dfuchs
parents: 16098
diff changeset
   336
        // We need to compute the localized name.
6c628e165476 8016127: NLS: logging.properties translatability recommendation
dfuchs
parents: 16098
diff changeset
   337
        // Either because it's the first time, or because our cached
6c628e165476 8016127: NLS: logging.properties translatability recommendation
dfuchs
parents: 16098
diff changeset
   338
        // value is for a different locale. Just return null.
6c628e165476 8016127: NLS: logging.properties translatability recommendation
dfuchs
parents: 16098
diff changeset
   339
        return null;
6c628e165476 8016127: NLS: logging.properties translatability recommendation
dfuchs
parents: 16098
diff changeset
   340
    }
6c628e165476 8016127: NLS: logging.properties translatability recommendation
dfuchs
parents: 16098
diff changeset
   341
6c628e165476 8016127: NLS: logging.properties translatability recommendation
dfuchs
parents: 16098
diff changeset
   342
    final synchronized String getLocalizedLevelName() {
6c628e165476 8016127: NLS: logging.properties translatability recommendation
dfuchs
parents: 16098
diff changeset
   343
6c628e165476 8016127: NLS: logging.properties translatability recommendation
dfuchs
parents: 16098
diff changeset
   344
        // See if we have a cached localized name
6c628e165476 8016127: NLS: logging.properties translatability recommendation
dfuchs
parents: 16098
diff changeset
   345
        final String cachedLocalizedName = getCachedLocalizedLevelName();
6c628e165476 8016127: NLS: logging.properties translatability recommendation
dfuchs
parents: 16098
diff changeset
   346
        if (cachedLocalizedName != null) {
6c628e165476 8016127: NLS: logging.properties translatability recommendation
dfuchs
parents: 16098
diff changeset
   347
            return cachedLocalizedName;
6c628e165476 8016127: NLS: logging.properties translatability recommendation
dfuchs
parents: 16098
diff changeset
   348
        }
6c628e165476 8016127: NLS: logging.properties translatability recommendation
dfuchs
parents: 16098
diff changeset
   349
6c628e165476 8016127: NLS: logging.properties translatability recommendation
dfuchs
parents: 16098
diff changeset
   350
        // No cached localized name or cache invalid.
6c628e165476 8016127: NLS: logging.properties translatability recommendation
dfuchs
parents: 16098
diff changeset
   351
        // Need to compute the localized name.
6c628e165476 8016127: NLS: logging.properties translatability recommendation
dfuchs
parents: 16098
diff changeset
   352
        final Locale newLocale = Locale.getDefault();
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   353
        try {
19795
6c628e165476 8016127: NLS: logging.properties translatability recommendation
dfuchs
parents: 16098
diff changeset
   354
            localizedLevelName = computeLocalizedLevelName(newLocale);
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   355
        } catch (Exception ex) {
16098
9001e536ab4e 6664509: Add logging context
mchung
parents: 9035
diff changeset
   356
            localizedLevelName = name;
9001e536ab4e 6664509: Add logging context
mchung
parents: 9035
diff changeset
   357
        }
19795
6c628e165476 8016127: NLS: logging.properties translatability recommendation
dfuchs
parents: 16098
diff changeset
   358
        cachedLocale = newLocale;
16098
9001e536ab4e 6664509: Add logging context
mchung
parents: 9035
diff changeset
   359
        return localizedLevelName;
9001e536ab4e 6664509: Add logging context
mchung
parents: 9035
diff changeset
   360
    }
9001e536ab4e 6664509: Add logging context
mchung
parents: 9035
diff changeset
   361
9001e536ab4e 6664509: Add logging context
mchung
parents: 9035
diff changeset
   362
    // Returns a mirrored Level object that matches the given name as
9001e536ab4e 6664509: Add logging context
mchung
parents: 9035
diff changeset
   363
    // specified in the Level.parse method.  Returns null if not found.
9001e536ab4e 6664509: Add logging context
mchung
parents: 9035
diff changeset
   364
    //
9001e536ab4e 6664509: Add logging context
mchung
parents: 9035
diff changeset
   365
    // It returns the same Level object as the one returned by Level.parse
9001e536ab4e 6664509: Add logging context
mchung
parents: 9035
diff changeset
   366
    // method if the given name is a non-localized name or integer.
9001e536ab4e 6664509: Add logging context
mchung
parents: 9035
diff changeset
   367
    //
9001e536ab4e 6664509: Add logging context
mchung
parents: 9035
diff changeset
   368
    // If the name is a localized name, findLevel and parse method may
9001e536ab4e 6664509: Add logging context
mchung
parents: 9035
diff changeset
   369
    // return a different level value if there is a custom Level subclass
9001e536ab4e 6664509: Add logging context
mchung
parents: 9035
diff changeset
   370
    // that overrides Level.getLocalizedName() to return a different string
9001e536ab4e 6664509: Add logging context
mchung
parents: 9035
diff changeset
   371
    // than what's returned by the default implementation.
9001e536ab4e 6664509: Add logging context
mchung
parents: 9035
diff changeset
   372
    //
9001e536ab4e 6664509: Add logging context
mchung
parents: 9035
diff changeset
   373
    static Level findLevel(String name) {
9001e536ab4e 6664509: Add logging context
mchung
parents: 9035
diff changeset
   374
        if (name == null) {
9001e536ab4e 6664509: Add logging context
mchung
parents: 9035
diff changeset
   375
            throw new NullPointerException();
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   376
        }
16098
9001e536ab4e 6664509: Add logging context
mchung
parents: 9035
diff changeset
   377
40944
dba53de83476 6543126: Level.known can leak memory
dfuchs
parents: 36511
diff changeset
   378
        Optional<Level> level;
16098
9001e536ab4e 6664509: Add logging context
mchung
parents: 9035
diff changeset
   379
9001e536ab4e 6664509: Add logging context
mchung
parents: 9035
diff changeset
   380
        // Look for a known Level with the given non-localized name.
40944
dba53de83476 6543126: Level.known can leak memory
dfuchs
parents: 36511
diff changeset
   381
        level = KnownLevel.findByName(name, KnownLevel::mirrored);
dba53de83476 6543126: Level.known can leak memory
dfuchs
parents: 36511
diff changeset
   382
        if (level.isPresent()) {
dba53de83476 6543126: Level.known can leak memory
dfuchs
parents: 36511
diff changeset
   383
            return level.get();
16098
9001e536ab4e 6664509: Add logging context
mchung
parents: 9035
diff changeset
   384
        }
9001e536ab4e 6664509: Add logging context
mchung
parents: 9035
diff changeset
   385
9001e536ab4e 6664509: Add logging context
mchung
parents: 9035
diff changeset
   386
        // Now, check if the given name is an integer.  If so,
9001e536ab4e 6664509: Add logging context
mchung
parents: 9035
diff changeset
   387
        // first look for a Level with the given value and then
9001e536ab4e 6664509: Add logging context
mchung
parents: 9035
diff changeset
   388
        // if necessary create one.
9001e536ab4e 6664509: Add logging context
mchung
parents: 9035
diff changeset
   389
        try {
9001e536ab4e 6664509: Add logging context
mchung
parents: 9035
diff changeset
   390
            int x = Integer.parseInt(name);
40944
dba53de83476 6543126: Level.known can leak memory
dfuchs
parents: 36511
diff changeset
   391
            level = KnownLevel.findByValue(x, KnownLevel::mirrored);
48226
ea47055160ef 8187073: The java.util.logging.Level.findLevel() will not correctly find a Level by it's int value
dfuchs
parents: 47216
diff changeset
   392
            if (level.isPresent()) {
ea47055160ef 8187073: The java.util.logging.Level.findLevel() will not correctly find a Level by it's int value
dfuchs
parents: 47216
diff changeset
   393
                return level.get();
16098
9001e536ab4e 6664509: Add logging context
mchung
parents: 9035
diff changeset
   394
            }
48226
ea47055160ef 8187073: The java.util.logging.Level.findLevel() will not correctly find a Level by it's int value
dfuchs
parents: 47216
diff changeset
   395
            // add new Level
ea47055160ef 8187073: The java.util.logging.Level.findLevel() will not correctly find a Level by it's int value
dfuchs
parents: 47216
diff changeset
   396
            Level levelObject = new Level(name, x);
ea47055160ef 8187073: The java.util.logging.Level.findLevel() will not correctly find a Level by it's int value
dfuchs
parents: 47216
diff changeset
   397
            // There's no need to use a reachability fence here because
ea47055160ef 8187073: The java.util.logging.Level.findLevel() will not correctly find a Level by it's int value
dfuchs
parents: 47216
diff changeset
   398
            // KnownLevel keeps a strong reference on the level when
ea47055160ef 8187073: The java.util.logging.Level.findLevel() will not correctly find a Level by it's int value
dfuchs
parents: 47216
diff changeset
   399
            // level.getClass() == Level.class.
ea47055160ef 8187073: The java.util.logging.Level.findLevel() will not correctly find a Level by it's int value
dfuchs
parents: 47216
diff changeset
   400
            return KnownLevel.findByValue(x, KnownLevel::mirrored).get();
16098
9001e536ab4e 6664509: Add logging context
mchung
parents: 9035
diff changeset
   401
        } catch (NumberFormatException ex) {
9001e536ab4e 6664509: Add logging context
mchung
parents: 9035
diff changeset
   402
            // Not an integer.
9001e536ab4e 6664509: Add logging context
mchung
parents: 9035
diff changeset
   403
            // Drop through.
9001e536ab4e 6664509: Add logging context
mchung
parents: 9035
diff changeset
   404
        }
9001e536ab4e 6664509: Add logging context
mchung
parents: 9035
diff changeset
   405
40944
dba53de83476 6543126: Level.known can leak memory
dfuchs
parents: 36511
diff changeset
   406
        level = KnownLevel.findByLocalizedLevelName(name,
dba53de83476 6543126: Level.known can leak memory
dfuchs
parents: 36511
diff changeset
   407
                KnownLevel::mirrored);
dba53de83476 6543126: Level.known can leak memory
dfuchs
parents: 36511
diff changeset
   408
        if (level.isPresent()) {
dba53de83476 6543126: Level.known can leak memory
dfuchs
parents: 36511
diff changeset
   409
            return level.get();
16098
9001e536ab4e 6664509: Add logging context
mchung
parents: 9035
diff changeset
   410
        }
9001e536ab4e 6664509: Add logging context
mchung
parents: 9035
diff changeset
   411
9001e536ab4e 6664509: Add logging context
mchung
parents: 9035
diff changeset
   412
        return null;
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   413
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   414
90ce3da70b43 Initial load
duke
parents:
diff changeset
   415
    /**
3853
9d2382b74894 6882363: 4/4 typos in java.util.logging javadocs
dcubed
parents: 2
diff changeset
   416
     * Returns a string representation of this Level.
9d2382b74894 6882363: 4/4 typos in java.util.logging javadocs
dcubed
parents: 2
diff changeset
   417
     *
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   418
     * @return the non-localized name of the Level, for example "INFO".
90ce3da70b43 Initial load
duke
parents:
diff changeset
   419
     */
19795
6c628e165476 8016127: NLS: logging.properties translatability recommendation
dfuchs
parents: 16098
diff changeset
   420
    @Override
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   421
    public final String toString() {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   422
        return name;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   423
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   424
90ce3da70b43 Initial load
duke
parents:
diff changeset
   425
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   426
     * Get the integer value for this level.  This integer value
90ce3da70b43 Initial load
duke
parents:
diff changeset
   427
     * can be used for efficient ordering comparisons between
90ce3da70b43 Initial load
duke
parents:
diff changeset
   428
     * Level objects.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   429
     * @return the integer value for this level.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   430
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   431
    public final int intValue() {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   432
        return value;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   433
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   434
90ce3da70b43 Initial load
duke
parents:
diff changeset
   435
    private static final long serialVersionUID = -8176160795706313070L;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   436
90ce3da70b43 Initial load
duke
parents:
diff changeset
   437
    // Serialization magic to prevent "doppelgangers".
90ce3da70b43 Initial load
duke
parents:
diff changeset
   438
    // This is a performance optimization.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   439
    private Object readResolve() {
40944
dba53de83476 6543126: Level.known can leak memory
dfuchs
parents: 36511
diff changeset
   440
        Optional<Level> level = KnownLevel.matches(this);
dba53de83476 6543126: Level.known can leak memory
dfuchs
parents: 36511
diff changeset
   441
        if (level.isPresent()) {
dba53de83476 6543126: Level.known can leak memory
dfuchs
parents: 36511
diff changeset
   442
            return level.get();
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   443
        }
16098
9001e536ab4e 6664509: Add logging context
mchung
parents: 9035
diff changeset
   444
        // Woops.  Whoever sent us this object knows
9001e536ab4e 6664509: Add logging context
mchung
parents: 9035
diff changeset
   445
        // about a new log level.  Add it to our list.
40944
dba53de83476 6543126: Level.known can leak memory
dfuchs
parents: 36511
diff changeset
   446
        return new Level(this.name, this.value, this.resourceBundleName);
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   447
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   448
90ce3da70b43 Initial load
duke
parents:
diff changeset
   449
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   450
     * Parse a level name string into a Level.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   451
     * <p>
90ce3da70b43 Initial load
duke
parents:
diff changeset
   452
     * The argument string may consist of either a level name
90ce3da70b43 Initial load
duke
parents:
diff changeset
   453
     * or an integer value.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   454
     * <p>
90ce3da70b43 Initial load
duke
parents:
diff changeset
   455
     * For example:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   456
     * <ul>
90ce3da70b43 Initial load
duke
parents:
diff changeset
   457
     * <li>     "SEVERE"
90ce3da70b43 Initial load
duke
parents:
diff changeset
   458
     * <li>     "1000"
90ce3da70b43 Initial load
duke
parents:
diff changeset
   459
     * </ul>
16098
9001e536ab4e 6664509: Add logging context
mchung
parents: 9035
diff changeset
   460
     *
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   461
     * @param  name   string to be parsed
90ce3da70b43 Initial load
duke
parents:
diff changeset
   462
     * @throws NullPointerException if the name is null
90ce3da70b43 Initial load
duke
parents:
diff changeset
   463
     * @throws IllegalArgumentException if the value is not valid.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   464
     * Valid values are integers between <CODE>Integer.MIN_VALUE</CODE>
90ce3da70b43 Initial load
duke
parents:
diff changeset
   465
     * and <CODE>Integer.MAX_VALUE</CODE>, and all known level names.
3853
9d2382b74894 6882363: 4/4 typos in java.util.logging javadocs
dcubed
parents: 2
diff changeset
   466
     * Known names are the levels defined by this class (e.g., <CODE>FINE</CODE>,
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   467
     * <CODE>FINER</CODE>, <CODE>FINEST</CODE>), or created by this class with
90ce3da70b43 Initial load
duke
parents:
diff changeset
   468
     * appropriate package access, or new levels defined or created
90ce3da70b43 Initial load
duke
parents:
diff changeset
   469
     * by subclasses.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   470
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   471
     * @return The parsed value. Passing an integer that corresponds to a known name
3853
9d2382b74894 6882363: 4/4 typos in java.util.logging javadocs
dcubed
parents: 2
diff changeset
   472
     * (e.g., 700) will return the associated name (e.g., <CODE>CONFIG</CODE>).
9d2382b74894 6882363: 4/4 typos in java.util.logging javadocs
dcubed
parents: 2
diff changeset
   473
     * Passing an integer that does not (e.g., 1) will return a new level name
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   474
     * initialized to that value.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   475
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   476
    public static synchronized Level parse(String name) throws IllegalArgumentException {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   477
        // Check that name is not null.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   478
        name.length();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   479
40944
dba53de83476 6543126: Level.known can leak memory
dfuchs
parents: 36511
diff changeset
   480
        Optional<Level> level;
16098
9001e536ab4e 6664509: Add logging context
mchung
parents: 9035
diff changeset
   481
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   482
        // Look for a known Level with the given non-localized name.
40944
dba53de83476 6543126: Level.known can leak memory
dfuchs
parents: 36511
diff changeset
   483
        level = KnownLevel.findByName(name, KnownLevel::referent);
dba53de83476 6543126: Level.known can leak memory
dfuchs
parents: 36511
diff changeset
   484
        if (level.isPresent()) {
dba53de83476 6543126: Level.known can leak memory
dfuchs
parents: 36511
diff changeset
   485
            return level.get();
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   486
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   487
90ce3da70b43 Initial load
duke
parents:
diff changeset
   488
        // Now, check if the given name is an integer.  If so,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   489
        // first look for a Level with the given value and then
90ce3da70b43 Initial load
duke
parents:
diff changeset
   490
        // if necessary create one.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   491
        try {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   492
            int x = Integer.parseInt(name);
40944
dba53de83476 6543126: Level.known can leak memory
dfuchs
parents: 36511
diff changeset
   493
            level = KnownLevel.findByValue(x, KnownLevel::referent);
dba53de83476 6543126: Level.known can leak memory
dfuchs
parents: 36511
diff changeset
   494
            if (level.isPresent()) {
dba53de83476 6543126: Level.known can leak memory
dfuchs
parents: 36511
diff changeset
   495
                return level.get();
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   496
            }
40944
dba53de83476 6543126: Level.known can leak memory
dfuchs
parents: 36511
diff changeset
   497
            // add new Level.
dba53de83476 6543126: Level.known can leak memory
dfuchs
parents: 36511
diff changeset
   498
            Level levelObject = new Level(name, x);
dba53de83476 6543126: Level.known can leak memory
dfuchs
parents: 36511
diff changeset
   499
            // There's no need to use a reachability fence here because
dba53de83476 6543126: Level.known can leak memory
dfuchs
parents: 36511
diff changeset
   500
            // KnownLevel keeps a strong reference on the level when
dba53de83476 6543126: Level.known can leak memory
dfuchs
parents: 36511
diff changeset
   501
            // level.getClass() == Level.class.
dba53de83476 6543126: Level.known can leak memory
dfuchs
parents: 36511
diff changeset
   502
            return KnownLevel.findByValue(x, KnownLevel::referent).get();
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   503
        } catch (NumberFormatException ex) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   504
            // Not an integer.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   505
            // Drop through.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   506
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   507
90ce3da70b43 Initial load
duke
parents:
diff changeset
   508
        // Finally, look for a known level with the given localized name,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   509
        // in the current default locale.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   510
        // This is relatively expensive, but not excessively so.
40944
dba53de83476 6543126: Level.known can leak memory
dfuchs
parents: 36511
diff changeset
   511
        level = KnownLevel.findByLocalizedLevelName(name, KnownLevel::referent);
dba53de83476 6543126: Level.known can leak memory
dfuchs
parents: 36511
diff changeset
   512
        if (level .isPresent()) {
dba53de83476 6543126: Level.known can leak memory
dfuchs
parents: 36511
diff changeset
   513
            return level.get();
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   514
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   515
90ce3da70b43 Initial load
duke
parents:
diff changeset
   516
        // OK, we've tried everything and failed
90ce3da70b43 Initial load
duke
parents:
diff changeset
   517
        throw new IllegalArgumentException("Bad level \"" + name + "\"");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   518
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   519
90ce3da70b43 Initial load
duke
parents:
diff changeset
   520
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   521
     * Compare two objects for value equality.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   522
     * @return true if and only if the two objects have the same level value.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   523
     */
19795
6c628e165476 8016127: NLS: logging.properties translatability recommendation
dfuchs
parents: 16098
diff changeset
   524
    @Override
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   525
    public boolean equals(Object ox) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   526
        try {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   527
            Level lx = (Level)ox;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   528
            return (lx.value == this.value);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   529
        } catch (Exception ex) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   530
            return false;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   531
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   532
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   533
90ce3da70b43 Initial load
duke
parents:
diff changeset
   534
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   535
     * Generate a hashcode.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   536
     * @return a hashcode based on the level value
90ce3da70b43 Initial load
duke
parents:
diff changeset
   537
     */
19795
6c628e165476 8016127: NLS: logging.properties translatability recommendation
dfuchs
parents: 16098
diff changeset
   538
    @Override
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   539
    public int hashCode() {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   540
        return this.value;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   541
    }
16098
9001e536ab4e 6664509: Add logging context
mchung
parents: 9035
diff changeset
   542
9001e536ab4e 6664509: Add logging context
mchung
parents: 9035
diff changeset
   543
    // KnownLevel class maintains the global list of all known levels.
9001e536ab4e 6664509: Add logging context
mchung
parents: 9035
diff changeset
   544
    // The API allows multiple custom Level instances of the same name/value
9001e536ab4e 6664509: Add logging context
mchung
parents: 9035
diff changeset
   545
    // be created. This class provides convenient methods to find a level
9001e536ab4e 6664509: Add logging context
mchung
parents: 9035
diff changeset
   546
    // by a given name, by a given value, or by a given localized name.
9001e536ab4e 6664509: Add logging context
mchung
parents: 9035
diff changeset
   547
    //
9001e536ab4e 6664509: Add logging context
mchung
parents: 9035
diff changeset
   548
    // KnownLevel wraps the following Level objects:
9001e536ab4e 6664509: Add logging context
mchung
parents: 9035
diff changeset
   549
    // 1. levelObject:   standard Level object or custom Level object
9001e536ab4e 6664509: Add logging context
mchung
parents: 9035
diff changeset
   550
    // 2. mirroredLevel: Level object representing the level specified in the
9001e536ab4e 6664509: Add logging context
mchung
parents: 9035
diff changeset
   551
    //                   logging configuration.
9001e536ab4e 6664509: Add logging context
mchung
parents: 9035
diff changeset
   552
    //
9001e536ab4e 6664509: Add logging context
mchung
parents: 9035
diff changeset
   553
    // Level.getName, Level.getLocalizedName, Level.getResourceBundleName methods
9001e536ab4e 6664509: Add logging context
mchung
parents: 9035
diff changeset
   554
    // are non-final but the name and resource bundle name are parameters to
9001e536ab4e 6664509: Add logging context
mchung
parents: 9035
diff changeset
   555
    // the Level constructor.  Use the mirroredLevel object instead of the
9001e536ab4e 6664509: Add logging context
mchung
parents: 9035
diff changeset
   556
    // levelObject to prevent the logging framework to execute foreign code
9001e536ab4e 6664509: Add logging context
mchung
parents: 9035
diff changeset
   557
    // implemented by untrusted Level subclass.
9001e536ab4e 6664509: Add logging context
mchung
parents: 9035
diff changeset
   558
    //
9001e536ab4e 6664509: Add logging context
mchung
parents: 9035
diff changeset
   559
    // Implementation Notes:
9001e536ab4e 6664509: Add logging context
mchung
parents: 9035
diff changeset
   560
    // If Level.getName, Level.getLocalizedName, Level.getResourceBundleName methods
9001e536ab4e 6664509: Add logging context
mchung
parents: 9035
diff changeset
   561
    // were final, the following KnownLevel implementation can be removed.
9001e536ab4e 6664509: Add logging context
mchung
parents: 9035
diff changeset
   562
    // Future API change should take this into consideration.
40944
dba53de83476 6543126: Level.known can leak memory
dfuchs
parents: 36511
diff changeset
   563
    static final class KnownLevel extends WeakReference<Level> {
16098
9001e536ab4e 6664509: Add logging context
mchung
parents: 9035
diff changeset
   564
        private static Map<String, List<KnownLevel>> nameToLevels = new HashMap<>();
9001e536ab4e 6664509: Add logging context
mchung
parents: 9035
diff changeset
   565
        private static Map<Integer, List<KnownLevel>> intToLevels = new HashMap<>();
40944
dba53de83476 6543126: Level.known can leak memory
dfuchs
parents: 36511
diff changeset
   566
        private static final ReferenceQueue<Level> QUEUE = new ReferenceQueue<>();
dba53de83476 6543126: Level.known can leak memory
dfuchs
parents: 36511
diff changeset
   567
dba53de83476 6543126: Level.known can leak memory
dfuchs
parents: 36511
diff changeset
   568
        // CUSTOM_LEVEL_CLV is used to register custom level instances with
dba53de83476 6543126: Level.known can leak memory
dfuchs
parents: 36511
diff changeset
   569
        // their defining class loader, so that they are garbage collected
dba53de83476 6543126: Level.known can leak memory
dfuchs
parents: 36511
diff changeset
   570
        // if and only if their class loader is no longer strongly
dba53de83476 6543126: Level.known can leak memory
dfuchs
parents: 36511
diff changeset
   571
        // referenced.
dba53de83476 6543126: Level.known can leak memory
dfuchs
parents: 36511
diff changeset
   572
        private static final ClassLoaderValue<List<Level>> CUSTOM_LEVEL_CLV =
dba53de83476 6543126: Level.known can leak memory
dfuchs
parents: 36511
diff changeset
   573
                    new ClassLoaderValue<>();
dba53de83476 6543126: Level.known can leak memory
dfuchs
parents: 36511
diff changeset
   574
20745
3d2e35965c56 8026027: Level.parse should return the custom Level instance instead of the mirrored Level
mchung
parents: 19795
diff changeset
   575
        final Level mirroredLevel;   // mirror of the custom Level
16098
9001e536ab4e 6664509: Add logging context
mchung
parents: 9035
diff changeset
   576
        KnownLevel(Level l) {
40944
dba53de83476 6543126: Level.known can leak memory
dfuchs
parents: 36511
diff changeset
   577
            super(l, QUEUE);
16098
9001e536ab4e 6664509: Add logging context
mchung
parents: 9035
diff changeset
   578
            if (l.getClass() == Level.class) {
9001e536ab4e 6664509: Add logging context
mchung
parents: 9035
diff changeset
   579
                this.mirroredLevel = l;
9001e536ab4e 6664509: Add logging context
mchung
parents: 9035
diff changeset
   580
            } else {
20745
3d2e35965c56 8026027: Level.parse should return the custom Level instance instead of the mirrored Level
mchung
parents: 19795
diff changeset
   581
                // this mirrored level object is hidden
40944
dba53de83476 6543126: Level.known can leak memory
dfuchs
parents: 36511
diff changeset
   582
                this.mirroredLevel = new Level(l.name, l.value,
dba53de83476 6543126: Level.known can leak memory
dfuchs
parents: 36511
diff changeset
   583
                        l.resourceBundleName, false);
16098
9001e536ab4e 6664509: Add logging context
mchung
parents: 9035
diff changeset
   584
            }
9001e536ab4e 6664509: Add logging context
mchung
parents: 9035
diff changeset
   585
        }
9001e536ab4e 6664509: Add logging context
mchung
parents: 9035
diff changeset
   586
40944
dba53de83476 6543126: Level.known can leak memory
dfuchs
parents: 36511
diff changeset
   587
        Optional<Level> mirrored() {
dba53de83476 6543126: Level.known can leak memory
dfuchs
parents: 36511
diff changeset
   588
            return Optional.of(mirroredLevel);
dba53de83476 6543126: Level.known can leak memory
dfuchs
parents: 36511
diff changeset
   589
        }
dba53de83476 6543126: Level.known can leak memory
dfuchs
parents: 36511
diff changeset
   590
dba53de83476 6543126: Level.known can leak memory
dfuchs
parents: 36511
diff changeset
   591
        Optional<Level> referent() {
dba53de83476 6543126: Level.known can leak memory
dfuchs
parents: 36511
diff changeset
   592
            return Optional.ofNullable(get());
dba53de83476 6543126: Level.known can leak memory
dfuchs
parents: 36511
diff changeset
   593
        }
dba53de83476 6543126: Level.known can leak memory
dfuchs
parents: 36511
diff changeset
   594
dba53de83476 6543126: Level.known can leak memory
dfuchs
parents: 36511
diff changeset
   595
        private void remove() {
dba53de83476 6543126: Level.known can leak memory
dfuchs
parents: 36511
diff changeset
   596
            Optional.ofNullable(nameToLevels.get(mirroredLevel.name))
dba53de83476 6543126: Level.known can leak memory
dfuchs
parents: 36511
diff changeset
   597
                    .ifPresent((x) -> x.remove(this));
dba53de83476 6543126: Level.known can leak memory
dfuchs
parents: 36511
diff changeset
   598
            Optional.ofNullable(intToLevels.get(mirroredLevel.value))
dba53de83476 6543126: Level.known can leak memory
dfuchs
parents: 36511
diff changeset
   599
                    .ifPresent((x) -> x.remove(this));
dba53de83476 6543126: Level.known can leak memory
dfuchs
parents: 36511
diff changeset
   600
        }
dba53de83476 6543126: Level.known can leak memory
dfuchs
parents: 36511
diff changeset
   601
dba53de83476 6543126: Level.known can leak memory
dfuchs
parents: 36511
diff changeset
   602
        // Remove all stale KnownLevel instances
dba53de83476 6543126: Level.known can leak memory
dfuchs
parents: 36511
diff changeset
   603
        static synchronized void purge() {
dba53de83476 6543126: Level.known can leak memory
dfuchs
parents: 36511
diff changeset
   604
            Reference<? extends Level> ref;
dba53de83476 6543126: Level.known can leak memory
dfuchs
parents: 36511
diff changeset
   605
            while ((ref = QUEUE.poll()) != null) {
dba53de83476 6543126: Level.known can leak memory
dfuchs
parents: 36511
diff changeset
   606
                if (ref instanceof KnownLevel) {
dba53de83476 6543126: Level.known can leak memory
dfuchs
parents: 36511
diff changeset
   607
                    ((KnownLevel)ref).remove();
dba53de83476 6543126: Level.known can leak memory
dfuchs
parents: 36511
diff changeset
   608
                }
dba53de83476 6543126: Level.known can leak memory
dfuchs
parents: 36511
diff changeset
   609
            }
dba53de83476 6543126: Level.known can leak memory
dfuchs
parents: 36511
diff changeset
   610
        }
dba53de83476 6543126: Level.known can leak memory
dfuchs
parents: 36511
diff changeset
   611
dba53de83476 6543126: Level.known can leak memory
dfuchs
parents: 36511
diff changeset
   612
        private static void registerWithClassLoader(Level customLevel) {
51532
5f40be158613 8209987: Minor cleanup in Level.java
dfuchs
parents: 48226
diff changeset
   613
            PrivilegedAction<ClassLoader> pa = customLevel.getClass()::getClassLoader;
40944
dba53de83476 6543126: Level.known can leak memory
dfuchs
parents: 36511
diff changeset
   614
            final ClassLoader cl = AccessController.doPrivileged(pa);
dba53de83476 6543126: Level.known can leak memory
dfuchs
parents: 36511
diff changeset
   615
            CUSTOM_LEVEL_CLV.computeIfAbsent(cl, (c, v) -> new ArrayList<>())
dba53de83476 6543126: Level.known can leak memory
dfuchs
parents: 36511
diff changeset
   616
                .add(customLevel);
dba53de83476 6543126: Level.known can leak memory
dfuchs
parents: 36511
diff changeset
   617
        }
dba53de83476 6543126: Level.known can leak memory
dfuchs
parents: 36511
diff changeset
   618
16098
9001e536ab4e 6664509: Add logging context
mchung
parents: 9035
diff changeset
   619
        static synchronized void add(Level l) {
40944
dba53de83476 6543126: Level.known can leak memory
dfuchs
parents: 36511
diff changeset
   620
            purge();
16098
9001e536ab4e 6664509: Add logging context
mchung
parents: 9035
diff changeset
   621
            // the mirroredLevel object is always added to the list
9001e536ab4e 6664509: Add logging context
mchung
parents: 9035
diff changeset
   622
            // before the custom Level instance
9001e536ab4e 6664509: Add logging context
mchung
parents: 9035
diff changeset
   623
            KnownLevel o = new KnownLevel(l);
51532
5f40be158613 8209987: Minor cleanup in Level.java
dfuchs
parents: 48226
diff changeset
   624
            nameToLevels.computeIfAbsent(l.name, (k) -> new ArrayList<>())
5f40be158613 8209987: Minor cleanup in Level.java
dfuchs
parents: 48226
diff changeset
   625
                .add(o);
5f40be158613 8209987: Minor cleanup in Level.java
dfuchs
parents: 48226
diff changeset
   626
            intToLevels.computeIfAbsent(l.value, (k) -> new ArrayList<>())
5f40be158613 8209987: Minor cleanup in Level.java
dfuchs
parents: 48226
diff changeset
   627
                .add(o);
40944
dba53de83476 6543126: Level.known can leak memory
dfuchs
parents: 36511
diff changeset
   628
dba53de83476 6543126: Level.known can leak memory
dfuchs
parents: 36511
diff changeset
   629
            // keep the custom level reachable from its class loader
dba53de83476 6543126: Level.known can leak memory
dfuchs
parents: 36511
diff changeset
   630
            // This will ensure that custom level values are not GC'ed
dba53de83476 6543126: Level.known can leak memory
dfuchs
parents: 36511
diff changeset
   631
            // until there class loader is GC'ed.
dba53de83476 6543126: Level.known can leak memory
dfuchs
parents: 36511
diff changeset
   632
            if (o.mirroredLevel != l) {
dba53de83476 6543126: Level.known can leak memory
dfuchs
parents: 36511
diff changeset
   633
                registerWithClassLoader(l);
dba53de83476 6543126: Level.known can leak memory
dfuchs
parents: 36511
diff changeset
   634
            }
dba53de83476 6543126: Level.known can leak memory
dfuchs
parents: 36511
diff changeset
   635
16098
9001e536ab4e 6664509: Add logging context
mchung
parents: 9035
diff changeset
   636
        }
9001e536ab4e 6664509: Add logging context
mchung
parents: 9035
diff changeset
   637
9001e536ab4e 6664509: Add logging context
mchung
parents: 9035
diff changeset
   638
        // Returns a KnownLevel with the given non-localized name.
40944
dba53de83476 6543126: Level.known can leak memory
dfuchs
parents: 36511
diff changeset
   639
        static synchronized Optional<Level> findByName(String name,
dba53de83476 6543126: Level.known can leak memory
dfuchs
parents: 36511
diff changeset
   640
                Function<KnownLevel, Optional<Level>> selector) {
dba53de83476 6543126: Level.known can leak memory
dfuchs
parents: 36511
diff changeset
   641
            purge();
dba53de83476 6543126: Level.known can leak memory
dfuchs
parents: 36511
diff changeset
   642
            return nameToLevels.getOrDefault(name, Collections.emptyList())
dba53de83476 6543126: Level.known can leak memory
dfuchs
parents: 36511
diff changeset
   643
                        .stream()
dba53de83476 6543126: Level.known can leak memory
dfuchs
parents: 36511
diff changeset
   644
                        .map(selector)
dba53de83476 6543126: Level.known can leak memory
dfuchs
parents: 36511
diff changeset
   645
                        .flatMap(Optional::stream)
dba53de83476 6543126: Level.known can leak memory
dfuchs
parents: 36511
diff changeset
   646
                        .findFirst();
16098
9001e536ab4e 6664509: Add logging context
mchung
parents: 9035
diff changeset
   647
        }
9001e536ab4e 6664509: Add logging context
mchung
parents: 9035
diff changeset
   648
9001e536ab4e 6664509: Add logging context
mchung
parents: 9035
diff changeset
   649
        // Returns a KnownLevel with the given value.
40944
dba53de83476 6543126: Level.known can leak memory
dfuchs
parents: 36511
diff changeset
   650
        static synchronized Optional<Level> findByValue(int value,
dba53de83476 6543126: Level.known can leak memory
dfuchs
parents: 36511
diff changeset
   651
                Function<KnownLevel, Optional<Level>> selector) {
dba53de83476 6543126: Level.known can leak memory
dfuchs
parents: 36511
diff changeset
   652
            purge();
dba53de83476 6543126: Level.known can leak memory
dfuchs
parents: 36511
diff changeset
   653
            return intToLevels.getOrDefault(value, Collections.emptyList())
dba53de83476 6543126: Level.known can leak memory
dfuchs
parents: 36511
diff changeset
   654
                        .stream()
dba53de83476 6543126: Level.known can leak memory
dfuchs
parents: 36511
diff changeset
   655
                        .map(selector)
dba53de83476 6543126: Level.known can leak memory
dfuchs
parents: 36511
diff changeset
   656
                        .flatMap(Optional::stream)
dba53de83476 6543126: Level.known can leak memory
dfuchs
parents: 36511
diff changeset
   657
                        .findFirst();
16098
9001e536ab4e 6664509: Add logging context
mchung
parents: 9035
diff changeset
   658
        }
9001e536ab4e 6664509: Add logging context
mchung
parents: 9035
diff changeset
   659
9001e536ab4e 6664509: Add logging context
mchung
parents: 9035
diff changeset
   660
        // Returns a KnownLevel with the given localized name matching
9001e536ab4e 6664509: Add logging context
mchung
parents: 9035
diff changeset
   661
        // by calling the Level.getLocalizedLevelName() method (i.e. found
9001e536ab4e 6664509: Add logging context
mchung
parents: 9035
diff changeset
   662
        // from the resourceBundle associated with the Level object).
9001e536ab4e 6664509: Add logging context
mchung
parents: 9035
diff changeset
   663
        // This method does not call Level.getLocalizedName() that may
9001e536ab4e 6664509: Add logging context
mchung
parents: 9035
diff changeset
   664
        // be overridden in a subclass implementation
40944
dba53de83476 6543126: Level.known can leak memory
dfuchs
parents: 36511
diff changeset
   665
        static synchronized Optional<Level> findByLocalizedLevelName(String name,
dba53de83476 6543126: Level.known can leak memory
dfuchs
parents: 36511
diff changeset
   666
                Function<KnownLevel, Optional<Level>> selector) {
dba53de83476 6543126: Level.known can leak memory
dfuchs
parents: 36511
diff changeset
   667
            purge();
dba53de83476 6543126: Level.known can leak memory
dfuchs
parents: 36511
diff changeset
   668
            return nameToLevels.values().stream()
dba53de83476 6543126: Level.known can leak memory
dfuchs
parents: 36511
diff changeset
   669
                         .flatMap(List::stream)
dba53de83476 6543126: Level.known can leak memory
dfuchs
parents: 36511
diff changeset
   670
                         .map(selector)
dba53de83476 6543126: Level.known can leak memory
dfuchs
parents: 36511
diff changeset
   671
                         .flatMap(Optional::stream)
dba53de83476 6543126: Level.known can leak memory
dfuchs
parents: 36511
diff changeset
   672
                         .filter(l -> name.equals(l.getLocalizedLevelName()))
dba53de83476 6543126: Level.known can leak memory
dfuchs
parents: 36511
diff changeset
   673
                         .findFirst();
16098
9001e536ab4e 6664509: Add logging context
mchung
parents: 9035
diff changeset
   674
        }
9001e536ab4e 6664509: Add logging context
mchung
parents: 9035
diff changeset
   675
40944
dba53de83476 6543126: Level.known can leak memory
dfuchs
parents: 36511
diff changeset
   676
        static synchronized Optional<Level> matches(Level l) {
dba53de83476 6543126: Level.known can leak memory
dfuchs
parents: 36511
diff changeset
   677
            purge();
16098
9001e536ab4e 6664509: Add logging context
mchung
parents: 9035
diff changeset
   678
            List<KnownLevel> list = nameToLevels.get(l.name);
9001e536ab4e 6664509: Add logging context
mchung
parents: 9035
diff changeset
   679
            if (list != null) {
40944
dba53de83476 6543126: Level.known can leak memory
dfuchs
parents: 36511
diff changeset
   680
                for (KnownLevel ref : list) {
dba53de83476 6543126: Level.known can leak memory
dfuchs
parents: 36511
diff changeset
   681
                    Level levelObject = ref.get();
dba53de83476 6543126: Level.known can leak memory
dfuchs
parents: 36511
diff changeset
   682
                    if (levelObject == null) continue;
dba53de83476 6543126: Level.known can leak memory
dfuchs
parents: 36511
diff changeset
   683
                    Level other = ref.mirroredLevel;
43197
883675f526b8 8162577: Standardize logging levels
dfuchs
parents: 42462
diff changeset
   684
                    Class<? extends Level> type = levelObject.getClass();
16098
9001e536ab4e 6664509: Add logging context
mchung
parents: 9035
diff changeset
   685
                    if (l.value == other.value &&
9001e536ab4e 6664509: Add logging context
mchung
parents: 9035
diff changeset
   686
                           (l.resourceBundleName == other.resourceBundleName ||
9001e536ab4e 6664509: Add logging context
mchung
parents: 9035
diff changeset
   687
                               (l.resourceBundleName != null &&
9001e536ab4e 6664509: Add logging context
mchung
parents: 9035
diff changeset
   688
                                l.resourceBundleName.equals(other.resourceBundleName)))) {
43197
883675f526b8 8162577: Standardize logging levels
dfuchs
parents: 42462
diff changeset
   689
                        if (type == l.getClass()) {
883675f526b8 8162577: Standardize logging levels
dfuchs
parents: 42462
diff changeset
   690
                            return Optional.of(levelObject);
883675f526b8 8162577: Standardize logging levels
dfuchs
parents: 42462
diff changeset
   691
                        }
16098
9001e536ab4e 6664509: Add logging context
mchung
parents: 9035
diff changeset
   692
                    }
9001e536ab4e 6664509: Add logging context
mchung
parents: 9035
diff changeset
   693
                }
9001e536ab4e 6664509: Add logging context
mchung
parents: 9035
diff changeset
   694
            }
40944
dba53de83476 6543126: Level.known can leak memory
dfuchs
parents: 36511
diff changeset
   695
            return Optional.empty();
16098
9001e536ab4e 6664509: Add logging context
mchung
parents: 9035
diff changeset
   696
        }
9001e536ab4e 6664509: Add logging context
mchung
parents: 9035
diff changeset
   697
    }
9001e536ab4e 6664509: Add logging context
mchung
parents: 9035
diff changeset
   698
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   699
}