mirror of git://gcc.gnu.org/git/gcc.git
				
				
				
			
		
			
				
	
	
		
			1186 lines
		
	
	
		
			38 KiB
		
	
	
	
		
			Java
		
	
	
	
			
		
		
	
	
			1186 lines
		
	
	
		
			38 KiB
		
	
	
	
		
			Java
		
	
	
	
/* Logger.java -- a class for logging messages
 | 
						|
   Copyright (C) 2002, 2004 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 StackTraceElement getCallerStackFrame()
 | 
						|
  {
 | 
						|
    Throwable t = new Throwable();
 | 
						|
    StackTraceElement[] stackTrace = t.getStackTrace();
 | 
						|
    int index = 0;
 | 
						|
    // skip to stackentries until this class
 | 
						|
    while(!stackTrace[index].getClassName().equals(getClass().getName())){index++;}
 | 
						|
    // skip the stackentries of this class
 | 
						|
    while(stackTrace[index].getClassName().equals(getClass().getName())){index++;}
 | 
						|
 | 
						|
    return stackTrace[index];
 | 
						|
  }
 | 
						|
  
 | 
						|
}
 |