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    
006    This file is part of GNU Classpath.
007    
008    GNU Classpath is free software; you can redistribute it and/or modify
009    it under the terms of the GNU General Public License as published by
010    the Free Software Foundation; either version 2, or (at your option)
011    any later version.
012    
013    GNU Classpath is distributed in the hope that it will be useful, but
014    WITHOUT ANY WARRANTY; without even the implied warranty of
015    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
016    General Public License for more details.
017    
018    You should have received a copy of the GNU General Public License
019    along with GNU Classpath; see the file COPYING.  If not, write to the
020    Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
021    02110-1301 USA.
022    
023    Linking this library statically or dynamically with other modules is
024    making a combined work based on this library.  Thus, the terms and
025    conditions of the GNU General Public License cover the whole
026    combination.
027    
028    As a special exception, the copyright holders of this library give you
029    permission to link this library with independent modules to produce an
030    executable, regardless of the license terms of these independent
031    modules, and to copy and distribute the resulting executable under
032    terms of your choice, provided that you also meet, for each linked
033    independent module, the terms and conditions of the license of that
034    module.  An independent module is a module which is not derived from
035    or based on this library.  If you modify this library, you may extend
036    this exception to your version of the library, but you are not
037    obligated to do so.  If you do not wish to do so, delete this
038    exception statement from your version. */
039    
040    
041    package 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     */
051    public 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    }
194