/* LogManager.java -- a class for maintaining Loggers and managing
   configuration properties
   Copyright (C) 2002, 2005, 2006, 2007 Free Software Foundation, Inc.

This file is part of GNU Classpath.

GNU Classpath is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2, or (at your option)
any later version.

GNU Classpath is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
General Public License for more details.

You should have received a copy of the GNU General Public License
along with GNU Classpath; see the file COPYING.  If not, write to the
Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
02110-1301 USA.

Linking this library statically or dynamically with other modules is
making a combined work based on this library.  Thus, the terms and
conditions of the GNU General Public License cover the whole
combination.

As a special exception, the copyright holders of this library give you
permission to link this library with independent modules to produce an
executable, regardless of the license terms of these independent
modules, and to copy and distribute the resulting executable under
terms of your choice, provided that you also meet, for each linked
independent module, the terms and conditions of the license of that
module.  An independent module is a module which is not derived from
or based on this library.  If you modify this library, you may extend
this exception to your version of the library, but you are not
obligated to do so.  If you do not wish to do so, delete this
exception statement from your version. */


package java.util.logging;

import gnu.classpath.SystemProperties;

import java.beans.PropertyChangeListener;
import java.beans.PropertyChangeSupport;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.lang.ref.WeakReference;
import java.net.URL;
import java.util.Collections;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Properties;
import java.util.StringTokenizer;

/**
 * The <code>LogManager</code> maintains a hierarchical namespace
 * of Logger objects and manages properties for configuring the logging
 * framework. There exists only one single <code>LogManager</code>
 * per virtual machine. This instance can be retrieved using the
 * static method {@link #getLogManager()}.
 *
 * <p><strong>Configuration Process:</strong> The global LogManager
 * object is created and configured when the class
 * <code>java.util.logging.LogManager</code> is initialized.
 * The configuration process includes the subsequent steps:
 *
 * <ul>
 * <li>If the system property <code>java.util.logging.manager</code>
 *     is set to the name of a subclass of
 *     <code>java.util.logging.LogManager</code>, an instance of
 *     that subclass is created and becomes the global LogManager.
 *     Otherwise, a new instance of LogManager is created.</li>
 * <li>The <code>LogManager</code> constructor tries to create
 *     a new instance of the class specified by the system
 *     property <code>java.util.logging.config.class</code>.
 *     Typically, the constructor of this class will call
 *     <code>LogManager.getLogManager().readConfiguration(java.io.InputStream)</code>
 *     for configuring the logging framework.
 *     The configuration process stops at this point if
 *     the system property <code>java.util.logging.config.class</code>
 *     is set (irrespective of whether the class constructor
 *     could be called or an exception was thrown).</li>
 *
 * <li>If the system property <code>java.util.logging.config.class</code>
 *     is <em>not</em> set, the configuration parameters are read in from
 *     a file and passed to
 *     {@link #readConfiguration(java.io.InputStream)}.
 *     The name and location of this file are specified by the system
 *     property <code>java.util.logging.config.file</code>.</li>
 * <li>If the system property <code>java.util.logging.config.file</code>
 *     is not set, however, the contents of the URL
 *     "{gnu.classpath.home.url}/logging.properties" are passed to
 *     {@link #readConfiguration(java.io.InputStream)}.
 *     Here, "{gnu.classpath.home.url}" stands for the value of
 *     the system property <code>gnu.classpath.home.url</code>.</li>
 * </ul>
 *
 * <p>The <code>LogManager</code> has a level of <code>INFO</code> by
 * default, and this will be inherited by <code>Logger</code>s unless they
 * override it either by properties or programmatically.
 *
 * @author Sascha Brawer (brawer@acm.org)
 */
public class LogManager
{
  /**
   * The object name for the logging management bean.
   * @since 1.5
   */
  public static final String LOGGING_MXBEAN_NAME
    = "java.util.logging:type=Logging";

  /**
   * The singleton LogManager instance.
   */
  private static LogManager logManager;

  /**
   * The singleton logging bean.
   */
  private static LoggingMXBean loggingBean;

  /**
   * The registered named loggers; maps the name of a Logger to
   * a WeakReference to it.
   */
  private Map<String, WeakReference<Logger>> loggers;

  /**
   * The properties for the logging framework which have been
   * read in last.
   */
  private Properties properties;

