001    /*
002     * CDDL HEADER START
003     *
004     * The contents of this file are subject to the terms of the
005     * Common Development and Distribution License, Version 1.0 only
006     * (the "License").  You may not use this file except in compliance
007     * with the License.
008     *
009     * You can obtain a copy of the license at
010     * trunk/opends/resource/legal-notices/OpenDS.LICENSE
011     * or https://OpenDS.dev.java.net/OpenDS.LICENSE.
012     * See the License for the specific language governing permissions
013     * and limitations under the License.
014     *
015     * When distributing Covered Code, include this CDDL HEADER in each
016     * file and include the License file at
017     * trunk/opends/resource/legal-notices/OpenDS.LICENSE.  If applicable,
018     * add the following below this CDDL HEADER, with the fields enclosed
019     * by brackets "[]" replaced with your own identifying information:
020     *      Portions Copyright [yyyy] [name of copyright owner]
021     *
022     * CDDL HEADER END
023     *
024     *
025     *      Copyright 2006-2008 Sun Microsystems, Inc.
026     */
027    
028    package org.opends.server.loggers;
029    
030    import static org.opends.server.util.ServerConstants.LOG_SEVERITY_DISABLED;
031    import static org.opends.server.util.ServerConstants.LOG_SEVERITY_ALL;
032    
033    import java.util.*;
034    
035    
036    /**
037     * The Level class defines a set of standard logging levels that
038     * can be used to control logging output.  The logging Level objects
039     * are ordered and are specified by ordered integers.  Enabling logging
040     * at a given level also enables logging at all higher levels.
041     */
042    public class LogLevel
043    {
044      private static ArrayList<LogLevel> known =  new ArrayList<LogLevel>();
045    
046      /**
047       * OFF is a special level that can be used to turn off logging.
048       * This level is initialized to <CODE>Integer.MAX_VALUE</CODE>.
049       */
050      public static final LogLevel DISABLED = new LogLevel(
051          LOG_SEVERITY_DISABLED,Integer.MAX_VALUE);
052    
053    
054    
055      /**
056       * ALL indicates that all messages should be logged.
057       * This level is initialized to <CODE>Integer.MIN_VALUE</CODE>.
058       */
059      public static final LogLevel ALL = new LogLevel(
060          LOG_SEVERITY_ALL, Integer.MIN_VALUE);
061    
062    
063    
064      /**
065       * The non-localized name of the level.
066       */
067      private final String name;
068    
069      /**
070       * The integer value of the level.
071       */
072      private final int value;
073    
074    
075      /**
076       * Create a named Level with a given integer value.
077       * <p>
078       * Note that this constructor is "protected" to allow subclassing.
079       *
080       * @param name  the name of the Level, for example "SEVERE".
081       * @param value an integer value for the level.
082       */
083      protected LogLevel(String name, int value) {
084        if (name == null) {
085          throw new NullPointerException();
086        }
087        this.name = name;
088        this.value = value;
089    
090        known.add(this);
091      }
092    
093      /**
094       * Return the non-localized string name of the Level.
095       *
096       * @return non-localized name
097       */
098      public String getName() {
099        return name;
100      }
101    
102      /**
103       * Retrieve the string reprentation of this log level.
104       *
105       * @return the non-localized name of the Level, for example "INFO".
106       */
107      public final String toString() {
108        return name;
109      }
110    
111      /**
112       * Get the integer value for this level.  This integer value
113       * can be used for efficient ordering comparisons between
114       * Level objects.
115       * @return the integer value for this level.
116       */
117      public final int intValue() {
118        return value;
119      }
120    
121      /**
122       * Parse a level name string into a LogLevel.
123       * <p>
124       * The argument string may consist of either a level name
125       * or an integer value.
126       * <p>
127       * For example:
128       * <ul>
129       * <li> "SEVERE"
130       * <li> "1000"
131       * </ul>
132       * @param  name   string to be parsed
133       * @throws IllegalArgumentException if the value is not valid.
134       * Valid values are integers between <CODE>Integer.MIN_VALUE</CODE>
135       * and <CODE>Integer.MAX_VALUE</CODE>, and all known level names.
136       * Known names are the levels defined by this class (i.e. <CODE>FINE</CODE>,
137       * <CODE>FINER</CODE>, <CODE>FINEST</CODE>), or created by this class with
138       * appropriate package access, or new levels defined or created
139       * by subclasses.
140       *
141       * @return The parsed value. Passing an integer that corresponds to a
142       * known name (eg 700) will return the associated name
143       * (eg <CODE>CONFIG</CODE>). Passing an integer that does not (eg 1)
144       * will return a new level name initialized to that value.
145       */
146      public static synchronized LogLevel parse(String name)
147          throws IllegalArgumentException {
148        // Check that name is not null.
149        name.length();
150    
151        // Look for a known Level with the given non-localized name.
152        for (int i = 0; i < known.size(); i++) {
153          LogLevel l = known.get(i);
154          if (name.equalsIgnoreCase(l.name)) {
155            return l;
156          }
157        }
158    
159        // Now, check if the given name is an integer.  If so,
160        // first look for a Level with the given value and then
161        // if necessary create one.
162        try {
163          int x = Integer.parseInt(name);
164          for (int i = 0; i < known.size(); i++) {
165            LogLevel l = known.get(i);
166            if (l.value == x) {
167              return l;
168            }
169          }
170          // Create a new Level.
171          return new LogLevel(name, x);
172        } catch (NumberFormatException ex) {
173          // Not an integer.
174          // Drop through.
175        }
176    
177        // OK, we've tried everything and failed
178        throw new IllegalArgumentException("Bad level \"" + name + "\"");
179      }
180    
181      /**
182       * Compare two objects for value equality.
183       *
184       * @param ox the LogLevel object to test.
185       * @return true if and only if the two objects have the same level value.
186       */
187      public boolean equals(Object ox) {
188        try {
189          LogLevel lx = (LogLevel)ox;
190          return (lx.value == this.value);
191        } catch (Exception ex) {
192          return false;
193        }
194      }
195    
196      /**
197       * Retrives the hashcode for this log level. It is just the integer value.
198       *
199       * @return the hashCode for this log level.
200       */
201      public int hashCode()
202      {
203        return this.value;
204      }
205    
206      /**
207       * Returns the string representations of all the levels. All strings will
208       * be in lower case.
209       * @return The string representations of the levels in lower case.
210       */
211      public static HashSet<String> getLevelStrings()
212      {
213        HashSet<String> strings = new HashSet<String>();
214    
215        for (int i = 0; i < known.size(); i++)
216        {
217          strings.add(known.get(i).name.toLowerCase());
218        }
219    
220        return strings;
221      }
222    }