/* MemoryHandler.java -- a class for buffering log messages in a memory buffer
   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;

/**
 * A <code>MemoryHandler</code> maintains a circular buffer of
 * log records.
 *
 * <p><strong>Configuration:</strong> Values of the subsequent
 * <code>LogManager</code> properties are taken into consideration
 * when a <code>MemoryHandler</code> is initialized.
 * If a property is not defined, or if it has an invalid
 * value, a default is taken without an exception being thrown.
 *
 * <ul>
 * <li><code>java.util.MemoryHandler.level</code> - specifies
 *     the initial severity level threshold. Default value:
 *     <code>Level.ALL</code>.</li>
 * <li><code>java.util.MemoryHandler.filter</code> - specifies
 *     the name of a Filter class. Default value: No Filter.</li>
 * <li><code>java.util.MemoryHandler.size</code> - specifies the
 *     maximum number of log records that are kept in the circular
 *     buffer.  Default value: 1000.</li>
 * <li><code>java.util.MemoryHandler.push</code> - specifies the
 *     <code>pushLevel</code>. Default value:
 *     <code>Level.SEVERE</code>.</li>
 * <li><code>java.util.MemoryHandler.target</code> - specifies the
 *     name of a subclass of {@link Handler} that will be used as the
 *     target handler.  There is no default value for this property;
 *     if it is not set, the no-argument MemoryHandler constructor
 *     will throw an exception.</li>
 * </ul>
 *
 * @author Sascha Brawer (brawer@acm.org)
 */
