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