/* Handler.java -- a class for publishing log 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., 51 Franklin Street, Fifth Floor, Boston, MA
02110-1301 USA.

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

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


package java.util.logging;

import java.io.UnsupportedEncodingException;

/**
 * A <code>Handler</code> publishes <code>LogRecords</code> to
 * a sink, for example a file, the console or a network socket.
 * There are different subclasses of <code>Handler</code>
 * to deal with different kinds of sinks.
 *
 * <p>FIXME: Are handlers thread-safe, or is the assumption that only
 * loggers are, and a handler can belong only to one single logger? If
 * the latter, should we enforce it? (Spec not clear). In any
 * case, it needs documentation.
 *
 * @author Sascha Brawer (brawer@acm.org)
 */
public abstract class Handler
{
  Formatter     formatter;
  Filter        filter;
  Level         level;
  ErrorManager  errorManager;
  String        encoding;

  /**
   * Constructs a Handler with a logging severity level of
   * <code>Level.ALL</code>, no formatter, no filter, and
   * an instance of <code>ErrorManager</code> managing errors.
   *
   * <p><strong>Specification Note:</strong> The specification of the
   * Java<sup>TM</sup> Logging API does not mention which character
   * encoding is to be used by freshly constructed Handlers.  The GNU
   * implementation uses the default platform encoding, but other
   * Java implementations might behave differently.
   *
   * <p><strong>Specification Note:</strong> While a freshly constructed
   * Handler is required to have <em>no filter</em> according to the
   * specification, <code>null</code> is not a valid parameter for
   * <code>Handler.setFormatter</code>.  Therefore, the following
   * code will throw a <code>java.lang.NullPointerException</code>:
   *
   * <p><pre>Handler h = new MyConcreteSubclassOfHandler();
h.setFormatter(h.getFormatter());</pre>
   *
   * It seems strange that a freshly constructed Handler is not
   * supposed to provide a Formatter, but this is what the specification
   * says.
   */
  protected Handler()
  {
    level = Level.ALL;
  }


  /**
   * Publishes a <code>LogRecord</code> to an appropriate sink,
   * provided the record passes all tests for being loggable.  The
   * <code>Handler</code> will localize the message of the log
   * record and substitute any message parameters.
   *
   * <p>Most applications do not need to call this method directly.
   * Instead, they will use use a {@link Logger}, which will
   * create LogRecords and distribute them to registered handlers.
   *
   * <p>In case of an I/O failure, the <code>ErrorManager</code>
   * of this <code>Handler</code> will be informed, but the caller
   * of this method will not receive an exception.
   *
   * @param record the log event to be published.
   */
  public abstract void publish(LogRecord record);


  /**
   * Forces any data that may have been buffered to the underlying
   * output device.
   *
   * <p>In case of an I/O failure, the <code>ErrorManager</code>
   * of this <code>Handler</code> will be informed, but the caller
   * of this method will not receive an exception.
   */
  public abstract void flush();


  /**
   * Closes this <code>Handler</code> after having flushed
   * the buffers.  As soon as <code>close</code> has been called,
   * a <code>Handler</code> should not be used anymore. Attempts
   * to publish log records, to flush buffers, or to modify the
   * <code>Handler</code> in any other way may throw runtime
   * exceptions after calling <code>close</code>.
   *
   * <p>In case of an I/O failure, the <code>ErrorManager</code>
   * of this <code>Handler</code> will be informed, but the caller
   * of this method will not receive an exception.
   *
   * @throws SecurityException if a security manager exists and
   *         the caller is not granted the permission to control
   *         the logging infrastructure.
   */
  public abstract void close()
    throws SecurityException;


  /**
   * Returns the <code>Formatter</code> which will be used to
   * localize the text of log messages and to substitute
   * message parameters.  A <code>Handler</code> is encouraged,
   * but not required to actually use an assigned
   * <code>Formatter</code>.
   *
   * @return the <code>Formatter</code> being used, or
   *         <code>null</code> if this <code>Handler</code>
   *         does not use formatters and no formatter has
   *         ever been set by calling <code>setFormatter</code>.
   */
  public Formatter getFormatter()
  {
    return formatter;
  }


  /**
   * Sets the <code>Formatter</code> which will be used to
   * localize the text of log messages and to substitute
   * message parameters.  A <code>Handler</code> is encouraged,
   * but not required to actually use an assigned
   * <code>Formatter</code>.
   *
   * @param formatter the new <code>Formatter</code> to use.
   *
   * @throws SecurityException if a security manager exists and
   *         the caller is not granted the permission to control
   *         the logging infrastructure.
   *
   * @throws NullPointerException if <code>formatter</code> is
   *         <code>null</code>.
   */
  public void setFormatter(Formatter formatter)
    throws SecurityException
  {
    LogManager.getLogManager().checkAccess();

    /* Throws a NullPointerException if formatter is null. */
    formatter.getClass();

    this.formatter = formatter;
  }


