/* Logger.java -- a class for logging messages
   Copyright (C) 2002, 2004, 2006, 2007 Free Software Foundation, Inc.

This file is part of GNU Classpath.

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

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

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

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

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


package java.util.logging;

import gnu.java.lang.CPStringBuilder;

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;

  /**
   * Use to lock methods on this class instead of calling synchronize on methods
   * to avoid deadlocks. Yeah, no kidding, we got them :)
   */
  private static final Object[] lock = new Object[0];
  
  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;

    if (name == null)
      throw new NullPointerException();

    /*
     * 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 (lock)
      {
        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 String getResourceBundleName()
  {
    synchronized (lock)
      {
        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 ResourceBundle getResourceBundle()
  {
    synchronized (lock)
      {
        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 Level getLevel()
  {
    synchronized (lock)
      {
        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 boolean isLoggable(Level level)
  {
    synchronized (lock)
      {
        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 void setLevel(Level level)
  {
    synchronized (lock)
      {
        /*
         * 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 Filter getFilter()
  {
    synchronized (lock)
      {
        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 void setFilter(Filter filter) throws SecurityException
  {
    synchronized (lock)
      {
        /*
         * 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 void log(LogRecord record)
  {
    synchronized (lock)
      {
        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 void log(Level level, String message, Object param)
  {
    synchronized (lock)
      {
        if (isLoggable(level))
          {
            StackTraceElement caller = getCallerStackFrame();
            logp(level, caller != null ? caller.getClassName() : "<unknown>",
                 caller != null ? caller.getMethodName() : "<unknown>",
                 message, param);
          }
      }
  }

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

          }
      }
  }

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

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

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

  }

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

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

        return null;
      }
  }

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

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

        log(rec);
      }
  }

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

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

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

        log(rec);
      }
  }

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

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

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

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

        log(rec);
      }
  }

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

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

        log(rec);
      }
  }

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

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

  public void entering(String sourceClass, String sourceMethod, Object[] params)
  {
    synchronized (lock)
      {
        if (isLoggable(Level.FINER))
          {
            CPStringBuilder buf = new CPStringBuilder(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 void exiting(String sourceClass, String sourceMethod)
  {
    synchronized (lock)
      {
        if (isLoggable(Level.FINER))
          logp(Level.FINER, sourceClass, sourceMethod, "RETURN");
      }
  }

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

  public void throwing(String sourceClass, String sourceMethod, Throwable thrown)
  {
    synchronized (lock)
      {
        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 void severe(String message)
  {
    synchronized (lock)
      {
        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 void warning(String message)
  {
    synchronized (lock)
      {
        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 void info(String message)
  {
    synchronized (lock)
      {
        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 void config(String message)
  {
    synchronized (lock)
      {
        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 void fine(String message)
  {
    synchronized (lock)
      {
        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 void finer(String message)
  {
    synchronized (lock)
      {
        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 void finest(String message)
  {
    synchronized (lock)
      {
        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 void addHandler(Handler handler) throws SecurityException
  {
    synchronized (lock)
      {
        if (handler == null)
          throw new NullPointerException();

        /*
         * 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 void removeHandler(Handler handler) throws SecurityException
  {
    synchronized (lock)
      {
        /*
         * An application is allowed to control an anonymous logger without
         * having the permission to control the logging infrastructure.
         */
        if (! anonymous)
          LogManager.getLogManager().checkAccess();

        if (handler == null)
          throw new NullPointerException();

        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 Handler[] getHandlers()
  {
    synchronized (lock)
      {
        /*
         * 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 boolean getUseParentHandlers()
  {
    synchronized (lock)
      {
        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 void setUseParentHandlers(boolean useParentHandlers)
  {
    synchronized (lock)
      {
        /*
         * 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 Logger getParent()
  {
    synchronized (lock)
      {
        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 void setParent(Logger parent)
  {
    synchronized (lock)
      {
        if (parent == null)
          throw new NullPointerException();

        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 StackTraceElement getCallerStackFrame()
  {
    Throwable t = new Throwable();
    StackTraceElement[] stackTrace = t.getStackTrace();
    int index = 0;

    // skip to stackentries until this class
    while (index < stackTrace.length
           && ! stackTrace[index].getClassName().equals(getClass().getName()))
      index++;

    // skip the stackentries of this class
    while (index < stackTrace.length
           && stackTrace[index].getClassName().equals(getClass().getName()))
      index++;

    return index < stackTrace.length ? stackTrace[index] : null;
  }

  /**
   * Reset and close handlers attached to this logger. This function is package
   * private because it must only be available to the LogManager.
   */
  void resetLogger()
  {
    for (int i = 0; i < handlers.length; i++)
      {
        handlers[i].close();
        handlerList.remove(handlers[i]);
      }
    handlers = getHandlers();
  }
}
