1 /* 2 * Licensed to the Apache Software Foundation (ASF) under one or more 3 * contributor license agreements. See the NOTICE file distributed with 4 * this work for additional information regarding copyright ownership. 5 * The ASF licenses this file to You under the Apache License, Version 2.0 6 * (the "License"); you may not use this file except in compliance with 7 * the License. You may obtain a copy of the License at 8 * 9 * http://www.apache.org/licenses/LICENSE-2.0 10 * 11 * Unless required by applicable law or agreed to in writing, software 12 * distributed under the License is distributed on an "AS IS" BASIS, 13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 * See the License for the specific language governing permissions and 15 * limitations under the License. 16 */ 17 18 // $Id: TransformerException.java 569994 2007-08-27 04:28:57Z mrglavas $ 19 20 package javax.xml.transform; 21 22 import java.lang.reflect.Method; 23 import java.lang.reflect.InvocationTargetException; 24 25 /** 26 * This class specifies an exceptional condition that occurred 27 * during the transformation process. 28 */ 29 public class TransformerException extends Exception { 30 31 // Added serialVersionUID to preserve binary compatibility 32 private static final long serialVersionUID = 975798773772956428L; 33 34 /** Field locator specifies where the error occurred */ 35 SourceLocator locator; 36 37 /** 38 * Method getLocator retrieves an instance of a SourceLocator 39 * object that specifies where an error occurred. 40 * 41 * @return A SourceLocator object, or null if none was specified. 42 */ 43 public SourceLocator getLocator() { 44 return locator; 45 } 46 47 /** 48 * Method setLocator sets an instance of a SourceLocator 49 * object that specifies where an error occurred. 50 * 51 * @param location A SourceLocator object, or null to clear the location. 52 */ 53 public void setLocator(SourceLocator location) { 54 locator = location; 55 } 56 57 /** Field containedException specifies a wrapped exception. May be null. */ 58 Throwable containedException; 59 60 /** 61 * This method retrieves an exception that this exception wraps. 62 * 63 * @return An Throwable object, or null. 64 * @see #getCause 65 */ 66 public Throwable getException() { 67 return containedException; 68 } 69 70 /** 71 * Returns the cause of this throwable or <code>null</code> if the 72 * cause is nonexistent or unknown. (The cause is the throwable that 73 * caused this throwable to get thrown.) 74 */ 75 public Throwable getCause() { 76 77 return ((containedException == this) 78 ? null 79 : containedException); 80 } 81 82 /** 83 * Initializes the <i>cause</i> of this throwable to the specified value. 84 * (The cause is the throwable that caused this throwable to get thrown.) 85 * 86 * <p>This method can be called at most once. It is generally called from 87 * within the constructor, or immediately after creating the 88 * throwable. If this throwable was created 89 * with {@link #TransformerException(Throwable)} or 90 * {@link #TransformerException(String,Throwable)}, this method cannot be called 91 * even once. 92 * 93 * @param cause the cause (which is saved for later retrieval by the 94 * {@link #getCause()} method). (A <tt>null</tt> value is 95 * permitted, and indicates that the cause is nonexistent or 96 * unknown.) 97 * @return a reference to this <code>Throwable</code> instance. 98 * @throws IllegalArgumentException if <code>cause</code> is this 99 * throwable. (A throwable cannot 100 * be its own cause.) 101 * @throws IllegalStateException if this throwable was 102 * created with {@link #TransformerException(Throwable)} or 103 * {@link #TransformerException(String,Throwable)}, or this method has already 104 * been called on this throwable. 105 */ 106 public synchronized Throwable initCause(Throwable cause) { 107 108 if (this.containedException != null) { 109 throw new IllegalStateException("Can't overwrite cause"); 110 } 111 112 if (cause == this) { 113 throw new IllegalArgumentException( 114 "Self-causation not permitted"); 115 } 116 117 this.containedException = cause; 118 119 return this; 120 } 121 122 /** 123 * Create a new TransformerException. 124 * 125 * @param message The error or warning message. 126 */ 127 public TransformerException(String message) { 128 129 super(message); 130 131 this.containedException = null; 132 this.locator = null; 133 } 134 135 /** 136 * Create a new TransformerException wrapping an existing exception. 137 * 138 * @param e The exception to be wrapped. 139 */ 140 public TransformerException(Throwable e) { 141 142 super(e.toString()); 143 144 this.containedException = e; 145 this.locator = null; 146 } 147 148 /** 149 * Wrap an existing exception in a TransformerException. 150 * 151 * <p>This is used for throwing processor exceptions before 152 * the processing has started.</p> 153 * 154 * @param message The error or warning message, or null to 155 * use the message from the embedded exception. 156 * @param e Any exception 157 */ 158 public TransformerException(String message, Throwable e) { 159 160 super(((message == null) || (message.length() == 0)) 161 ? e.toString() 162 : message); 163 164 this.containedException = e; 165 this.locator = null; 166 } 167 168 /** 169 * Create a new TransformerException from a message and a Locator. 170 * 171 * <p>This constructor is especially useful when an application is 172 * creating its own exception from within a DocumentHandler 173 * callback.</p> 174 * 175 * @param message The error or warning message. 176 * @param locator The locator object for the error or warning. 177 */ 178 public TransformerException(String message, SourceLocator locator) { 179 180 super(message); 181 182 this.containedException = null; 183 this.locator = locator; 184 } 185 186 /** 187 * Wrap an existing exception in a TransformerException. 188 * 189 * @param message The error or warning message, or null to 190 * use the message from the embedded exception. 191 * @param locator The locator object for the error or warning. 192 * @param e Any exception 193 */ 194 public TransformerException(String message, SourceLocator locator, 195 Throwable e) { 196 197 super(message); 198 199 this.containedException = e; 200 this.locator = locator; 201 } 202 203 /** 204 * Get the error message with location information 205 * appended. 206 * 207 * @return A <code>String</code> representing the error message with 208 * location information appended. 209 */ 210 public String getMessageAndLocation() { 211 212 StringBuffer sbuffer = new StringBuffer(); 213 String message = super.getMessage(); 214 215 if (null != message) { 216 sbuffer.append(message); 217 } 218 219 if (null != locator) { 220 String systemID = locator.getSystemId(); 221 int line = locator.getLineNumber(); 222 int column = locator.getColumnNumber(); 223 224 if (null != systemID) { 225 sbuffer.append("; SystemID: "); 226 sbuffer.append(systemID); 227 } 228 229 if (0 != line) { 230 sbuffer.append("; Line#: "); 231 sbuffer.append(line); 232 } 233 234 if (0 != column) { 235 sbuffer.append("; Column#: "); 236 sbuffer.append(column); 237 } 238 } 239 240 return sbuffer.toString(); 241 } 242 243 /** 244 * Get the location information as a string. 245 * 246 * @return A string with location info, or null 247 * if there is no location information. 248 */ 249 public String getLocationAsString() { 250 251 if (null != locator) { 252 StringBuffer sbuffer = new StringBuffer(); 253 String systemID = locator.getSystemId(); 254 int line = locator.getLineNumber(); 255 int column = locator.getColumnNumber(); 256 257 if (null != systemID) { 258 sbuffer.append("; SystemID: "); 259 sbuffer.append(systemID); 260 } 261 262 if (0 != line) { 263 sbuffer.append("; Line#: "); 264 sbuffer.append(line); 265 } 266 267 if (0 != column) { 268 sbuffer.append("; Column#: "); 269 sbuffer.append(column); 270 } 271 272 return sbuffer.toString(); 273 } else { 274 return null; 275 } 276 } 277 278 /** 279 * Print the the trace of methods from where the error 280 * originated. This will trace all nested exception 281 * objects, as well as this object. 282 */ 283 public void printStackTrace() { 284 printStackTrace(new java.io.PrintWriter(System.err, true)); 285 } 286 287 /** 288 * Print the the trace of methods from where the error 289 * originated. This will trace all nested exception 290 * objects, as well as this object. 291 * @param s The stream where the dump will be sent to. 292 */ 293 public void printStackTrace(java.io.PrintStream s) { 294 printStackTrace(new java.io.PrintWriter(s)); 295 } 296 297 /** 298 * Print the the trace of methods from where the error 299 * originated. This will trace all nested exception 300 * objects, as well as this object. 301 * @param s The writer where the dump will be sent to. 302 */ 303 public void printStackTrace(java.io.PrintWriter s) { 304 305 if (s == null) { 306 s = new java.io.PrintWriter(System.err, true); 307 } 308 309 try { 310 String locInfo = getLocationAsString(); 311 312 if (null != locInfo) { 313 s.println(locInfo); 314 } 315 316 super.printStackTrace(s); 317 } catch (Throwable e) {} 318 319 boolean isJdk14OrHigher = false; 320 try { 321 Throwable.class.getMethod("getCause",(Class[]) null); 322 isJdk14OrHigher = true; 323 } catch (NoSuchMethodException nsme) { 324 // do nothing 325 } 326 327 // The printStackTrace method of the Throwable class in jdk 1.4 328 // and higher will include the cause when printing the backtrace. 329 // The following code is only required when using jdk 1.3 or lower 330 if (!isJdk14OrHigher) { 331 Throwable exception = getException(); 332 333 for (int i = 0; (i < 10) && (null != exception); i++) { 334 s.println("---------"); 335 336 try { 337 if (exception instanceof TransformerException) { 338 String locInfo = 339 ((TransformerException) exception) 340 .getLocationAsString(); 341 342 if (null != locInfo) { 343 s.println(locInfo); 344 } 345 } 346 347 exception.printStackTrace(s); 348 } catch (Throwable e) { 349 s.println("Could not print stack trace..."); 350 } 351 352 try { 353 Method meth = 354 ((Object) exception).getClass().getMethod("getException", 355 (Class[]) null); 356 357 if (null != meth) { 358 Throwable prev = exception; 359 360 exception = (Throwable) meth.invoke(exception, (Object[]) null); 361 362 if (prev == exception) { 363 break; 364 } 365 } else { 366 exception = null; 367 } 368 } catch (InvocationTargetException ite) { 369 exception = null; 370 } catch (IllegalAccessException iae) { 371 exception = null; 372 } catch (NoSuchMethodException nsme) { 373 exception = null; 374 } 375 } 376 } 377 // insure output is written 378 s.flush(); 379 } 380 }