/* Logger.java -- a class for logging messages
   Copyright (C) 2002, 2004, 2006 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 java.util.List;
import java.util.MissingResourceException;
import java.util.ResourceBundle;
import java.security.AccessController;
import java.security.PrivilegedAction;

/**
 * A Logger is used for logging information about events. Usually, there
 * is a seprate logger for each subsystem or component, although there
 * is a shared instance for components that make only occasional use of
 * the logging framework.
 *
 * <p>It is common to name a logger after the name of a corresponding
 * Java package.  Loggers are organized into a hierarchical namespace;
 * for example, the logger <code>"org.gnu.foo"</code> is the
 * <em>parent</em> of logger <code>"org.gnu.foo.bar"</code>.
 *
 * <p>A logger for a named subsystem can be obtained through {@link
 * java.util.logging.Logger#getLogger(java.lang.String)}.  However,
 * only code which has been granted the permission to control the
 * logging infrastructure will be allowed to customize that logger.
 * Untrusted code can obtain a private, anonymous logger through
 * {@link #getAnonymousLogger()} if it wants to perform any
 * modifications to the logger.
 *
 * <p>FIXME: Write more documentation.
 *
 * @author Sascha Brawer (brawer@acm.org)
 */
public class Logger
{

  static final Logger root = new Logger("", null);

  /**
   * A logger provided to applications that make only occasional use
   * of the logging framework, typically early prototypes.  Serious
   * products are supposed to create and use their own Loggers, so
   * they can be controlled individually.
   */
  public static final Logger global;

  static
    {
      // Our class might be initialized from an unprivileged context
      global = (Logger) AccessController.doPrivileged
	(new PrivilegedAction()
	  {
	    public Object run()
	    {
	      return getLogger("global");
	    }
	  });
    }


  /**
   * The name of the Logger, or <code>null</code> if the logger is
   * anonymous.
   *
   * <p>A previous version of the GNU Classpath implementation granted
   * untrusted code the permission to control any logger whose name
   * was null.  However, test code revealed that the Sun J2SE 1.4
   * reference implementation enforces the security control for any
   * logger that was not created through getAnonymousLogger, even if
   * it has a null name.  Therefore, a separate flag {@link
   * Logger#anonymous} was introduced.
   */
  private final String name;


  /**
   * The name of the resource bundle used for localization.
   *
   * <p>This variable cannot be declared as <code>final</code>
   * because its value can change as a result of calling
   * getLogger(String,String).
   */
  private String resourceBundleName;


  /**
   * The resource bundle used for localization.
   *
   * <p>This variable cannot be declared as <code>final</code>
   * because its value can change as a result of calling
   * getLogger(String,String).
   */
  private ResourceBundle resourceBundle;

  private Filter filter;

  private final List handlerList = new java.util.ArrayList(4);
  private Handler[] handlers = new Handler[0];

  /**
   * Indicates whether or not this logger is anonymous.  While
   * a LoggingPermission is required for any modifications to
   * a normal logger, untrusted code can obtain an anonymous logger
   * and modify it according to its needs.
   *
   * <p>A previous version of the GNU Classpath implementation
   * granted access to every logger whose name was null.
   * However, test code revealed that the Sun J2SE 1.4 reference
   * implementation enforces the security control for any logger
   * that was not created through getAnonymousLogger, even
   * if it has a null name.
   */
  private boolean anonymous;


  private boolean useParentHandlers;

  private Level level;

  private Logger parent;

