/* LogManager.java -- a class for maintaining Loggers and managing
   configuration properties
   Copyright (C) 2002 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., 59 Temple Place, Suite 330, Boston, MA
02111-1307 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 java.beans.PropertyChangeListener;
import java.beans.PropertyChangeSupport;
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.Iterator;
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>
 *
 * @author Sascha Brawer (brawer@acm.org)
 */
public class LogManager
{
  /**
   * The singleton LogManager instance.
   */
  private static LogManager logManager;
  

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

  final Logger rootLogger;


  /**
   * 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()
  {
    if (logManager != null)
      throw new IllegalStateException(
        "there can be only one LogManager; use LogManager.getLogManager()");

    logManager = this;
    loggers = new java.util.HashMap();
    rootLogger = new Logger("", null);
    addLogger(rootLogger);
    
    /* Make sure that Logger.global has the rootLogger as its parent.
     *
     * Logger.global is set during class initialization of Logger,
     * which may or may not be before this code is being executed.
     * For example, on the Sun 1.3.1 and 1.4.0 JVMs, Logger.global
     * has been set before this code is being executed. In contrast,
     * Logger.global still is null on GCJ 3.2.  Since the LogManager
     * and Logger classes are mutually dependent, both behaviors are
     * correct.
     *
     * This means that we cannot depend on Logger.global to have its
     * value when this code executes, although that variable is final.
     * Since Logger.getLogger will always return the same logger for
     * the same name, the subsequent line works fine irrespective of
     * the order in which classes are initialized.
     */
    Logger.getLogger("global").setParent(rootLogger);
    Logger.getLogger("global").setUseParentHandlers(true);
  }


  /**
   * Returns the globally shared LogManager instance.
   */
  public static LogManager getLogManager()
  {
    return logManager;
  }

  static
  {
    makeLogManager();
    
    /* The Javadoc description of the class explains
     * what is going on here.
     */
    Object configurator = createInstance(
      System.getProperty("java.util.logging.config.class"),
      /* must be instance of */ Object.class);

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

  private static LogManager makeLogManager()
  {
    String      managerClassName;
    LogManager  manager;

    managerClassName = System.getProperty("java.util.logging.manager");
    manager = (LogManager) createInstance(managerClassName, LogManager.class);
    if (manager != null)
      return manager;

    if (managerClassName != null)
      System.err.println("WARNING: System property \"java.util.logging.manager\""
			 + " should be the name of a subclass of java.util.logging.LogManager");

    return new LogManager();
  }


  /**
   * 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 = (WeakReference) 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));
    if (parent != logger.getParent())
      logger.setParent(parent);

    /* 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".
     */
    if (parent != rootLogger)
    {
      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 = rootLogger;
    int    bestNameLength = 0;

    Logger  cand;
    String  candName;
    int     candNameLength;

    if (child == rootLogger)
      return null;

    for (Iterator iter = loggers.keySet().iterator(); iter.hasNext();)
    {
      candName = (String) iter.next();
      candNameLength = candName.length();

      if (candNameLength > bestNameLength
	  && childNameLength > candNameLength
	  && childName.startsWith(candName)
	  && childName.charAt(candNameLength) == '.')
      {
        cand = (Logger) ((WeakReference) 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  ref;

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

    ref = (WeakReference) loggers.get(name);
    if (ref != null)
      return (Logger) 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 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 iter = loggers.values().iterator();
    while (iter.hasNext())
    {
      WeakReference  ref;
      Logger         logger;

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

	if (logger == null)
	  iter.remove();
	else if (logger != rootLogger)
	  logger.setLevel(null);
      }
    }

    rootLogger.setLevel(Level.INFO);
  }


  /**
   * 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");
      inputStream = new URL(url).openStream();
    }
    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);
    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))
        {
          StringTokenizer tokenizer = new StringTokenizer(value);
          while(tokenizer.hasMoreTokens())
            {
              String handlerName = tokenizer.nextToken();	
              try
                {
              	  Class handlerClass = Class.forName(handlerName);
              	  getLogger("").addHandler((Handler)handlerClass.newInstance()); 
                }
              catch (ClassCastException ex)
                {
                  System.err.println("[LogManager] class " + handlerName + " is not subclass of java.util.logging.Handler");
                }
              catch (Exception ex)
                {
                  //System.out.println("[LogManager.readConfiguration]"+ex);
                }
            }
        }
	  
      if (key.endsWith(".level"))
      {
	String loggerName = key.substring(0, key.length() - 6);
	Logger logger = getLogger(loggerName);
	if (logger != null)
	{
	  try
	  {
	    logger.setLevel(Level.parse(value));
	  }
	  catch (Exception _)
	  {
        //System.out.println("[LogManager.readConfiguration] "+_);
	  }
	  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 (new Boolean(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
    {
      return Level.parse(getLogManager().getProperty(propertyName));
    }
    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)
  {
    Class usingClass = null;

    try
    {
      String propertyValue = logManager.getProperty(propertyName);
      if (propertyValue != null)
        usingClass = Class.forName(propertyValue);
      if (usingClass != null)
        return usingClass;
    }
    catch (Exception _)
    {
    }

    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 (Exception _)
    {
    }

    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.
   *
   * @param className the name of the class of which a new instance
   *        should be created.
   *       
   * @param ofClass the class to which the new instance should
   *        be either an instance or an instance of a subclass.
   *        FIXME: This description is just terrible.
   *
   * @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.
   */
  static final Object createInstance(String className, Class ofClass)
  {
    Class   klass;

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

    try
    {
      klass = Class.forName(className);
      if (!ofClass.isAssignableFrom(klass))
	return null;

      return klass.newInstance();
    }
    catch (Exception _)
    {
      return null;
    }
    catch (java.lang.LinkageError _)
    {
      return null;
    }
  }
}
