1 /*
2 * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved.
3 */
4 /*
5 * Licensed to the Apache Software Foundation (ASF) under one or more
6 * contributor license agreements. See the NOTICE file distributed with
7 * this work for additional information regarding copyright ownership.
8 * The ASF licenses this file to You under the Apache License, Version 2.0
9 * (the "License"); you may not use this file except in compliance with
10 * the License. You may obtain a copy of the License at
11 *
12 * http://www.apache.org/licenses/LICENSE-2.0
13 *
14 * Unless required by applicable law or agreed to in writing, software
15 * distributed under the License is distributed on an "AS IS" BASIS,
16 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17 * See the License for the specific language governing permissions and
18 * limitations under the License.
19 */
20
21 package com.sun.org.apache.xpath.internal;
22
23 import javax.xml.transform.TransformerException;
24 import org.w3c.dom.Node;
25
26 /**
27 * This class implements an exception object that all
28 * XPath classes will throw in case of an error. This class
29 * extends TransformerException, and may hold other exceptions. In the
30 * case of nested exceptions, printStackTrace will dump
31 * all the traces of the nested exceptions, not just the trace
32 * of this object.
33 * @xsl.usage general
34 * @LastModified: Oct 2017
35 */
36 public class XPathException extends TransformerException
37 {
38 static final long serialVersionUID = 4263549717619045963L;
39
40 /** The home of the expression that caused the error.
41 * @serial */
42 Object m_styleNode = null;
43
44 /**
45 * Get the stylesheet node from where this error originated.
46 * @return The stylesheet node from where this error originated, or null.
47 */
48 public Object getStylesheetNode()
49 {
50 return m_styleNode;
51 }
52
53 /**
54 * Set the stylesheet node from where this error originated.
55 * @param styleNode The stylesheet node from where this error originated, or null.
56 */
57 public void setStylesheetNode(Object styleNode)
58 {
59 m_styleNode = styleNode;
60 }
61
62
63 /** A nested exception.
64 * @serial */
65 protected Exception m_exception;
66
67 /**
68 * Create an XPathException object that holds
69 * an error message.
70 * @param message The error message.
71 */
72 public XPathException(String message, ExpressionNode ex)
73 {
74 super(message);
75 this.setLocator(ex);
76 setStylesheetNode(getStylesheetNode(ex));
77 }
78
79 /**
80 * Create an XPathException object that holds
81 * an error message.
82 * @param message The error message.
83 */
84 public XPathException(String message)
85 {
86 super(message);
87 }
88
89
90 /**
91 * Get the XSLT ElemVariable that this sub-expression references. In order for
92 * this to work, the SourceLocator must be the owning ElemTemplateElement.
93 * @return The dereference to the ElemVariable, or null if not found.
94 */
95 public org.w3c.dom.Node getStylesheetNode(ExpressionNode ex)
96 {
97
98 ExpressionNode owner = getExpressionOwner(ex);
99
100 if (null != owner && owner instanceof org.w3c.dom.Node)
101 {
102 return ((org.w3c.dom.Node)owner);
103 }
104 return null;
105
106 }
107
108 /**
109 * Get the first non-Expression parent of this node.
110 * @return null or first ancestor that is not an Expression.
111 */
112 protected ExpressionNode getExpressionOwner(ExpressionNode ex)
113 {
114 ExpressionNode parent = ex.exprGetParent();
115 while((null != parent) && (parent instanceof Expression))
116 parent = parent.exprGetParent();
117 return parent;
118 }
119
120
121
122 /**
123 * Create an XPathException object that holds
124 * an error message and the stylesheet node that
125 * the error originated from.
126 * @param message The error message.
127 * @param styleNode The stylesheet node that the error originated from.
128 */
129 public XPathException(String message, Object styleNode)
130 {
131
132 super(message);
133
134 m_styleNode = styleNode;
135 }
136
137 /**
138 * Create an XPathException object that holds
139 * an error message, the stylesheet node that
140 * the error originated from, and another exception
141 * that caused this exception.
142 * @param message The error message.
143 * @param styleNode The stylesheet node that the error originated from.
144 * @param e The exception that caused this exception.
145 */
146 public XPathException(String message, Node styleNode, Exception e)
147 {
148
149 super(message);
150
151 m_styleNode = styleNode;
152 this.m_exception = e;
153 }
154
155 /**
156 * Create an XPathException object that holds
157 * an error message, and another exception
158 * that caused this exception.
159 * @param message The error message.
160 * @param e The exception that caused this exception.
161 */
162 public XPathException(String message, Exception e)
163 {
164
165 super(message);
166
167 this.m_exception = e;
168 }
169
170 /**
171 * Print the the trace of methods from where the error
172 * originated. This will trace all nested exception
173 * objects, as well as this object.
174 * @param s The stream where the dump will be sent to.
175 */
176 public void printStackTrace(java.io.PrintStream s)
177 {
178
179 if (s == null)
180 s = System.err;
181
182 try
183 {
184 super.printStackTrace(s);
185 }
186 catch (Exception e){}
187
188 Throwable exception = m_exception;
189
190 for (int i = 0; (i < 10) && (null != exception); i++)
191 {
192 s.println("---------");
193 exception.printStackTrace(s);
194
195 if (exception instanceof TransformerException)
196 {
197 TransformerException se = (TransformerException) exception;
198 Throwable prev = exception;
199
200 exception = se.getException();
201
202 if (prev == exception)
203 break;
204 }
205 else
206 {
207 exception = null;
208 }
209 }
210 }
211
212 /**
213 * Find the most contained message.
214 *
215 * @return The error message of the originating exception.
216 */
217 public String getMessage()
218 {
219
220 String lastMessage = super.getMessage();
221 Throwable exception = m_exception;
222
223 while (null != exception)
224 {
225 String nextMessage = exception.getMessage();
226
227 if (null != nextMessage)
228 lastMessage = nextMessage;
229
230 if (exception instanceof TransformerException)
231 {
232 TransformerException se = (TransformerException) exception;
233 Throwable prev = exception;
234
235 exception = se.getException();
236
237 if (prev == exception)
238 break;
239 }
240 else
241 {
242 exception = null;
243 }
244 }
245
246 return (null != lastMessage) ? lastMessage : "";
247 }
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 {
257
258 if (s == null)
259 s = new java.io.PrintWriter(System.err);
260
261 try
262 {
263 super.printStackTrace(s);
264 }
265 catch (Exception e){}
266
267
268 boolean isJdk14OrHigher = false;
269 try {
270 Throwable.class.getMethod("getCause", (Class<?>[]) null);
271 isJdk14OrHigher = true;
272 } catch (NoSuchMethodException nsme) {
273 // do nothing
274 }
275
276 // The printStackTrace method of the Throwable class in jdk 1.4
277 // and higher will include the cause when printing the backtrace.
278 // The following code is only required when using jdk 1.3 or lower
279 if (!isJdk14OrHigher) {
280
281 Throwable exception = m_exception;
282
283 for (int i = 0; (i < 10) && (null != exception); i++)
284 {
285 s.println("---------");
286
287 try
288 {
289 exception.printStackTrace(s);
290 }
291 catch (Exception e)
292 {
293 s.println("Could not print stack trace...");
294 }
295
296 if (exception instanceof TransformerException)
297 {
298 TransformerException se = (TransformerException) exception;
299 Throwable prev = exception;
300
301 exception = se.getException();
302
303 if (prev == exception)
304 {
305 exception = null;
306
307 break;
308 }
309 }
310 else
311 {
312 exception = null;
313 }
314 }
315 }
316 }
317
318 /**
319 * Return the embedded exception, if any.
320 * Overrides javax.xml.transform.TransformerException.getException().
321 *
322 * @return The embedded exception, or null if there is none.
323 */
324 public Throwable getException()
325 {
326 return m_exception;
327 }
328 }
--- EOF ---