  /**
   * Constructs a Logger for a subsystem.  Most applications do not
   * need to create new Loggers explicitly; instead, they should call
   * the static factory methods
   * {@link #getLogger(java.lang.String,java.lang.String) getLogger}
   * (with ResourceBundle for localization) or
   * {@link #getLogger(java.lang.String) getLogger} (without
   * ResourceBundle), respectively.
   *
   * @param name the name for the logger, for example "java.awt"
   *             or "com.foo.bar". The name should be based on
   *             the name of the package issuing log records
   *             and consist of dot-separated Java identifiers.
   *
   * @param resourceBundleName the name of a resource bundle
   *        for localizing messages, or <code>null</code>
   *	    to indicate that messages do not need to be localized.
   *
   * @throws java.util.MissingResourceException if
   *         <code>resourceBundleName</code> is not <code>null</code>
   *         and no such bundle could be located.
   */
  protected Logger(String name, String resourceBundleName)
    throws MissingResourceException
  {
    this.name = name;
    this.resourceBundleName = resourceBundleName;

    if (resourceBundleName == null)
      resourceBundle = null;
    else
      resourceBundle = ResourceBundle.getBundle(resourceBundleName);

    level = null;

    /* This is null when the root logger is being constructed,
     * and the root logger afterwards.
     */
    parent = root;

    useParentHandlers = (parent != null);
  }



  /**
   * Finds a registered logger for a subsystem, or creates one in
   * case no logger has been registered yet.
   *
   * @param name the name for the logger, for example "java.awt"
   *             or "com.foo.bar". The name should be based on
   *             the name of the package issuing log records
   *             and consist of dot-separated Java identifiers.
   *
   * @throws IllegalArgumentException if a logger for the subsystem
   *         identified by <code>name</code> has already been created,
   *         but uses a a resource bundle for localizing messages.
   *
   * @throws NullPointerException if <code>name</code> is
   *         <code>null</code>.
   *
   * @return a logger for the subsystem specified by <code>name</code>
   *         that does not localize messages.
   */
  public static Logger getLogger(String name)
  {
    return getLogger(name, null);
  }

    
  /**
   * Finds a registered logger for a subsystem, or creates one in case
   * no logger has been registered yet.
   *
   * <p>If a logger with the specified name has already been
   * registered, the behavior depends on the resource bundle that is
   * currently associated with the existing logger.
   *
   * <ul><li>If the existing logger uses the same resource bundle as
   * specified by <code>resourceBundleName</code>, the existing logger
   * is returned.</li>
   *
   * <li>If the existing logger currently does not localize messages,
   * the existing logger is modified to use the bundle specified by
   * <code>resourceBundleName</code>.  The existing logger is then
   * returned.  Therefore, all subsystems currently using this logger
   * will produce localized messages from now on.</li>
   *
   * <li>If the existing logger already has an associated resource
   * bundle, but a different one than specified by
   * <code>resourceBundleName</code>, an
   * <code>IllegalArgumentException</code> is thrown.</li></ul>
   *
   * @param name the name for the logger, for example "java.awt"
   *             or "org.gnu.foo". The name should be based on
   *             the name of the package issuing log records
   *             and consist of dot-separated Java identifiers.
   *
   * @param resourceBundleName the name of a resource bundle
   *        for localizing messages, or <code>null</code>
   *	    to indicate that messages do not need to be localized.
   *
   * @return a logger for the subsystem specified by <code>name</code>.
   *
   * @throws java.util.MissingResourceException if
   *         <code>resourceBundleName</code> is not <code>null</code>
   *         and no such bundle could be located.   
   *
   * @throws IllegalArgumentException if a logger for the subsystem
   *         identified by <code>name</code> has already been created,
   *         but uses a different resource bundle for localizing
   *         messages.
   *
   * @throws NullPointerException if <code>name</code> is
   *         <code>null</code>.
   */
  public static Logger getLogger(String name, String resourceBundleName)
  {
    LogManager lm = LogManager.getLogManager();
    Logger     result;

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

    /* Without synchronized(lm), it could happen that another thread
     * would create a logger between our calls to getLogger and
     * addLogger.  While addLogger would indicate this by returning
     * false, we could not be sure that this other logger was still
     * existing when we called getLogger a second time in order
     * to retrieve it -- note that LogManager is only allowed to
     * keep weak references to registered loggers, so Loggers
     * can be garbage collected at any time in general, and between
     * our call to addLogger and our second call go getLogger
     * in particular.
     *
     * Of course, we assume here that LogManager.addLogger etc.
     * are synchronizing on the global LogManager object. There
     * is a comment in the implementation of LogManager.addLogger
     * referring to this comment here, so that any change in
     * the synchronization of LogManager will be reflected here.
     */
    synchronized (lm)
    {
      result = lm.getLogger(name);
      if (result == null)
      {
	boolean couldBeAdded;

	result = new Logger(name, resourceBundleName);
	couldBeAdded = lm.addLogger(result);
	if (!couldBeAdded)
	  throw new IllegalStateException("cannot register new logger");
      }
      else
      {
	/* The logger already exists. Make sure it uses
	 * the same resource bundle for localizing messages.
	 */
	String existingBundleName = result.getResourceBundleName();

	/* The Sun J2SE 1.4 reference implementation will return the
	 * registered logger object, even if it does not have a resource
	 * bundle associated with it. However, it seems to change the
	 * resourceBundle of the registered logger to the bundle
	 * whose name was passed to getLogger.
	 */
	if ((existingBundleName == null) && (resourceBundleName != null))
	{
	  /* If ResourceBundle.getBundle throws an exception, the
	   * existing logger will be unchanged.  This would be
	   * different if the assignment to resourceBundleName
	   * came first.
	   */
	  result.resourceBundle = ResourceBundle.getBundle(resourceBundleName);
	  result.resourceBundleName = resourceBundleName;
	  return result;
	}

	if ((existingBundleName != resourceBundleName)
	    && ((existingBundleName == null)
		|| !existingBundleName.equals(resourceBundleName)))
	{
	  throw new IllegalArgumentException();
	}
      }
    }

    return result;
  }

  
  /**
   * Creates a new, unnamed logger.  Unnamed loggers are not
   * registered in the namespace of the LogManager, and no special
   * security permission is required for changing their state.
   * Therefore, untrusted applets are able to modify their private
   * logger instance obtained through this method.
   *
   * <p>The parent of the newly created logger will the the root
   * logger, from which the level threshold and the handlers are
   * inherited.
   */
  public static Logger getAnonymousLogger()
  {
    return getAnonymousLogger(null);
  }