public class MemoryHandler
  extends Handler
{
  /**
   * The storage area used for buffering the unpushed log records in
   * memory.
   */
  private final LogRecord[] buffer;


  /**
   * The current position in the circular buffer. For a new
   * MemoryHandler, or immediately after {@link #push()} was called,
   * the value of this variable is zero.  Each call to {@link
   * #publish(LogRecord)} will store the published LogRecord into
   * <code>buffer[position]</code> before position is incremented by
   * one.  If position becomes greater than the size of the buffer, it
   * is reset to zero.
   */
  private int position;


  /**
   * The number of log records which have been published, but not
   * pushed yet to the target handler.
   */
  private int numPublished;


  /**
   * The push level threshold for this <code>Handler</code>.  When a
   * record is published whose severity level is greater than or equal
   * to the <code>pushLevel</code> of this <code>MemoryHandler</code>,
   * the {@link #push()} method will be invoked for pushing the buffer
   * contents to the target <code>Handler</code>.
   */
  private Level pushLevel;


  /**
   * The Handler to which log records are forwarded for actual
   * publication.
   */
  private final Handler target;


  /**
   * Constructs a <code>MemoryHandler</code> for keeping a circular
   * buffer of LogRecords; the initial configuration is determined by
   * the <code>LogManager</code> properties described above.
   */
  public MemoryHandler()
  {
    this((Handler) LogManager.getInstanceProperty(
           "java.util.logging.MemoryHandler.target",
           Handler.class, /* default */ null),
         LogManager.getIntPropertyClamped(
           "java.util.logging.MemoryHandler.size",
           /* default */ 1000,
           /* minimum value */ 1,
           /* maximum value */ Integer.MAX_VALUE),
         LogManager.getLevelProperty(
           "java.util.logging.MemoryHandler.push",
           /* default push level */ Level.SEVERE));
  }


  /**
   * Constructs a <code>MemoryHandler</code> for keeping a circular
   * buffer of LogRecords, given some parameters. The values of the
   * other parameters are taken from LogManager properties, as
   * described above.
   *
   * @param target the target handler that will receive those
   *               log records that are passed on for publication.
   *
   * @param size the number of log records that are kept in the buffer.
   *             The value must be a at least one.
   *
   * @param pushLevel the push level threshold for this
   *     <code>MemoryHandler</code>.  When a record is published whose
   *     severity level is greater than or equal to
   *     <code>pushLevel</code>, the {@link #push()} method will be
   *     invoked in order to push the bufffer contents to
   *     <code>target</code>.
   *
   * @throws java.lang.IllegalArgumentException if <code>size</code>
   *         is negative or zero. The GNU implementation also throws
   *         an IllegalArgumentException if <code>target</code> or
   *         <code>pushLevel</code> are <code>null</code>, but the
   *         API specification does not prescribe what should happen
   *         in those cases.
   */
  public MemoryHandler(Handler target, int size, Level pushLevel)
  {
    if ((target == null) || (size <= 0) || (pushLevel == null))
      throw new IllegalArgumentException();

    buffer = new LogRecord[size];
    this.pushLevel = pushLevel;
    this.target = target;

    setLevel(LogManager.getLevelProperty(
      "java.util.logging.MemoryHandler.level",
      /* default value */ Level.ALL));

    setFilter((Filter) LogManager.getInstanceProperty(
      "java.util.logging.MemoryHandler.filter",
      /* must be instance of */ Filter.class,
      /* default value */ null));
  }


  /**
   * Stores a <code>LogRecord</code> in a fixed-size circular buffer,
   * provided the record passes all tests for being loggable.  If the
   * buffer is full, the oldest record will be discarded.
   *
   * <p>If the record has a severity level which is greater than or
   * equal to the <code>pushLevel</code> of this
   * <code>MemoryHandler</code>, the {@link #push()} method will be
   * invoked for pushing the buffer contents to the target
   * <code>Handler</code>.
   *
   * <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.
   *
   * @param record the log event to be published.
   */
  public void publish(LogRecord record)
  {
    if (!isLoggable(record))
      return;

    buffer[position] = record;
    position = (position + 1) % buffer.length;
    numPublished = numPublished + 1;

    if (record.getLevel().intValue() >= pushLevel.intValue())
      push();
  }


  /**
   * Pushes the contents of the memory buffer to the target
   * <code>Handler</code> and clears the buffer. Note that
   * the target handler will discard those records that do
   * not satisfy its own severity level threshold, or that are
   * not considered loggable by an installed {@link Filter}.
   *
   * <p>In case of an I/O failure, the {@link ErrorManager} of the
   * target <code>Handler</code> will be notified, but the caller of
   * this method will not receive an exception.
   */
  public void push()
  {
    int i;

    if (numPublished < buffer.length)
    {
      for (i = 0; i < position; i++)
        target.publish(buffer[i]);
    }
    else
    {
      for (i = position; i < buffer.length; i++)
        target.publish(buffer[i]);
      for (i = 0; i < position; i++)
        target.publish(buffer[i]);
    }

    numPublished = 0;
    position = 0;
  }


  /**
   * Forces any data that may have been buffered by the target
   * <code>Handler</code> to the underlying output device, but
   * does <em>not</em> push the contents of the circular memory
   * buffer to the target handler.
   *
   * <p>In case of an I/O failure, the {@link ErrorManager} of the
   * target <code>Handler</code> will be notified, but the caller of
   * this method will not receive an exception.
   *
   * @see #push()
   */
  public void flush()
  {
    target.flush();
  }


  /**
   * Closes this <code>MemoryHandler</code> and its associated target
   * handler, discarding the contents of the memory buffer.  However,
   * any data that may have been buffered by the target
   * <code>Handler</code> is forced 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
   * the associated target <code>Handler</code> will be informed, but
   * the caller of this method will not receive an exception.</p>
   *
   * @throws SecurityException if a security manager exists and
   *         the caller is not granted the permission to control
   *         the logging infrastructure.
   *
   * @see #push()
   */
  public void close()
    throws SecurityException
  {
    push();

    /* This will check for LoggingPermission("control"). If the
     * current security context does not grant this permission,
     * push() has been executed, but this does not impose a
     * security risk.
     */
    target.close();
  }



  /**
   * Returns the push level threshold for this <code>Handler</code>.
   * When a record is published whose severity level is greater
   * than or equal to the <code>pushLevel</code> of this
   * <code>MemoryHandler</code>, the {@link #push()} method will be
   * invoked for pushing the buffer contents to the target
   * <code>Handler</code>.
   *
   * @return the push level threshold for automatic pushing.
   */
  public Level getPushLevel()
  {
    return pushLevel;
  }


  /**
   * Sets the push level threshold for this <code>Handler</code>.
   * When a record is published whose severity level is greater
   * than or equal to the <code>pushLevel</code> of this
   * <code>MemoryHandler</code>, the {@link #push()} method will be
   * invoked for pushing the buffer contents to the target
   * <code>Handler</code>.
   *
   * @param pushLevel the push level threshold for automatic pushing.
   *
   * @exception SecurityException if a security manager exists and
   *            the caller is not granted the permission to control
   *            the logging infrastructure.
   *
   * @exception NullPointerException if <code>pushLevel</code> is
   *            <code>null</code>.
   */
  public void setPushLevel(Level pushLevel)
  {
    LogManager.getLogManager().checkAccess();

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

    this.pushLevel = pushLevel;
  }
}
