/* 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;
  }
}