  /**
   * Creates a new, unnamed logger.  Unnamed loggers are not
   * registered in the namespace of the LogManager, and no special
   * security permission is required for changing their state.
   * Therefore, untrusted applets are able to modify their private
   * logger instance obtained through this method.
   *
   * <p>The parent of the newly created logger will the the root
   * logger, from which the level threshold and the handlers are
   * inherited.
   *
   * @param resourceBundleName the name of a resource bundle
   *        for localizing messages, or <code>null</code>
   *	    to indicate that messages do not need to be localized.
   *
   * @throws java.util.MissingResourceException if
   *         <code>resourceBundleName</code> is not <code>null</code>
   *         and no such bundle could be located.
   */
  public static Logger getAnonymousLogger(String resourceBundleName)
    throws MissingResourceException
  {
    Logger  result;

    result = new Logger(null, resourceBundleName);
    result.anonymous = true;
    return result;
  }


  /**
   * Returns the name of the resource bundle that is being used for
   * localizing messages.
   *
   * @return the name of the resource bundle used for localizing messages,
   *         or <code>null</code> if the parent's resource bundle
   *         is used for this purpose.
   */
  public synchronized String getResourceBundleName()
  {
    return resourceBundleName;
  }


  /**
   * Returns the resource bundle that is being used for localizing
   * messages.
   *
   * @return the resource bundle used for localizing messages,
   *         or <code>null</code> if the parent's resource bundle
   *         is used for this purpose.
   */
  public synchronized ResourceBundle getResourceBundle()
  {
    return resourceBundle;
  }


  /**
   * Returns the severity level threshold for this <code>Handler</code>.
   * All log records with a lower severity level will be discarded;
   * a log record of the same or a higher level will be published
   * unless an installed <code>Filter</code> decides to discard it.
   *
   * @return the severity level below which all log messages will be
   *         discarded, or <code>null</code> if the logger inherits
   *         the threshold from its parent.
   */
  public synchronized Level getLevel()
  {
    return level;
  }


  /**
   * Returns whether or not a message of the specified level
   * would be logged by this logger.
   *
   * @throws NullPointerException if <code>level</code>
   *         is <code>null</code>.
   */
  public synchronized boolean isLoggable(Level level)
  {
    if (this.level != null)
      return this.level.intValue() <= level.intValue();

    if (parent != null)
      return parent.isLoggable(level);
    else
      return false;
  }


