View Javadoc
1   /*
2    * Copyright (c) 2000, 2006, Oracle and/or its affiliates. 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.  Oracle designates this
8    * particular file as subject to the "Classpath" exception as provided
9    * by Oracle 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22   * or visit www.oracle.com if you need additional information or have any
23   * 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 }