151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski/* 251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Copyright (c) 2000, 2010, Oracle and/or its affiliates. All rights reserved. 351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * 551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * This code is free software; you can redistribute it and/or modify it 651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * under the terms of the GNU General Public License version 2 only, as 751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * published by the Free Software Foundation. Oracle designates this 851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * particular file as subject to the "Classpath" exception as provided 951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * by Oracle in the LICENSE file that accompanied this code. 1051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * 1151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * This code is distributed in the hope that it will be useful, but WITHOUT 1251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 1351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 1451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * version 2 for more details (a copy is included in the LICENSE file that 1551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * accompanied this code). 1651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * 1751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * You should have received a copy of the GNU General Public License version 1851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * 2 along with this work; if not, write to the Free Software Foundation, 1951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 2051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * 2151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 2251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * or visit www.oracle.com if you need additional information or have any 2351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * questions. 2451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 2551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 2651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebskipackage java.util.logging; 2751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebskiimport java.util.ArrayList; 2851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebskiimport java.util.HashMap; 2951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebskiimport java.util.List; 30ed0a7b5290c302f8c58fdb3fb4ed8df5e0d32bd4Shubham Ajmeraimport java.util.Locale; 3151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebskiimport java.util.Map; 32ed0a7b5290c302f8c58fdb3fb4ed8df5e0d32bd4Shubham Ajmeraimport java.util.MissingResourceException; 3351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebskiimport java.util.ResourceBundle; 3451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 35ed0a7b5290c302f8c58fdb3fb4ed8df5e0d32bd4Shubham Ajmeraimport dalvik.system.VMStack; 36ed0a7b5290c302f8c58fdb3fb4ed8df5e0d32bd4Shubham Ajmera 3751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski/** 3851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * The Level class defines a set of standard logging levels that 3951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * can be used to control logging output. The logging Level objects 4051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * are ordered and are specified by ordered integers. Enabling logging 4151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * at a given level also enables logging at all higher levels. 4251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * <p> 4351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Clients should normally use the predefined Level constants such 4451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * as Level.SEVERE. 4551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * <p> 4651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * The levels in descending order are: 4751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * <ul> 4851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * <li>SEVERE (highest value) 4951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * <li>WARNING 5051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * <li>INFO 5151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * <li>CONFIG 5251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * <li>FINE 5351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * <li>FINER 5451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * <li>FINEST (lowest value) 5551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * </ul> 5651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * In addition there is a level OFF that can be used to turn 5751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * off logging, and a level ALL that can be used to enable 5851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * logging of all messages. 5951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * <p> 6051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * It is possible for third parties to define additional logging 6151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * levels by subclassing Level. In such cases subclasses should 6251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * take care to chose unique integer level values and to ensure that 6351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * they maintain the Object uniqueness property across serialization 6451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * by defining a suitable readResolve method. 6551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * 6651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @since 1.4 6751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 6851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 6951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebskipublic class Level implements java.io.Serializable { 7051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski private static String defaultBundle = "sun.util.logging.resources.logging"; 7151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 7251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /** 7351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @serial The non-localized name of the level. 7451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 7551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski private final String name; 7651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 7751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /** 7851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @serial The integer value of the level. 7951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 8051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski private final int value; 8151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 8251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /** 8351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @serial The resource bundle name to be used in localizing the level name. 8451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 8551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski private final String resourceBundleName; 8651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 8751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // localized level name 8851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski private String localizedLevelName; 8951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 90ed0a7b5290c302f8c58fdb3fb4ed8df5e0d32bd4Shubham Ajmera private transient ResourceBundle rb; 91ed0a7b5290c302f8c58fdb3fb4ed8df5e0d32bd4Shubham Ajmera 9251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /** 9351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * OFF is a special level that can be used to turn off logging. 9451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * This level is initialized to <CODE>Integer.MAX_VALUE</CODE>. 9551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 9651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski public static final Level OFF = new Level("OFF",Integer.MAX_VALUE, defaultBundle); 9751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 9851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /** 9951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * SEVERE is a message level indicating a serious failure. 10051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * <p> 10151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * In general SEVERE messages should describe events that are 10251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * of considerable importance and which will prevent normal 10351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * program execution. They should be reasonably intelligible 10451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * to end users and to system administrators. 10551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * This level is initialized to <CODE>1000</CODE>. 10651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 10751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski public static final Level SEVERE = new Level("SEVERE",1000, defaultBundle); 10851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 10951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /** 11051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * WARNING is a message level indicating a potential problem. 11151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * <p> 11251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * In general WARNING messages should describe events that will 11351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * be of interest to end users or system managers, or which 11451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * indicate potential problems. 11551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * This level is initialized to <CODE>900</CODE>. 11651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 11751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski public static final Level WARNING = new Level("WARNING", 900, defaultBundle); 11851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 11951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /** 12051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * INFO is a message level for informational messages. 12151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * <p> 12251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Typically INFO messages will be written to the console 12351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * or its equivalent. So the INFO level should only be 12451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * used for reasonably significant messages that will 12551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * make sense to end users and system administrators. 12651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * This level is initialized to <CODE>800</CODE>. 12751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 12851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski public static final Level INFO = new Level("INFO", 800, defaultBundle); 12951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 13051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /** 13151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * CONFIG is a message level for static configuration messages. 13251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * <p> 13351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * CONFIG messages are intended to provide a variety of static 13451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * configuration information, to assist in debugging problems 13551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * that may be associated with particular configurations. 13651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * For example, CONFIG message might include the CPU type, 13751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * the graphics depth, the GUI look-and-feel, etc. 13851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * This level is initialized to <CODE>700</CODE>. 13951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 14051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski public static final Level CONFIG = new Level("CONFIG", 700, defaultBundle); 14151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 14251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /** 14351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * FINE is a message level providing tracing information. 14451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * <p> 14551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * All of FINE, FINER, and FINEST are intended for relatively 14651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * detailed tracing. The exact meaning of the three levels will 14751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * vary between subsystems, but in general, FINEST should be used 14851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * for the most voluminous detailed output, FINER for somewhat 14951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * less detailed output, and FINE for the lowest volume (and 15051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * most important) messages. 15151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * <p> 15251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * In general the FINE level should be used for information 15351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * that will be broadly interesting to developers who do not have 15451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * a specialized interest in the specific subsystem. 15551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * <p> 15651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * FINE messages might include things like minor (recoverable) 15751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * failures. Issues indicating potential performance problems 15851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * are also worth logging as FINE. 15951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * This level is initialized to <CODE>500</CODE>. 16051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 16151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski public static final Level FINE = new Level("FINE", 500, defaultBundle); 16251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 16351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /** 16451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * FINER indicates a fairly detailed tracing message. 16551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * By default logging calls for entering, returning, or throwing 16651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * an exception are traced at this level. 16751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * This level is initialized to <CODE>400</CODE>. 16851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 16951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski public static final Level FINER = new Level("FINER", 400, defaultBundle); 17051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 17151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /** 17251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * FINEST indicates a highly detailed tracing message. 17351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * This level is initialized to <CODE>300</CODE>. 17451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 17551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski public static final Level FINEST = new Level("FINEST", 300, defaultBundle); 17651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 17751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /** 17851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * ALL indicates that all messages should be logged. 17951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * This level is initialized to <CODE>Integer.MIN_VALUE</CODE>. 18051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 18151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski public static final Level ALL = new Level("ALL", Integer.MIN_VALUE, defaultBundle); 18251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 18351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /** 18451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Create a named Level with a given integer value. 18551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * <p> 18651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Note that this constructor is "protected" to allow subclassing. 18751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * In general clients of logging should use one of the constant Level 18851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * objects such as SEVERE or FINEST. However, if clients need to 18951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * add new logging levels, they may subclass Level and define new 19051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * constants. 19151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @param name the name of the Level, for example "SEVERE". 19251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @param value an integer value for the level. 19351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @throws NullPointerException if the name is null 19451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 19551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski protected Level(String name, int value) { 19651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski this(name, value, null); 19751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 19851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 19951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /** 20051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Create a named Level with a given integer value and a 20151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * given localization resource name. 20251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * <p> 20351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @param name the name of the Level, for example "SEVERE". 20451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @param value an integer value for the level. 20551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @param resourceBundleName name of a resource bundle to use in 20651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * localizing the given name. If the resourceBundleName is null 20751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * or an empty string, it is ignored. 20851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @throws NullPointerException if the name is null 20951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 21051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski protected Level(String name, int value, String resourceBundleName) { 21151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (name == null) { 21251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski throw new NullPointerException(); 21351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 21451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski this.name = name; 21551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski this.value = value; 21651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski this.resourceBundleName = resourceBundleName; 217ed0a7b5290c302f8c58fdb3fb4ed8df5e0d32bd4Shubham Ajmera if (resourceBundleName != null) { 218ed0a7b5290c302f8c58fdb3fb4ed8df5e0d32bd4Shubham Ajmera try { 219ed0a7b5290c302f8c58fdb3fb4ed8df5e0d32bd4Shubham Ajmera ClassLoader cl = VMStack.getCallingClassLoader(); 220ed0a7b5290c302f8c58fdb3fb4ed8df5e0d32bd4Shubham Ajmera if (cl != null) { 221ed0a7b5290c302f8c58fdb3fb4ed8df5e0d32bd4Shubham Ajmera rb = ResourceBundle.getBundle(resourceBundleName, Locale.getDefault(), cl); 222ed0a7b5290c302f8c58fdb3fb4ed8df5e0d32bd4Shubham Ajmera } else { 223ed0a7b5290c302f8c58fdb3fb4ed8df5e0d32bd4Shubham Ajmera rb = ResourceBundle.getBundle(resourceBundleName); 224ed0a7b5290c302f8c58fdb3fb4ed8df5e0d32bd4Shubham Ajmera } 225ed0a7b5290c302f8c58fdb3fb4ed8df5e0d32bd4Shubham Ajmera } catch (MissingResourceException ex) { 226ed0a7b5290c302f8c58fdb3fb4ed8df5e0d32bd4Shubham Ajmera rb = null; 227ed0a7b5290c302f8c58fdb3fb4ed8df5e0d32bd4Shubham Ajmera } 228ed0a7b5290c302f8c58fdb3fb4ed8df5e0d32bd4Shubham Ajmera } 22951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski this.localizedLevelName = resourceBundleName == null ? name : null; 23051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski KnownLevel.add(this); 23151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 23251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 23351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /** 23451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Return the level's localization resource bundle name, or 23551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * null if no localization bundle is defined. 23651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * 23751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @return localization resource bundle name 23851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 23951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski public String getResourceBundleName() { 24051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return resourceBundleName; 24151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 24251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 24351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /** 24451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Return the non-localized string name of the Level. 24551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * 24651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @return non-localized name 24751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 24851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski public String getName() { 24951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return name; 25051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 25151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 25251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /** 25351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Return the localized string name of the Level, for 25451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * the current default locale. 25551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * <p> 25651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * If no localization information is available, the 25751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * non-localized name is returned. 25851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * 25951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @return localized name 26051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 26151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski public String getLocalizedName() { 26251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return getLocalizedLevelName(); 26351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 26451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 26551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // package-private getLevelName() is used by the implementation 26651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // instead of getName() to avoid calling the subclass's version 26751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski final String getLevelName() { 26851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return this.name; 26951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 27051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 27151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski final synchronized String getLocalizedLevelName() { 27251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (localizedLevelName != null) { 27351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return localizedLevelName; 27451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 27551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 27651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski try { 27751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski localizedLevelName = rb.getString(name); 27851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } catch (Exception ex) { 27951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski localizedLevelName = name; 28051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 28151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return localizedLevelName; 28251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 28351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 28451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // Returns a mirrored Level object that matches the given name as 28551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // specified in the Level.parse method. Returns null if not found. 28651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // 28751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // It returns the same Level object as the one returned by Level.parse 28851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // method if the given name is a non-localized name or integer. 28951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // 29051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // If the name is a localized name, findLevel and parse method may 29151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // return a different level value if there is a custom Level subclass 29251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // that overrides Level.getLocalizedName() to return a different string 29351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // than what's returned by the default implementation. 29451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // 29551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski static Level findLevel(String name) { 29651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (name == null) { 29751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski throw new NullPointerException(); 29851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 29951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 30051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski KnownLevel level; 30151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 30251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // Look for a known Level with the given non-localized name. 30351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski level = KnownLevel.findByName(name); 30451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (level != null) { 30551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return level.mirroredLevel; 30651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 30751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 30851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // Now, check if the given name is an integer. If so, 30951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // first look for a Level with the given value and then 31051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // if necessary create one. 31151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski try { 31251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski int x = Integer.parseInt(name); 31351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski level = KnownLevel.findByValue(x); 31451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (level == null) { 31551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // add new Level 31651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski Level levelObject = new Level(name, x); 31751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski level = KnownLevel.findByValue(x); 31851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 31951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return level.mirroredLevel; 32051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } catch (NumberFormatException ex) { 32151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // Not an integer. 32251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // Drop through. 32351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 32451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 32551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski level = KnownLevel.findByLocalizedLevelName(name); 32651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (level != null) { 32751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return level.mirroredLevel; 32851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 32951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 33051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return null; 33151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 33251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 33351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /** 33451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Returns a string representation of this Level. 33551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * 33651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @return the non-localized name of the Level, for example "INFO". 33751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 33851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski public final String toString() { 33951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return name; 34051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 34151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 34251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /** 34351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Get the integer value for this level. This integer value 34451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * can be used for efficient ordering comparisons between 34551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Level objects. 34651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @return the integer value for this level. 34751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 34851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski public final int intValue() { 34951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return value; 35051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 35151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 35251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski private static final long serialVersionUID = -8176160795706313070L; 35351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 35451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // Serialization magic to prevent "doppelgangers". 35551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // This is a performance optimization. 35651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski private Object readResolve() { 35751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski KnownLevel o = KnownLevel.matches(this); 35851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (o != null) { 35951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return o.levelObject; 36051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 36151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 36251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // Woops. Whoever sent us this object knows 36351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // about a new log level. Add it to our list. 36451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski Level level = new Level(this.name, this.value, this.resourceBundleName); 36551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return level; 36651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 36751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 36851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /** 36951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Parse a level name string into a Level. 37051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * <p> 37151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * The argument string may consist of either a level name 37251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * or an integer value. 37351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * <p> 37451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * For example: 37551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * <ul> 37651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * <li> "SEVERE" 37751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * <li> "1000" 37851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * </ul> 37951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * 38051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @param name string to be parsed 38151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @throws NullPointerException if the name is null 38251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @throws IllegalArgumentException if the value is not valid. 38351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Valid values are integers between <CODE>Integer.MIN_VALUE</CODE> 38451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * and <CODE>Integer.MAX_VALUE</CODE>, and all known level names. 38551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Known names are the levels defined by this class (e.g., <CODE>FINE</CODE>, 38651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * <CODE>FINER</CODE>, <CODE>FINEST</CODE>), or created by this class with 38751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * appropriate package access, or new levels defined or created 38851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * by subclasses. 38951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * 39051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @return The parsed value. Passing an integer that corresponds to a known name 39151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * (e.g., 700) will return the associated name (e.g., <CODE>CONFIG</CODE>). 39251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Passing an integer that does not (e.g., 1) will return a new level name 39351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * initialized to that value. 39451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 39551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski public static synchronized Level parse(String name) throws IllegalArgumentException { 39651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // Check that name is not null. 39751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski name.length(); 39851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 39951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski KnownLevel level; 40051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 40151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // Look for a known Level with the given non-localized name. 40251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski level = KnownLevel.findByName(name); 40351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (level != null) { 40451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return level.levelObject; 40551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 40651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 40751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // Now, check if the given name is an integer. If so, 40851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // first look for a Level with the given value and then 40951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // if necessary create one. 41051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski try { 41151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski int x = Integer.parseInt(name); 41251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski level = KnownLevel.findByValue(x); 41351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (level == null) { 41451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // add new Level 41551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski Level levelObject = new Level(name, x); 41651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski level = KnownLevel.findByValue(x); 41751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 41851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return level.levelObject; 41951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } catch (NumberFormatException ex) { 42051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // Not an integer. 42151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // Drop through. 42251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 42351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 42451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // Finally, look for a known level with the given localized name, 42551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // in the current default locale. 42651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // This is relatively expensive, but not excessively so. 42751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski level = KnownLevel.findByLocalizedName(name); 42851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (level != null) { 42951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return level.levelObject; 43051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 43151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 43251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // OK, we've tried everything and failed 43351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski throw new IllegalArgumentException("Bad level \"" + name + "\""); 43451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 43551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 43651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /** 43751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Compare two objects for value equality. 43851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @return true if and only if the two objects have the same level value. 43951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 44051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski public boolean equals(Object ox) { 44151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski try { 44251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski Level lx = (Level)ox; 44351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return (lx.value == this.value); 44451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } catch (Exception ex) { 44551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return false; 44651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 44751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 44851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 44951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /** 45051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Generate a hashcode. 45151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @return a hashcode based on the level value 45251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 45351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski public int hashCode() { 45451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return this.value; 45551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 45651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 45751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // KnownLevel class maintains the global list of all known levels. 45851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // The API allows multiple custom Level instances of the same name/value 45951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // be created. This class provides convenient methods to find a level 46051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // by a given name, by a given value, or by a given localized name. 46151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // 46251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // KnownLevel wraps the following Level objects: 46351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // 1. levelObject: standard Level object or custom Level object 46451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // 2. mirroredLevel: Level object representing the level specified in the 46551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // logging configuration. 46651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // 46751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // Level.getName, Level.getLocalizedName, Level.getResourceBundleName methods 46851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // are non-final but the name and resource bundle name are parameters to 46951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // the Level constructor. Use the mirroredLevel object instead of the 47051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // levelObject to prevent the logging framework to execute foreign code 47151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // implemented by untrusted Level subclass. 47251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // 47351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // Implementation Notes: 47451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // If Level.getName, Level.getLocalizedName, Level.getResourceBundleName methods 47551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // were final, the following KnownLevel implementation can be removed. 47651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // Future API change should take this into consideration. 47751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski static final class KnownLevel { 47851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski private static Map<String, List<KnownLevel>> nameToLevels = new HashMap<>(); 47951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski private static Map<Integer, List<KnownLevel>> intToLevels = new HashMap<>(); 48051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski final Level levelObject; // instance of Level class or Level subclass 48151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski final Level mirroredLevel; // instance of Level class 48251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski KnownLevel(Level l) { 48351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski this.levelObject = l; 48451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (l.getClass() == Level.class) { 48551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski this.mirroredLevel = l; 48651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } else { 48751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski this.mirroredLevel = new Level(l.name, l.value, l.resourceBundleName); 48851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 48951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 49051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 49151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski static synchronized void add(Level l) { 49251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // the mirroredLevel object is always added to the list 49351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // before the custom Level instance 49451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski KnownLevel o = new KnownLevel(l); 49551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski List<KnownLevel> list = nameToLevels.get(l.name); 49651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (list == null) { 49751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski list = new ArrayList<>(); 49851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski nameToLevels.put(l.name, list); 49951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 50051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski list.add(o); 50151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 50251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski list = intToLevels.get(l.value); 50351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (list == null) { 50451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski list = new ArrayList<>(); 50551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski intToLevels.put(l.value, list); 50651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 50751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski list.add(o); 50851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 50951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 51051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // Returns a KnownLevel with the given non-localized name. 51151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski static synchronized KnownLevel findByName(String name) { 51251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski List<KnownLevel> list = nameToLevels.get(name); 51351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (list != null) { 51451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return list.get(0); 51551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 51651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return null; 51751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 51851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 51951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // Returns a KnownLevel with the given value. 52051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski static synchronized KnownLevel findByValue(int value) { 52151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski List<KnownLevel> list = intToLevels.get(value); 52251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (list != null) { 52351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return list.get(0); 52451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 52551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return null; 52651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 52751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 52851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // Returns a KnownLevel with the given localized name matching 52951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // by calling the Level.getLocalizedLevelName() method (i.e. found 53051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // from the resourceBundle associated with the Level object). 53151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // This method does not call Level.getLocalizedName() that may 53251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // be overridden in a subclass implementation 53351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski static synchronized KnownLevel findByLocalizedLevelName(String name) { 53451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski for (List<KnownLevel> levels : nameToLevels.values()) { 53551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski for (KnownLevel l : levels) { 53651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski String lname = l.levelObject.getLocalizedLevelName(); 53751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (name.equals(lname)) { 53851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return l; 53951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 54051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 54151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 54251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return null; 54351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 54451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 54551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // Returns a KnownLevel with the given localized name matching 54651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // by calling the Level.getLocalizedName() method 54751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski static synchronized KnownLevel findByLocalizedName(String name) { 54851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski for (List<KnownLevel> levels : nameToLevels.values()) { 54951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski for (KnownLevel l : levels) { 55051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski String lname = l.levelObject.getLocalizedName(); 55151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (name.equals(lname)) { 55251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return l; 55351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 55451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 55551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 55651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return null; 55751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 55851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 55951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski static synchronized KnownLevel matches(Level l) { 56051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski List<KnownLevel> list = nameToLevels.get(l.name); 56151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (list != null) { 56251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski for (KnownLevel level : list) { 56351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski Level other = level.mirroredLevel; 56451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (l.value == other.value && 56551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski (l.resourceBundleName == other.resourceBundleName || 56651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski (l.resourceBundleName != null && 56751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski l.resourceBundleName.equals(other.resourceBundleName)))) { 56851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return level; 56951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 57051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 57151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 57251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return null; 57351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 57451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 57551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 57651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski} 577