    001/*
    002 * Copyright 2001-2004 The Apache Software Foundation.
    003 *
    004 * Licensed under the Apache License, Version 2.0 (the "License");
    005 * you may not use this file except in compliance with the License.
    006 * You may obtain a copy of the License at
    007 *
    008 *      http://www.apache.org/licenses/LICENSE-2.0
    009 *
    010 * Unless required by applicable law or agreed to in writing, software
    011 * distributed under the License is distributed on an "AS IS" BASIS,
    012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    013 * See the License for the specific language governing permissions and
    014 * limitations under the License.
    015 */
    016
    017// Contributors:  Kitching Simon <Simon.Kitching@orange.ch>
    018//                Nicholas Wolff
    019
    020package org.apache.log4j;
    021
    022import java.io.IOException;
    023import java.io.ObjectInputStream;
    024import java.io.ObjectOutputStream;
    025import java.io.ObjectStreamException;
    026import java.io.Serializable;
    027
    028/**
    029   Defines the minimum set of levels recognized by the system, that is
    030   <code>OFF</code>, <code>FATAL</code>, <code>ERROR</code>,
    031   <code>WARN</code>, <code>INFO</code>, <code>DEBUG</code> and
    032   <code>ALL</code>.
    033
    034   <p>The <code>Level</code> class may be subclassed to define a larger
    035   level set.
    036
    037   @author Ceki G&uuml;lc&uuml;
    038
    039 */
    040public class Level extends Priority implements Serializable {
    041
    042    /**
    043     * TRACE level integer value.
    044     * @since 1.2.12
    045     */
    046    public static final int TRACE_INT = 5000;
    047
    048    // match jboss' xlevel
    049    public static final int X_TRACE_INT = DEBUG_INT - 100;
    050
    051    /**
    052       The <code>OFF</code> has the highest possible rank and is
    053       intended to turn off logging.  */
    054    final static public Level OFF = new Level(OFF_INT, "OFF", 0);
    055
    056    /**
    057       The <code>FATAL</code> level designates very severe error
    058       events that will presumably lead the application to abort.
    059     */
    060    final static public Level FATAL = new Level(FATAL_INT, "FATAL", 0);
    061
    062    /**
    063       The <code>ERROR</code> level designates error events that
    064       might still allow the application to continue running.  */
    065    final static public Level ERROR = new Level(ERROR_INT, "ERROR", 3);
    066
    067    /**
    068       The <code>WARN</code> level designates potentially harmful situations.
    069    */
    070    final static public Level WARN = new Level(WARN_INT, "WARN", 4);
    071
    072    /**
    073       The <code>INFO</code> level designates informational messages
    074       that highlight the progress of the application at coarse-grained
    075       level.  */
    076    final static public Level INFO = new Level(INFO_INT, "INFO", 6);
    077
    078    /**
    079       The <code>DEBUG</code> Level designates fine-grained
    080       informational events that are most useful to debug an
    081       application.  */
    082    final static public Level DEBUG = new Level(DEBUG_INT, "DEBUG", 7);
    083
    084    /**
    085      * The <code>TRACE</code> Level designates finer-grained
    086      * informational events than the <code>DEBUG</code level.
    087     *  @since 1.2.12
    088      */
    089    public static final Level TRACE = new Level(TRACE_INT, "TRACE", 7);
    090
    091    /**
    092       The <code>ALL</code> has the lowest possible rank and is intended to
    093       turn on all logging.  */
    094    final static public Level ALL = new Level(ALL_INT, "ALL", 7);
    095
    096    /**
    097     * Serialization version id.
    098     */
    099    static final long serialVersionUID = 3491141966387921974L;
    100
    101    /**
    102       Instantiate a Level object.
    103     */
    104    protected Level(int level, String levelStr, int syslogEquivalent) {
    105        super(level, levelStr, syslogEquivalent);
    106    }
    107
    108    /**
    109       Convert the string passed as argument to a level. If the
    110       conversion fails, then this method returns {@link #DEBUG}.
    111    */
    112    public static Level toLevel(String sArg) {
    113        return (Level) toLevel(sArg, Level.DEBUG);
    114    }
    115
    116    /**
    117      Convert an integer passed as argument to a level. If the
    118      conversion fails, then this method returns {@link #DEBUG}.
    119
    120    */
    121    public static Level toLevel(int val) {
    122        return (Level) toLevel(val, Level.DEBUG);
    123    }
    124
    125    /**
    126      Convert an integer passed as argument to a level. If the
    127      conversion fails, then this method returns the specified default.
    128    */
    129    public static Level toLevel(int val, Level defaultLevel) {
    130        switch (val) {
    131        case ALL_INT:
    132            return ALL;
    133        case DEBUG_INT:
    134            return Level.DEBUG;
    135        case INFO_INT:
    136            return Level.INFO;
    137        case WARN_INT:
    138            return Level.WARN;
    139        case ERROR_INT:
    140            return Level.ERROR;
    141        case FATAL_INT:
    142            return Level.FATAL;
    143        case OFF_INT:
    144            return OFF;
    145        case TRACE_INT:
    146            return Level.TRACE;
    147        default:
    148            return defaultLevel;
    149        }
    150    }
    151
    152    /**
    153       Convert the string passed as argument to a level. If the
    154       conversion fails, then this method returns the value of
    155       <code>defaultLevel</code>.
    156    */
    157    public static Level toLevel(String sArg, Level defaultLevel) {
    158        if (sArg == null)
    159            return defaultLevel;
    160
    161        String s = sArg.toUpperCase();
    162
    163        if (s.equals("ALL"))
    164            return Level.ALL;
    165        if (s.equals("DEBUG"))
    166            return Level.DEBUG;
    167        if (s.equals("INFO"))
    168            return Level.INFO;
    169        if (s.equals("WARN"))
    170            return Level.WARN;
    171        if (s.equals("ERROR"))
    172            return Level.ERROR;
    173        if (s.equals("FATAL"))
    174            return Level.FATAL;
    175        if (s.equals("OFF"))
    176            return Level.OFF;
    177        if (s.equals("TRACE"))
    178            return Level.TRACE;
    179        return defaultLevel;
    180    }
    181
    182    /**
    183     * Custom deserialization of Level.
    184     * @param s serialization stream.
    185     * @throws IOException if IO exception.
    186     * @throws ClassNotFoundException if class not found.
    187     */
    188    private void readObject(final ObjectInputStream s) throws IOException, ClassNotFoundException {
    189        s.defaultReadObject();
    190        level = s.readInt();
    191        syslogEquivalent = s.readInt();
    192        levelStr = s.readUTF();
    193        if (levelStr == null) {
    194            levelStr = "";
    195        }
    196    }
    197
    198    /**
    199     * Serialize level.
    200     * @param s serialization stream.
    201     * @throws IOException if exception during serialization.
    202     */
    203    private void writeObject(final ObjectOutputStream s) throws IOException {
    204        s.defaultWriteObject();
    205        s.writeInt(level);
    206        s.writeInt(syslogEquivalent);
    207        s.writeUTF(levelStr);
    208    }
    209
    210    /**
    211     * Resolved deserialized level to one of the stock instances.
    212     * May be overridden in classes derived from Level.
    213     * @return resolved object.
    214     * @throws ObjectStreamException if exception during resolution.
    215     */
    216    private Object readResolve() throws ObjectStreamException {
    217        //
    218        // if the deserialized object is exactly an instance of Level
    219        //
    220        if (getClass() == Level.class) {
    221            return toLevel(level);
    222        }
    223        //
    224        // extension of Level can't substitute stock item
    225        //
    226        return this;
    227    }
    228}