  /**
   * Sets the severity level threshold for this <code>Handler</code>.
   * All log records with a lower severity level will be discarded
   * immediately.  A log record of the same or a higher level will be
   * published unless an installed <code>Filter</code> decides to
   * discard it.
   *
   * @param level the severity level below which all log messages
   *              will be discarded, or <code>null</code> to
   *              indicate that the logger should inherit the
   *              threshold from its parent.
   *
   * @throws SecurityException if this logger is not anonymous, a
   *     security manager exists, and the caller is not granted
   *     the permission to control the logging infrastructure by
   *     having LoggingPermission("control").  Untrusted code can
   *     obtain an anonymous logger through the static factory method
   *     {@link #getAnonymousLogger(java.lang.String) getAnonymousLogger}.
   */
  public synchronized void setLevel(Level level)
  {
    /* An application is allowed to control an anonymous logger
     * without having the permission to control the logging
     * infrastructure.
     */
    if (!anonymous)
      LogManager.getLogManager().checkAccess();

    this.level = level;
  }


  public synchronized Filter getFilter()
  {
    return filter;
  }


  /**
   * @throws SecurityException if this logger is not anonymous, a
   *     security manager exists, and the caller is not granted
   *     the permission to control the logging infrastructure by
   *     having LoggingPermission("control").  Untrusted code can
   *     obtain an anonymous logger through the static factory method
   *     {@link #getAnonymousLogger(java.lang.String) getAnonymousLogger}.
   */
  public synchronized void setFilter(Filter filter)
    throws SecurityException
  {
    /* An application is allowed to control an anonymous logger
     * without having the permission to control the logging
     * infrastructure.
     */
    if (!anonymous)
      LogManager.getLogManager().checkAccess();

    this.filter = filter;
  }




  /**
   * Returns the name of this logger.
   *
   * @return the name of this logger, or <code>null</code> if
   *         the logger is anonymous.
   */
  public String getName()
  {
    /* Note that the name of a logger cannot be changed during
     * its lifetime, so no synchronization is needed.
     */
    return name;
  }


  /**
   * Passes a record to registered handlers, provided the record
   * is considered as loggable both by {@link #isLoggable(Level)}
   * and a possibly installed custom {@link #setFilter(Filter) filter}.
   *
   * <p>If the logger has been configured to use parent handlers,
   * the record will be forwarded to the parent of this logger
   * in addition to being processed by the handlers registered with
   * this logger.
   *
   * <p>The other logging methods in this class are convenience methods
   * that merely create a new LogRecord and pass it to this method.
   * Therefore, subclasses usually just need to override this single
   * method for customizing the logging behavior.
   *
   * @param record the log record to be inspected and possibly forwarded.
   */
  public synchronized void log(LogRecord record)
  {
    if (!isLoggable(record.getLevel()))
      return;

    if ((filter != null) && !filter.isLoggable(record))
      return;

    /* If no logger name has been set for the log record,
     * use the name of this logger.
     */
    if (record.getLoggerName() == null)
      record.setLoggerName(name);

    /* Avoid that some other thread is changing the logger hierarchy
     * while we are traversing it.
     */
    synchronized (LogManager.getLogManager())
    {
      Logger curLogger = this;

      do
      {
        /* The Sun J2SE 1.4 reference implementation seems to call the
	 * filter only for the logger whose log method is called,
	 * never for any of its parents.  Also, parent loggers publish
	 * log record whatever their level might be.  This is pretty
	 * weird, but GNU Classpath tries to be as compatible as
	 * possible to the reference implementation.
	 */
        for (int i = 0; i < curLogger.handlers.length; i++)
          curLogger.handlers[i].publish(record);

	if (curLogger.getUseParentHandlers() == false)
	  break;
	
	curLogger = curLogger.getParent();
      }
      while (parent != null);
    }
  }


  public void log(Level level, String message)
  {
    if (isLoggable(level))
      log(level, message, (Object[]) null);
  }


