1. /*
  2. * Copyright 2003 Sun Microsystems, Inc. All rights reserved.
  3. * SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
  4. */
  5. /*
  6. * @(#)TransformerException.java 1.12 03/01/23
  7. */
  8. package javax.xml.transform;
  9. import java.lang.reflect.Method;
  10. import java.lang.IllegalAccessException;
  11. import java.lang.reflect.InvocationTargetException;
  12. import javax.xml.transform.SourceLocator;
  13. /**
  14. * This class specifies an exceptional condition that occured
  15. * during the transformation process.
  16. */
  17. public class TransformerException extends Exception {
  18. /** Field locator specifies where the error occured */
  19. SourceLocator locator;
  20. /**
  21. * Method getLocator retrieves an instance of a SourceLocator
  22. * object that specifies where an error occured.
  23. *
  24. * @return A SourceLocator object, or null if none was specified.
  25. */
  26. public SourceLocator getLocator() {
  27. return locator;
  28. }
  29. /**
  30. * Method setLocator sets an instance of a SourceLocator
  31. * object that specifies where an error occured.
  32. *
  33. * @param location A SourceLocator object, or null to clear the location.
  34. */
  35. public void setLocator(SourceLocator location) {
  36. locator = location;
  37. }
  38. /** Field containedException specifies a wrapped exception. May be null. */
  39. Throwable containedException;
  40. /**
  41. * This method retrieves an exception that this exception wraps.
  42. *
  43. * @return An Throwable object, or null.
  44. * @see #getCause
  45. */
  46. public Throwable getException() {
  47. return containedException;
  48. }
  49. /**
  50. * Returns the cause of this throwable or <code>null</code> if the
  51. * cause is nonexistent or unknown. (The cause is the throwable that
  52. * caused this throwable to get thrown.)
  53. */
  54. public Throwable getCause() {
  55. return ((containedException == this)
  56. ? null
  57. : containedException);
  58. }
  59. /**
  60. * Initializes the <i>cause</i> of this throwable to the specified value.
  61. * (The cause is the throwable that caused this throwable to get thrown.)
  62. *
  63. * <p>This method can be called at most once. It is generally called from
  64. * within the constructor, or immediately after creating the
  65. * throwable. If this throwable was created
  66. * with {@link #TransformerException(Throwable)} or
  67. * {@link #TransformerException(String,Throwable)}, this method cannot be called
  68. * even once.
  69. *
  70. * @param cause the cause (which is saved for later retrieval by the
  71. * {@link #getCause()} method). (A <tt>null</tt> value is
  72. * permitted, and indicates that the cause is nonexistent or
  73. * unknown.)
  74. * @return a reference to this <code>Throwable</code> instance.
  75. * @throws IllegalArgumentException if <code>cause</code> is this
  76. * throwable. (A throwable cannot
  77. * be its own cause.)
  78. * @throws IllegalStateException if this throwable was
  79. * created with {@link #TransformerException(Throwable)} or
  80. * {@link #TransformerException(String,Throwable)}, or this method has already
  81. * been called on this throwable.
  82. */
  83. public synchronized Throwable initCause(Throwable cause) {
  84. if (this.containedException != null) {
  85. throw new IllegalStateException("Can't overwrite cause");
  86. }
  87. if (cause == this) {
  88. throw new IllegalArgumentException(
  89. "Self-causation not permitted");
  90. }
  91. this.containedException = cause;
  92. return this;
  93. }
  94. /**
  95. * Create a new TransformerException.
  96. *
  97. * @param message The error or warning message.
  98. */
  99. public TransformerException(String message) {
  100. super(message);
  101. this.containedException = null;
  102. this.locator = null;
  103. }
  104. /**
  105. * Create a new TransformerException wrapping an existing exception.
  106. *
  107. * @param e The exception to be wrapped.
  108. */
  109. public TransformerException(Throwable e) {
  110. super(e.toString());
  111. this.containedException = e;
  112. this.locator = null;
  113. }
  114. /**
  115. * Wrap an existing exception in a TransformerException.
  116. *
  117. * <p>This is used for throwing processor exceptions before
  118. * the processing has started.</p>
  119. *
  120. * @param message The error or warning message, or null to
  121. * use the message from the embedded exception.
  122. * @param e Any exception
  123. */
  124. public TransformerException(String message, Throwable e) {
  125. super(((message == null) || (message.length() == 0))
  126. ? e.toString()
  127. : message);
  128. this.containedException = e;
  129. this.locator = null;
  130. }
  131. /**
  132. * Create a new TransformerException from a message and a Locator.
  133. *
  134. * <p>This constructor is especially useful when an application is
  135. * creating its own exception from within a DocumentHandler
  136. * callback.</p>
  137. *
  138. * @param message The error or warning message.
  139. * @param locator The locator object for the error or warning.
  140. */
  141. public TransformerException(String message, SourceLocator locator) {
  142. super(message);
  143. this.containedException = null;
  144. this.locator = locator;
  145. }
  146. /**
  147. * Wrap an existing exception in a TransformerException.
  148. *
  149. * @param message The error or warning message, or null to
  150. * use the message from the embedded exception.
  151. * @param locator The locator object for the error or warning.
  152. * @param e Any exception
  153. */
  154. public TransformerException(String message, SourceLocator locator,
  155. Throwable e) {
  156. super(message);
  157. this.containedException = e;
  158. this.locator = locator;
  159. }
  160. /**
  161. * Get the error message with location information
  162. * appended.
  163. *
  164. * @return A <code>String</code> representing the error message with
  165. * location information appended.
  166. */
  167. public String getMessageAndLocation() {
  168. StringBuffer sbuffer = new StringBuffer();
  169. String message = super.getMessage();
  170. if (null != message) {
  171. sbuffer.append(message);
  172. }
  173. if (null != locator) {
  174. String systemID = locator.getSystemId();
  175. int line = locator.getLineNumber();
  176. int column = locator.getColumnNumber();
  177. if (null != systemID) {
  178. sbuffer.append("; SystemID: ");
  179. sbuffer.append(systemID);
  180. }
  181. if (0 != line) {
  182. sbuffer.append("; Line#: ");
  183. sbuffer.append(line);
  184. }
  185. if (0 != column) {
  186. sbuffer.append("; Column#: ");
  187. sbuffer.append(column);
  188. }
  189. }
  190. return sbuffer.toString();
  191. }
  192. /**
  193. * Get the location information as a string.
  194. *
  195. * @return A string with location info, or null
  196. * if there is no location information.
  197. */
  198. public String getLocationAsString() {
  199. if (null != locator) {
  200. StringBuffer sbuffer = new StringBuffer();
  201. String systemID = locator.getSystemId();
  202. int line = locator.getLineNumber();
  203. int column = locator.getColumnNumber();
  204. if (null != systemID) {
  205. sbuffer.append("; SystemID: ");
  206. sbuffer.append(systemID);
  207. }
  208. if (0 != line) {
  209. sbuffer.append("; Line#: ");
  210. sbuffer.append(line);
  211. }
  212. if (0 != column) {
  213. sbuffer.append("; Column#: ");
  214. sbuffer.append(column);
  215. }
  216. return sbuffer.toString();
  217. } else {
  218. return null;
  219. }
  220. }
  221. /**
  222. * Print the the trace of methods from where the error
  223. * originated. This will trace all nested exception
  224. * objects, as well as this object.
  225. */
  226. public void printStackTrace() {
  227. printStackTrace(new java.io.PrintWriter(System.err, true));
  228. }
  229. /**
  230. * Print the the trace of methods from where the error
  231. * originated. This will trace all nested exception
  232. * objects, as well as this object.
  233. * @param s The stream where the dump will be sent to.
  234. */
  235. public void printStackTrace(java.io.PrintStream s) {
  236. printStackTrace(new java.io.PrintWriter(s));
  237. }
  238. /**
  239. * Print the the trace of methods from where the error
  240. * originated. This will trace all nested exception
  241. * objects, as well as this object.
  242. * @param s The writer where the dump will be sent to.
  243. */
  244. public void printStackTrace(java.io.PrintWriter s) {
  245. if (s == null) {
  246. s = new java.io.PrintWriter(System.err, true);
  247. }
  248. try {
  249. String locInfo = getLocationAsString();
  250. if (null != locInfo) {
  251. s.println(locInfo);
  252. }
  253. super.printStackTrace(s);
  254. } catch (Throwable e) {}
  255. Throwable exception = getException();
  256. for (int i = 0; (i < 10) && (null != exception); i++) {
  257. s.println("---------");
  258. try {
  259. if (exception instanceof TransformerException) {
  260. String locInfo =
  261. ((TransformerException) exception)
  262. .getLocationAsString();
  263. if (null != locInfo) {
  264. s.println(locInfo);
  265. }
  266. }
  267. exception.printStackTrace(s);
  268. } catch (Throwable e) {
  269. s.println("Could not print stack trace...");
  270. }
  271. try {
  272. Method meth =
  273. ((Object) exception).getClass().getMethod("getException",
  274. null);
  275. if (null != meth) {
  276. Throwable prev = exception;
  277. exception = (Throwable) meth.invoke(exception, null);
  278. if (prev == exception) {
  279. break;
  280. }
  281. } else {
  282. exception = null;
  283. }
  284. } catch (InvocationTargetException ite) {
  285. exception = null;
  286. } catch (IllegalAccessException iae) {
  287. exception = null;
  288. } catch (NoSuchMethodException nsme) {
  289. exception = null;
  290. }
  291. }
  292. s.flush();
  293. }
  294. }