/* 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., 59 Temple Place, Suite 330, Boston, MA
02111-1307 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;
  }
}