  /**
   * A delegate object that provides support for handling
   * PropertyChangeEvents.  The API specification does not
   * mention which bean should be the source in the distributed
   * PropertyChangeEvents, but Mauve test code has determined that
   * the Sun J2SE 1.4 reference implementation uses the LogManager
   * class object. This is somewhat strange, as the class object
   * is not the bean with which listeners have to register, but
   * there is no reason for the GNU Classpath implementation to
   * behave differently from the reference implementation in
   * this case.
   */
  private final PropertyChangeSupport pcs = new PropertyChangeSupport( /* source bean */
                                                                      LogManager.class);

  protected LogManager()
  {
    loggers = new HashMap();
  }

  /**
   * Returns the globally shared LogManager instance.
   */
  public static synchronized LogManager getLogManager()
  {
    if (logManager == null)
      {
        logManager = makeLogManager();
        initLogManager();
      }
    return logManager;
  }

  private static final String MANAGER_PROPERTY = "java.util.logging.manager";

  private static LogManager makeLogManager()
  {
    String managerClassName = SystemProperties.getProperty(MANAGER_PROPERTY);
    LogManager manager = (LogManager) createInstance
      (managerClassName, LogManager.class, MANAGER_PROPERTY);
    if (manager == null)
      manager = new LogManager();
    return manager;
  }

  private static final String CONFIG_PROPERTY = "java.util.logging.config.class";

  private static void initLogManager()
  {
    LogManager manager = getLogManager();
    Logger.root.setLevel(Level.INFO);
    manager.addLogger(Logger.root);

    /* The Javadoc description of the class explains
     * what is going on here.
     */
    Object configurator = createInstance(System.getProperty(CONFIG_PROPERTY),
                                         /* must be instance of */ Object.class,
                                         CONFIG_PROPERTY);

    try
      {
        if (configurator == null)
          manager.readConfiguration();
      }
    catch (IOException ex)
      {
        /* FIXME: Is it ok to ignore exceptions here? */
      }
  }

  /**
   * Registers a listener which will be notified when the
   * logging properties are re-read.
   */
  public synchronized void addPropertyChangeListener(PropertyChangeListener listener)
  {
    /* do not register null. */
    listener.getClass();

    pcs.addPropertyChangeListener(listener);
  }

  /**
   * Unregisters a listener.
   *
   * If <code>listener</code> has not been registered previously,
   * nothing happens.  Also, no exception is thrown if
   * <code>listener</code> is <code>null</code>.
   */
  public synchronized void removePropertyChangeListener(PropertyChangeListener listener)
  {
    if (listener != null)
      pcs.removePropertyChangeListener(listener);
  }

  /**
   * Adds a named logger.  If a logger with the same name has
   * already been registered, the method returns <code>false</code>
   * without adding the logger.
   *
   * <p>The <code>LogManager</code> only keeps weak references
   * to registered loggers.  Therefore, names can become available
   * after automatic garbage collection.
   *
   * @param logger the logger to be added.
   *
   * @return <code>true</code>if <code>logger</code> was added,
   *         <code>false</code> otherwise.
   *
   * @throws NullPointerException if <code>name</code> is
   *         <code>null</code>.
   */
  public synchronized boolean addLogger(Logger logger)
  {
    /* To developers thinking about to remove the 'synchronized'
     * declaration from this method: Please read the comment
     * in java.util.logging.Logger.getLogger(String, String)
     * and make sure that whatever you change wrt. synchronization
     * does not endanger thread-safety of Logger.getLogger.
     * The current implementation of Logger.getLogger assumes
     * that LogManager does its synchronization on the globally
     * shared instance of LogManager.
     */
    String name;
    WeakReference ref;

    /* This will throw a NullPointerException if logger is null,
     * as required by the API specification.
     */
    name = logger.getName();

    ref = loggers.get(name);
    if (ref != null)
      {
	if (ref.get() != null)
	  return false;

	/* There has been a logger under this name in the past,
	 * but it has been garbage collected.
	 */
	loggers.remove(ref);
      }

    /* Adding a named logger requires a security permission. */
    if ((name != null) && ! name.equals(""))
      checkAccess();

    Logger parent = findAncestor(logger);
    loggers.put(name, new WeakReference<Logger>(logger));
    if (parent != logger.getParent())
      logger.setParent(parent);

    // The level of the newly added logger must be specified.
    // The easiest case is if there is a level for exactly this logger
    // in the properties. If no such level exists the level needs to be 
    // searched along the hirachy. So if there is a new logger 'foo.blah.blub'
    // and an existing parent logger 'foo' the properties 'foo.blah.blub.level'
    // and 'foo.blah.level' need to be checked. If both do not exist in the 
    // properties the level of the new logger is set to 'null' (i.e. it uses the
    // level of its parent 'foo').
    Level logLevel = logger.getLevel();
    String searchName = name;
    String parentName = parent != null ? parent.getName() : "";
    while (logLevel == null && ! searchName.equals(parentName))
      {
        logLevel = getLevelProperty(searchName + ".level", logLevel);
        int index = searchName.lastIndexOf('.');
        if(index > -1)
          searchName = searchName.substring(0,index);
        else
          searchName = "";
      }
    logger.setLevel(logLevel);

    /* It can happen that existing loggers should be children of
     * the newly added logger. For example, assume that there
     * already exist loggers under the names "", "foo", and "foo.bar.baz".
     * When adding "foo.bar", the logger "foo.bar.baz" should change
     * its parent to "foo.bar".
     */
    for (Iterator iter = loggers.keySet().iterator(); iter.hasNext();)
      {
	Logger possChild = (Logger) ((WeakReference) loggers.get(iter.next()))
	  .get();
	if ((possChild == null) || (possChild == logger)
	    || (possChild.getParent() != parent))
	  continue;
	
	if (! possChild.getName().startsWith(name))
	  continue;
	
	if (possChild.getName().charAt(name.length()) != '.')
	  continue;
	
	possChild.setParent(logger);
      }

    return true;
  }

