harmony-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From smish...@apache.org
Subject svn commit: r441006 [2/4] - /incubator/harmony/enhanced/classlib/trunk/modules/logging/src/main/java/java/util/logging/
Date Thu, 07 Sep 2006 07:32:52 GMT
Modified: incubator/harmony/enhanced/classlib/trunk/modules/logging/src/main/java/java/util/logging/Level.java
URL: http://svn.apache.org/viewvc/incubator/harmony/enhanced/classlib/trunk/modules/logging/src/main/java/java/util/logging/Level.java?view=diff&rev=441006&r1=441005&r2=441006
==============================================================================
--- incubator/harmony/enhanced/classlib/trunk/modules/logging/src/main/java/java/util/logging/Level.java (original)
+++ incubator/harmony/enhanced/classlib/trunk/modules/logging/src/main/java/java/util/logging/Level.java Thu Sep  7 00:32:50 2006
@@ -1,363 +1,363 @@
-/* Copyright 2004 The Apache Software Foundation or its licensors, as applicable
- * 
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- * 
- *     http://www.apache.org/licenses/LICENSE-2.0
- * 
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-
-package java.util.logging;
-
-import java.io.Serializable;
-import java.util.HashMap;
-import java.util.Map;
-import java.util.ResourceBundle;
-
-/**
- * <code>Level</code> objects are used to indicate the level of logging. There
- * are a set of predefined logging levels, each associated with an integer
- * value. Enabling a certain logging level also enables all logging levels with
- * larger values.
- * <p>
- * The predefined levels in ascending order are FINEST, FINER, FINE, CONFIG,
- * INFO, WARNING, SEVERE. There are two additional predefined levels, which are
- * ALL and OFF. ALL indicates logging all messages, and OFF indicates logging no
- * messages.
- * </p>
- * 
- */
-public class Level implements Serializable {
-    
-    
-    //for serialization compatibility
-    private static final long serialVersionUID = -8176160795706313070L;    
-
-    /*
-     * -------------------------------------------------------------------
-     * Constants
-     * -------------------------------------------------------------------
-     */
-
-	/*
-     * -------------------------------------------------------------------
-     * Class variables
-     * -------------------------------------------------------------------
-     */
-    private static Map<String, Level> levels = new HashMap<String, Level>();
-	
-    // The following string constants define the name of all predefined levels.
-    private static final String SEVERESTR = "SEVERE"; //$NON-NLS-1$
-
-    private static final String WARNINGSTR = "WARNING"; //$NON-NLS-1$
-
-    private static final String INFOSTR = "INFO"; //$NON-NLS-1$
-
-    private static final String CONFIGSTR = "CONFIG"; //$NON-NLS-1$
-
-    private static final String FINESTR = "FINE"; //$NON-NLS-1$
-
-    private static final String FINERSTR = "FINER"; //$NON-NLS-1$
-
-    private static final String FINESTSTR = "FINEST"; //$NON-NLS-1$
-
-    private static final String OFFSTR = "OFF"; //$NON-NLS-1$
-
-    private static final String ALLSTR = "ALL"; //$NON-NLS-1$
-
-    /**
-     * The SEVERE level indicates a severe failure.
-     */
-    public static final Level SEVERE = new Level(SEVERESTR, 1000);
-
-    /**
-     * The WARNING level indicates a warning.
-     */
-    public static final Level WARNING = new Level(WARNINGSTR, 900);
-
-    /**
-     * The INFO level indicates an informative message.
-     */
-    public static final Level INFO = new Level(INFOSTR, 800);
-
-    /**
-     * The CONFIG level indicates a static configuration message.
-     */
-    public static final Level CONFIG = new Level(CONFIGSTR, 700);
-
-    /**
-     * The FINE level provides tracing messages.
-     */
-    public static final Level FINE = new Level(FINESTR, 500);
-
-    /**
-     * The FINER level provides more detailed tracing messages.
-     */
-    public static final Level FINER = new Level(FINERSTR, 400);
-
-    /**
-     * The FINEST level provides highly detailed tracing messages.
-     */
-    public static final Level FINEST = new Level(FINESTSTR, 300);
-
-    /**
-     * The OFF level provides no logging messages.
-     */
-    public static final Level OFF = new Level(OFFSTR, Integer.MAX_VALUE);
-
-    /**
-     * The ALL level provides all logging messages.
-     */
-    public static final Level ALL = new Level(ALLSTR, Integer.MIN_VALUE);
-
-
-    /*
-     * -------------------------------------------------------------------
-     * Global initialization
-     * -------------------------------------------------------------------
-     */
-
-    static {
-		levels.remove(null);
-    }
-
-    /*
-     * -------------------------------------------------------------------
-     * Instance variables
-     * -------------------------------------------------------------------
-     */
-
-    /**
-     * The name of this Level.
-     * 
-     * @serial
-     */
-    private final String name;
-
-    /**
-     * The integer value indicating the level.
-     * 
-     * @serial
-     */
-    private final int value;
-
-    /**
-     * The name of the resource bundle used to localize the level name.
-     * 
-     * @serial
-     */
-    private final String resourceBundleName;
-
-    /*
-     * The resource bundle associated with this level, used to localize the
-     * level name.
-     */
-    private transient ResourceBundle rb;
-
-    /*
-     * -------------------------------------------------------------------
-     * Constructors
-     * -------------------------------------------------------------------
-     */
-
-    /**
-     * Constructs an instance of <code>Level</code> taking the supplied name
-     * and level value.
-     * 
-     * @param name
-     *            name of the level
-     * @param level
-     *            an integer value indicating the level
-     */
-    protected Level(String name, int level) {
-        this(name, level, null);
-    }
-
-    /**
-     * Constructs an instance of <code>Level</code> taking the supplied name
-     * and level value.
-     * 
-     * @param name
-     *            name of the level
-     * @param level
-     *            an integer value indicating the level
-     * @param resourceBundleName
-     *            the name of the resource bundle to use
-     */
-    protected Level(String name, int level, String resourceBundleName) {
-        if (null == name) {
-            throw new NullPointerException("The 'name' parameter is null."); //$NON-NLS-1$
-        }
-        this.name = name;
-        this.value = level;
-        this.resourceBundleName = resourceBundleName;
-		//put value into known values list in Constructor
-		if(null==levels.get(name)){
-			levels.put(name,this);
-		}
-		if(null==levels.get(String.valueOf(level))){
-			levels.put(String.valueOf(this.intValue()), this);
-		}
-    }
-
-    /*
-     * -------------------------------------------------------------------
-     * Methods
-     * -------------------------------------------------------------------
-     */
-
-    /**
-     * Gets the name of this <code>Level</code>.
-     * 
-     * @return the name of this <code>Level</code>
-     */
-    public String getName() {
-        return this.name;
-    }
-
-    /**
-     * Gets the name of the resource bundle associated with this
-     * <code>Level</code>.
-     * 
-     * @return the name of the resource bundle associated with this
-     *         <code>Level</code>
-     */
-    public String getResourceBundleName() {
-        return this.resourceBundleName;
-    }
-
-    /**
-     * Gets the integer value indicating this <code>Level</code>.
-     * 
-     * @return the integer value indicating this <code>Level</code>
-     */
-    public final int intValue() {
-        return this.value;
-    }
-
-    /**
-     * Parses a level name into a <code>Level</code> object.
-     * 
-     * @param name
-     *            the name of the desired level, which cannot be null
-     * @return a <code>Level</code> object with the specified name
-     * @throws NullPointerException
-     *             If <code>name</code> is null.
-     * @throws IllegalArgumentException
-     *             When <code>name</code> cannot be parsed.
-     */
-    public static final Level parse(String name) {
-        if (null == name) {
-            throw new NullPointerException("The 'name' parameter is null."); //$NON-NLS-1$
-        }
-        // Check if the name is a predefined one
-        Level result = levels.get(name);
-        if (null != result) {
-            return result;
-        }
-        // Try to parse the name as an integer
-        try {
-            int v = Integer.parseInt(name);
-            result = new Level(name, v);
-            return result;
-        } catch (NumberFormatException e) {
-            throw new IllegalArgumentException("Cannot parse this name: " //$NON-NLS-1$
-                    + name);
-        }
-    }
-
-    /**
-     * Gets the localized name of this level. The default locale is used. If no
-     * resource bundle is associated with this <code>Level</code>, the
-     * original level name is returned.
-     * 
-     * @return the localized name of this level
-     */
-    public String getLocalizedName() {
-        String result = name;
-        if (null != resourceBundleName && null == rb) {
-            try {
-                rb = ResourceBundle.getBundle(resourceBundleName);
-            } catch (Exception e) {
-                rb = null;
-            }
-        }
-        if (null != rb) {
-            try {
-                result = rb.getString(name);
-            } catch (Exception e) {
-                result = name;
-            }
-        }
-        return result;
-    }
-
-    /*
-     * Maintains the Object uniqueness property across serialization.
-     */
-    private Object readResolve() {
-        String levelName = this.getName();
-        Level result = levels.get(levelName);
-
-        if (null != result) {
-            boolean sameResourceBundle = (this.resourceBundleName == null ? result
-                    .getResourceBundleName() == null
-                    : this.resourceBundleName.equals(result
-                            .getResourceBundleName()));
-            if (result.intValue() == this.value && sameResourceBundle) {
-                return result;
-            }
-        }
-        return this;
-    }
-
-    /*
-     * -------------------------------------------------------------------
-     * Methods overriding parent class Object
-     * -------------------------------------------------------------------
-     */
-
-    /**
-     * Compares two <code>Level</code> objects for equality. They are
-     * considered to be equal if they have the same value.
-     * 
-     * @param o
-     *            the other object to be compared with
-     * @return <code>true</code> if this object equals to the supplied object,
-     *         otherwise <code>false</code>
-     */
-    public boolean equals(Object o) {
-        if (!(o instanceof Level)) {
-            return false;
-        }
-        return ((Level) o).intValue() == this.value;
-    }
-
-    /**
-     * Returns the hash code of this <code>Level</code> object.
-     * 
-     * @return the hash code of this <code>Level</code> object
-     */
-    public int hashCode() {
-        return this.value;
-    }
-
-    /**
-     * Returns the string representation of this <code>Level</code> object.
-     * Usually this will include its name.
-     * 
-     * @return the string representation of this <code>Level</code> object
-     */
-    public final String toString() {
-        return this.name;
-    }
-
-}
-
+/* Copyright 2004 The Apache Software Foundation or its licensors, as applicable
+ * 
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+
+package java.util.logging;
+
+import java.io.Serializable;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.ResourceBundle;
+
+/**
+ * <code>Level</code> objects are used to indicate the level of logging. There
+ * are a set of predefined logging levels, each associated with an integer
+ * value. Enabling a certain logging level also enables all logging levels with
+ * larger values.
+ * <p>
+ * The predefined levels in ascending order are FINEST, FINER, FINE, CONFIG,
+ * INFO, WARNING, SEVERE. There are two additional predefined levels, which are
+ * ALL and OFF. ALL indicates logging all messages, and OFF indicates logging no
+ * messages.
+ * </p>
+ * 
+ */
+public class Level implements Serializable {
+    
+    
+    //for serialization compatibility
+    private static final long serialVersionUID = -8176160795706313070L;    
+
+    /*
+     * -------------------------------------------------------------------
+     * Constants
+     * -------------------------------------------------------------------
+     */
+
+	/*
+     * -------------------------------------------------------------------
+     * Class variables
+     * -------------------------------------------------------------------
+     */
+    private static Map<String, Level> levels = new HashMap<String, Level>();
+	
+    // The following string constants define the name of all predefined levels.
+    private static final String SEVERESTR = "SEVERE"; //$NON-NLS-1$
+
+    private static final String WARNINGSTR = "WARNING"; //$NON-NLS-1$
+
+    private static final String INFOSTR = "INFO"; //$NON-NLS-1$
+
+    private static final String CONFIGSTR = "CONFIG"; //$NON-NLS-1$
+
+    private static final String FINESTR = "FINE"; //$NON-NLS-1$
+
+    private static final String FINERSTR = "FINER"; //$NON-NLS-1$
+
+    private static final String FINESTSTR = "FINEST"; //$NON-NLS-1$
+
+    private static final String OFFSTR = "OFF"; //$NON-NLS-1$
+
+    private static final String ALLSTR = "ALL"; //$NON-NLS-1$
+
+    /**
+     * The SEVERE level indicates a severe failure.
+     */
+    public static final Level SEVERE = new Level(SEVERESTR, 1000);
+
+    /**
+     * The WARNING level indicates a warning.
+     */
+    public static final Level WARNING = new Level(WARNINGSTR, 900);
+
+    /**
+     * The INFO level indicates an informative message.
+     */
+    public static final Level INFO = new Level(INFOSTR, 800);
+
+    /**
+     * The CONFIG level indicates a static configuration message.
+     */
+    public static final Level CONFIG = new Level(CONFIGSTR, 700);
+
+    /**
+     * The FINE level provides tracing messages.
+     */
+    public static final Level FINE = new Level(FINESTR, 500);
+
+    /**
+     * The FINER level provides more detailed tracing messages.
+     */
+    public static final Level FINER = new Level(FINERSTR, 400);
+
+    /**
+     * The FINEST level provides highly detailed tracing messages.
+     */
+    public static final Level FINEST = new Level(FINESTSTR, 300);
+
+    /**
+     * The OFF level provides no logging messages.
+     */
+    public static final Level OFF = new Level(OFFSTR, Integer.MAX_VALUE);
+
+    /**
+     * The ALL level provides all logging messages.
+     */
+    public static final Level ALL = new Level(ALLSTR, Integer.MIN_VALUE);
+
+
+    /*
+     * -------------------------------------------------------------------
+     * Global initialization
+     * -------------------------------------------------------------------
+     */
+
+    static {
+		levels.remove(null);
+    }
+
+    /*
+     * -------------------------------------------------------------------
+     * Instance variables
+     * -------------------------------------------------------------------
+     */
+
+    /**
+     * The name of this Level.
+     * 
+     * @serial
+     */
+    private final String name;
+
+    /**
+     * The integer value indicating the level.
+     * 
+     * @serial
+     */
+    private final int value;
+
+    /**
+     * The name of the resource bundle used to localize the level name.
+     * 
+     * @serial
+     */
+    private final String resourceBundleName;
+
+    /*
+     * The resource bundle associated with this level, used to localize the
+     * level name.
+     */
+    private transient ResourceBundle rb;
+
+    /*
+     * -------------------------------------------------------------------
+     * Constructors
+     * -------------------------------------------------------------------
+     */
+
+    /**
+     * Constructs an instance of <code>Level</code> taking the supplied name
+     * and level value.
+     * 
+     * @param name
+     *            name of the level
+     * @param level
+     *            an integer value indicating the level
+     */
+    protected Level(String name, int level) {
+        this(name, level, null);
+    }
+
+    /**
+     * Constructs an instance of <code>Level</code> taking the supplied name
+     * and level value.
+     * 
+     * @param name
+     *            name of the level
+     * @param level
+     *            an integer value indicating the level
+     * @param resourceBundleName
+     *            the name of the resource bundle to use
+     */
+    protected Level(String name, int level, String resourceBundleName) {
+        if (null == name) {
+            throw new NullPointerException("The 'name' parameter is null."); //$NON-NLS-1$
+        }
+        this.name = name;
+        this.value = level;
+        this.resourceBundleName = resourceBundleName;
+		//put value into known values list in Constructor
+		if(null==levels.get(name)){
+			levels.put(name,this);
+		}
+		if(null==levels.get(String.valueOf(level))){
+			levels.put(String.valueOf(this.intValue()), this);
+		}
+    }
+
+    /*
+     * -------------------------------------------------------------------
+     * Methods
+     * -------------------------------------------------------------------
+     */
+
+    /**
+     * Gets the name of this <code>Level</code>.
+     * 
+     * @return the name of this <code>Level</code>
+     */
+    public String getName() {
+        return this.name;
+    }
+
+    /**
+     * Gets the name of the resource bundle associated with this
+     * <code>Level</code>.
+     * 
+     * @return the name of the resource bundle associated with this
+     *         <code>Level</code>
+     */
+    public String getResourceBundleName() {
+        return this.resourceBundleName;
+    }
+
+    /**
+     * Gets the integer value indicating this <code>Level</code>.
+     * 
+     * @return the integer value indicating this <code>Level</code>
+     */
+    public final int intValue() {
+        return this.value;
+    }
+
+    /**
+     * Parses a level name into a <code>Level</code> object.
+     * 
+     * @param name
+     *            the name of the desired level, which cannot be null
+     * @return a <code>Level</code> object with the specified name
+     * @throws NullPointerException
+     *             If <code>name</code> is null.
+     * @throws IllegalArgumentException
+     *             When <code>name</code> cannot be parsed.
+     */
+    public static final Level parse(String name) {
+        if (null == name) {
+            throw new NullPointerException("The 'name' parameter is null."); //$NON-NLS-1$
+        }
+        // Check if the name is a predefined one
+        Level result = levels.get(name);
+        if (null != result) {
+            return result;
+        }
+        // Try to parse the name as an integer
+        try {
+            int v = Integer.parseInt(name);
+            result = new Level(name, v);
+            return result;
+        } catch (NumberFormatException e) {
+            throw new IllegalArgumentException("Cannot parse this name: " //$NON-NLS-1$
+                    + name);
+        }
+    }
+
+    /**
+     * Gets the localized name of this level. The default locale is used. If no
+     * resource bundle is associated with this <code>Level</code>, the
+     * original level name is returned.
+     * 
+     * @return the localized name of this level
+     */
+    public String getLocalizedName() {
+        String result = name;
+        if (null != resourceBundleName && null == rb) {
+            try {
+                rb = ResourceBundle.getBundle(resourceBundleName);
+            } catch (Exception e) {
+                rb = null;
+            }
+        }
+        if (null != rb) {
+            try {
+                result = rb.getString(name);
+            } catch (Exception e) {
+                result = name;
+            }
+        }
+        return result;
+    }
+
+    /*
+     * Maintains the Object uniqueness property across serialization.
+     */
+    private Object readResolve() {
+        String levelName = this.getName();
+        Level result = levels.get(levelName);
+
+        if (null != result) {
+            boolean sameResourceBundle = (this.resourceBundleName == null ? result
+                    .getResourceBundleName() == null
+                    : this.resourceBundleName.equals(result
+                            .getResourceBundleName()));
+            if (result.intValue() == this.value && sameResourceBundle) {
+                return result;
+            }
+        }
+        return this;
+    }
+
+    /*
+     * -------------------------------------------------------------------
+     * Methods overriding parent class Object
+     * -------------------------------------------------------------------
+     */
+
+    /**
+     * Compares two <code>Level</code> objects for equality. They are
+     * considered to be equal if they have the same value.
+     * 
+     * @param o
+     *            the other object to be compared with
+     * @return <code>true</code> if this object equals to the supplied object,
+     *         otherwise <code>false</code>
+     */
+    public boolean equals(Object o) {
+        if (!(o instanceof Level)) {
+            return false;
+        }
+        return ((Level) o).intValue() == this.value;
+    }
+
+    /**
+     * Returns the hash code of this <code>Level</code> object.
+     * 
+     * @return the hash code of this <code>Level</code> object
+     */
+    public int hashCode() {
+        return this.value;
+    }
+
+    /**
+     * Returns the string representation of this <code>Level</code> object.
+     * Usually this will include its name.
+     * 
+     * @return the string representation of this <code>Level</code> object
+     */
+    public final String toString() {
+        return this.name;
+    }
+
+}
+

