1 /* Copyright 2002-2004 Elliotte Rusty Harold 2 3 This library is free software; you can redistribute it and/or modify 4 it under the terms of version 2.1 of the GNU Lesser General Public 5 License as published by the Free Software Foundation. 6 7 This library is distributed in the hope that it will be useful, 8 but WITHOUT ANY WARRANTY; without even the implied warranty of 9 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 10 GNU Lesser General Public License for more details. 11 12 You should have received a copy of the GNU Lesser General Public 13 License along with this library; if not, write to the 14 Free Software Foundation, Inc., 59 Temple Place, Suite 330, 15 Boston, MA 02111-1307 USA 16 17 You can contact Elliotte Rusty Harold by sending e-mail to 18 elharo@ibiblio.org. Please include the word "XOM" in the 19 subject line. The XOM home page is located at http://www.xom.nu/ 20 */ 21 22 package nu.xom; 23 24 /** 25 * <p> 26 * The generic superclass for all the 27 * checked exceptions thrown in XOM. The general 28 * principle followed is that anything that could 29 * plausibly be detected by testing such as 30 * using spaces in an element name is a runtime exception. 31 * Exceptions that depend on environmental conditions, 32 * such as might occur when parsing an external file, 33 * are checked exceptions, because these depend on variable input, 34 * and thus problems may not all be detected during testing. 35 * </p> 36 * 37 * @author Elliotte Rusty Harold 38 * @version 1.1b3 39 * 40 */ 41 public class ParsingException extends Exception { 42 43 44 private static final long serialVersionUID = -5185450480590174490L; 45 46 private Throwable cause; 47 private int lineNumber = -1; 48 private int columnNumber = -1; 49 private String uri; 50 51 52 /** 53 * <p> 54 * Creates a new <code>ParsingException</code> with a detail message 55 * and an underlying root cause. 56 * </p> 57 * 58 * @param message a string indicating the specific problem 59 * @param cause the original cause of this exception 60 */ ParsingException(String message, Throwable cause)61 public ParsingException(String message, Throwable cause) { 62 super(message); 63 this.initCause(cause); 64 } 65 66 67 /** 68 * <p> 69 * Creates a new <code>ParsingException</code> with a detail message 70 * and an underlying root cause. 71 * </p> 72 * 73 * @param message a string indicating the specific problem 74 * @param uri the URI of the document that caused this exception 75 * @param cause the original cause of this exception 76 */ ParsingException(String message, String uri, Throwable cause)77 public ParsingException(String message, String uri, Throwable cause) { 78 super(message); 79 this.uri = uri; 80 this.initCause(cause); 81 } 82 83 84 /** 85 * <p> 86 * Creates a new <code>ParsingException</code> with a detail message 87 * and line and column numbers. 88 * </p> 89 * 90 * @param message a string indicating the specific problem 91 * @param lineNumber the approximate line number 92 * where the problem occurs 93 * @param columnNumber the approximate column number 94 * where the problem occurs 95 */ ParsingException(String message, int lineNumber, int columnNumber)96 public ParsingException(String message, 97 int lineNumber, int columnNumber) { 98 this(message, null, lineNumber, columnNumber, null); 99 } 100 101 102 /** 103 * <p> 104 * Creates a new <code>ParsingException</code> with a detail message 105 * and line and column numbers. 106 * </p> 107 * 108 * @param message a string indicating the specific problem 109 * @param uri the URI of the document that caused this exception 110 * @param lineNumber the approximate line number 111 * where the problem occurs 112 * @param columnNumber the approximate column number 113 * where the problem occurs 114 */ ParsingException(String message, String uri, int lineNumber, int columnNumber)115 public ParsingException(String message, String uri, 116 int lineNumber, int columnNumber) { 117 this(message, uri, lineNumber, columnNumber, null); 118 } 119 120 121 /** 122 * <p> 123 * Creates a new <code>ParsingException</code> with a detail 124 * message, line and column numbers, and an underlying exception. 125 * </p> 126 * 127 * @param message a string indicating the specific problem 128 * @param uri the URI of the document that caused this exception 129 * @param lineNumber the approximate line number 130 * where the problem occurs 131 * @param columnNumber the approximate column number 132 * where the problem occurs 133 * @param cause the original cause of this exception 134 */ ParsingException(String message, String uri, int lineNumber, int columnNumber, Throwable cause)135 public ParsingException(String message, String uri, int lineNumber, 136 int columnNumber, Throwable cause) { 137 super(message); 138 this.lineNumber = lineNumber; 139 this.columnNumber = columnNumber; 140 this.uri = uri; 141 this.initCause(cause); 142 } 143 144 145 /** 146 * <p> 147 * Creates a new <code>ParsingException</code> with a detail 148 * message, line and column numbers, and an underlying exception. 149 * </p> 150 * 151 * @param message a string indicating the specific problem 152 * @param lineNumber the approximate line number 153 * where the problem occurs 154 * @param columnNumber the approximate column number 155 * where the problem occurs 156 * @param cause the original cause of this exception 157 */ ParsingException(String message, int lineNumber, int columnNumber, Throwable cause)158 public ParsingException(String message, int lineNumber, 159 int columnNumber, Throwable cause) { 160 super(message); 161 this.lineNumber = lineNumber; 162 this.columnNumber = columnNumber; 163 this.initCause(cause); 164 } 165 166 167 /** 168 * <p> 169 * Creates a new <code>ParsingException</code> with a detail message. 170 * </p> 171 * 172 * @param message a string indicating the specific problem 173 */ ParsingException(String message)174 public ParsingException(String message) { 175 super(message); 176 } 177 178 179 /** 180 * <p> 181 * Returns the approximate row number of the construct that 182 * caused this exception. If the row number is not known, 183 * -1 is returned. 184 * </p> 185 * 186 * @return row number where the exception occurred 187 */ getLineNumber()188 public int getLineNumber() { 189 return this.lineNumber; 190 } 191 192 /** 193 * <p> 194 * Returns the approximate column number of the construct that 195 * caused this exception. If the column number is not known, 196 * -1 is returned. 197 * </p> 198 * 199 * @return column number where the exception occurred 200 */ getColumnNumber()201 public int getColumnNumber() { 202 return this.columnNumber; 203 } 204 205 206 /** 207 * <p> 208 * Returns the system ID (generally a URL) of the document that 209 * caused this exception. If this is not known, for instance 210 * because the document was parsed from a raw input stream or from 211 * a string, it returns null. 212 * </p> 213 * 214 * @return the URI of the document that caused this exception 215 */ getURI()216 public String getURI() { 217 return this.uri; 218 } 219 220 221 // null is insufficient for determining unset cause. 222 // The cause may be set to null which may not then be reset. 223 private boolean causeSet = false; 224 225 /** 226 * <p> 227 * Sets the root cause of this exception. This may 228 * only be called once. Subsequent calls throw an 229 * <code>IllegalStateException</code>. 230 * </p> 231 * 232 * <p> 233 * This method is unnecessary in Java 1.4 where it could easily be 234 * inherited from the superclass. However, including it here 235 * allows this method to be used in Java 1.3 and earlier. 236 * </p> 237 * 238 * @param cause the root cause of this exception 239 * 240 * @return this <code>XMLException</code> 241 * 242 * @throws IllegalArgumentException if the cause is this exception 243 * (An exception cannot be its own cause.) 244 * @throws IllegalStateException if this method is called twice 245 */ initCause(Throwable cause)246 public final Throwable initCause(Throwable cause) { 247 248 if (causeSet) { 249 throw new IllegalStateException("Can't overwrite cause"); 250 } 251 else if (cause == this) { 252 throw new IllegalArgumentException("Self-causation not permitted"); 253 } 254 else this.cause = cause; 255 causeSet = true; 256 return this; 257 258 } 259 260 261 /** 262 * <p> 263 * Returns the underlying exception that caused this exception. 264 * </p> 265 * 266 * @return the root exception that caused this exception 267 * to be thrown 268 */ getCause()269 public Throwable getCause() { 270 return this.cause; 271 } 272 273 274 /** 275 * <p> 276 * Returns a string suitable for display to the developer 277 * summarizing what went wrong where. 278 * </p> 279 * 280 * @return an exception message suitable for display to a developer 281 */ toString()282 public String toString() { 283 StringBuffer result = new StringBuffer(super.toString()); 284 if (lineNumber >= 0) { 285 result.append(" at line "); 286 result.append(lineNumber); 287 result.append(", column "); 288 result.append(columnNumber); 289 } 290 291 if (this.uri != null) { 292 result.append(" in "); 293 result.append(uri); 294 } 295 return result.toString(); 296 } 297 298 299 }