emul/compact/src/main/java/java/util/logging/Level.java
branchjdk7-b147
changeset 1258 724f3e1ea53e
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/emul/compact/src/main/java/java/util/logging/Level.java	Sat Sep 07 13:51:24 2013 +0200
     1.3 @@ -0,0 +1,378 @@
     1.4 +/*
     1.5 + * Copyright (c) 2000, 2010, Oracle and/or its affiliates. All rights reserved.
     1.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
     1.7 + *
     1.8 + * This code is free software; you can redistribute it and/or modify it
     1.9 + * under the terms of the GNU General Public License version 2 only, as
    1.10 + * published by the Free Software Foundation.  Oracle designates this
    1.11 + * particular file as subject to the "Classpath" exception as provided
    1.12 + * by Oracle in the LICENSE file that accompanied this code.
    1.13 + *
    1.14 + * This code is distributed in the hope that it will be useful, but WITHOUT
    1.15 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
    1.16 + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
    1.17 + * version 2 for more details (a copy is included in the LICENSE file that
    1.18 + * accompanied this code).
    1.19 + *
    1.20 + * You should have received a copy of the GNU General Public License version
    1.21 + * 2 along with this work; if not, write to the Free Software Foundation,
    1.22 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
    1.23 + *
    1.24 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
    1.25 + * or visit www.oracle.com if you need additional information or have any
    1.26 + * questions.
    1.27 + */
    1.28 +
    1.29 +package java.util.logging;
    1.30 +import java.util.ResourceBundle;
    1.31 +
    1.32 +/**
    1.33 + * The Level class defines a set of standard logging levels that
    1.34 + * can be used to control logging output.  The logging Level objects
    1.35 + * are ordered and are specified by ordered integers.  Enabling logging
    1.36 + * at a given level also enables logging at all higher levels.
    1.37 + * <p>
    1.38 + * Clients should normally use the predefined Level constants such
    1.39 + * as Level.SEVERE.
    1.40 + * <p>
    1.41 + * The levels in descending order are:
    1.42 + * <ul>
    1.43 + * <li>SEVERE (highest value)
    1.44 + * <li>WARNING
    1.45 + * <li>INFO
    1.46 + * <li>CONFIG
    1.47 + * <li>FINE
    1.48 + * <li>FINER
    1.49 + * <li>FINEST  (lowest value)
    1.50 + * </ul>
    1.51 + * In addition there is a level OFF that can be used to turn
    1.52 + * off logging, and a level ALL that can be used to enable
    1.53 + * logging of all messages.
    1.54 + * <p>
    1.55 + * It is possible for third parties to define additional logging
    1.56 + * levels by subclassing Level.  In such cases subclasses should
    1.57 + * take care to chose unique integer level values and to ensure that
    1.58 + * they maintain the Object uniqueness property across serialization
    1.59 + * by defining a suitable readResolve method.
    1.60 + *
    1.61 + * @since 1.4
    1.62 + */
    1.63 +
    1.64 +public class Level implements java.io.Serializable {
    1.65 +    private static java.util.ArrayList<Level> known = new java.util.ArrayList<>();
    1.66 +    private static String defaultBundle = "sun.util.logging.resources.logging";
    1.67 +
    1.68 +    /**
    1.69 +     * @serial  The non-localized name of the level.
    1.70 +     */
    1.71 +    private final String name;
    1.72 +
    1.73 +    /**
    1.74 +     * @serial  The integer value of the level.
    1.75 +     */
    1.76 +    private final int value;
    1.77 +
    1.78 +    /**
    1.79 +     * @serial The resource bundle name to be used in localizing the level name.
    1.80 +     */
    1.81 +    private final String resourceBundleName;
    1.82 +
    1.83 +    /**
    1.84 +     * OFF is a special level that can be used to turn off logging.
    1.85 +     * This level is initialized to <CODE>Integer.MAX_VALUE</CODE>.
    1.86 +     */
    1.87 +    public static final Level OFF = new Level("OFF",Integer.MAX_VALUE, defaultBundle);
    1.88 +
    1.89 +    /**
    1.90 +     * SEVERE is a message level indicating a serious failure.
    1.91 +     * <p>
    1.92 +     * In general SEVERE messages should describe events that are
    1.93 +     * of considerable importance and which will prevent normal
    1.94 +     * program execution.   They should be reasonably intelligible
    1.95 +     * to end users and to system administrators.
    1.96 +     * This level is initialized to <CODE>1000</CODE>.
    1.97 +     */
    1.98 +    public static final Level SEVERE = new Level("SEVERE",1000, defaultBundle);
    1.99 +
   1.100 +    /**
   1.101 +     * WARNING is a message level indicating a potential problem.
   1.102 +     * <p>
   1.103 +     * In general WARNING messages should describe events that will
   1.104 +     * be of interest to end users or system managers, or which
   1.105 +     * indicate potential problems.
   1.106 +     * This level is initialized to <CODE>900</CODE>.
   1.107 +     */
   1.108 +    public static final Level WARNING = new Level("WARNING", 900, defaultBundle);
   1.109 +
   1.110 +    /**
   1.111 +     * INFO is a message level for informational messages.
   1.112 +     * <p>
   1.113 +     * Typically INFO messages will be written to the console
   1.114 +     * or its equivalent.  So the INFO level should only be
   1.115 +     * used for reasonably significant messages that will
   1.116 +     * make sense to end users and system administrators.
   1.117 +     * This level is initialized to <CODE>800</CODE>.
   1.118 +     */
   1.119 +    public static final Level INFO = new Level("INFO", 800, defaultBundle);
   1.120 +
   1.121 +    /**
   1.122 +     * CONFIG is a message level for static configuration messages.
   1.123 +     * <p>
   1.124 +     * CONFIG messages are intended to provide a variety of static
   1.125 +     * configuration information, to assist in debugging problems
   1.126 +     * that may be associated with particular configurations.
   1.127 +     * For example, CONFIG message might include the CPU type,
   1.128 +     * the graphics depth, the GUI look-and-feel, etc.
   1.129 +     * This level is initialized to <CODE>700</CODE>.
   1.130 +     */
   1.131 +    public static final Level CONFIG = new Level("CONFIG", 700, defaultBundle);
   1.132 +
   1.133 +    /**
   1.134 +     * FINE is a message level providing tracing information.
   1.135 +     * <p>
   1.136 +     * All of FINE, FINER, and FINEST are intended for relatively
   1.137 +     * detailed tracing.  The exact meaning of the three levels will
   1.138 +     * vary between subsystems, but in general, FINEST should be used
   1.139 +     * for the most voluminous detailed output, FINER for somewhat
   1.140 +     * less detailed output, and FINE for the  lowest volume (and
   1.141 +     * most important) messages.
   1.142 +     * <p>
   1.143 +     * In general the FINE level should be used for information
   1.144 +     * that will be broadly interesting to developers who do not have
   1.145 +     * a specialized interest in the specific subsystem.
   1.146 +     * <p>
   1.147 +     * FINE messages might include things like minor (recoverable)
   1.148 +     * failures.  Issues indicating potential performance problems
   1.149 +     * are also worth logging as FINE.
   1.150 +     * This level is initialized to <CODE>500</CODE>.
   1.151 +     */
   1.152 +    public static final Level FINE = new Level("FINE", 500, defaultBundle);
   1.153 +
   1.154 +    /**
   1.155 +     * FINER indicates a fairly detailed tracing message.
   1.156 +     * By default logging calls for entering, returning, or throwing
   1.157 +     * an exception are traced at this level.
   1.158 +     * This level is initialized to <CODE>400</CODE>.
   1.159 +     */
   1.160 +    public static final Level FINER = new Level("FINER", 400, defaultBundle);
   1.161 +
   1.162 +    /**
   1.163 +     * FINEST indicates a highly detailed tracing message.
   1.164 +     * This level is initialized to <CODE>300</CODE>.
   1.165 +     */
   1.166 +    public static final Level FINEST = new Level("FINEST", 300, defaultBundle);
   1.167 +
   1.168 +    /**
   1.169 +     * ALL indicates that all messages should be logged.
   1.170 +     * This level is initialized to <CODE>Integer.MIN_VALUE</CODE>.
   1.171 +     */
   1.172 +    public static final Level ALL = new Level("ALL", Integer.MIN_VALUE, defaultBundle);
   1.173 +
   1.174 +    /**
   1.175 +     * Create a named Level with a given integer value.
   1.176 +     * <p>
   1.177 +     * Note that this constructor is "protected" to allow subclassing.
   1.178 +     * In general clients of logging should use one of the constant Level
   1.179 +     * objects such as SEVERE or FINEST.  However, if clients need to
   1.180 +     * add new logging levels, they may subclass Level and define new
   1.181 +     * constants.
   1.182 +     * @param name  the name of the Level, for example "SEVERE".
   1.183 +     * @param value an integer value for the level.
   1.184 +     * @throws NullPointerException if the name is null
   1.185 +     */
   1.186 +    protected Level(String name, int value) {
   1.187 +        this(name, value, null);
   1.188 +    }
   1.189 +
   1.190 +    /**
   1.191 +     * Create a named Level with a given integer value and a
   1.192 +     * given localization resource name.
   1.193 +     * <p>
   1.194 +     * @param name  the name of the Level, for example "SEVERE".
   1.195 +     * @param value an integer value for the level.
   1.196 +     * @param resourceBundleName name of a resource bundle to use in
   1.197 +     *    localizing the given name. If the resourceBundleName is null
   1.198 +     *    or an empty string, it is ignored.
   1.199 +     * @throws NullPointerException if the name is null
   1.200 +     */
   1.201 +    protected Level(String name, int value, String resourceBundleName) {
   1.202 +        if (name == null) {
   1.203 +            throw new NullPointerException();
   1.204 +        }
   1.205 +        this.name = name;
   1.206 +        this.value = value;
   1.207 +        this.resourceBundleName = resourceBundleName;
   1.208 +        synchronized (Level.class) {
   1.209 +            known.add(this);
   1.210 +        }
   1.211 +    }
   1.212 +
   1.213 +    /**
   1.214 +     * Return the level's localization resource bundle name, or
   1.215 +     * null if no localization bundle is defined.
   1.216 +     *
   1.217 +     * @return localization resource bundle name
   1.218 +     */
   1.219 +    public String getResourceBundleName() {
   1.220 +        return resourceBundleName;
   1.221 +    }
   1.222 +
   1.223 +    /**
   1.224 +     * Return the non-localized string name of the Level.
   1.225 +     *
   1.226 +     * @return non-localized name
   1.227 +     */
   1.228 +    public String getName() {
   1.229 +        return name;
   1.230 +    }
   1.231 +
   1.232 +    /**
   1.233 +     * Return the localized string name of the Level, for
   1.234 +     * the current default locale.
   1.235 +     * <p>
   1.236 +     * If no localization information is available, the
   1.237 +     * non-localized name is returned.
   1.238 +     *
   1.239 +     * @return localized name
   1.240 +     */
   1.241 +    public String getLocalizedName() {
   1.242 +        try {
   1.243 +            ResourceBundle rb = ResourceBundle.getBundle(resourceBundleName);
   1.244 +            return rb.getString(name);
   1.245 +        } catch (Exception ex) {
   1.246 +            return name;
   1.247 +        }
   1.248 +    }
   1.249 +
   1.250 +    /**
   1.251 +     * Returns a string representation of this Level.
   1.252 +     *
   1.253 +     * @return the non-localized name of the Level, for example "INFO".
   1.254 +     */
   1.255 +    public final String toString() {
   1.256 +        return name;
   1.257 +    }
   1.258 +
   1.259 +    /**
   1.260 +     * Get the integer value for this level.  This integer value
   1.261 +     * can be used for efficient ordering comparisons between
   1.262 +     * Level objects.
   1.263 +     * @return the integer value for this level.
   1.264 +     */
   1.265 +    public final int intValue() {
   1.266 +        return value;
   1.267 +    }
   1.268 +
   1.269 +    private static final long serialVersionUID = -8176160795706313070L;
   1.270 +
   1.271 +    // Serialization magic to prevent "doppelgangers".
   1.272 +    // This is a performance optimization.
   1.273 +    private Object readResolve() {
   1.274 +        synchronized (Level.class) {
   1.275 +            for (int i = 0; i < known.size(); i++) {
   1.276 +                Level other = known.get(i);
   1.277 +                if (this.name.equals(other.name) && this.value == other.value
   1.278 +                        && (this.resourceBundleName == other.resourceBundleName ||
   1.279 +                            (this.resourceBundleName != null &&
   1.280 +                            this.resourceBundleName.equals(other.resourceBundleName)))) {
   1.281 +                    return other;
   1.282 +                }
   1.283 +            }
   1.284 +            // Woops.  Whoever sent us this object knows
   1.285 +            // about a new log level.  Add it to our list.
   1.286 +            known.add(this);
   1.287 +            return this;
   1.288 +        }
   1.289 +    }
   1.290 +
   1.291 +    /**
   1.292 +     * Parse a level name string into a Level.
   1.293 +     * <p>
   1.294 +     * The argument string may consist of either a level name
   1.295 +     * or an integer value.
   1.296 +     * <p>
   1.297 +     * For example:
   1.298 +     * <ul>
   1.299 +     * <li>     "SEVERE"
   1.300 +     * <li>     "1000"
   1.301 +     * </ul>
   1.302 +     * @param  name   string to be parsed
   1.303 +     * @throws NullPointerException if the name is null
   1.304 +     * @throws IllegalArgumentException if the value is not valid.
   1.305 +     * Valid values are integers between <CODE>Integer.MIN_VALUE</CODE>
   1.306 +     * and <CODE>Integer.MAX_VALUE</CODE>, and all known level names.
   1.307 +     * Known names are the levels defined by this class (e.g., <CODE>FINE</CODE>,
   1.308 +     * <CODE>FINER</CODE>, <CODE>FINEST</CODE>), or created by this class with
   1.309 +     * appropriate package access, or new levels defined or created
   1.310 +     * by subclasses.
   1.311 +     *
   1.312 +     * @return The parsed value. Passing an integer that corresponds to a known name
   1.313 +     * (e.g., 700) will return the associated name (e.g., <CODE>CONFIG</CODE>).
   1.314 +     * Passing an integer that does not (e.g., 1) will return a new level name
   1.315 +     * initialized to that value.
   1.316 +     */
   1.317 +    public static synchronized Level parse(String name) throws IllegalArgumentException {
   1.318 +        // Check that name is not null.
   1.319 +        name.length();
   1.320 +
   1.321 +        // Look for a known Level with the given non-localized name.
   1.322 +        for (int i = 0; i < known.size(); i++) {
   1.323 +            Level l = known.get(i);
   1.324 +            if (name.equals(l.name)) {
   1.325 +                return l;
   1.326 +            }
   1.327 +        }
   1.328 +
   1.329 +        // Now, check if the given name is an integer.  If so,
   1.330 +        // first look for a Level with the given value and then
   1.331 +        // if necessary create one.
   1.332 +        try {
   1.333 +            int x = Integer.parseInt(name);
   1.334 +            for (int i = 0; i < known.size(); i++) {
   1.335 +                Level l = known.get(i);
   1.336 +                if (l.value == x) {
   1.337 +                    return l;
   1.338 +                }
   1.339 +            }
   1.340 +            // Create a new Level.
   1.341 +            return new Level(name, x);
   1.342 +        } catch (NumberFormatException ex) {
   1.343 +            // Not an integer.
   1.344 +            // Drop through.
   1.345 +        }
   1.346 +
   1.347 +        // Finally, look for a known level with the given localized name,
   1.348 +        // in the current default locale.
   1.349 +        // This is relatively expensive, but not excessively so.
   1.350 +        for (int i = 0; i < known.size(); i++) {
   1.351 +            Level l =  known.get(i);
   1.352 +            if (name.equals(l.getLocalizedName())) {
   1.353 +                return l;
   1.354 +            }
   1.355 +        }
   1.356 +
   1.357 +        // OK, we've tried everything and failed
   1.358 +        throw new IllegalArgumentException("Bad level \"" + name + "\"");
   1.359 +    }
   1.360 +
   1.361 +    /**
   1.362 +     * Compare two objects for value equality.
   1.363 +     * @return true if and only if the two objects have the same level value.
   1.364 +     */
   1.365 +    public boolean equals(Object ox) {
   1.366 +        try {
   1.367 +            Level lx = (Level)ox;
   1.368 +            return (lx.value == this.value);
   1.369 +        } catch (Exception ex) {
   1.370 +            return false;
   1.371 +        }
   1.372 +    }
   1.373 +
   1.374 +    /**
   1.375 +     * Generate a hashcode.
   1.376 +     * @return a hashcode based on the level value
   1.377 +     */
   1.378 +    public int hashCode() {
   1.379 +        return this.value;
   1.380 +    }
   1.381 +}