001/**
002 * Logback: the reliable, generic, fast and flexible logging framework.
003 * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
004 *
005 * This program and the accompanying materials are dual-licensed under
006 * either the terms of the Eclipse Public License v1.0 as published by
007 * the Eclipse Foundation
008 *
009 *   or (per the licensee's choosing)
010 *
011 * under the terms of the GNU Lesser General Public License version 2.1
012 * as published by the Free Software Foundation.
013 */
014package ch.qos.logback.classic;
015
016import org.slf4j.spi.LocationAwareLogger;
017
018/**
019 * Defines the set of levels recognized by logback-classic, that is {@link #OFF},
020 * {@link #ERROR}, {@link #WARN}, {@link #INFO}, {@link #DEBUG},
021 * {@link #TRACE} and {@link #ALL}. <p/> The <code>Level</code> class is
022 * final and cannot be sub-classed.
023 * </p>
024 */
025public final class Level implements java.io.Serializable {
026
027    private static final long serialVersionUID = -814092767334282137L;
028
029    public static final int OFF_INT = Integer.MAX_VALUE;
030    public static final int ERROR_INT = 40000;
031    public static final int WARN_INT = 30000;
032    public static final int INFO_INT = 20000;
033    public static final int DEBUG_INT = 10000;
034    public static final int TRACE_INT = 5000;
035    public static final int ALL_INT = Integer.MIN_VALUE;
036
037    public static final Integer OFF_INTEGER = OFF_INT;
038    public static final Integer ERROR_INTEGER = ERROR_INT;
039    public static final Integer WARN_INTEGER = WARN_INT;
040    public static final Integer INFO_INTEGER = INFO_INT;
041    public static final Integer DEBUG_INTEGER = DEBUG_INT;
042    public static final Integer TRACE_INTEGER = TRACE_INT;
043    public static final Integer ALL_INTEGER = ALL_INT;
044
045    /**
046     * The <code>OFF</code> is used to turn off logging.
047     */
048    public static final Level OFF = new Level(OFF_INT, "OFF");
049
050    /**
051     * The <code>ERROR</code> level designates error events which may or not
052     * be fatal to the application.
053     */
054    public static final Level ERROR = new Level(ERROR_INT, "ERROR");
055
056    /**
057     * The <code>WARN</code> level designates potentially harmful situations.
058     */
059    public static final Level WARN = new Level(WARN_INT, "WARN");
060
061    /**
062     * The <code>INFO</code> level designates informational messages
063     * highlighting overall progress of the application.
064     */
065    public static final Level INFO = new Level(INFO_INT, "INFO");
066
067    /**
068     * The <code>DEBUG</code> level designates informational events of lower
069     * importance.
070     */
071    public static final Level DEBUG = new Level(DEBUG_INT, "DEBUG");
072
073    /**
074     * The <code>TRACE</code> level designates informational events of very low
075     * importance.
076     */
077    public static final Level TRACE = new Level(TRACE_INT, "TRACE");
078
079    /**
080     * The <code>ALL</code> is used to turn on all logging.
081     */
082    public static final Level ALL = new Level(ALL_INT, "ALL");
083
084    public final int levelInt;
085    public final String levelStr;
086
087    /**
088     * Instantiate a Level object.
089     */
090    private Level(int levelInt, String levelStr) {
091        this.levelInt = levelInt;
092        this.levelStr = levelStr;
093    }
094
095    /**
096     * Returns the string representation of this Level.
097     */
098    public String toString() {
099        return levelStr;
100    }
101
102    /**
103     * Returns the integer representation of this Level.
104     */
105    public int toInt() {
106        return levelInt;
107    }
108
109    /**
110     * Convert a Level to an Integer object.
111     *
112     * @return This level's Integer mapping.
113     */
114    public Integer toInteger() {
115        switch (levelInt) {
116        case ALL_INT:
117            return ALL_INTEGER;
118        case TRACE_INT:
119            return TRACE_INTEGER;
120        case DEBUG_INT:
121            return DEBUG_INTEGER;
122        case INFO_INT:
123            return INFO_INTEGER;
124        case WARN_INT:
125            return WARN_INTEGER;
126        case ERROR_INT:
127            return ERROR_INTEGER;
128        case OFF_INT:
129            return OFF_INTEGER;
130        default:
131            throw new IllegalStateException("Level " + levelStr + ", " + levelInt + " is unknown.");
132        }
133    }
134
135    /**
136     * Returns <code>true</code> if this Level has a higher or equal Level than
137     * the Level passed as argument, <code>false</code> otherwise.
138     */
139    public boolean isGreaterOrEqual(Level r) {
140        return levelInt >= r.levelInt;
141    }
142
143    /**
144     * Convert the string passed as argument to a Level. If the conversion fails,
145     * then this method returns {@link #DEBUG}.
146     */
147    public static Level toLevel(String sArg) {
148        return toLevel(sArg, Level.DEBUG);
149    }
150
151    /**
152     * This method exists in order to comply with Joran's valueOf convention.
153     *
154     * @param sArg
155     * @return
156     */
157    public static Level valueOf(String sArg) {
158        return toLevel(sArg, Level.DEBUG);
159    }
160
161    /**
162     * Convert an integer passed as argument to a Level. If the conversion fails,
163     * then this method returns {@link #DEBUG}.
164     */
165    public static Level toLevel(int val) {
166        return toLevel(val, Level.DEBUG);
167    }
168
169    /**
170     * Convert an integer passed as argument to a Level. If the conversion fails,
171     * then this method returns the specified default.
172     */
173    public static Level toLevel(int val, Level defaultLevel) {
174        switch (val) {
175        case ALL_INT:
176            return ALL;
177        case TRACE_INT:
178            return TRACE;
179        case DEBUG_INT:
180            return DEBUG;
181        case INFO_INT:
182            return INFO;
183        case WARN_INT:
184            return WARN;
185        case ERROR_INT:
186            return ERROR;
187        case OFF_INT:
188            return OFF;
189        default:
190            return defaultLevel;
191        }
192    }
193
194    /**
195     * Convert the string passed as argument to a Level. If the conversion fails,
196     * then this method returns the value of <code>defaultLevel</code>.
197     */
198    public static Level toLevel(final String sArg, Level defaultLevel) {
199        if (sArg == null) {
200            return defaultLevel;
201        }
202
203        // see LOGBACK-1288
204        final String in = sArg.trim();
205        
206        if (in.equalsIgnoreCase("ALL")) {
207            return Level.ALL;
208        }
209        if (in.equalsIgnoreCase("TRACE")) {
210            return Level.TRACE;
211        }
212        if (in.equalsIgnoreCase("DEBUG")) {
213            return Level.DEBUG;
214        }
215        if (in.equalsIgnoreCase("INFO")) {
216            return Level.INFO;
217        }
218        if (in.equalsIgnoreCase("WARN")) {
219            return Level.WARN;
220        }
221        if (in.equalsIgnoreCase("ERROR")) {
222            return Level.ERROR;
223        }
224        if (in.equalsIgnoreCase("OFF")) {
225            return Level.OFF;
226        }
227        return defaultLevel;
228    }
229
230    /**
231     * Return the flyweight instance of the level received through serizalization,
232     * i.e. 'this'.
233     *
234     * @return The appropriate flyweight instance
235     */
236    private Object readResolve() {
237        return toLevel(this.levelInt);
238    }
239
240    /**
241     * Convert one of the integer values defined in {@link LocationAwareLogger}
242     * interface to an instance of this class, i.e. a Level.
243     *
244     * @param levelInt An integer value representing a level as defined in LocationAwareLogger
245     * @return an instance of this class, i.e. a Level.
246     * @since 1.0.1
247     */
248    public static Level fromLocationAwareLoggerInteger(int levelInt) {
249        Level level;
250        switch (levelInt) {
251        case LocationAwareLogger.TRACE_INT:
252            level = TRACE;
253            break;
254        case LocationAwareLogger.DEBUG_INT:
255            level = DEBUG;
256            break;
257        case LocationAwareLogger.INFO_INT:
258            level = INFO;
259            break;
260        case LocationAwareLogger.WARN_INT:
261            level = WARN;
262            break;
263        case LocationAwareLogger.ERROR_INT:
264            level = ERROR;
265            break;
266        default:
267            throw new IllegalArgumentException(levelInt + " not a valid level value");
268        }
269        return level;
270    }
271
272    /**
273     * Convert this level instance to an integer  value defined in the
274     * {@link LocationAwareLogger} interface.
275     *
276     * @param level The level to convert to LocationAwareLogger integer
277     * @return int An integer corresponding to this level as defined in LocationAwareLogger
278     * @since 1.0.1
279     */
280    public static int toLocationAwareLoggerInteger(Level level) {
281        if (level == null)
282            throw new IllegalArgumentException("null level parameter is not admitted");
283        switch (level.toInt()) {
284        case Level.TRACE_INT:
285            return LocationAwareLogger.TRACE_INT;
286        case Level.DEBUG_INT:
287            return LocationAwareLogger.DEBUG_INT;
288        case Level.INFO_INT:
289            return LocationAwareLogger.INFO_INT;
290        case Level.WARN_INT:
291            return LocationAwareLogger.WARN_INT;
292        case Level.ERROR_INT:
293            return LocationAwareLogger.ERROR_INT;
294        default:
295            throw new IllegalArgumentException(level + " not a valid level value");
296        }
297    }
298}