  public synchronized void log(Level level,
			       String message,
			       Object param)
  {
    if (isLoggable(level))
      {
        StackTraceElement caller = getCallerStackFrame();
        logp(level,
             caller != null ? caller.getClassName() : "<unknown>",
             caller != null ? caller.getMethodName() : "<unknown>",
             message,
             param);
      }
  }


  public synchronized void log(Level level,
			       String message,
			       Object[] params)
  {
    if (isLoggable(level))
      {
        StackTraceElement caller = getCallerStackFrame();
        logp(level,
             caller != null ? caller.getClassName() : "<unknown>",
             caller != null ? caller.getMethodName() : "<unknown>",
             message,
             params);
      }
  }


  public synchronized void log(Level level,
			       String message,
			       Throwable thrown)
  {
    if (isLoggable(level))
      {
        StackTraceElement caller = getCallerStackFrame();    
        logp(level,
             caller != null ? caller.getClassName() : "<unknown>",
             caller != null ? caller.getMethodName() : "<unknown>",
             message,
             thrown);
      }
  }


  public synchronized void logp(Level level,
				String sourceClass,
				String sourceMethod,
				String message)
  {
    logp(level, sourceClass, sourceMethod, message,
	 (Object[]) null);
  }


  public synchronized void logp(Level level,
				String sourceClass,
				String sourceMethod,
				String message,
				Object param)
  {
    logp(level, sourceClass, sourceMethod, message,
	 new Object[] { param });
  }


  private synchronized ResourceBundle findResourceBundle()
  {
    if (resourceBundle != null)
      return resourceBundle;

    if (parent != null)
      return parent.findResourceBundle();

    return null;
  }


  private synchronized void logImpl(Level level,
				    String sourceClass,
				    String sourceMethod,
				    String message,
				    Object[] params)
  {
    LogRecord rec = new LogRecord(level, message);

    rec.setResourceBundle(findResourceBundle());
    rec.setSourceClassName(sourceClass);
    rec.setSourceMethodName(sourceMethod);
    rec.setParameters(params);

    log(rec);
  }


  public synchronized void logp(Level level,
				String sourceClass,
				String sourceMethod,
				String message,
				Object[] params)
  {
    logImpl(level, sourceClass, sourceMethod, message, params);
  }


  public synchronized void logp(Level level,
				String sourceClass,
				String sourceMethod,
				String message,
				Throwable thrown)
  {
    LogRecord rec = new LogRecord(level, message);

    rec.setResourceBundle(resourceBundle);
    rec.setSourceClassName(sourceClass);
    rec.setSourceMethodName(sourceMethod);
    rec.setThrown(thrown);

    log(rec);
  }


  public synchronized void logrb(Level level,
				 String sourceClass,
				 String sourceMethod,
				 String bundleName,
				 String message)
  {
    logrb(level, sourceClass, sourceMethod, bundleName,
	  message, (Object[]) null);
  }


  public synchronized void logrb(Level level,
				 String sourceClass,
				 String sourceMethod,
				 String bundleName,
				 String message,
				 Object param)
  {
    logrb(level, sourceClass, sourceMethod, bundleName,
	  message, new Object[] { param });
  }


  public synchronized void logrb(Level level,
				 String sourceClass,
				 String sourceMethod,
				 String bundleName,
				 String message,
				 Object[] params)
  {
    LogRecord rec = new LogRecord(level, message);

    rec.setResourceBundleName(bundleName);
    rec.setSourceClassName(sourceClass);
    rec.setSourceMethodName(sourceMethod);
    rec.setParameters(params);

    log(rec);
  }


  public synchronized void logrb(Level level,
				 String sourceClass,
				 String sourceMethod,
				 String bundleName,
				 String message,
				 Throwable thrown)
  {
    LogRecord rec = new LogRecord(level, message);

    rec.setResourceBundleName(bundleName);
    rec.setSourceClassName(sourceClass);
    rec.setSourceMethodName(sourceMethod);
    rec.setThrown(thrown);

    log(rec);
  }


  public synchronized void entering(String sourceClass,
				    String sourceMethod)
  {
    if (isLoggable(Level.FINER))
      logp(Level.FINER, sourceClass, sourceMethod, "ENTRY");
  }