  /**
   * Finds the closest ancestor for a logger among the currently
   * registered ones.  For example, if the currently registered
   * loggers have the names "", "foo", and "foo.bar", the result for
   * "foo.bar.baz" will be the logger whose name is "foo.bar".
   *
   * @param child a logger for whose name no logger has been
   *        registered.
   *
   * @return the closest ancestor for <code>child</code>,
   *         or <code>null</code> if <code>child</code>
   *         is the root logger.
   *
   * @throws NullPointerException if <code>child</code>
   *         is <code>null</code>.
   */
  private synchronized Logger findAncestor(Logger child)
  {
    String childName = child.getName();
    int childNameLength = childName.length();
    Logger best = Logger.root;
    int bestNameLength = 0;

    Logger cand;
    int candNameLength;

    if (child == Logger.root)
      return null;

    for (String candName : loggers.keySet())
      {
	candNameLength = candName.length();

	if (candNameLength > bestNameLength
	    && childNameLength > candNameLength
	    && childName.startsWith(candName)
	    && childName.charAt(candNameLength) == '.')
	  {
	    cand = loggers.get(candName).get();
	    if ((cand == null) || (cand == child))
	      continue;

	    bestNameLength = candName.length();
	    best = cand;
	  }
      }

    return best;
  }

  /**
   * Returns a Logger given its name.
   *
   * @param name the name of the logger.
   *
   * @return a named Logger, or <code>null</code> if there is no
   *     logger with that name.
   *
   * @throw java.lang.NullPointerException if <code>name</code>
   *     is <code>null</code>.
   */
  public synchronized Logger getLogger(String name)
  {
    WeakReference<Logger> ref;

    /* Throw a NullPointerException if name is null. */
    name.getClass();

    ref = loggers.get(name);
    if (ref != null)
      return ref.get();
    else
      return null;
  }

  /**
   * Returns an Enumeration of currently registered Logger names.
   * Since other threads can register loggers at any time, the
   * result could be different any time this method is called.
   *
   * @return an Enumeration with the names of the currently
   *    registered Loggers.
   */
  public synchronized Enumeration<String> getLoggerNames()
  {
    return Collections.enumeration(loggers.keySet());
  }

  /**
   * Resets the logging configuration by removing all handlers for
   * registered named loggers and setting their level to <code>null</code>.
   * The level of the root logger will be set to <code>Level.INFO</code>.
   *
   * @throws SecurityException if a security manager exists and
   *         the caller is not granted the permission to control
   *         the logging infrastructure.
   */
  public synchronized void reset() throws SecurityException
  {
    /* Throw a SecurityException if the caller does not have the
     * permission to control the logging infrastructure.
     */
    checkAccess();

    properties = new Properties();

    Iterator<WeakReference<Logger>> iter = loggers.values().iterator();
    while (iter.hasNext())
      {
	WeakReference<Logger> ref;
	Logger logger;

	ref = iter.next();
	if (ref != null)
	  {
	    logger = ref.get();

	    if (logger == null)
	      iter.remove();
	    else if (logger != Logger.root)
	      {
	        logger.resetLogger();
	        logger.setLevel(null);
	      }
	  }
      }

    Logger.root.setLevel(Level.INFO);
    Logger.root.resetLogger();
  }

