1 /*
2 * Copyright 2000-2006 Sun Microsystems, Inc. All Rights Reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation. Sun designates this
8 * particular file as subject to the "Classpath" exception as provided
9 * by Sun in the LICENSE file that accompanied this code.
10 *
11 * This code is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 * version 2 for more details (a copy is included in the LICENSE file that
15 * accompanied this code).
16 *
17 * You should have received a copy of the GNU General Public License version
18 * 2 along with this work; if not, write to the Free Software Foundation,
19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20 *
21 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
22 * CA 95054 USA or visit www.sun.com if you need additional information or
23 * have any questions.
24 */
25
26 package javax.xml.transform;
27
28 import java.lang.reflect.Method;
29 import java.lang.reflect.InvocationTargetException;
30
31 /**
32 * This class specifies an exceptional condition that occured
33 * during the transformation process.
34 */
35 public class TransformerException extends Exception {
36
37 /** Field locator specifies where the error occured */
38 SourceLocator locator;
39
40 /**
41 * Method getLocator retrieves an instance of a SourceLocator
42 * object that specifies where an error occured.
43 *
44 * @return A SourceLocator object, or null if none was specified.
45 */
46 public SourceLocator getLocator() {
47 return locator;
48 }
49
50 /**
51 * Method setLocator sets an instance of a SourceLocator
52 * object that specifies where an error occured.
53 *
54 * @param location A SourceLocator object, or null to clear the location.
55 */
56 public void setLocator(SourceLocator location) {
57 locator = location;
58 }
59
60 /** Field containedException specifies a wrapped exception. May be null. */
61 Throwable containedException;
62
63 /**
64 * This method retrieves an exception that this exception wraps.
65 *
66 * @return An Throwable object, or null.
67 * @see #getCause
68 */
69 public Throwable getException() {
70 return containedException;
71 }
72
73 /**
74 * Returns the cause of this throwable or <code>null</code> if the
75 * cause is nonexistent or unknown. (The cause is the throwable that
76 * caused this throwable to get thrown.)
77 */
78 public Throwable getCause() {
79
80 return ((containedException == this)
81 ? null
82 : containedException);
83 }
84
85 /**
86 * Initializes the <i>cause</i> of this throwable to the specified value.
87 * (The cause is the throwable that caused this throwable to get thrown.)
88 *
89 * <p>This method can be called at most once. It is generally called from
90 * within the constructor, or immediately after creating the
91 * throwable. If this throwable was created
92 * with {@link #TransformerException(Throwable)} or
93 * {@link #TransformerException(String,Throwable)}, this method cannot be called
94 * even once.
95 *
96 * @param cause the cause (which is saved for later retrieval by the
97 * {@link #getCause()} method). (A <code>null</code> value is
98 * permitted, and indicates that the cause is nonexistent or
99 * unknown.)
100 * @return a reference to this <code>Throwable</code> instance.
101 * @throws IllegalArgumentException if <code>cause</code> is this
102 * throwable. (A throwable cannot
103 * be its own cause.)
104 * @throws IllegalStateException if this throwable was
105 * created with {@link #TransformerException(Throwable)} or
106 * {@link #TransformerException(String,Throwable)}, or this method has already
107 * been called on this throwable.
108 */
109 public synchronized Throwable initCause(Throwable cause) {
110
111 if (this.containedException != null) {
112 throw new IllegalStateException("Can't overwrite cause");
113 }
114
115 if (cause == this) {
116 throw new IllegalArgumentException(
117 "Self-causation not permitted");
118 }
119
120 this.containedException = cause;
121
122 return this;
123 }
124
125 /**
126 * Create a new TransformerException.
127 *
128 * @param message The error or warning message.
129 */
130 public TransformerException(String message) {
131
132 super(message);
133
134 this.containedException = null;
135 this.locator = null;
136 }
137
138 /**
139 * Create a new TransformerException wrapping an existing exception.
140 *
141 * @param e The exception to be wrapped.
142 */
143 public TransformerException(Throwable e) {
144
145 super(e.toString());
146
147 this.containedException = e;
148 this.locator = null;
149 }
150
151 /**
152 * Wrap an existing exception in a TransformerException.
153 *
154 * <p>This is used for throwing processor exceptions before
155 * the processing has started.</p>
156 *
157 * @param message The error or warning message, or null to
158 * use the message from the embedded exception.
159 * @param e Any exception
160 */
161 public TransformerException(String message, Throwable e) {
162
163 super(((message == null) || (message.length() == 0))
164 ? e.toString()
165 : message);
166
167 this.containedException = e;
168 this.locator = null;
169 }
170
171 /**
172 * Create a new TransformerException from a message and a Locator.
173 *
174 * <p>This constructor is especially useful when an application is
175 * creating its own exception from within a DocumentHandler
176 * callback.</p>
177 *
178 * @param message The error or warning message.
179 * @param locator The locator object for the error or warning.
180 */
181 public TransformerException(String message, SourceLocator locator) {
182
183 super(message);
184
185 this.containedException = null;
186 this.locator = locator;
187 }
188
189 /**
190 * Wrap an existing exception in a TransformerException.
191 *
192 * @param message The error or warning message, or null to
193 * use the message from the embedded exception.
194 * @param locator The locator object for the error or warning.
195 * @param e Any exception
196 */
197 public TransformerException(String message, SourceLocator locator,
198 Throwable e) {
199
200 super(message);
201
202 this.containedException = e;
203 this.locator = locator;
204 }
205
206 /**
207 * Get the error message with location information
208 * appended.
209 *
210 * @return A <code>String</code> representing the error message with
211 * location information appended.
212 */
213 public String getMessageAndLocation() {
214
215 StringBuffer sbuffer = new StringBuffer();
216 String message = super.getMessage();
217
218 if (null != message) {
219 sbuffer.append(message);
220 }
221
222 if (null != locator) {
223 String systemID = locator.getSystemId();
224 int line = locator.getLineNumber();
225 int column = locator.getColumnNumber();
226
227 if (null != systemID) {
228 sbuffer.append("; SystemID: ");
229 sbuffer.append(systemID);
230 }
231
232 if (0 != line) {
233 sbuffer.append("; Line#: ");
234 sbuffer.append(line);
235 }
236
237 if (0 != column) {
238 sbuffer.append("; Column#: ");
239 sbuffer.append(column);
240 }
241 }
242
243 return sbuffer.toString();
244 }
245
246 /**
247 * Get the location information as a string.
248 *
249 * @return A string with location info, or null
250 * if there is no location information.
251 */
252 public String getLocationAsString() {
253
254 if (null != locator) {
255 StringBuffer sbuffer = new StringBuffer();
256 String systemID = locator.getSystemId();
257 int line = locator.getLineNumber();
258 int column = locator.getColumnNumber();
259
260 if (null != systemID) {
261 sbuffer.append("; SystemID: ");
262 sbuffer.append(systemID);
263 }
264
265 if (0 != line) {
266 sbuffer.append("; Line#: ");
267 sbuffer.append(line);
268 }
269
270 if (0 != column) {
271 sbuffer.append("; Column#: ");
272 sbuffer.append(column);
273 }
274
275 return sbuffer.toString();
276 } else {
277 return null;
278 }
279 }
280
281 /**
282 * Print the the trace of methods from where the error
283 * originated. This will trace all nested exception
284 * objects, as well as this object.
285 */
286 public void printStackTrace() {
287 printStackTrace(new java.io.PrintWriter(System.err, true));
288 }
289
290 /**
291 * Print the the trace of methods from where the error
292 * originated. This will trace all nested exception
293 * objects, as well as this object.
294 * @param s The stream where the dump will be sent to.
295 */
296 public void printStackTrace(java.io.PrintStream s) {
297 printStackTrace(new java.io.PrintWriter(s));
298 }
299
300 /**
301 * Print the the trace of methods from where the error
302 * originated. This will trace all nested exception
303 * objects, as well as this object.
304 * @param s The writer where the dump will be sent to.
305 */
306 public void printStackTrace(java.io.PrintWriter s) {
307
308 if (s == null) {
309 s = new java.io.PrintWriter(System.err, true);
310 }
311
312 try {
313 String locInfo = getLocationAsString();
314
315 if (null != locInfo) {
316 s.println(locInfo);
317 }
318
319 super.printStackTrace(s);
320 } catch (Throwable e) {}
321
322 Throwable exception = getException();
323
324 for (int i = 0; (i < 10) && (null != exception); i++) {
325 s.println("---------");
326
327 try {
328 if (exception instanceof TransformerException) {
329 String locInfo =
330 ((TransformerException) exception)
331 .getLocationAsString();
332
333 if (null != locInfo) {
334 s.println(locInfo);
335 }
336 }
337
338 exception.printStackTrace(s);
339 } catch (Throwable e) {
340 s.println("Could not print stack trace...");
341 }
342
343 try {
344 Method meth =
345 ((Object) exception).getClass().getMethod("getException",
346 (Class[]) null);
347
348 if (null != meth) {
349 Throwable prev = exception;
350
351 exception = (Throwable) meth.invoke(exception, (Object[]) null);
352
353 if (prev == exception) {
354 break;
355 }
356 } else {
357 exception = null;
358 }
359 } catch (InvocationTargetException ite) {
360 exception = null;
361 } catch (IllegalAccessException iae) {
362 exception = null;
363 } catch (NoSuchMethodException nsme) {
364 exception = null;
365 }
366 }
367 // insure output is written
368 s.flush();
369 }
370 }