  public synchronized void entering(String sourceClass,
				    String sourceMethod,
				    Object param)
  {
    if (isLoggable(Level.FINER))
      logp(Level.FINER, sourceClass, sourceMethod, "ENTRY {0}", param);
  }


  public synchronized void entering(String sourceClass,
				    String sourceMethod,
				    Object[] params)
  {
    if (isLoggable(Level.FINER))
    {
      StringBuffer buf = new StringBuffer(80);
      buf.append("ENTRY");
      for (int i = 0; i < params.length; i++)
      {
	buf.append(" {");
	buf.append(i);
	buf.append('}');
      }
      
      logp(Level.FINER, sourceClass, sourceMethod, buf.toString(), params);
    }
  }


  public synchronized void exiting(String sourceClass,
				   String sourceMethod)
  {
    if (isLoggable(Level.FINER))
      logp(Level.FINER, sourceClass, sourceMethod, "RETURN");
  }

   
  public synchronized void exiting(String sourceClass,
				   String sourceMethod,
				   Object result)
  {
    if (isLoggable(Level.FINER))
      logp(Level.FINER, sourceClass, sourceMethod, "RETURN {0}", result);
  }

 
  public synchronized void throwing(String sourceClass,
				    String sourceMethod,
				    Throwable thrown)
  {
    if (isLoggable(Level.FINER))
      logp(Level.FINER, sourceClass, sourceMethod, "THROW", thrown);
  }


  /**
   * Logs a message with severity level SEVERE, indicating a serious
   * failure that prevents normal program execution.  Messages at this
   * level should be understandable to an inexperienced, non-technical
   * end user.  Ideally, they explain in simple words what actions the
   * user can take in order to resolve the problem.
   *
   * @see Level#SEVERE
   *
   * @param message the message text, also used as look-up key if the
   *                logger is localizing messages with a resource
   *                bundle.  While it is possible to pass
   *                <code>null</code>, this is not recommended, since
   *                a logging message without text is unlikely to be
   *                helpful.
   */
  public synchronized void severe(String message)
  {
    if (isLoggable(Level.SEVERE))
      log(Level.SEVERE, message);
  }


  /**
   * Logs a message with severity level WARNING, indicating a
   * potential problem that does not prevent normal program execution.
   * Messages at this level should be understandable to an
   * inexperienced, non-technical end user.  Ideally, they explain in
   * simple words what actions the user can take in order to resolve
   * the problem.
   *
   * @see Level#WARNING
   *
   * @param message the message text, also used as look-up key if the
   *                logger is localizing messages with a resource
   *                bundle.  While it is possible to pass
   *                <code>null</code>, this is not recommended, since
   *                a logging message without text is unlikely to be
   *                helpful.
   */
  public synchronized void warning(String message)
  {
    if (isLoggable(Level.WARNING))
      log(Level.WARNING, message);
  }


  /**
   * Logs a message with severity level INFO.  {@link Level#INFO} is
   * intended for purely informational messages that do not indicate
   * error or warning situations. In the default logging
   * configuration, INFO messages will be written to the system
   * console.  For this reason, the INFO level should be used only for
   * messages that are important to end users and system
   * administrators.  Messages at this level should be understandable
   * to an inexperienced, non-technical user.
   *
   * @param message the message text, also used as look-up key if the
   *                logger is localizing messages with a resource
   *                bundle.  While it is possible to pass
   *                <code>null</code>, this is not recommended, since
   *                a logging message without text is unlikely to be
   *                helpful.
   */
  public synchronized void info(String message)
  {
    if (isLoggable(Level.INFO))
      log(Level.INFO, message);
  }


  /**
   * Logs a message with severity level CONFIG.  {@link Level#CONFIG} is
   * intended for static configuration messages, for example about the
   * windowing environment, the operating system version, etc.
   *
   * @param message the message text, also used as look-up key if the
   *     logger is localizing messages with a resource bundle.  While
   *     it is possible to pass <code>null</code>, this is not
   *     recommended, since a logging message without text is unlikely
   *     to be helpful.
   */
  public synchronized void config(String message)
  {
    if (isLoggable(Level.CONFIG))
      log(Level.CONFIG, message);
  }


