/* StreamHandler.java --
   A class for publishing log messages to instances of java.io.OutputStream
   Copyright (C) 2002 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.OutputStream;
import java.io.OutputStreamWriter;
import java.io.UnsupportedEncodingException;
import java.io.Writer;

/**
 * A <code>StreamHandler</code> publishes <code>LogRecords</code> to
 * a instances of <code>java.io.OutputStream</code>.
 *
 * @author Sascha Brawer (brawer@acm.org)
 */
public class StreamHandler
  extends Handler
{
  private OutputStream  out;
  private Writer        writer;


 /**
  * Indicates the current state of this StreamHandler.  The value
  * should be one of STATE_FRESH, STATE_PUBLISHED, or STATE_CLOSED.
  */
  private int streamState = STATE_FRESH;


  /**
   * streamState having this value indicates that the StreamHandler
   * has been created, but the publish(LogRecord) method has not been
   * called yet.  If the StreamHandler has been constructed without an
   * OutputStream, writer will be null, otherwise it is set to a
   * freshly created OutputStreamWriter.
   */
  private static final int STATE_FRESH = 0;


  /**
   * streamState having this value indicates that the publish(LocRecord)
   * method has been called at least once.
   */
  private static final int STATE_PUBLISHED = 1;


  /**
   * streamState having this value indicates that the close() method
   * has been called.
   */
  private static final int STATE_CLOSED = 2;


  /**
   * Creates a <code>StreamHandler</code> without an output stream.
   * Subclasses can later use {@link
   * #setOutputStream(java.io.OutputStream)} to associate an output
   * stream with this StreamHandler.
   */
  public StreamHandler()
  {
    this(null, null);
  }


  /**
   * Creates a <code>StreamHandler</code> that formats log messages
   * with the specified Formatter and publishes them to the specified
   * output stream.
   *
   * @param out the output stream to which the formatted log messages
   *     are published.
   *
   * @param formatter the <code>Formatter</code> that will be used
   *     to format log messages.
   */
  public StreamHandler(OutputStream out, Formatter formatter)
  {
    this(out, "java.util.logging.StreamHandler", Level.INFO,
         formatter, SimpleFormatter.class);
  }


  StreamHandler(
    OutputStream out,
    String propertyPrefix,
    Level defaultLevel,
    Formatter formatter, Class defaultFormatterClass)
  {
    this.level = LogManager.getLevelProperty(propertyPrefix + ".level",
                                             defaultLevel);

    this.filter = (Filter) LogManager.getInstanceProperty(
      propertyPrefix + ".filter",
      /* must be instance of */       Filter.class,
      /* default: new instance of */  null);

    if (formatter != null)
      this.formatter = formatter;
    else
      this.formatter = (Formatter) LogManager.getInstanceProperty(
        propertyPrefix + ".formatter",
        /* must be instance of */       Formatter.class,
        /* default: new instance of */  defaultFormatterClass);

    try
    {
      String enc = LogManager.getLogManager().getProperty(propertyPrefix
                                                          + ".encoding");

      /* make sure enc actually is a valid encoding */
      if ((enc != null) && (enc.length() > 0))
        new String(new byte[0], enc);

      this.encoding = enc;
    }
    catch (Exception _)
    {
    }

    if (out != null)
    {
      try
      {
        changeWriter(out, getEncoding());
      }
      catch (UnsupportedEncodingException uex)
      {
        /* This should never happen, since the validity of the encoding
         * name has been checked above.
         */
        throw new RuntimeException(uex.getMessage());
      }
    }
  }


  private void checkOpen()
  {
    if (streamState == STATE_CLOSED)
      throw new IllegalStateException(this.toString() + " has been closed");
  }

  private void checkFresh()
  {
    checkOpen();
    if (streamState != STATE_FRESH)
      throw new IllegalStateException("some log records have been published to " + this);
  }


  private void changeWriter(OutputStream out, String encoding)
    throws UnsupportedEncodingException
  {
    OutputStreamWriter writer;

    /* The logging API says that a null encoding means the default
     * platform encoding. However, java.io.OutputStreamWriter needs
     * another constructor for the default platform encoding,
     * passing null would throw an exception.
     */
    if (encoding == null)
      writer = new OutputStreamWriter(out);
    else
      writer = new OutputStreamWriter(out, encoding);

    /* Closing the stream has side effects -- do this only after
     * creating a new writer has been successful.
     */
    if ((streamState != STATE_FRESH) || (this.writer != null))
      close();

    this.writer = writer;
    this.out = out;
    this.encoding = encoding;
    streamState = STATE_FRESH;
  }


  /**
   * Sets the character encoding which this handler uses for publishing
   * log records.  The encoding of a <code>StreamHandler</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.
   *
   * @throws SecurityException if a security manager exists and
   *     the caller is not granted the permission to control the
   *     the logging infrastructure.
   *
   * @exception IllegalStateException if any log records have been
   *     published to this <code>StreamHandler</code> before.  Please
   *     be aware that this is a pecularity of the GNU implementation.
   *     While the API specification indicates that it is an error
   *     if the encoding is set after records have been published,
   *     it does not mandate any specific behavior for that case.
   */
  public void setEncoding(String encoding)
    throws SecurityException, UnsupportedEncodingException
  {
    /* The inherited implementation first checks whether the invoking
     * code indeed has the permission to control the logging infra-
     * structure, and throws a SecurityException if this was not the
     * case.
     *
     * Next, it verifies that the encoding is supported and throws
     * an UnsupportedEncodingExcpetion otherwise. Finally, it remembers
     * the name of the encoding.
     */
    super.setEncoding(encoding);

    checkFresh();

    /* If out is null, setEncoding is being called before an output
     * stream has been set. In that case, we need to check that the
     * encoding is valid, and remember it if this is the case.  Since
     * this is exactly what the inherited implementation of
     * Handler.setEncoding does, we can delegate.
     */
    if (out != null)
    {
      /* The logging API says that a null encoding means the default
       * platform encoding. However, java.io.OutputStreamWriter needs
       * another constructor for the default platform encoding, passing
       * null would throw an exception.
       */
      if (encoding == null)
        writer = new OutputStreamWriter(out);
      else
        writer = new OutputStreamWriter(out, encoding);
    }
  }


  /**
   * Changes the output stream to which this handler publishes
   * logging records.
   *
   * @throws SecurityException if a security manager exists and
   *         the caller is not granted the permission to control
   *         the logging infrastructure.
   *
   * @throws NullPointerException if <code>out</code>
   *         is <code>null</code>.
   */
  protected void setOutputStream(OutputStream out)
    throws SecurityException
  {
    LogManager.getLogManager().checkAccess();

    /* Throw a NullPointerException if out is null. */
    out.getClass();

    try
    {
      changeWriter(out, getEncoding());
    }
    catch (UnsupportedEncodingException ex)
    {
      /* This seems quite unlikely to happen, unless the underlying
       * implementation of java.io.OutputStreamWriter changes its
       * mind (at runtime) about the set of supported character
       * encodings.
       */
      throw new RuntimeException(ex.getMessage());
    }
  }


  /**
   * Publishes a <code>LogRecord</code> to the associated output
   * stream, provided the record passes all tests for being loggable.
   * The <code>StreamHandler</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.
   *
   * <p>If a log record is being published to a
   * <code>StreamHandler</code> that has been closed earlier, the Sun
   * J2SE 1.4 reference can be observed to silently ignore the
   * call. The GNU implementation, however, intentionally behaves
   * differently by informing the <code>ErrorManager</code> associated
   * with this <code>StreamHandler</code>.  Since the condition
   * indicates a programming error, the programmer should be
   * informed. It also seems extremely unlikely that any application
   * would depend on the exact behavior in this rather obscure,
   * erroneous case -- especially since the API specification does not
   * prescribe what is supposed to happen.
   *
   * @param record the log event to be published.
   */
  public void publish(LogRecord record)
  {
    String formattedMessage;

    if (!isLoggable(record))
      return;

    if (streamState == STATE_FRESH)
    {
      try
      {
        writer.write(formatter.getHead(this));
      }
      catch (java.io.IOException ex)
      {
        reportError(null, ex, ErrorManager.WRITE_FAILURE);
        return;
      }
      catch (Exception ex)
      {
        reportError(null, ex, ErrorManager.GENERIC_FAILURE);
        return;
      }

      streamState = STATE_PUBLISHED;
    }

    try
    {
      formattedMessage = formatter.format(record);
    }
    catch (Exception ex)
    {
      reportError(null, ex, ErrorManager.FORMAT_FAILURE);
      return;
    }

    try
    {
      writer.write(formattedMessage);
    }
    catch (Exception ex)
    {
      reportError(null, ex, ErrorManager.WRITE_FAILURE);
    }
  }


  /**
   * Checks whether or not a <code>LogRecord</code> would be logged
   * if it was passed to this <code>StreamHandler</code> for publication.
   *
   * <p>The <code>StreamHandler</code> implementation first checks
   * whether a writer is present and the handler's 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>StreamHandler</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)
  {
    return (writer != null) && super.isLoggable(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.
   *
   * <p>If a <code>StreamHandler</code> that has been closed earlier
   * is closed a second time, the Sun J2SE 1.4 reference can be
   * observed to silently ignore the call. The GNU implementation,
   * however, intentionally behaves differently by informing the
   * <code>ErrorManager</code> associated with this
   * <code>StreamHandler</code>.  Since the condition indicates a
   * programming error, the programmer should be informed. It also
   * seems extremely unlikely that any application would depend on the
   * exact behavior in this rather obscure, erroneous case --
   * especially since the API specification does not prescribe what is
   * supposed to happen.
   */
  public void flush()
  {
    try
    {
      checkOpen();
      if (writer != null)
        writer.flush();
    }
    catch (Exception ex)
    {
      reportError(null, ex, ErrorManager.FLUSH_FAILURE);
    }
  }


  /**
   * Closes this <code>StreamHandler</code> after having forced any
   * data that may have been buffered to the underlying output
   * device.
   *
   * <p>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>
   *
   * <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.</p>
   *
   * <p>If a <code>StreamHandler</code> that has been closed earlier
   * is closed a second time, the Sun J2SE 1.4 reference can be
   * observed to silently ignore the call. The GNU implementation,
   * however, intentionally behaves differently by informing the
   * <code>ErrorManager</code> associated with this
   * <code>StreamHandler</code>.  Since the condition indicates a
   * programming error, the programmer should be informed. It also
   * seems extremely unlikely that any application would depend on the
   * exact behavior in this rather obscure, erroneous case --
   * especially since the API specification does not prescribe what is
   * supposed to happen.
   *
   * @throws SecurityException if a security manager exists and
   *         the caller is not granted the permission to control
   *         the logging infrastructure.
   */
  public void close()
    throws SecurityException
  {
    LogManager.getLogManager().checkAccess();

    try
    {
      /* Although  flush also calls checkOpen, it catches
       * any exceptions and reports them to the ErrorManager
       * as flush failures.  However, we want to report
       * a closed stream as a close failure, not as a
       * flush failure here.  Therefore, we call checkOpen()
       * before flush().
       */
      checkOpen();
      flush();

      if (writer != null)
      {
        if (formatter != null)
        {
          /* Even if the StreamHandler has never published a record,
           * it emits head and tail upon closing. An earlier version
           * of the GNU Classpath implementation did not emitted
           * anything. However, this had caused XML log files to be
           * entirely empty instead of containing no log records.
           */
          if (streamState == STATE_FRESH)
            writer.write(formatter.getHead(this));
          if (streamState != STATE_CLOSED)
            writer.write(formatter.getTail(this));
        }
        streamState = STATE_CLOSED;
        writer.close();
      }
    }
    catch (Exception ex)
    {
      reportError(null, ex, ErrorManager.CLOSE_FAILURE);
    }
  }
}