  /**
   * Configures the logging framework by reading a configuration file.
   * The name and location of this file are specified by the system
   * property <code>java.util.logging.config.file</code>.  If this
   * property is not set, the URL
   * "{gnu.classpath.home.url}/logging.properties" is taken, where
   * "{gnu.classpath.home.url}" stands for the value of the system
   * property <code>gnu.classpath.home.url</code>.
   *
   * <p>The task of configuring the framework is then delegated to
   * {@link #readConfiguration(java.io.InputStream)}, which will
   * notify registered listeners after having read the properties.
   *
   * @throws SecurityException if a security manager exists and
   *         the caller is not granted the permission to control
   *         the logging infrastructure, or if the caller is
   *         not granted the permission to read the configuration
   *         file.
   *
   * @throws IOException if there is a problem reading in the
   *         configuration file.
   */
  public synchronized void readConfiguration()
    throws IOException, SecurityException
  {
    String path;
    InputStream inputStream;

    path = System.getProperty("java.util.logging.config.file");
    if ((path == null) || (path.length() == 0))
      {
        String url = (System.getProperty("gnu.classpath.home.url")
                      + "/logging.properties");
        try
          {
            inputStream = new URL(url).openStream();
          } 
        catch (Exception e)
          {
            inputStream=null;
          }

        // If no config file could be found use a default configuration.
        if(inputStream == null)
          {
            String defaultConfig = "handlers = java.util.logging.ConsoleHandler   \n"
              + ".level=INFO \n";
            inputStream = new ByteArrayInputStream(defaultConfig.getBytes());
          }
      }
    else
      inputStream = new java.io.FileInputStream(path);

    try
      {
        readConfiguration(inputStream);
      }
    finally
      {
        // Close the stream in order to save
        // resources such as file descriptors.
        inputStream.close();
      }
  }

  public synchronized void readConfiguration(InputStream inputStream)
    throws IOException, SecurityException
  {
    Properties newProperties;
    Enumeration keys;

    checkAccess();
    newProperties = new Properties();
    newProperties.load(inputStream);
    reset();
    this.properties = newProperties;
    keys = newProperties.propertyNames();

    while (keys.hasMoreElements())
      {
	String key = ((String) keys.nextElement()).trim();
	String value = newProperties.getProperty(key);

	if (value == null)
	  continue;

	value = value.trim();

	if ("handlers".equals(key))
	  {
	    // In Java 5 and earlier this was specified to be
	    // whitespace-separated, but in reality it also accepted
	    // commas (tomcat relied on this), and in Java 6 the
	    // documentation was updated to fit the implementation.
	    StringTokenizer tokenizer = new StringTokenizer(value,
							    " \t\n\r\f,");
	    while (tokenizer.hasMoreTokens())
	      {
		String handlerName = tokenizer.nextToken();
                Handler handler = (Handler)
                  createInstance(handlerName, Handler.class, key);
		// Tomcat also relies on the implementation ignoring
		// items in 'handlers' which are not class names.
		if (handler != null)
		  Logger.root.addHandler(handler);
	      }
	  }

	if (key.endsWith(".level"))
	  {
	    String loggerName = key.substring(0, key.length() - 6);
	    Logger logger = getLogger(loggerName);

	    if (logger == null)
	      {
		logger = Logger.getLogger(loggerName);
		addLogger(logger);
	      }
            Level level = null;
	    try
              {
                level = Level.parse(value);
              }
            catch (IllegalArgumentException e)
              {
                warn("bad level \'" + value + "\'", e);
              }
            if (level != null)
              {
                logger.setLevel(level);
              }
	    continue;
	  }
      }

    /* The API specification does not talk about the
     * property name that is distributed with the
     * PropertyChangeEvent.  With test code, it could
     * be determined that the Sun J2SE 1.4 reference
     * implementation uses null for the property name.
     */
    pcs.firePropertyChange(null, null, null);
  }

  /**
   * Returns the value of a configuration property as a String.
   */
  public synchronized String getProperty(String name)
  {
    if (properties != null)
      return properties.getProperty(name);
    else
      return null;
  }