Propchange: incubator/harmony/enhanced/classlib/trunk/modules/logging/src/main/java/java/util/logging/Level.java
------------------------------------------------------------------------------
    svn:eol-style = native

Modified: incubator/harmony/enhanced/classlib/trunk/modules/logging/src/main/java/java/util/logging/LogManager.java
URL: http://svn.apache.org/viewvc/incubator/harmony/enhanced/classlib/trunk/modules/logging/src/main/java/java/util/logging/LogManager.java?view=diff&rev=441006&r1=441005&r2=441006
==============================================================================
--- incubator/harmony/enhanced/classlib/trunk/modules/logging/src/main/java/java/util/logging/LogManager.java (original)
+++ incubator/harmony/enhanced/classlib/trunk/modules/logging/src/main/java/java/util/logging/LogManager.java Thu Sep  7 00:32:50 2006
@@ -1,591 +1,591 @@
-/* Copyright 2004, 2006 The Apache Software Foundation or its licensors, as applicable
- * 
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- * 
- *     http://www.apache.org/licenses/LICENSE-2.0
- * 
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package java.util.logging;
-
-import java.beans.PropertyChangeListener;
-import java.beans.PropertyChangeSupport;
-import java.io.BufferedInputStream;
-import java.io.File;
-import java.io.FileInputStream;
-import java.io.IOException;
-import java.io.InputStream;
-import java.security.AccessController;
-import java.security.PrivilegedAction;
-import java.util.Enumeration;
-import java.util.Hashtable;
-import java.util.Iterator;
-import java.util.Properties;
-import java.util.StringTokenizer;
-
-/**
- * <code>LogManager</code> is used to maintain configuration properties of the
- * logging framework, and to manage a hierarchical namespace of all named
- * <code>Logger</code> objects.
- * <p>
- * There is only one global <code>LogManager</code> instance in the
- * application, which can be get by calling static method
- * <code>LogManager.getLogManager()</code>. This instance is created and
- * initialized during class initialization and cannot be changed.
- * </p>
- * <p>
- * The <code>LogManager</code> class can be specified by
- * java.util.logging.manager system property, if the property is unavailable or
- * invalid, the default class <code>java.util.logging.LogManager</code> will
- * be used.
- * </p>
- * <p>
- * When initialization, <code>LogManager</code> read its configuration from a
- * properties file, which by default is the "lib/logging.properties" in the JRE
- * directory.
- * </p>
- * <p>
- * However, two optional system properties can be used to customize the initial
- * configuration process of <code>LogManager</code>.
- * <ul>
- * <li>"java.util.logging.config.class"</li>
- * <li>"java.util.logging.config.file"</li>
- * </ul>
- * </p>
- * <p>
- * These two properties can be set in three ways, by the Preferences API, by the
- * "java" command line property definitions, or by system property definitions
- * passed to JNI_CreateJavaVM.
- * </p>
- * <p>
- * The "java.util.logging.config.class" should specifies a class name. If it is
- * set, this given class will be loaded and instantiated during
- * <code>LogManager</code> initialization, so that this object's default
- * constructor can read the initial configuration and define properties for
- * <code>LogManager</code>.
- * </p>
- * <p>
- * If "java.util.logging.config.class" property is not set, or it is invalid, or
- * some exception is thrown during the instantiation, then the
- * "java.util.logging.config.file" system property can be used to specify a
- * properties file. The <code>LogManager</code> will read initial
- * configuration from this file.
- * </p>
- * <p>
- * If neither of these properties is defined, or some exception is thrown
- * during these two properties using, the <code>LogManager</code> will read
- * its initial configuration from default properties file, as described above.
- * </p>
- * <p>
- * The global logging properties may include:
- * <ul>
- * <li>"handlers". This property's values should be a list of class names for
- * handler classes separated by whitespace, these classes must be subclasses of
- * <code>Handler</code> and each must have a default constructor, these
- * classes will be loaded, instantiated and registered as handlers on the root
- * <code>Logger</code> (the <code>Logger</code> named ""). These
- * <code>Handler</code>s maybe initialized lazily.</li>
- * <li>"config". The property defines a list of class names separated by
- * whitespace. Each class must have a default constructor, in which it can
- * update the logging configuration, such as levels, handlers, or filters for
- * some logger, etc. These classes will be loaded and instantiated during
- * <code>LogManager</code> configuration</li>
- * </ul>
- * </p>
- * <p>
- * This class, together with any handler and configuration classes associated
- * with it, <b>must</b> be loaded from the system classpath when
- * <code>LogManager</code> configuration occurs.
- * </p>
- * <p>
- * Besides global properties, the properties for loggers and Handlers can be
- * specified in the property files. The names of these properties will start
- * with the complete dot separated names for the handlers or loggers.
- * </p>
- * <p>
- * In the <code>LogManager</code>'s hierarchical namespace,
- * <code>Loggers</code> are organized based on their dot separated names. For
- * example, "x.y.z" is child of "x.y".
- * </p>
- * <p>
- * Levels for <code>Loggers</code> can be defined by properties whose name end
- * with ".level". Thus "alogger.level" defines a level for the logger named as
- * "alogger" and for all its children in the naming hierarchy. Log levels
- * properties are read and applied in the same order as they are specified in
- * the property file. The root logger's level can be defined by the property
- * named as ".level".
- * </p>
- * <p>
- * All methods on this type can be taken as being thread safe.
- * </p>
- * 
- */
-public class LogManager {
-    /*
-     * -------------------------------------------------------------------
-     * Class variables
-     * -------------------------------------------------------------------
-     */
-
-    // The line separator of the underlying OS
-    // Use privileged code to read the line.separator system property
-    private static final String lineSeparator = getPrivilegedSystemProperty("line.separator"); //$NON-NLS-1$
-
-    // The shared logging permission
-    private static final LoggingPermission perm = new LoggingPermission(
-            "control", null); //$NON-NLS-1$
-
-    // the singleton instance
-    private static LogManager manager;
-    
-    /**
-     * <p>The String value of the {@link LoggingMXBean}'s ObjectName.</p>
-     */
-    public static final String LOGGING_MXBEAN_NAME = "java.util.logging:type=Logging";
-
-    public static LoggingMXBean getLoggingMXBean() {
-        throw new AssertionError("This method is not currently implemented.");
-    }
-    /*
-     * -------------------------------------------------------------------
-     * Instance variables
-     * -------------------------------------------------------------------
-     */
-    private Hashtable<String, Logger> loggers;
-
-    // the configuration properties
-    private Properties props;
-
-    // the property change listener
-    private PropertyChangeSupport listeners;
-
-    /*
-     * -------------------------------------------------------------------
-     * Global initialization
-     * -------------------------------------------------------------------
-     */
-
-    static {
-		// init LogManager singleton instance
-		AccessController.doPrivileged(new PrivilegedAction<Object>() {
-			public Object run() {
-				String className = System.getProperty("java.util.logging.manager"); //$NON-NLS-1$
-				if (null != className) {
-					manager = (LogManager) getInstanceByClass(className);
-				}
-				if (null == manager) {
-					manager = new LogManager();
-				}
-
-				// read configuration
-				try {
-					manager.readConfigurationImpl(true);
-				} catch (Exception e) {
-					e.printStackTrace();
-				}
-
-				// if global logger has been initialized, set root as its parent
-                Logger root = manager.getLogger("");
-				if (null != Logger.global && null != root) {
-					Logger.global.setParent(root);
-				}
-				return null;
-			}
-		});
-	}
-
-    /**
-     * Default constructor. This is not public because there should be only one
-     * <code>LogManager</code> instance, which can be get by
-     * <code>LogManager.getLogManager(</code>. This is protected so that
-     * application can subclass the object.
-     */
-    protected LogManager() {
-        loggers = new Hashtable<String, Logger>();
-        props = new Properties();
-        listeners = new PropertyChangeSupport(this);
-        // add shutdown hook to ensure that the associated resource will be
-        // freed when JVM exits
-        AccessController.doPrivileged(new PrivilegedAction<Object>() {
-            public Object run() {
-                Runtime.getRuntime().addShutdownHook(new Thread() {
-                    public void run() {
-                        reset();
-                    }
-                });
-                return null;
-            }
-        });
-    }
-
-    /*
-     * -------------------------------------------------------------------
-     * Methods
-     * -------------------------------------------------------------------
-     */
-    /*
-     * Package private utilities Returns the line separator of the underlying
-     * OS.
-     */
-    static String getSystemLineSeparator() {
-        return lineSeparator;
-    }
-
-    /**
-     * Check that the caller has <code>LoggingPermission("control")</code> so
-     * that it is trusted to modify the configuration for logging framework. If
-     * the check passes, just return, otherwise <code>SecurityException</code>
-     * will be thrown.
-     * 
-     * @throws SecurityException
-     *             if there is a security manager in operation and the invoker
-     *             of this method does not have the required security permission
-     *             <code>LoggingPermission("control")</code>
-     */
-    public void checkAccess() {
-        if (null != System.getSecurityManager()) {
-            System.getSecurityManager().checkPermission(perm);
-        }
-    }
-
-    /**
-     * Add a given logger into the hierarchical namespace. The
-     * <code>Logger.addLogger()</code> factory methods call this method to add
-     * newly created Logger. This returns false if a logger with the given name
-     * has existed in the namespace
-     * <p>
-     * Note that the <code>LogManager</code> may only retain weak references
-     * to registered loggers. In order to prevent <code>Logger</code> objects
-     * from being unexpectedly garbage collected it is necessary for
-     * <i>applications</i> to maintain references to them.
-     * </p>
-     * 
-     * @param logger
-     *            the logger to be added
-     * @return true if the given logger is added into the namespace
-     *         successfully, false if the logger of given name has existed in
-     *         the namespace
-     */
-    public synchronized boolean addLogger(Logger logger) {
-        String name = logger.getName();
-        if (null != loggers.get(name)) {
-            return false;
-        }
-        addToFamilyTree(logger, name);
-        loggers.put(name, logger);
-
-        setLoggerLevel(logger, name, false);
-        logger.manager = this;
-        return true;
-    }
-
-    private void setLoggerLevel(Logger logger, String loggerName,
-                                boolean inherit) {
-        String configedLevel = getProperty(loggerName + ".level");
-        if (null != configedLevel) {
-            try {
-                logger.setLevel(Level.parse(configedLevel));
-            } catch (IllegalArgumentException e) {
-                // Print invalid level setting to the screen
-                System.err.print("Invalid level name: " + configedLevel
-                        + ".");
-            }
-        } else if (inherit) {
-            logger.setLevel(null);
-        }
-    }
-
-    private void addToFamilyTree(Logger logger, String name) {
-        Logger parent = null;
-        // find parent
-        int lastSeparator;
-        String parentName = name;
-        while ((lastSeparator = parentName.lastIndexOf('.')) != -1) {
-            parentName = parentName.substring(0, lastSeparator);
-            if ((parent = loggers.get(parentName)) != null) {
-                logger.internalSetParent(parent);
-                break;
-            }
-        }
-        if (parent == null && null != (parent = loggers.get(""))) {
-            logger.internalSetParent(parent);
-        }
-
-        // find children
-        Logger[] values = loggers.values().toArray(new Logger[0]);
-        for (Logger child : values) {
-            Logger oldParent = child.getParent();
-            if (parent == oldParent
-                    && (name.length() == 0 || child.getName().startsWith(
-                            name + '.'))) {
-                child.setParent(logger);
-                if (null != oldParent) {
-                    //-- remove from old parent as the parent has been changed
-                    oldParent.removeChild(child);
-                }
-            }
-        }
-    }
-
-    /**
-     * Get the logger with the given name
-     * 
-     * @param name
-     *            name of logger
-     * @return logger with given name, or null if nothing is found
-     */
-    public synchronized Logger getLogger(String name) {
-        return loggers.get(name);
-    }
-
-    /**
-     * Get a <code>Enumeration</code> of all registered logger names
-     * 
-     * @return enumeration of registered logger names
-     */
-    public synchronized Enumeration<String> getLoggerNames() {
-        return loggers.keys();
-    }
-
-    /**
-     * Get the global <code>LogManager</code> instance
-     * 
-     * @return the global <code>LogManager</code> instance
-     */
-    public static LogManager getLogManager() {
-        return manager;
-    }
-
-    /**
-     * Get the value of property with given name
-     * 
-     * @param name
-     *            the name of property
-     * @return the value of property
-     */
-    public synchronized String getProperty(String name) {
-        return props.getProperty(name);
-    }
-
-    /**
-     * Re-initialize the properties and configuration. The initialization process
-     * is same as the <code>LogManager</code> instantiation.
-     * <p>
-     * A <code>PropertyChangeEvent</code> must be fired.
-     * </p>
-     * 
-     * @throws IOException
-     *             if any IO related problems happened
-     * @throws SecurityException
-     *             if security manager exists and it determines that caller does
-     *             not have the required permissions to perform this action
-     */
-    public void readConfiguration() throws IOException {
-        readConfigurationImpl(false);
-    }
-
-    // use privilege code to get system property
-    static String getPrivilegedSystemProperty(final String key) {
-        return AccessController.doPrivileged(new PrivilegedAction<String>() {
-            public String run() {
-                return System.getProperty(key);
-            }
-        });
-    }
-
-    // use SystemClassLoader to load class from system classpath
-    static Object getInstanceByClass(final String className) {
-        try {
-            Class<?> clazz = ClassLoader.getSystemClassLoader().loadClass(
-                    className);
-            return clazz.newInstance();
-        } catch (Exception e) {
-            e.printStackTrace();
-            return null;
-        }
-
-    }
-
-    // actual default initialization process
-    private synchronized void readConfigurationImpl(boolean createLoggers) throws IOException {
-        checkAccess();
-        boolean needInit = true;
-
-        // check config class
-        String configClassName = System.getProperty("java.util.logging.config.class"); //$NON-NLS-1$
-        if (null != configClassName) {
-            if (null == getInstanceByClass(configClassName)) {
-                throw new RuntimeException("Cannot instantiate " //$NON-NLS-1$
-                        + configClassName);
-            }
-            needInit = false;
-        }
-        // if config class failed, check config file
-        if (needInit) {
-            String configFile = System.getProperty("java.util.logging.config.file"); //$NON-NLS-1$
-            if (null == configFile) {
-                // if cannot find configFile, use default logging.properties
-                configFile = new StringBuilder().append(
-                        System.getProperty("java.home")).append(File.separator) //$NON-NLS-1$
-                        .append("lib").append(File.separator).append( //$NON-NLS-1$
-                                "logging.properties").toString(); //$NON-NLS-1$
-            }
-            InputStream input = null;
-            try {
-                input = new BufferedInputStream(new FileInputStream(configFile));
-                readConfigurationImpl(input, createLoggers);
-            } finally {
-                try {
-                    input.close();
-                } catch (Exception e) {// ignore
-                }
-            }
-        }
-    }
-
-    // actual initialization process from a given input stream
-    private synchronized void readConfigurationImpl(InputStream ins, boolean createLoggers)
-            throws IOException {
-        reset();
-        props.load(ins);
-
-        // configs
-        parseConfigProp();
-
-        // set levels for logger
-        initLoggers(createLoggers);
-        listeners.firePropertyChange(null, null, null);
-    }
-
-    // init "level" properties for all registered loggers
-    private void initLoggers(boolean createLoggers) {
-        Enumeration<?> enumeration = props.propertyNames();
-        while (enumeration.hasMoreElements()) {
-            // search for all properties whose name is ended with ".level"
-            String property = (String) enumeration.nextElement();
-            if (property.endsWith(".level")) { //$NON-NLS-1$
-                String loggerName = property.substring(0,
-                        property.length() - ".level".length());
-                Logger l = createLoggers?Logger.getLogger(loggerName):loggers.get(loggerName);
-                if (null != l) {
-                    setLoggerLevel(l, loggerName, true);
-                }
-            }else if(createLoggers && property.endsWith(".handlers")){ //$NON-NLS-1$
-                String loggerName = property.substring(0,
-                        property.length() - ".handlers".length());
-                Logger.getLogger(loggerName);
-                //lazily load handlers because some of them are expensive
-            }
-        }
-    }
-
-    // parse property "config" and apply setting
-    private void parseConfigProp() {
-        String configs = props.getProperty("config"); //$NON-NLS-1$
-        if (null != configs) {
-            StringTokenizer st = new StringTokenizer(configs, " "); //$NON-NLS-1$
-            while (st.hasMoreTokens()) {
-                String configerName = st.nextToken();
-                getInstanceByClass(configerName);
-            }
-        }
-    }
-
-    /**
-     * Re-initialize the properties and configuration from the given
-     * <code>InputStream</code>
-     * <p>
-     * A <code>PropertyChangeEvent</code> must be fired.
-     * </p>
-     * 
-     * @param ins
-     *            the input stream.
-     * @throws IOException
-     *             if any IO related problems happened
-     * @throws SecurityException
-     *             if security manager exists and it determines that caller does
-     *             not have the required permissions to perform this action
-     */
-    public void readConfiguration(InputStream ins) throws IOException {
-        checkAccess();
-        readConfigurationImpl(ins, false);
-    }
-
-    /**
-     * Reset configuration.
-     * <p>
-     * All handlers are closed and removed from any named loggers. All loggers'
-     * level is set to null, except the root logger's level is set to
-     * <code>Level.INFO</code>.
-     * </p>
-     * 
-     * @throws SecurityException
-     *             if security manager exists and it determines that caller does
-     *             not have the required permissions to perform this action
-     */
-    public synchronized void reset() {
-        checkAccess();
-        props.clear();
-        Iterator<Logger> it = loggers.values().iterator();
-        while (it.hasNext()) {
-            Logger l = (Logger) it.next();
-            l.setLevel(null);
-            if(l.handlers != null){
-                for (Handler element : l.handlers) {
-                    // close all handlers, when unknown exceptions happen,
-                    // ignore them and go on
-                    try {
-                        element.close();
-                    } catch (Exception e) {
-                        // Ignored.
-                    }
-                }
-                l.handlers = null;
-            }
-        }
-        Logger root = loggers.get("");
-        if (null != root) {
-            root.setLevel(Level.INFO);
-        }
-    }
-
-    /**
-     * Add a <code>PropertyChangeListener</code>, which will be invoked when
-     * the properties are reread.
-     * 
-     * @param l
-     *            the <code>PropertyChangeListener</code> to be added
-     * @throws SecurityException
-     *             if security manager exists and it determines that caller does
-     *             not have the required permissions to perform this action
-     */
-    public void addPropertyChangeListener(PropertyChangeListener l) {
-        if(l == null){
-            throw new NullPointerException();
-        }
-        checkAccess();
-        listeners.addPropertyChangeListener(l);
-    }
-
-    /**
-     * Remove a <code>PropertyChangeListener</code>, do nothing if the given
-     * listener is not found.
-     * 
-     * @param l
-     *            the <code>PropertyChangeListener</code> to be removed
-     * @throws SecurityException
-     *             if security manager exists and it determines that caller does
-     *             not have the required permissions to perform this action
-     */
-    public void removePropertyChangeListener(PropertyChangeListener l) {
-        checkAccess();
-        listeners.removePropertyChangeListener(l);
-    }
-}
+/* Copyright 2004, 2006 The Apache Software Foundation or its licensors, as applicable
+ * 
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package java.util.logging;
+
+import java.beans.PropertyChangeListener;
+import java.beans.PropertyChangeSupport;
+import java.io.BufferedInputStream;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.security.AccessController;
+import java.security.PrivilegedAction;
+import java.util.Enumeration;
+import java.util.Hashtable;
+import java.util.Iterator;
+import java.util.Properties;
+import java.util.StringTokenizer;
+
+/**
+ * <code>LogManager</code> is used to maintain configuration properties of the
+ * logging framework, and to manage a hierarchical namespace of all named
+ * <code>Logger</code> objects.
+ * <p>
+ * There is only one global <code>LogManager</code> instance in the
+ * application, which can be get by calling static method
+ * <code>LogManager.getLogManager()</code>. This instance is created and
+ * initialized during class initialization and cannot be changed.
+ * </p>
+ * <p>
+ * The <code>LogManager</code> class can be specified by
+ * java.util.logging.manager system property, if the property is unavailable or
+ * invalid, the default class <code>java.util.logging.LogManager</code> will
+ * be used.
+ * </p>
+ * <p>
+ * When initialization, <code>LogManager</code> read its configuration from a
+ * properties file, which by default is the "lib/logging.properties" in the JRE
+ * directory.
+ * </p>
+ * <p>
+ * However, two optional system properties can be used to customize the initial
+ * configuration process of <code>LogManager</code>.
+ * <ul>
+ * <li>"java.util.logging.config.class"</li>
+ * <li>"java.util.logging.config.file"</li>
+ * </ul>
+ * </p>
+ * <p>
+ * These two properties can be set in three ways, by the Preferences API, by the
+ * "java" command line property definitions, or by system property definitions
+ * passed to JNI_CreateJavaVM.
+ * </p>
+ * <p>
+ * The "java.util.logging.config.class" should specifies a class name. If it is
+ * set, this given class will be loaded and instantiated during
+ * <code>LogManager</code> initialization, so that this object's default
+ * constructor can read the initial configuration and define properties for
+ * <code>LogManager</code>.
+ * </p>
+ * <p>
+ * If "java.util.logging.config.class" property is not set, or it is invalid, or
+ * some exception is thrown during the instantiation, then the
+ * "java.util.logging.config.file" system property can be used to specify a
+ * properties file. The <code>LogManager</code> will read initial
+ * configuration from this file.
+ * </p>
+ * <p>
+ * If neither of these properties is defined, or some exception is thrown
+ * during these two properties using, the <code>LogManager</code> will read
+ * its initial configuration from default properties file, as described above.
+ * </p>
+ * <p>
+ * The global logging properties may include:
+ * <ul>
+ * <li>"handlers". This property's values should be a list of class names for
+ * handler classes separated by whitespace, these classes must be subclasses of
+ * <code>Handler</code> and each must have a default constructor, these
+ * classes will be loaded, instantiated and registered as handlers on the root
+ * <code>Logger</code> (the <code>Logger</code> named ""). These
+ * <code>Handler</code>s maybe initialized lazily.</li>
+ * <li>"config". The property defines a list of class names separated by
+ * whitespace. Each class must have a default constructor, in which it can
+ * update the logging configuration, such as levels, handlers, or filters for
+ * some logger, etc. These classes will be loaded and instantiated during
+ * <code>LogManager</code> configuration</li>
+ * </ul>
+ * </p>
+ * <p>
+ * This class, together with any handler and configuration classes associated
+ * with it, <b>must</b> be loaded from the system classpath when
+ * <code>LogManager</code> configuration occurs.
+ * </p>
+ * <p>
+ * Besides global properties, the properties for loggers and Handlers can be
+ * specified in the property files. The names of these properties will start
+ * with the complete dot separated names for the handlers or loggers.
+ * </p>
+ * <p>
+ * In the <code>LogManager</code>'s hierarchical namespace,
+ * <code>Loggers</code> are organized based on their dot separated names. For
+ * example, "x.y.z" is child of "x.y".
+ * </p>
+ * <p>
+ * Levels for <code>Loggers</code> can be defined by properties whose name end
+ * with ".level". Thus "alogger.level" defines a level for the logger named as
+ * "alogger" and for all its children in the naming hierarchy. Log levels
+ * properties are read and applied in the same order as they are specified in
+ * the property file. The root logger's level can be defined by the property
+ * named as ".level".
+ * </p>
+ * <p>
+ * All methods on this type can be taken as being thread safe.
+ * </p>
+ * 
+ */
+public class LogManager {
+    /*
+     * -------------------------------------------------------------------
+     * Class variables
+     * -------------------------------------------------------------------
+     */
+
+    // The line separator of the underlying OS
+    // Use privileged code to read the line.separator system property
+    private static final String lineSeparator = getPrivilegedSystemProperty("line.separator"); //$NON-NLS-1$
+
+    // The shared logging permission
+    private static final LoggingPermission perm = new LoggingPermission(
+            "control", null); //$NON-NLS-1$
+
+    // the singleton instance
+    private static LogManager manager;
+    
+    /**
+     * <p>The String value of the {@link LoggingMXBean}'s ObjectName.</p>
+     */
+    public static final String LOGGING_MXBEAN_NAME = "java.util.logging:type=Logging";
+
+    public static LoggingMXBean getLoggingMXBean() {
+        throw new AssertionError("This method is not currently implemented.");
+    }
+    /*
+     * -------------------------------------------------------------------
+     * Instance variables
+     * -------------------------------------------------------------------
+     */
+    private Hashtable<String, Logger> loggers;
+
+    // the configuration properties
+    private Properties props;
+
+    // the property change listener
+    private PropertyChangeSupport listeners;
+
+    /*
+     * -------------------------------------------------------------------
+     * Global initialization
+     * -------------------------------------------------------------------
+     */
+
+    static {
+		// init LogManager singleton instance
+		AccessController.doPrivileged(new PrivilegedAction<Object>() {
+			public Object run() {
+				String className = System.getProperty("java.util.logging.manager"); //$NON-NLS-1$
+				if (null != className) {
+					manager = (LogManager) getInstanceByClass(className);
+				}
+				if (null == manager) {
+					manager = new LogManager();
+				}
+
+				// read configuration
+				try {
+					manager.readConfigurationImpl(true);
+				} catch (Exception e) {
+					e.printStackTrace();
+				}
+
+				// if global logger has been initialized, set root as its parent
+                Logger root = manager.getLogger("");
+				if (null != Logger.global && null != root) {
+					Logger.global.setParent(root);
+				}
+				return null;
+			}
+		});
+	}
+
+    /**
+     * Default constructor. This is not public because there should be only one
+     * <code>LogManager</code> instance, which can be get by
+     * <code>LogManager.getLogManager(</code>. This is protected so that
+     * application can subclass the object.
+     */
+    protected LogManager() {
+        loggers = new Hashtable<String, Logger>();
+        props = new Properties();
+        listeners = new PropertyChangeSupport(this);
+        // add shutdown hook to ensure that the associated resource will be
+        // freed when JVM exits
+        AccessController.doPrivileged(new PrivilegedAction<Object>() {
+            public Object run() {
+                Runtime.getRuntime().addShutdownHook(new Thread() {
+                    public void run() {
+                        reset();
+                    }
+                });
+                return null;
+            }
+        });
+    }
+
+    /*
+     * -------------------------------------------------------------------
+     * Methods
+     * -------------------------------------------------------------------
+     */
+    /*
+     * Package private utilities Returns the line separator of the underlying
+     * OS.
+     */
+    static String getSystemLineSeparator() {
+        return lineSeparator;
+    }
+
+    /**
+     * Check that the caller has <code>LoggingPermission("control")</code> so
+     * that it is trusted to modify the configuration for logging framework. If
+     * the check passes, just return, otherwise <code>SecurityException</code>
+     * will be thrown.
+     * 
+     * @throws SecurityException
+     *             if there is a security manager in operation and the invoker
+     *             of this method does not have the required security permission
+     *             <code>LoggingPermission("control")</code>
+     */
+    public void checkAccess() {
+        if (null != System.getSecurityManager()) {
+            System.getSecurityManager().checkPermission(perm);
+        }
+    }
+
+    /**
+     * Add a given logger into the hierarchical namespace. The
+     * <code>Logger.addLogger()</code> factory methods call this method to add
+     * newly created Logger. This returns false if a logger with the given name
+     * has existed in the namespace
+     * <p>
+     * Note that the <code>LogManager</code> may only retain weak references
+     * to registered loggers. In order to prevent <code>Logger</code> objects
+     * from being unexpectedly garbage collected it is necessary for
+     * <i>applications</i> to maintain references to them.
+     * </p>
+     * 
+     * @param logger
+     *            the logger to be added
+     * @return true if the given logger is added into the namespace
+     *         successfully, false if the logger of given name has existed in
+     *         the namespace
+     */
+    public synchronized boolean addLogger(Logger logger) {
+        String name = logger.getName();
+        if (null != loggers.get(name)) {
+            return false;
+        }
+        addToFamilyTree(logger, name);
+        loggers.put(name, logger);
+
+        setLoggerLevel(logger, name, false);
+        logger.manager = this;
+        return true;
+    }
+
+    private void setLoggerLevel(Logger logger, String loggerName,
+                                boolean inherit) {
+        String configedLevel = getProperty(loggerName + ".level");
+        if (null != configedLevel) {
+            try {
+                logger.setLevel(Level.parse(configedLevel));
+            } catch (IllegalArgumentException e) {
+                // Print invalid level setting to the screen
+                System.err.print("Invalid level name: " + configedLevel
+                        + ".");
+            }
+        } else if (inherit) {
+            logger.setLevel(null);
+        }
+    }
+
+    private void addToFamilyTree(Logger logger, String name) {
+        Logger parent = null;
+        // find parent
+        int lastSeparator;
+        String parentName = name;
+        while ((lastSeparator = parentName.lastIndexOf('.')) != -1) {
+            parentName = parentName.substring(0, lastSeparator);
+            if ((parent = loggers.get(parentName)) != null) {
+                logger.internalSetParent(parent);
+                break;
+            }
+        }
+        if (parent == null && null != (parent = loggers.get(""))) {
+            logger.internalSetParent(parent);
+        }
+
+        // find children
+        Logger[] values = loggers.values().toArray(new Logger[0]);
+        for (Logger child : values) {
+            Logger oldParent = child.getParent();
+            if (parent == oldParent
+                    && (name.length() == 0 || child.getName().startsWith(
+                            name + '.'))) {
+                child.setParent(logger);
+                if (null != oldParent) {
+                    //-- remove from old parent as the parent has been changed
+                    oldParent.removeChild(child);
+                }
+            }
+        }
+    }
+
+    /**
+     * Get the logger with the given name
+     * 
+     * @param name
+     *            name of logger
+     * @return logger with given name, or null if nothing is found
+     */
+    public synchronized Logger getLogger(String name) {
+        return loggers.get(name);
+    }
+
+    /**
+     * Get a <code>Enumeration</code> of all registered logger names
+     * 
+     * @return enumeration of registered logger names
+     */
+    public synchronized Enumeration<String> getLoggerNames() {
+        return loggers.keys();
+    }
+
+    /**
+     * Get the global <code>LogManager</code> instance
+     * 
+     * @return the global <code>LogManager</code> instance
+     */
+    public static LogManager getLogManager() {
+        return manager;
+    }
+
+    /**
+     * Get the value of property with given name
+     * 
+     * @param name
+     *            the name of property
+     * @return the value of property
+     */
+    public synchronized String getProperty(String name) {
+        return props.getProperty(name);
+    }
+
+    /**
+     * Re-initialize the properties and configuration. The initialization process
+     * is same as the <code>LogManager</code> instantiation.
+     * <p>
+     * A <code>PropertyChangeEvent</code> must be fired.
+     * </p>
+     * 
+     * @throws IOException
+     *             if any IO related problems happened
+     * @throws SecurityException
+     *             if security manager exists and it determines that caller does
+     *             not have the required permissions to perform this action
+     */
+    public void readConfiguration() throws IOException {
+        readConfigurationImpl(false);
+    }
+
+    // use privilege code to get system property
+    static String getPrivilegedSystemProperty(final String key) {
+        return AccessController.doPrivileged(new PrivilegedAction<String>() {
+            public String run() {
+                return System.getProperty(key);
+            }
+        });
+    }
+
+    // use SystemClassLoader to load class from system classpath
+    static Object getInstanceByClass(final String className) {
+        try {
+            Class<?> clazz = ClassLoader.getSystemClassLoader().loadClass(
+                    className);
+            return clazz.newInstance();
+        } catch (Exception e) {
+            e.printStackTrace();
+            return null;
+        }
+
+    }
+
+    // actual default initialization process
+    private synchronized void readConfigurationImpl(boolean createLoggers) throws IOException {
+        checkAccess();
+        boolean needInit = true;
+
+        // check config class
+        String configClassName = System.getProperty("java.util.logging.config.class"); //$NON-NLS-1$
+        if (null != configClassName) {
+            if (null == getInstanceByClass(configClassName)) {
+                throw new RuntimeException("Cannot instantiate " //$NON-NLS-1$
+                        + configClassName);
+            }
+            needInit = false;
+        }
+        // if config class failed, check config file
+        if (needInit) {
+            String configFile = System.getProperty("java.util.logging.config.file"); //$NON-NLS-1$
+            if (null == configFile) {
+                // if cannot find configFile, use default logging.properties
+                configFile = new StringBuilder().append(
+                        System.getProperty("java.home")).append(File.separator) //$NON-NLS-1$
+                        .append("lib").append(File.separator).append( //$NON-NLS-1$
+                                "logging.properties").toString(); //$NON-NLS-1$
+            }
+            InputStream input = null;
+            try {
+                input = new BufferedInputStream(new FileInputStream(configFile));
+                readConfigurationImpl(input, createLoggers);
+            } finally {
+                try {
+                    input.close();
+                } catch (Exception e) {// ignore
+                }
+            }
+        }
+    }
+
+    // actual initialization process from a given input stream
+    private synchronized void readConfigurationImpl(InputStream ins, boolean createLoggers)
+            throws IOException {
+        reset();
+        props.load(ins);
+
+        // configs
+        parseConfigProp();
+
+        // set levels for logger
+        initLoggers(createLoggers);
+        listeners.firePropertyChange(null, null, null);
+    }
+
+    // init "level" properties for all registered loggers
+    private void initLoggers(boolean createLoggers) {
+        Enumeration<?> enumeration = props.propertyNames();
+        while (enumeration.hasMoreElements()) {
+            // search for all properties whose name is ended with ".level"
+            String property = (String) enumeration.nextElement();
+            if (property.endsWith(".level")) { //$NON-NLS-1$
+                String loggerName = property.substring(0,
+                        property.length() - ".level".length());
+                Logger l = createLoggers?Logger.getLogger(loggerName):loggers.get(loggerName);
+                if (null != l) {
+                    setLoggerLevel(l, loggerName, true);
+                }
+            }else if(createLoggers && property.endsWith(".handlers")){ //$NON-NLS-1$
+                String loggerName = property.substring(0,
+                        property.length() - ".handlers".length());
+                Logger.getLogger(loggerName);
+                //lazily load handlers because some of them are expensive
+            }
+        }
+    }
+
+    // parse property "config" and apply setting
+    private void parseConfigProp() {
+        String configs = props.getProperty("config"); //$NON-NLS-1$
+        if (null != configs) {
+            StringTokenizer st = new StringTokenizer(configs, " "); //$NON-NLS-1$
+            while (st.hasMoreTokens()) {
+                String configerName = st.nextToken();
+                getInstanceByClass(configerName);
+            }
+        }
+    }
+
+    /**
+     * Re-initialize the properties and configuration from the given
+     * <code>InputStream</code>
+     * <p>
+     * A <code>PropertyChangeEvent</code> must be fired.
+     * </p>
+     * 
+     * @param ins
+     *            the input stream.
+     * @throws IOException
+     *             if any IO related problems happened
+     * @throws SecurityException
+     *             if security manager exists and it determines that caller does
+     *             not have the required permissions to perform this action
+     */
+    public void readConfiguration(InputStream ins) throws IOException {
+        checkAccess();
+        readConfigurationImpl(ins, false);
+    }
+
+    /**
+     * Reset configuration.
+     * <p>
+     * All handlers are closed and removed from any named loggers. All loggers'
+     * level is set to null, except the root logger's level is set to
+     * <code>Level.INFO</code>.
+     * </p>
+     * 
+     * @throws SecurityException
+     *             if security manager exists and it determines that caller does
+     *             not have the required permissions to perform this action
+     */
+    public synchronized void reset() {
+        checkAccess();
+        props.clear();
+        Iterator<Logger> it = loggers.values().iterator();
+        while (it.hasNext()) {
+            Logger l = (Logger) it.next();
+            l.setLevel(null);
+            if(l.handlers != null){
+                for (Handler element : l.handlers) {
+                    // close all handlers, when unknown exceptions happen,
+                    // ignore them and go on
+                    try {
+                        element.close();
+                    } catch (Exception e) {
+                        // Ignored.
+                    }
+                }
+                l.handlers = null;
+            }
+        }
+        Logger root = loggers.get("");
+        if (null != root) {
+            root.setLevel(Level.INFO);
+        }
+    }
+
+    /**
+     * Add a <code>PropertyChangeListener</code>, which will be invoked when
+     * the properties are reread.
+     * 
+     * @param l
+     *            the <code>PropertyChangeListener</code> to be added
+     * @throws SecurityException
+     *             if security manager exists and it determines that caller does
+     *             not have the required permissions to perform this action
+     */
+    public void addPropertyChangeListener(PropertyChangeListener l) {
+        if(l == null){
+            throw new NullPointerException();
+        }
+        checkAccess();
+        listeners.addPropertyChangeListener(l);
+    }
+
+    /**
+     * Remove a <code>PropertyChangeListener</code>, do nothing if the given
+     * listener is not found.
+     * 
+     * @param l
+     *            the <code>PropertyChangeListener</code> to be removed
+     * @throws SecurityException
+     *             if security manager exists and it determines that caller does
+     *             not have the required permissions to perform this action
+     */
+    public void removePropertyChangeListener(PropertyChangeListener l) {
+        checkAccess();
+        listeners.removePropertyChangeListener(l);
+    }
+}

Propchange: incubator/harmony/enhanced/classlib/trunk/modules/logging/src/main/java/java/util/logging/LogManager.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: incubator/harmony/enhanced/classlib/trunk/modules/logging/src/main/java/java/util/logging/LogRecord.java
------------------------------------------------------------------------------
    svn:eol-style = native



Mime
View raw message