  /**
   * Logs a message with severity level FINE.  {@link Level#FINE} is
   * intended for messages that are relevant for developers using
   * the component generating log messages. Examples include minor,
   * recoverable failures, or possible inefficiencies.
   *
   * @param message the message text, also used as look-up key if the
   *                logger is localizing messages with a resource
   *                bundle.  While it is possible to pass
   *                <code>null</code>, this is not recommended, since
   *                a logging message without text is unlikely to be
   *                helpful.
   */
  public synchronized void fine(String message)
  {
    if (isLoggable(Level.FINE))
      log(Level.FINE, message);
  }


  /**
   * Logs a message with severity level FINER.  {@link Level#FINER} is
   * intended for rather detailed tracing, for example entering a
   * method, returning from a method, or throwing an exception.
   *
   * @param message the message text, also used as look-up key if the
   *                logger is localizing messages with a resource
   *                bundle.  While it is possible to pass
   *                <code>null</code>, this is not recommended, since
   *                a logging message without text is unlikely to be
   *                helpful.
   */
  public synchronized void finer(String message)
  {
    if (isLoggable(Level.FINER))
      log(Level.FINER, message);
  }


  /**
   * Logs a message with severity level FINEST.  {@link Level#FINEST}
   * is intended for highly detailed tracing, for example reaching a
   * certain point inside the body of a method.
   *
   * @param message the message text, also used as look-up key if the
   *                logger is localizing messages with a resource
   *                bundle.  While it is possible to pass
   *                <code>null</code>, this is not recommended, since
   *                a logging message without text is unlikely to be
   *                helpful.
   */
  public synchronized void finest(String message)
  {
    if (isLoggable(Level.FINEST))
      log(Level.FINEST, message);
  }


  /**
   * Adds a handler to the set of handlers that get notified
   * when a log record is to be published.
   *
   * @param handler the handler to be added.
   *
   * @throws NullPointerException if <code>handler</code>
   *     is <code>null</code>.
   *
   * @throws SecurityException if this logger is not anonymous, a
   *     security manager exists, and the caller is not granted
   *     the permission to control the logging infrastructure by
   *     having LoggingPermission("control").  Untrusted code can
   *     obtain an anonymous logger through the static factory method
   *     {@link #getAnonymousLogger(java.lang.String) getAnonymousLogger}.
   */
  public synchronized void addHandler(Handler handler)
    throws SecurityException
  {
    /* Throw a new NullPointerException if handler is null. */
    handler.getClass();

    /* An application is allowed to control an anonymous logger
     * without having the permission to control the logging
     * infrastructure.
     */
    if (!anonymous)
      LogManager.getLogManager().checkAccess();

    if (!handlerList.contains(handler))
    {
      handlerList.add(handler);
      handlers = getHandlers();
    }
  }


  /**
   * Removes a handler from the set of handlers that get notified
   * when a log record is to be published.
   *
   * @param handler the handler to be removed.
   *
   * @throws SecurityException if this logger is not anonymous, a
   *     security manager exists, and the caller is not granted the
   *     permission to control the logging infrastructure by having
   *     LoggingPermission("control").  Untrusted code can obtain an
   *     anonymous logger through the static factory method {@link
   *     #getAnonymousLogger(java.lang.String) getAnonymousLogger}.
   *
   * @throws NullPointerException if <code>handler</code>
   *     is <code>null</code>.
   */
  public synchronized void removeHandler(Handler handler)
    throws SecurityException
  {
    /* An application is allowed to control an anonymous logger
     * without having the permission to control the logging
     * infrastructure.
     */
    if (!anonymous)
      LogManager.getLogManager().checkAccess();

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

    handlerList.remove(handler);
    handlers = getHandlers();
  }