  /**
   * Returns the value of a configuration property as an integer.
   * This function is a helper used by the Classpath implementation
   * of java.util.logging, it is <em>not</em> specified in the
   * logging API.
   *
   * @param name the name of the configuration property.
   *
   * @param defaultValue the value that will be returned if the
   *        property is not defined, or if its value is not an integer
   *        number.
   */
  static int getIntProperty(String name, int defaultValue)
  {
    try
      {
	return Integer.parseInt(getLogManager().getProperty(name));
      }
    catch (Exception ex)
      {
	return defaultValue;
      }
  }

  /**
   * Returns the value of a configuration property as an integer,
   * provided it is inside the acceptable range.
   * This function is a helper used by the Classpath implementation
   * of java.util.logging, it is <em>not</em> specified in the
   * logging API.
   *
   * @param name the name of the configuration property.
   *
   * @param minValue the lowest acceptable value.
   *
   * @param maxValue the highest acceptable value.
   *
   * @param defaultValue the value that will be returned if the
   *        property is not defined, or if its value is not an integer
   *        number, or if it is less than the minimum value,
   *        or if it is greater than the maximum value.
   */
  static int getIntPropertyClamped(String name, int defaultValue,
                                   int minValue, int maxValue)
  {
    int val = getIntProperty(name, defaultValue);
    if ((val < minValue) || (val > maxValue))
      val = defaultValue;
    return val;
  }

  /**
   * Returns the value of a configuration property as a boolean.
   * This function is a helper used by the Classpath implementation
   * of java.util.logging, it is <em>not</em> specified in the
   * logging API.
   *
   * @param name the name of the configuration property.
   *
   * @param defaultValue the value that will be returned if the
   *        property is not defined, or if its value is neither
   *        <code>"true"</code> nor <code>"false"</code>.
   */
  static boolean getBooleanProperty(String name, boolean defaultValue)
  {
    try
      {
	return (Boolean.valueOf(getLogManager().getProperty(name))).booleanValue();
      }
    catch (Exception ex)
      {
	return defaultValue;
      }
  }

  /**
   * Returns the value of a configuration property as a Level.
   * This function is a helper used by the Classpath implementation
   * of java.util.logging, it is <em>not</em> specified in the
   * logging API.
   *
   * @param propertyName the name of the configuration property.
   *
   * @param defaultValue the value that will be returned if the
   *        property is not defined, or if
   *        {@link Level#parse(java.lang.String)} does not like
   *        the property value.
   */
  static Level getLevelProperty(String propertyName, Level defaultValue)
  {
    try
      {
        String value = getLogManager().getProperty(propertyName);
	if (value != null)
	  return Level.parse(getLogManager().getProperty(propertyName));
        else
	   return defaultValue;
      }
    catch (Exception ex)
      {
	return defaultValue;
      }
  }

  /**
   * Returns the value of a configuration property as a Class.
   * This function is a helper used by the Classpath implementation
   * of java.util.logging, it is <em>not</em> specified in the
   * logging API.
   *
   * @param propertyName the name of the configuration property.
   *
   * @param defaultValue the value that will be returned if the
   *        property is not defined, or if it does not specify
   *        the name of a loadable class.
   */
  static final Class getClassProperty(String propertyName, Class defaultValue)
  {
    String propertyValue = logManager.getProperty(propertyName);

    if (propertyValue != null)
      try
        {
          return locateClass(propertyValue);
        }
      catch (ClassNotFoundException e)
        {
          warn(propertyName + " = " + propertyValue, e);
        }

    return defaultValue;
  }

  static final Object getInstanceProperty(String propertyName, Class ofClass,
                                          Class defaultClass)
  {
    Class klass = getClassProperty(propertyName, defaultClass);
    if (klass == null)
      return null;

    try
      {
        Object obj = klass.newInstance();
        if (ofClass.isInstance(obj))
          return obj;
      }
    catch (InstantiationException e)
      {
        warn(propertyName + " = " + klass.getName(), e);
      }
    catch (IllegalAccessException e)
      {
        warn(propertyName + " = " + klass.getName(), e);
      }

    if (defaultClass == null)
      return null;

    try
      {
	return defaultClass.newInstance();
      }
    catch (java.lang.InstantiationException ex)
      {
	throw new RuntimeException(ex.getMessage());
      }
    catch (java.lang.IllegalAccessException ex)
      {
	throw new RuntimeException(ex.getMessage());
      }
  }

  /**
   * An instance of <code>LoggingPermission("control")</code>
   * that is shared between calls to <code>checkAccess()</code>.
   */
  private static final LoggingPermission controlPermission = new LoggingPermission("control",
                                                                                   null);

