001/* ErrorManager.java --
002   A class for dealing with errors that a Handler encounters
003   during logging
004   Copyright (C) 2002, 2003 Free Software Foundation, Inc.
005
006This file is part of GNU Classpath.
007
008GNU Classpath is free software; you can redistribute it and/or modify
009it under the terms of the GNU General Public License as published by
010the Free Software Foundation; either version 2, or (at your option)
011any later version.
012
013GNU Classpath is distributed in the hope that it will be useful, but
014WITHOUT ANY WARRANTY; without even the implied warranty of
015MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
016General Public License for more details.
017
018You should have received a copy of the GNU General Public License
019along with GNU Classpath; see the file COPYING.  If not, write to the
020Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
02102110-1301 USA.
022
023Linking this library statically or dynamically with other modules is
024making a combined work based on this library.  Thus, the terms and
025conditions of the GNU General Public License cover the whole
026combination.
027
028As a special exception, the copyright holders of this library give you
029permission to link this library with independent modules to produce an
030executable, regardless of the license terms of these independent
031modules, and to copy and distribute the resulting executable under
032terms of your choice, provided that you also meet, for each linked
033independent module, the terms and conditions of the license of that
034module.  An independent module is a module which is not derived from
035or based on this library.  If you modify this library, you may extend
036this exception to your version of the library, but you are not
037obligated to do so.  If you do not wish to do so, delete this
038exception statement from your version. */
039
040
041package java.util.logging;
042
043/**
044 * An <code>ErrorManager</code> deals with errors that a <code>Handler</code>
045 * encounters while logging.
046 *
047 * @see Handler#setErrorManager(ErrorManager)
048 *
049 * @author Sascha Brawer (brawer@acm.org)
050 */
051public class ErrorManager
052{
053  /* The values have been taken from Sun's public J2SE 1.4 API
054   * documentation.
055   * See http://java.sun.com/j2se/1.4/docs/api/constant-values.html
056   */
057
058  /**
059   * Indicates that there was a failure that does not readily
060   * fall into any of the other categories.
061   */
062  public static final int GENERIC_FAILURE = 0;
063
064
065  /**
066   * Indicates that there was a problem upon writing to
067   * an output stream.
068   */
069  public static final int WRITE_FAILURE = 1;
070
071
072  /**
073   * Indicates that there was a problem upon flushing
074   * an output stream.
075   */
076  public static final int FLUSH_FAILURE = 2;
077
078
079  /**
080   * Indicates that there was a problem upon closing
081   * an output stream.
082   */
083  public static final int CLOSE_FAILURE = 3;
084
085
086  /**
087   * Indicates that there was a problem upon opening
088   * an output stream.
089   */
090  public static final int OPEN_FAILURE = 4;
091
092
093  /**
094   * Indicates that there was a problem upon formatting
095   * the message of a log record.
096   */
097  public static final int FORMAT_FAILURE = 5;
098
099
100  /**
101   * Indicates whether the {@link #error} method of this ErrorManager
102   * has ever been used.
103   *
104   * Declared volatile in order to correctly support the
105   * double-checked locking idiom (once the revised Java Memory Model
106   * gets adopted); see Classpath bug #2944.
107   */
108  private volatile boolean everUsed = false;
109
110
111  public ErrorManager()
112  {
113  }
114
115
116  /**
117   * Reports an error that occured upon logging.  The default implementation
118   * emits the very first error to System.err, ignoring subsequent errors.
119   *
120   * @param message a message describing the error, or <code>null</code> if
121   *                there is no suitable description.
122   *
123   * @param ex      an exception, or <code>null</code> if the error is not
124   *                related to an exception.
125   *
126   * @param errorCode  one of the defined error codes, for example
127   *                   <code>ErrorManager.CLOSE_FAILURE</code>.
128   */
129  public void error(String message, Exception ex, int errorCode)
130  {
131    if (everUsed)
132      return;
133
134    synchronized (this)
135    {
136      /* The double check is intentional. If the first check was
137       * omitted, the monitor would have to be entered every time
138       * error() method was called. If the second check was
139       * omitted, the code below could be executed by multiple
140       * threads simultaneously.
141       *
142       * This is the 'double-checked locking' idiom, which is broken
143       * with the current version of the Java memory model.  However,
144       * we assume that JVMs will have adopted a revised version of
145       * the Java Memory Model by the time GNU Classpath gains
146       * widespread acceptance. See Classpath bug #2944.
147       */
148      if (everUsed)
149        return;
150
151      everUsed = true;
152    }
153
154    String codeMsg;
155    switch (errorCode)
156    {
157    case GENERIC_FAILURE:
158      codeMsg = "GENERIC_FAILURE";
159      break;
160
161    case WRITE_FAILURE:
162      codeMsg = "WRITE_FAILURE";
163      break;
164
165    case FLUSH_FAILURE:
166      codeMsg = "FLUSH_FAILURE";
167      break;
168
169    case CLOSE_FAILURE:
170      codeMsg = "CLOSE_FAILURE";
171      break;
172
173    case OPEN_FAILURE:
174      codeMsg = "OPEN_FAILURE";
175      break;
176
177    case FORMAT_FAILURE:
178      codeMsg = "FORMAT_FAILURE";
179      break;
180
181    default:
182      codeMsg = String.valueOf(errorCode);
183      break;
184    }
185
186    System.err.println("Error upon logging: " + codeMsg);
187    if ((message != null) && (message.length() > 0))
188      System.err.println(message);
189
190    if (ex != null)
191      ex.printStackTrace();
192  }
193}