1 /* 2 * Copyright (c) 2003, 2020, 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 javax.xml.xpath; 27 28 import java.io.PrintWriter; 29 import java.io.IOException; 30 import java.io.ObjectInputStream; 31 import java.io.ObjectOutputStream; 32 import java.io.ObjectStreamField; 33 import java.io.InvalidClassException; 34 35 /** 36 * {@code XPathException} represents a generic XPath exception. 37 * 38 * @author Norman Walsh 39 * @author Jeff Suttor 40 * @since 1.5 41 */ 42 public class XPathException extends Exception { 43 /** 44 * serializable fields 45 */ 46 private static final ObjectStreamField[] serialPersistentFields = { 47 new ObjectStreamField( "cause", Throwable.class ) 48 }; 49 50 /** 51 * Stream Unique Identifier. 52 */ 53 private static final long serialVersionUID = -1837080260374986980L; 54 55 /** 56 * Constructs a new {@code XPathException} 57 * with the specified detail {@code message}. 58 * 59 * <p>The {@code cause} is not initialized. 60 * 61 * <p>If {@code message} is {@code null}, 62 * then a {@code NullPointerException} is thrown. 63 * 64 * @param message The detail message. 65 * 66 * @throws NullPointerException When {@code message} is 67 * {@code null}. 68 */ 69 public XPathException(String message) { 70 super(message); 71 if ( message == null ) { 72 throw new NullPointerException ( "message can't be null"); 73 } 74 } 75 76 /** 77 * Constructs a new {@code XPathException} 78 * with the specified {@code cause}. 79 * 80 * <p>If {@code cause} is {@code null}, 81 * then a {@code NullPointerException} is thrown. 82 * 83 * @param cause The cause. 84 * 85 * @throws NullPointerException if {@code cause} is {@code null}. 86 */ 87 public XPathException(Throwable cause) { 88 super(cause); 89 if ( cause == null ) { 90 throw new NullPointerException ( "cause can't be null"); 91 } 92 } 93 94 /** 95 * Get the cause of this XPathException. 96 * 97 * @return Cause of this XPathException. 98 */ 99 public Throwable getCause() { 100 return super.getCause(); 101 } 102 103 /** 104 * Writes "cause" field to the stream. 105 * The cause is got from the parent class. 106 * 107 * @param out stream used for serialization. 108 * @throws IOException thrown by {@code ObjectOutputStream} 109 * 110 */ 111 private void writeObject(ObjectOutputStream out) 112 throws IOException 113 { 114 ObjectOutputStream.PutField fields = out.putFields(); 115 fields.put("cause", super.getCause()); 116 out.writeFields(); 117 } 118 119 /** 120 * Reads the "cause" field from the stream. 121 * And initializes the "cause" if it wasn't 122 * done before. 123 * 124 * @param in stream used for deserialization 125 * @throws IOException thrown by {@code ObjectInputStream} 126 * @throws ClassNotFoundException thrown by {@code ObjectInputStream} 127 */ 128 private void readObject(ObjectInputStream in) 129 throws IOException, ClassNotFoundException 130 { 131 ObjectInputStream.GetField fields = in.readFields(); 132 Throwable scause = (Throwable) fields.get("cause", null); 133 134 if (super.getCause() == null && scause != null) { 135 try { 136 super.initCause(scause); 137 } catch(IllegalStateException e) { 138 throw new InvalidClassException("Inconsistent state: two causes"); 139 } 140 } 141 } 142 143 /** 144 * Print stack trace to specified {@code PrintStream}. 145 * 146 * @param s Print stack trace to this {@code PrintStream}. 147 */ 148 public void printStackTrace(java.io.PrintStream s) { 149 if (getCause() != null) { 150 getCause().printStackTrace(s); 151 s.println("--------------- linked to ------------------"); 152 } 153 154 super.printStackTrace(s); 155 } 156 157 /** 158 * Print stack trace to {@code System.err}. 159 */ 160 public void printStackTrace() { 161 printStackTrace(System.err); 162 } 163 164 /** 165 * Print stack trace to specified {@code PrintWriter}. 166 * 167 * @param s Print stack trace to this {@code PrintWriter}. 168 */ 169 public void printStackTrace(PrintWriter s) { 170 171 if (getCause() != null) { 172 getCause().printStackTrace(s); 173 s.println("--------------- linked to ------------------"); 174 } 175 176 super.printStackTrace(s); 177 } 178 }