1 /*
   2  * Copyright (c) 2000, 2019, Oracle and/or its affiliates. All rights reserved.
   3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   4  *
   5  * This code is free software; you can redistribute it and/or modify it
   6  * under the terms of the GNU General Public License version 2 only, as
   7  * published by the Free Software Foundation.  Oracle designates this
   8  * particular file as subject to the "Classpath" exception as provided
   9  * by Oracle in the LICENSE file that accompanied this code.
  10  *
  11  * This code is distributed in the hope that it will be useful, but WITHOUT
  12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  14  * version 2 for more details (a copy is included in the LICENSE file that
  15  * accompanied this code).
  16  *
  17  * You should have received a copy of the GNU General Public License version
  18  * 2 along with this work; if not, write to the Free Software Foundation,
  19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  20  *
  21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  22  * or visit www.oracle.com if you need additional information or have any
  23  * questions.
  24  */
  25 
  26 package org.xml.sax;
  27 
  28 import java.io.IOException;
  29 import java.io.InvalidClassException;
  30 import java.io.ObjectInputStream;
  31 import java.io.ObjectOutputStream;
  32 import java.io.ObjectStreamField;
  33 
  34 /**
  35  * Encapsulate a general SAX error or warning.
  36  *
  37  * <p>This class can contain basic error or warning information from
  38  * either the XML parser or the application: a parser writer or
  39  * application writer can subclass it to provide additional
  40  * functionality.  SAX handlers may throw this exception or
  41  * any exception subclassed from it.</p>
  42  *
  43  * <p>If the application needs to pass through other types of
  44  * exceptions, it must wrap those exceptions in a SAXException
  45  * or an exception derived from a SAXException.</p>
  46  *
  47  * <p>If the parser or application needs to include information about a
  48  * specific location in an XML document, it should use the
  49  * {@link org.xml.sax.SAXParseException SAXParseException} subclass.</p>
  50  *
  51  * @since 1.4, SAX 1.0
  52  * @author David Megginson
  53  * @version 2.0.1 (sax2r2)
  54  * @see org.xml.sax.SAXParseException
  55  */
  56 public class SAXException extends Exception {
  57 
  58 
  59     /**
  60      * Create a new SAXException.
  61      */
  62     public SAXException ()
  63     {
  64         super();
  65     }
  66 
  67 
  68     /**
  69      * Create a new SAXException.
  70      *
  71      * @param message The error or warning message.
  72      */
  73     public SAXException (String message) {
  74         super(message);
  75     }
  76 
  77 
  78     /**
  79      * Create a new SAXException wrapping an existing exception.
  80      *
  81      * <p>The existing exception will be embedded in the new
  82      * one, and its message will become the default message for
  83      * the SAXException.</p>
  84      *
  85      * @param e The exception to be wrapped in a SAXException.
  86      */
  87     public SAXException (Exception e)
  88     {
  89         super(e);
  90     }
  91 
  92 
  93     /**
  94      * Create a new SAXException from an existing exception.
  95      *
  96      * <p>The existing exception will be embedded in the new
  97      * one, but the new exception will have its own message.</p>
  98      *
  99      * @param message The detail message.
 100      * @param e The exception to be wrapped in a SAXException.
 101      */
 102     public SAXException (String message, Exception e)
 103     {
 104         super(message, e);
 105     }
 106 
 107 
 108     /**
 109      * Return a detail message for this exception.
 110      *
 111      * <p>If there is an embedded exception, and if the SAXException
 112      * has no detail message of its own, this method will return
 113      * the detail message from the embedded exception.</p>
 114      *
 115      * @return The error or warning message.
 116      */
 117     public String getMessage ()
 118     {
 119         String message = super.getMessage();
 120         Throwable cause = super.getCause();
 121 
 122         if (message == null && cause != null) {
 123             return cause.getMessage();
 124         } else {
 125             return message;
 126         }
 127     }
 128 
 129     /**
 130      * Return the embedded exception, if any.
 131      *
 132      * @return The embedded exception, or null if there is none.
 133      */
 134     public Exception getException ()
 135     {
 136         return getExceptionInternal();
 137     }
 138 
 139     /**
 140      * Return the cause of the exception
 141      *
 142      * @return Return the cause of the exception
 143      */
 144     public Throwable getCause() {
 145         return super.getCause();
 146     }
 147 
 148     /**
 149      * Override toString to pick up any embedded exception.
 150      *
 151      * @return A string representation of this exception.
 152      */
 153     public String toString ()
 154     {
 155         Throwable exception = super.getCause();
 156         if (exception != null) {
 157             return super.toString() + "\n" + exception.toString();
 158         } else {
 159             return super.toString();
 160         }
 161     }
 162 
 163 
 164 
 165     //////////////////////////////////////////////////////////////////////
 166     // Internal state.
 167     //////////////////////////////////////////////////////////////////////
 168 
 169     private static final ObjectStreamField[] serialPersistentFields = {
 170         new ObjectStreamField( "exception", Exception.class )
 171     };
 172 
 173     /**
 174      * Writes "exception" field to the stream.
 175      *
 176      * @param out stream used for serialization.
 177      * @throws IOException thrown by <code>ObjectOutputStream</code>
 178      */
 179     private void writeObject(ObjectOutputStream out)
 180             throws IOException {
 181         ObjectOutputStream.PutField fields = out.putFields();
 182         fields.put("exception", getExceptionInternal());
 183         out.writeFields();
 184     }
 185 
 186     /**
 187      * Reads the "exception" field from the stream.
 188      * And initializes the "exception" if it wasn't
 189      * done before.
 190      *
 191      * @param in stream used for deserialization
 192      * @throws IOException            thrown by <code>ObjectInputStream</code>
 193      * @throws ClassNotFoundException thrown by <code>ObjectInputStream</code>
 194      */
 195     private void readObject(ObjectInputStream in)
 196             throws IOException, ClassNotFoundException {
 197         ObjectInputStream.GetField fields = in.readFields();
 198         Exception exception = (Exception) fields.get("exception", null);
 199         Throwable superCause = super.getCause();
 200 
 201         // if super.getCause() and 'exception' fields present then always use
 202         // getCause() value. Otherwise, use 'exception' to initialize cause
 203         if (superCause == null && exception != null) {
 204             try {
 205                 super.initCause(exception);
 206             } catch (IllegalStateException e) {
 207                 throw new InvalidClassException("Inconsistent state: two causes");
 208             }
 209         }
 210     }
 211 
 212     // Internal method to guard against overriding of public getException
 213     // method by SAXException subclasses
 214     private Exception getExceptionInternal() {
 215         Throwable cause = super.getCause();
 216         if (cause instanceof Exception) {
 217             return (Exception) cause;
 218         } else {
 219             return null;
 220         }
 221     }
 222 
 223     // Added serialVersionUID to preserve binary compatibility
 224     static final long serialVersionUID = 583241635256073760L;
 225 }
 226 
 227 // end of SAXException.java