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