  /**
   * Returns the handlers currently registered for this Logger.
   * When a log record has been deemed as being loggable,
   * it will be passed to all registered handlers for
   * publication.  In addition, if the logger uses parent handlers
   * (see {@link #getUseParentHandlers() getUseParentHandlers}
   * and {@link #setUseParentHandlers(boolean) setUseParentHandlers},
   * the log record will be passed to the parent's handlers.
   */
  public synchronized Handler[] getHandlers()
  {
    /* We cannot return our internal handlers array
     * because we do not have any guarantee that the
     * caller would not change the array entries.
     */
    return (Handler[]) handlerList.toArray(new Handler[handlerList.size()]);
  }


  /**
   * Returns whether or not this Logger forwards log records to
   * handlers registered for its parent loggers.
   *
   * @return <code>false</code> if this Logger sends log records
   *         merely to Handlers registered with itself;
   *         <code>true</code> if this Logger sends log records
   *         not only to Handlers registered with itself, but also
   *         to those Handlers registered with parent loggers.
   */
  public synchronized boolean getUseParentHandlers()
  {
    return useParentHandlers;
  }


  /**
   * Sets whether or not this Logger forwards log records to
   * handlers registered for its parent loggers.
   *
   * @param useParentHandlers <code>false</code> to let this
   *         Logger send log records merely to Handlers registered
   *         with itself; <code>true</code> to let this Logger
   *         send log records not only to Handlers registered
   *         with itself, but also to those Handlers registered with
   *         parent loggers.
   *
   * @throws SecurityException if this logger is not anonymous, a
   *     security manager exists, and the caller is not granted
   *     the permission to control the logging infrastructure by
   *     having LoggingPermission("control").  Untrusted code can
   *     obtain an anonymous logger through the static factory method
   *     {@link #getAnonymousLogger(java.lang.String) getAnonymousLogger}.
   *
   */
  public synchronized void setUseParentHandlers(boolean useParentHandlers)
  {
    /* An application is allowed to control an anonymous logger
     * without having the permission to control the logging
     * infrastructure.
     */
    if (!anonymous)
      LogManager.getLogManager().checkAccess();

    this.useParentHandlers = useParentHandlers;
  }


  /**
   * Returns the parent of this logger.  By default, the parent is
   * assigned by the LogManager by inspecting the logger's name.
   *
   * @return the parent of this logger (as detemined by the LogManager
   *     by inspecting logger names), the root logger if no other
   *     logger has a name which is a prefix of this logger's name, or
   *     <code>null</code> for the root logger.
   */
  public synchronized Logger getParent()
  {
    return parent;
  }


  /**
   * Sets the parent of this logger.  Usually, applications do not
   * call this method directly.  Instead, the LogManager will ensure
   * that the tree of loggers reflects the hierarchical logger
   * namespace.  Basically, this method should not be public at all,
   * but the GNU implementation follows the API specification.
   *
   * @throws NullPointerException if <code>parent</code> is
   *     <code>null</code>.
   *
   * @throws SecurityException if this logger is not anonymous, a
   *     security manager exists, and the caller is not granted
   *     the permission to control the logging infrastructure by
   *     having LoggingPermission("control").  Untrusted code can
   *     obtain an anonymous logger through the static factory method
   *     {@link #getAnonymousLogger(java.lang.String) getAnonymousLogger}.
   */
  public synchronized void setParent(Logger parent)
  {
    /* Throw a new NullPointerException if parent is null. */
    parent.getClass();

    if (this == root)
        throw new IllegalArgumentException(
          "the root logger can only have a null parent");

    /* An application is allowed to control an anonymous logger
     * without having the permission to control the logging
     * infrastructure.
     */
    if (!anonymous)
      LogManager.getLogManager().checkAccess();

    this.parent = parent;
  }
  
  /**
   * Gets the StackTraceElement of the first class that is not this class.
   * That should be the initial caller of a logging method.
   * @return caller of the initial logging method or null if unknown.
   */
  private native StackTraceElement getCallerStackFrame();
  
  /**
   * Reset and close handlers attached to this logger. This function is package
   * private because it must only be avaiable to the LogManager.
   */
  void resetLogger()
  {
    for (int i = 0; i < handlers.length; i++)
      {
        handlers[i].close();
        handlerList.remove(handlers[i]);
      }
    handlers = getHandlers();
  }
}
