/* ErrorManager.java --
   A class for dealing with errors that a Handler encounters
   during logging
   Copyright (C) 2002, 2003 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;

/**
 * An <code>ErrorManager</code> deals with errors that a <code>Handler</code>
 * encounters while logging.
 *
 * @see Handler#setErrorManager(ErrorManager)
 *
 * @author Sascha Brawer (brawer@acm.org)
 */
public class ErrorManager
{
  /* The values have been taken from Sun's public J2SE 1.4 API
   * documentation.
   * See http://java.sun.com/j2se/1.4/docs/api/constant-values.html
   */

  /**
   * Indicates that there was a failure that does not readily
   * fall into any of the other categories.
   */
  public static final int GENERIC_FAILURE = 0;


  /**
   * Indicates that there was a problem upon writing to
   * an output stream.
   */
  public static final int WRITE_FAILURE = 1;


  /**
   * Indicates that there was a problem upon flushing
   * an output stream.
   */
  public static final int FLUSH_FAILURE = 2;


  /**
   * Indicates that there was a problem upon closing
   * an output stream.
   */
  public static final int CLOSE_FAILURE = 3;


  /**
   * Indicates that there was a problem upon opening
   * an output stream.
   */
  public static final int OPEN_FAILURE = 4;


  /**
   * Indicates that there was a problem upon formatting
   * the message of a log record.
   */
  public static final int FORMAT_FAILURE = 5;


  /**
   * Indicates whether the {@link #error} method of this ErrorManager
   * has ever been used.
   *
   * Declared volatile in order to correctly support the
   * double-checked locking idiom (once the revised Java Memory Model
   * gets adopted); see Classpath bug #2944.
   */
  private volatile boolean everUsed = false;


  public ErrorManager()
  {
  }


  /**
   * Reports an error that occured upon logging.  The default implementation
   * emits the very first error to System.err, ignoring subsequent errors.
   *
   * @param message a message describing the error, or <code>null</code> if
   *                there is no suitable description.
   *
   * @param ex      an exception, or <code>null</code> if the error is not
   *                related to an exception.
   *
   * @param errorCode  one of the defined error codes, for example
   *                   <code>ErrorManager.CLOSE_FAILURE</code>.
   */
  public void error(String message, Exception ex, int errorCode)
  {
    if (everUsed)
      return;

    synchronized (this)
    {
      /* The double check is intentional. If the first check was
       * omitted, the monitor would have to be entered every time
       * error() method was called. If the second check was
       * omitted, the code below could be executed by multiple
       * threads simultaneously.
       *
       * This is the 'double-checked locking' idiom, which is broken
       * with the current version of the Java memory model.  However,
       * we assume that JVMs will have adopted a revised version of
       * the Java Memory Model by the time GNU Classpath gains
       * widespread acceptance. See Classpath bug #2944.
       */
      if (everUsed)
        return;

      everUsed = true;
    }

    String codeMsg;
    switch (errorCode)
    {
    case GENERIC_FAILURE:
      codeMsg = "GENERIC_FAILURE";
      break;

    case WRITE_FAILURE:
      codeMsg = "WRITE_FAILURE";
      break;

    case FLUSH_FAILURE:
      codeMsg = "FLUSH_FAILURE";
      break;

    case CLOSE_FAILURE:
      codeMsg = "CLOSE_FAILURE";
      break;

    case OPEN_FAILURE:
      codeMsg = "OPEN_FAILURE";
      break;

    case FORMAT_FAILURE:
      codeMsg = "FORMAT_FAILURE";
      break;

    default:
      codeMsg = String.valueOf(errorCode);
      break;
    }

    System.err.println("Error upon logging: " + codeMsg);
    if ((message != null) && (message.length() > 0))
      System.err.println(message);

    if (ex != null)
      ex.printStackTrace();
  }
}
