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

/**
 * 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
{
  /**
   * 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 = 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 = LogManager.getLogManager().rootLogger;

    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)
  {
    log(level, message, (Object[]) null);
  }


  public synchronized void log(Level level,
			       String message,
			       Object param)
  {
  	StackTraceElement caller = getCallerStackFrame();
    logp(level,
	 caller.getClassName(),
	 caller.getMethodName(),
	 message,
	 param);
  }


  public synchronized void log(Level level,
			       String message,
			       Object[] params)
  {
    StackTraceElement caller = getCallerStackFrame();
    logp(level,
	 caller.getClassName(),
	 caller.getMethodName(),
	 message,
	 params);
  }


  public synchronized void log(Level level,
			       String message,
			       Throwable thrown)
  {
	StackTraceElement caller = getCallerStackFrame();    
    logp(level,
	 caller.getClassName(),
	 caller.getMethodName(),
	 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)
  {
    LogManager lm;

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

    lm = LogManager.getLogManager();

    if (this == lm.rootLogger)
    {
      if (parent != null)
        throw new IllegalArgumentException(
          "only the root logger can have a null parent");
      this.parent = null;
      return;
    }

    /* 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 looging method
   */
  private native StackTraceElement getCallerStackFrame();
}
