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