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: XPathException.java,v 1.12 2004/02/17 04:30:02 minchau Exp $
  18. */
  19. package com.sun.org.apache.xpath.internal;
  20. import javax.xml.transform.TransformerException;
  21. import org.w3c.dom.Node;
  22. /**
  23. * This class implements an exception object that all
  24. * XPath classes will throw in case of an error. This class
  25. * extends TransformerException, and may hold other exceptions. In the
  26. * case of nested exceptions, printStackTrace will dump
  27. * all the traces of the nested exceptions, not just the trace
  28. * of this object.
  29. * @xsl.usage general
  30. */
  31. public class XPathException extends TransformerException
  32. {
  33. /** The home of the expression that caused the error.
  34. * @serial */
  35. Object m_styleNode = null;
  36. /**
  37. * Get the stylesheet node from where this error originated.
  38. * @return The stylesheet node from where this error originated, or null.
  39. */
  40. public Object getStylesheetNode()
  41. {
  42. return m_styleNode;
  43. }
  44. /**
  45. * Set the stylesheet node from where this error originated.
  46. * @param styleNode The stylesheet node from where this error originated, or null.
  47. */
  48. public void setStylesheetNode(Object styleNode)
  49. {
  50. m_styleNode = styleNode;
  51. }
  52. /** A nested exception.
  53. * @serial */
  54. protected Exception m_exception;
  55. /**
  56. * Create an XPathException object that holds
  57. * an error message.
  58. * @param message The error message.
  59. */
  60. public XPathException(String message, ExpressionNode ex)
  61. {
  62. super(message);
  63. this.setLocator(ex);
  64. setStylesheetNode(getStylesheetNode(ex));
  65. }
  66. /**
  67. * Create an XPathException object that holds
  68. * an error message.
  69. * @param message The error message.
  70. */
  71. public XPathException(String message)
  72. {
  73. super(message);
  74. }
  75. /**
  76. * Get the XSLT ElemVariable that this sub-expression references. In order for
  77. * this to work, the SourceLocator must be the owning ElemTemplateElement.
  78. * @return The dereference to the ElemVariable, or null if not found.
  79. */
  80. public org.w3c.dom.Node getStylesheetNode(ExpressionNode ex)
  81. {
  82. ExpressionNode owner = getExpressionOwner(ex);
  83. if (null != owner && owner instanceof org.w3c.dom.Node)
  84. {
  85. return ((org.w3c.dom.Node)owner);
  86. }
  87. return null;
  88. }
  89. /**
  90. * Get the first non-Expression parent of this node.
  91. * @return null or first ancestor that is not an Expression.
  92. */
  93. protected ExpressionNode getExpressionOwner(ExpressionNode ex)
  94. {
  95. ExpressionNode parent = ex.exprGetParent();
  96. while((null != parent) && (parent instanceof Expression))
  97. parent = parent.exprGetParent();
  98. return parent;
  99. }
  100. /**
  101. * Create an XPathException object that holds
  102. * an error message and the stylesheet node that
  103. * the error originated from.
  104. * @param message The error message.
  105. * @param styleNode The stylesheet node that the error originated from.
  106. */
  107. public XPathException(String message, Object styleNode)
  108. {
  109. super(message);
  110. m_styleNode = styleNode;
  111. }
  112. /**
  113. * Create an XPathException object that holds
  114. * an error message, the stylesheet node that
  115. * the error originated from, and another exception
  116. * that caused this exception.
  117. * @param message The error message.
  118. * @param styleNode The stylesheet node that the error originated from.
  119. * @param e The exception that caused this exception.
  120. */
  121. public XPathException(String message, Node styleNode, Exception e)
  122. {
  123. super(message);
  124. m_styleNode = styleNode;
  125. this.m_exception = e;
  126. }
  127. /**
  128. * Create an XPathException object that holds
  129. * an error message, and another exception
  130. * that caused this exception.
  131. * @param message The error message.
  132. * @param e The exception that caused this exception.
  133. */
  134. public XPathException(String message, Exception e)
  135. {
  136. super(message);
  137. this.m_exception = e;
  138. }
  139. /**
  140. * Print the the trace of methods from where the error
  141. * originated. This will trace all nested exception
  142. * objects, as well as this object.
  143. * @param s The stream where the dump will be sent to.
  144. */
  145. public void printStackTrace(java.io.PrintStream s)
  146. {
  147. if (s == null)
  148. s = System.err;
  149. try
  150. {
  151. super.printStackTrace(s);
  152. }
  153. catch (Exception e){}
  154. Throwable exception = m_exception;
  155. for (int i = 0; (i < 10) && (null != exception); i++)
  156. {
  157. s.println("---------");
  158. exception.printStackTrace(s);
  159. if (exception instanceof TransformerException)
  160. {
  161. TransformerException se = (TransformerException) exception;
  162. Throwable prev = exception;
  163. exception = se.getException();
  164. if (prev == exception)
  165. break;
  166. }
  167. else
  168. {
  169. exception = null;
  170. }
  171. }
  172. }
  173. /**
  174. * Find the most contained message.
  175. *
  176. * @return The error message of the originating exception.
  177. */
  178. public String getMessage()
  179. {
  180. String lastMessage = super.getMessage();
  181. Throwable exception = m_exception;
  182. while (null != exception)
  183. {
  184. String nextMessage = exception.getMessage();
  185. if (null != nextMessage)
  186. lastMessage = nextMessage;
  187. if (exception instanceof TransformerException)
  188. {
  189. TransformerException se = (TransformerException) exception;
  190. Throwable prev = exception;
  191. exception = se.getException();
  192. if (prev == exception)
  193. break;
  194. }
  195. else
  196. {
  197. exception = null;
  198. }
  199. }
  200. return (null != lastMessage) ? lastMessage : "";
  201. }
  202. /**
  203. * Print the the trace of methods from where the error
  204. * originated. This will trace all nested exception
  205. * objects, as well as this object.
  206. * @param s The writer where the dump will be sent to.
  207. */
  208. public void printStackTrace(java.io.PrintWriter s)
  209. {
  210. if (s == null)
  211. s = new java.io.PrintWriter(System.err);
  212. try
  213. {
  214. super.printStackTrace(s);
  215. }
  216. catch (Exception e){}
  217. Throwable exception = m_exception;
  218. for (int i = 0; (i < 10) && (null != exception); i++)
  219. {
  220. s.println("---------");
  221. try
  222. {
  223. exception.printStackTrace(s);
  224. }
  225. catch (Exception e)
  226. {
  227. s.println("Could not print stack trace...");
  228. }
  229. if (exception instanceof TransformerException)
  230. {
  231. TransformerException se = (TransformerException) exception;
  232. Throwable prev = exception;
  233. exception = se.getException();
  234. if (prev == exception)
  235. {
  236. exception = null;
  237. break;
  238. }
  239. }
  240. else
  241. {
  242. exception = null;
  243. }
  244. }
  245. }
  246. /**
  247. * Return the embedded exception, if any.
  248. * Overrides javax.xml.transform.TransformerException.getException().
  249. *
  250. * @return The embedded exception, or null if there is none.
  251. */
  252. public Throwable getException()
  253. {
  254. return m_exception;
  255. }
  256. }