  /**
   * Checks whether the current security context allows changing
   * the configuration of the logging framework.  For the security
   * context to be trusted, it has to be granted
   * a LoggingPermission("control").
   *
   * @throws SecurityException if a security manager exists and
   *         the caller is not granted the permission to control
   *         the logging infrastructure.
   */
  public void checkAccess() throws SecurityException
  {
    SecurityManager sm = System.getSecurityManager();
    if (sm != null)
      sm.checkPermission(controlPermission);
  }

  /**
   * Creates a new instance of a class specified by name and verifies
   * that it is an instance (or subclass of) a given type.
   *
   * @param className the name of the class of which a new instance
   *        should be created.
   *
   * @param type the object created must be an instance of
   * <code>type</code> or any subclass of <code>type</code>
   *
   * @param property the system property to reference in error
   * messages
   *
   * @return the new instance, or <code>null</code> if
   *         <code>className</code> is <code>null</code>, if no class
   *         with that name could be found, if there was an error
   *         loading that class, or if the constructor of the class
   *         has thrown an exception.
   */
  private static final Object createInstance(String className, Class type,
                                             String property)
  {
    Class klass = null;

    if ((className == null) || (className.length() == 0))
      return null;

    try
      {
        klass = locateClass(className);
        if (type.isAssignableFrom(klass))
          return klass.newInstance();
        warn(property, className, "not an instance of " + type.getName());
      }
    catch (ClassNotFoundException e)
      {
        warn(property, className, "class not found", e);
      }
    catch (IllegalAccessException e)
      {
        warn(property, className, "illegal access", e);
      }
    catch (InstantiationException e)
      {
        warn(property, className, e);
      }
    catch (java.lang.LinkageError e)
      {
        warn(property, className, "linkage error", e);
      }

    return null;
  }

  private static final void warn(String property, String klass, Throwable t)
  {
    warn(property, klass, null, t);
  }

  private static final void warn(String property, String klass, String msg)
  {
    warn(property, klass, msg, null);
  }

  private static final void warn(String property, String klass, String msg,
                                 Throwable t)
  {
    warn("error instantiating '" + klass + "' referenced by " + property +
         (msg == null ? "" : ", " + msg), t);
  }

  /**
   * All debug warnings go through this method.
   */

  private static final void warn(String msg, Throwable t)
  {
    System.err.println("WARNING: " + msg);
    if (t != null)
      t.printStackTrace(System.err);
  }

  /**
   * Locates a class by first checking the system class loader and
   * then checking the context class loader.
   *
   * @param name the fully qualified name of the Class to locate
   * @return Class the located Class
   */

  private static Class locateClass(String name) throws ClassNotFoundException
  {
    // GCJ LOCAL
    // Unfortunately this can be called during bootstrap when
    // Thread.currentThread() will return null.
    // See bug #27658
    Thread t = Thread.currentThread();
    ClassLoader loader = (t == null) ? null : t.getContextClassLoader();
    try
      {
        return Class.forName(name, true, loader);
      }
    catch (ClassNotFoundException e)
      {
        loader = ClassLoader.getSystemClassLoader();
        return Class.forName(name, true, loader);
      }
  }

  /**
   * Return the logging bean.  There is a single logging bean per
   * VM instance.
   * @since 1.5
   */
  public static synchronized LoggingMXBean getLoggingMXBean()
  {
    if (loggingBean == null)
      {
        loggingBean = new LoggingMXBean()
        {
          public String getLoggerLevel(String logger)
          {
            LogManager mgr = getLogManager();
            Logger l = mgr.getLogger(logger);
            if (l == null)
              return null;
            Level lev = l.getLevel();
            if (lev == null)
              return "";
            return lev.getName();
          }

          public List getLoggerNames()
          {
            LogManager mgr = getLogManager();
            // This is inefficient, but perhaps better for maintenance.
            return Collections.list(mgr.getLoggerNames());
          }

          public String getParentLoggerName(String logger)
          {
            LogManager mgr = getLogManager();
            Logger l = mgr.getLogger(logger);
            if (l == null)
              return null;
            l = l.getParent();
            if (l == null)
              return "";
            return l.getName();
          }

          public void setLoggerLevel(String logger, String level)
          {
            LogManager mgr = getLogManager();
            Logger l = mgr.getLogger(logger);
            if (l == null)
              throw new IllegalArgumentException("no logger named " + logger);
            Level newLevel;
            if (level == null)
              newLevel = null;
            else
              newLevel = Level.parse(level);
            l.setLevel(newLevel);
          }
        };
      }
    return loggingBean;
  }
}
