diff options
Diffstat (limited to 'libjava/classpath/java/util/logging/Logger.java')
-rw-r--r-- | libjava/classpath/java/util/logging/Logger.java | 1624 |
1 files changed, 796 insertions, 828 deletions
diff --git a/libjava/classpath/java/util/logging/Logger.java b/libjava/classpath/java/util/logging/Logger.java index 01ef8f522b8..f7157c17698 100644 --- a/libjava/classpath/java/util/logging/Logger.java +++ b/libjava/classpath/java/util/logging/Logger.java @@ -45,110 +45,105 @@ 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. - * + * 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. + * 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"); - } - }); + 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. + * 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). + * <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). + * <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. + * 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; @@ -156,29 +151,26 @@ public class Logger 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} + * 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. - * + * {@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. + * <code>resourceBundleName</code> is not <code>null</code> + * and no such bundle could be located. */ protected Logger(String name, String resourceBundleName) - throws MissingResourceException + throws MissingResourceException { this.name = name; this.resourceBundleName = resourceBundleName; @@ -190,1002 +182,978 @@ public class Logger level = null; - /* This is null when the root logger is being constructed, - * and the root logger afterwards. + /* + * 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. + * 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. - * + * 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>. + * <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; + 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. + /* + * 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 + synchronized (lock) { - /* 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(); - } + 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. + * 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. - * + * 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. + * <code>resourceBundleName</code> is not <code>null</code> + * and no such bundle could be located. */ public static Logger getAnonymousLogger(String resourceBundleName) - throws MissingResourceException + throws MissingResourceException { - Logger result; + 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. + * 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() + public String getResourceBundleName() { - return resourceBundleName; + 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. + * 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() + public ResourceBundle getResourceBundle() { - return resourceBundle; + 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. + * 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() + public Level getLevel() { - return level; + 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>. + * 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) + public boolean isLoggable(Level level) { - if (this.level != null) - return this.level.intValue() <= level.intValue(); + synchronized (lock) + { + if (this.level != null) + return this.level.intValue() <= level.intValue(); - if (parent != null) - return parent.isLoggable(level); - else - return false; + 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}. + * 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) + public 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; + 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 synchronized Filter getFilter() + public Filter getFilter() { - return filter; + 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}. + * @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 + public 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; + 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. + * + * @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. + /* + * 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. - * + * 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) + public 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 + synchronized (lock) { - /* 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(); + 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); + } } - while (parent != null); - } } - public void log(Level level, String message) { if (isLoggable(level)) log(level, message, (Object[]) null); } - - public synchronized void log(Level level, - String message, - Object param) + public void log(Level level, String message, Object param) { - if (isLoggable(level)) + synchronized (lock) { - StackTraceElement caller = getCallerStackFrame(); - logp(level, - caller != null ? caller.getClassName() : "<unknown>", - caller != null ? caller.getMethodName() : "<unknown>", - message, - param); + if (isLoggable(level)) + { + StackTraceElement caller = getCallerStackFrame(); + logp(level, caller != null ? caller.getClassName() : "<unknown>", + caller != null ? caller.getMethodName() : "<unknown>", + message, param); + } } } - - public synchronized void log(Level level, - String message, - Object[] params) + public void log(Level level, String message, Object[] params) { - if (isLoggable(level)) + synchronized (lock) { - StackTraceElement caller = getCallerStackFrame(); - logp(level, - caller != null ? caller.getClassName() : "<unknown>", - caller != null ? caller.getMethodName() : "<unknown>", - message, - params); + if (isLoggable(level)) + { + StackTraceElement caller = getCallerStackFrame(); + logp(level, caller != null ? caller.getClassName() : "<unknown>", + caller != null ? caller.getMethodName() : "<unknown>", + message, params); + + } } } - - public synchronized void log(Level level, - String message, - Throwable thrown) + public void log(Level level, String message, Throwable thrown) { - if (isLoggable(level)) + synchronized (lock) { - StackTraceElement caller = getCallerStackFrame(); - logp(level, - caller != null ? caller.getClassName() : "<unknown>", - caller != null ? caller.getMethodName() : "<unknown>", - message, - thrown); + if (isLoggable(level)) + { + StackTraceElement caller = getCallerStackFrame(); + logp(level, caller != null ? caller.getClassName() : "<unknown>", + caller != null ? caller.getMethodName() : "<unknown>", + message, thrown); + } } } - - public synchronized void logp(Level level, - String sourceClass, - String sourceMethod, - String message) + public void logp(Level level, String sourceClass, String sourceMethod, + String message) { - logp(level, sourceClass, sourceMethod, message, - (Object[]) null); + synchronized (lock) + { + logp(level, sourceClass, sourceMethod, message, (Object[]) null); + } } - - public synchronized void logp(Level level, - String sourceClass, - String sourceMethod, - String message, - Object param) + public void logp(Level level, String sourceClass, String sourceMethod, + String message, Object param) { - logp(level, sourceClass, sourceMethod, message, - new Object[] { param }); - } + synchronized (lock) + { + logp(level, sourceClass, sourceMethod, message, new Object[] { param }); + } + } - private synchronized ResourceBundle findResourceBundle() + private ResourceBundle findResourceBundle() { - if (resourceBundle != null) - return resourceBundle; + synchronized (lock) + { + if (resourceBundle != null) + return resourceBundle; - if (parent != null) - return parent.findResourceBundle(); + if (parent != null) + return parent.findResourceBundle(); - return null; + return null; + } } - - private synchronized void logImpl(Level level, - String sourceClass, - String sourceMethod, - String message, - Object[] params) + private void logImpl(Level level, String sourceClass, String sourceMethod, + String message, Object[] params) { - LogRecord rec = new LogRecord(level, message); + synchronized (lock) + { + LogRecord rec = new LogRecord(level, message); - rec.setResourceBundle(findResourceBundle()); - rec.setSourceClassName(sourceClass); - rec.setSourceMethodName(sourceMethod); - rec.setParameters(params); + rec.setResourceBundle(findResourceBundle()); + rec.setSourceClassName(sourceClass); + rec.setSourceMethodName(sourceMethod); + rec.setParameters(params); - log(rec); + log(rec); + } } - - public synchronized void logp(Level level, - String sourceClass, - String sourceMethod, - String message, - Object[] params) + public void logp(Level level, String sourceClass, String sourceMethod, + String message, Object[] params) { - logImpl(level, sourceClass, sourceMethod, message, params); + synchronized (lock) + { + logImpl(level, sourceClass, sourceMethod, message, params); + } } - - public synchronized void logp(Level level, - String sourceClass, - String sourceMethod, - String message, - Throwable thrown) + public void logp(Level level, String sourceClass, String sourceMethod, + String message, Throwable thrown) { - LogRecord rec = new LogRecord(level, message); + synchronized (lock) + { + LogRecord rec = new LogRecord(level, message); - rec.setResourceBundle(resourceBundle); - rec.setSourceClassName(sourceClass); - rec.setSourceMethodName(sourceMethod); - rec.setThrown(thrown); + rec.setResourceBundle(resourceBundle); + rec.setSourceClassName(sourceClass); + rec.setSourceMethodName(sourceMethod); + rec.setThrown(thrown); - log(rec); + log(rec); + } } - - public synchronized void logrb(Level level, - String sourceClass, - String sourceMethod, - String bundleName, - String message) + public void logrb(Level level, String sourceClass, String sourceMethod, + String bundleName, String message) { - logrb(level, sourceClass, sourceMethod, bundleName, - message, (Object[]) null); + synchronized (lock) + { + logrb(level, sourceClass, sourceMethod, bundleName, message, + (Object[]) null); + } } - - public synchronized void logrb(Level level, - String sourceClass, - String sourceMethod, - String bundleName, - String message, - Object param) + public void logrb(Level level, String sourceClass, String sourceMethod, + String bundleName, String message, Object param) { - logrb(level, sourceClass, sourceMethod, bundleName, - message, new Object[] { param }); + synchronized (lock) + { + 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) + public void logrb(Level level, String sourceClass, String sourceMethod, + String bundleName, String message, Object[] params) { - LogRecord rec = new LogRecord(level, message); + synchronized (lock) + { + LogRecord rec = new LogRecord(level, message); - rec.setResourceBundleName(bundleName); - rec.setSourceClassName(sourceClass); - rec.setSourceMethodName(sourceMethod); - rec.setParameters(params); + rec.setResourceBundleName(bundleName); + rec.setSourceClassName(sourceClass); + rec.setSourceMethodName(sourceMethod); + rec.setParameters(params); - log(rec); + log(rec); + } } - - public synchronized void logrb(Level level, - String sourceClass, - String sourceMethod, - String bundleName, - String message, - Throwable thrown) + public void logrb(Level level, String sourceClass, String sourceMethod, + String bundleName, String message, Throwable thrown) { - LogRecord rec = new LogRecord(level, message); + synchronized (lock) + { + LogRecord rec = new LogRecord(level, message); - rec.setResourceBundleName(bundleName); - rec.setSourceClassName(sourceClass); - rec.setSourceMethodName(sourceMethod); - rec.setThrown(thrown); + rec.setResourceBundleName(bundleName); + rec.setSourceClassName(sourceClass); + rec.setSourceMethodName(sourceMethod); + rec.setThrown(thrown); - log(rec); + log(rec); + } } - - public synchronized void entering(String sourceClass, - String sourceMethod) + public void entering(String sourceClass, String sourceMethod) { - if (isLoggable(Level.FINER)) - logp(Level.FINER, sourceClass, sourceMethod, "ENTRY"); + synchronized (lock) + { + if (isLoggable(Level.FINER)) + logp(Level.FINER, sourceClass, sourceMethod, "ENTRY"); + } } - - public synchronized void entering(String sourceClass, - String sourceMethod, - Object param) + public void entering(String sourceClass, String sourceMethod, Object param) { - if (isLoggable(Level.FINER)) - logp(Level.FINER, sourceClass, sourceMethod, "ENTRY {0}", param); + synchronized (lock) + { + if (isLoggable(Level.FINER)) + logp(Level.FINER, sourceClass, sourceMethod, "ENTRY {0}", param); + } } - - public synchronized void entering(String sourceClass, - String sourceMethod, - Object[] params) + public 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++) + synchronized (lock) { - buf.append(" {"); - buf.append(i); - buf.append('}'); + 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); + } } - - logp(Level.FINER, sourceClass, sourceMethod, buf.toString(), params); - } } - - public synchronized void exiting(String sourceClass, - String sourceMethod) + public void exiting(String sourceClass, String sourceMethod) { - if (isLoggable(Level.FINER)) - logp(Level.FINER, sourceClass, sourceMethod, "RETURN"); + synchronized (lock) + { + if (isLoggable(Level.FINER)) + logp(Level.FINER, sourceClass, sourceMethod, "RETURN"); + } } - - public synchronized void exiting(String sourceClass, - String sourceMethod, - Object result) + public void exiting(String sourceClass, String sourceMethod, Object result) { - if (isLoggable(Level.FINER)) - logp(Level.FINER, sourceClass, sourceMethod, "RETURN {0}", result); + synchronized (lock) + { + if (isLoggable(Level.FINER)) + logp(Level.FINER, sourceClass, sourceMethod, "RETURN {0}", result); + } } - - public synchronized void throwing(String sourceClass, - String sourceMethod, - Throwable thrown) + public void throwing(String sourceClass, String sourceMethod, Throwable thrown) { - if (isLoggable(Level.FINER)) - logp(Level.FINER, sourceClass, sourceMethod, "THROW", 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. - * + * 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. + * @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) + public void severe(String message) { - if (isLoggable(Level.SEVERE)) - log(Level.SEVERE, 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. - * + * 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. + * @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) + public void warning(String message) { - if (isLoggable(Level.WARNING)) - log(Level.WARNING, 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. + * 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) + public void info(String message) { - if (isLoggable(Level.INFO)) - log(Level.INFO, 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. + * 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) + public void config(String message) { - if (isLoggable(Level.CONFIG)) - log(Level.CONFIG, 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. + * 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) + public void fine(String message) { - if (isLoggable(Level.FINE)) - log(Level.FINE, 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. + * 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) + public void finer(String message) { - if (isLoggable(Level.FINER)) - log(Level.FINER, 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. + * 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) + public void finest(String message) { - if (isLoggable(Level.FINEST)) - log(Level.FINEST, 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. - * + * 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}. + * @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 + public void addHandler(Handler handler) throws SecurityException { - 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(); - } + 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. - * + * 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>. + * @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 + public 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(); - - if (handler == null) - throw new NullPointerException(); - - handlerList.remove(handler); - handlers = getHandlers(); + 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. + * 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() + public 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()]); + 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. + * 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() + public boolean getUseParentHandlers() { - return useParentHandlers; + 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}. - * + * 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) + public 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; + 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. + * 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() + public Logger getParent() { - return parent; + 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}. + * 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) + public void setParent(Logger parent) { - if (parent == null) - throw new NullPointerException(); + synchronized (lock) + { + if (parent == null) + throw new NullPointerException(); - if (this == root) - throw new IllegalArgumentException( - "the root logger can only have a null parent"); + 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(); + /* + * 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; + 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. + * 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() @@ -1195,18 +1163,18 @@ public class Logger int index = 0; // skip to stackentries until this class - while(index < stackTrace.length - && !stackTrace[index].getClassName().equals(getClass().getName())) + 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())) + 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. |