  /**
   * Returns the character encoding which this handler uses for publishing
   * log records.
   *
   * @return the name of a character encoding, or <code>null</code>
   *         for the default platform encoding.
   */
  public String getEncoding()
  {
    return encoding;
  }


  /**
   * Sets the character encoding which this handler uses for publishing
   * log records.  The encoding of a <code>Handler</code> must be
   * set before any log records have been published.
   *
   * @param encoding the name of a character encoding, or <code>null</code>
   *            for the default encoding.
   *
   * @exception SecurityException if a security manager exists and
   *            the caller is not granted the permission to control
   *            the logging infrastructure.
   *
   */
  public void setEncoding(String encoding)
    throws SecurityException, UnsupportedEncodingException
  {
    /* Should any developer ever change this implementation, they are
     * advised to have a look at StreamHandler.setEncoding(String),
     * which overrides this method without calling super.setEncoding.
     */
    LogManager.getLogManager().checkAccess();

    /* Simple check for supported encodings. This is more expensive
     * than it could be, but this method is overwritten by StreamHandler
     * anyway.
     */
    if (encoding != null)
      new String(new byte[0], encoding);

    this.encoding = encoding;
  }


  /**
   * Returns the <code>Filter</code> that currently controls which
   * log records are being published by this <code>Handler</code>.
   *
   * @return the currently active <code>Filter</code>, or
   *         <code>null</code> if no filter has been associated.
   *         In the latter case, log records are filtered purely
   *         based on their severity level.
   */
  public Filter getFilter()
  {
    return filter;
  }


  /**
   * Sets the <code>Filter</code> for controlling which
   * log records will be published by this <code>Handler</code>.
   *
   * @param filter the <code>Filter</code> to use, or
   *         <code>null</code> to filter log records purely based
   *         on their severity level.
   */
  public void setFilter(Filter filter)
    throws SecurityException
  {
    LogManager.getLogManager().checkAccess();
    this.filter = filter;
  }


  /**
   * Returns the <code>ErrorManager</code> that currently deals
   * with errors originating from this Handler.
   *
   * @exception SecurityException if a security manager exists and
   *            the caller is not granted the permission to control
   *            the logging infrastructure.
   */
  public ErrorManager getErrorManager()
  {
    LogManager.getLogManager().checkAccess();

    /* Developers wanting to change the subsequent code should
     * have a look at Handler.reportError -- it also can create
     * an ErrorManager, but does so without checking permissions
     * to control the logging infrastructure.
     */
    if (errorManager == null)
      errorManager = new ErrorManager();

    return errorManager;
  }


  public void setErrorManager(ErrorManager manager)
  {
    LogManager.getLogManager().checkAccess();

    /* Make sure manager is not null. */
    manager.getClass();

    this.errorManager = manager;
  }


  protected void reportError(String message, Exception ex, int code)
  {
    if (errorManager == null)
      errorManager = new ErrorManager();

    errorManager.error(message, ex, code);
  }


  /**
   * 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.
   */
  public Level getLevel()
  {
    return level;
  }


  /**
   * Sets 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.
   *
   * @param level the severity level below which all log messages
   *              will be discarded.
   *
   * @exception SecurityException if a security manager exists and
   *            the caller is not granted the permission to control
   *            the logging infrastructure.
   *
   * @exception NullPointerException if <code>level</code> is
   *            <code>null</code>.
   */
  public void setLevel(Level level)
  {
    LogManager.getLogManager().checkAccess();

    /* Throw NullPointerException if level is null.  */
    level.getClass();
    this.level = level;
  }


  /**
   * Checks whether a <code>LogRecord</code> would be logged
   * if it was passed to this <code>Handler</code> for publication.
   *
   * <p>The <code>Handler</code> implementation considers a record as
   * loggable if its level is greater than or equal to the severity
   * level threshold.  In a second step, if a {@link Filter} has
   * been installed, its {@link Filter#isLoggable(LogRecord) isLoggable}
   * method is invoked. Subclasses of <code>Handler</code> can override
   * this method to impose their own constraints.
   *
   * @param record the <code>LogRecord</code> to be checked.
   *
   * @return <code>true</code> if <code>record</code> would
   *         be published by {@link #publish(LogRecord) publish},
   *         <code>false</code> if it would be discarded.
   *
   * @see #setLevel(Level)
   * @see #setFilter(Filter)
   * @see Filter#isLoggable(LogRecord)
   *
   * @throws NullPointerException if <code>record</code>
   *         is <code>null</code>.
   */
  public boolean isLoggable(LogRecord record)
  {
    if (record.getLevel().intValue() < level.intValue())
      return false;

    if (filter != null)
      return filter.isLoggable(record);
    else
      return true;
  }
}
