KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > jdom > JDOMException


1 /*--
2
3  $Id: JDOMException.java,v 1.23 2004/02/27 11:32:57 jhunter Exp $
4
5  Copyright (C) 2000-2004 Jason Hunter & Brett McLaughlin.
6  All rights reserved.
7  
8  Redistribution and use in source and binary forms, with or without
9  modification, are permitted provided that the following conditions
10  are met:
11  
12  1. Redistributions of source code must retain the above copyright
13     notice, this list of conditions, and the following disclaimer.
14  
15  2. Redistributions in binary form must reproduce the above copyright
16     notice, this list of conditions, and the disclaimer that follows
17     these conditions in the documentation and/or other materials
18     provided with the distribution.
19
20  3. The name "JDOM" must not be used to endorse or promote products
21     derived from this software without prior written permission. For
22     written permission, please contact <request_AT_jdom_DOT_org>.
23  
24  4. Products derived from this software may not be called "JDOM", nor
25     may "JDOM" appear in their name, without prior written permission
26     from the JDOM Project Management <request_AT_jdom_DOT_org>.
27  
28  In addition, we request (but do not require) that you include in the
29  end-user documentation provided with the redistribution and/or in the
30  software itself an acknowledgement equivalent to the following:
31      "This product includes software developed by the
32       JDOM Project (http://www.jdom.org/)."
33  Alternatively, the acknowledgment may be graphical using the logos
34  available at http://www.jdom.org/images/logos.
35
36  THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
37  WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
38  OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
39  DISCLAIMED. IN NO EVENT SHALL THE JDOM AUTHORS OR THE PROJECT
40  CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
41  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
42  LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
43  USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
44  ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
45  OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
46  OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
47  SUCH DAMAGE.
48
49  This software consists of voluntary contributions made by many
50  individuals on behalf of the JDOM Project and was originally
51  created by Jason Hunter <jhunter_AT_jdom_DOT_org> and
52  Brett McLaughlin <brett_AT_jdom_DOT_org>. For more information
53  on the JDOM Project, please see <http://www.jdom.org/>.
54  
55  */

56
57 package org.jdom;
58
59 import java.io.*;
60 import java.lang.reflect.*;
61 import java.rmi.*;
62 import java.sql.*;
63
64 import org.xml.sax.*;
65
66 /**
67  * The top level exception that JDOM classes can throw. Its subclasses add
68  * specificity to the problems that can occur using JDOM. This single exception
69  * can be caught to handle all JDOM specific problems (some methods may throw
70  * {@link java.io.IOException} and such).
71  *
72  * @version $Revision: 1.23 $, $Date: 2004/02/27 11:32:57 $
73  * @author Brett McLaughlin
74  * @author Jason Hunter
75  */

76 public class JDOMException extends Exception JavaDoc {
77
78     private static final String JavaDoc CVS_ID =
79       "@(#) $RCSfile: JDOMException.java,v $ $Revision: 1.23 $ $Date: 2004/02/27 11:32:57 $ $Name: $";
80
81     /** A wrapped <code>Throwable</code> */
82     private Throwable JavaDoc cause;
83
84     /**
85      * This will create an <code>Exception</code>.
86      */

87     public JDOMException() {
88         super("Error occurred in JDOM application.");
89     }
90
91     /**
92      * This will create an <code>Exception</code> with the given message.
93      *
94      * @param message <code>String</code> message indicating
95      * the problem that occurred.
96      */

97     public JDOMException(String JavaDoc message) {
98         super(message);
99     }
100
101     /**
102      * This will create an <code>Exception</code> with the given message
103      * and wrap another <code>Exception</code>. This is useful when
104      * the originating <code>Exception</code> should be held on to.
105      *
106      * @param message <code>String</code> message indicating
107      * the problem that occurred.
108      * @param cause <code>Throwable</code> that caused this
109      * to be thrown.
110      */

111     public JDOMException(String JavaDoc message, Throwable JavaDoc cause) {
112         super(message);
113         this.cause = cause;
114     }
115
116     /**
117      * Intializes the cause of this exception to be the specified value.
118      *
119      * @param cause <code>Throwable</code> that caused this
120      * to be thrown.
121      * @return a pointer to this throwable
122      */

123     // Created to match the JDK 1.4 Throwable method.
124
public Throwable JavaDoc initCause(Throwable JavaDoc cause) {
125         this.cause = cause;
126         return this;
127     }
128
129     /**
130      * This returns the message for the <code>Exception</code>. If
131      * there are one or more nested exceptions, their messages
132      * are appended.
133      *
134      * @return <code>String</code> - message for <code>Exception</code>.
135      */

136     public String JavaDoc getMessage() {
137         // Get this exception's message.
138
String JavaDoc msg = super.getMessage();
139
140         Throwable JavaDoc parent = this;
141         Throwable JavaDoc child;
142         
143         // Look for nested exceptions.
144
while((child = getNestedException(parent)) != null) {
145             // Get the child's message.
146
String JavaDoc msg2 = child.getMessage();
147             
148             // Special case: If a SAXException has no message of its own, but has a
149
// nested exception, then it returns the nested exception's message as its
150
// message. We don't want to add that message twice.
151
if (child instanceof SAXException) {
152                 Throwable JavaDoc grandchild = ((SAXException)child).getException();
153                 // If the SAXException tells us that it's message is identical to
154
// its nested exception's message, then we skip it, so we don't
155
// add it twice.
156
if (grandchild != null && msg2 != null && msg2.equals(grandchild.getMessage())) {
157                     msg2 = null;
158                 }
159             }
160
161             // If we found a message for the child exception, we append it.
162
if (msg2 != null) {
163                 if (msg != null) {
164                     msg += ": " + msg2;
165                 } else {
166                     msg = msg2;
167                 }
168             }
169
170             // Any nested JDOMException will append its own children,
171
// so we need to break out of here.
172
if (child instanceof JDOMException) {
173                 break;
174             }
175             parent = child;
176         }
177
178         // Return the completed message.
179
return msg;
180     }
181
182     /**
183      * This prints the stack trace of the <code>Exception</code>. If
184      * there is a root cause, the stack trace of the root
185      * <code>Exception</code> is printed right after.
186      */

187     public void printStackTrace() {
188         // Print the stack trace for this exception.
189
super.printStackTrace();
190
191         Throwable JavaDoc parent = this;
192         Throwable JavaDoc child;
193
194         // Print the stack trace for each nested exception.
195
while((child = getNestedException(parent)) != null) {
196             System.err.print("Caused by: ");
197             child.printStackTrace();
198             // Any nested JDOMException will print its own children,
199
// so we need to break out of here.
200
if (child instanceof JDOMException) {
201                 break;
202             }
203             parent = child;
204         }
205     }
206
207     /**
208      * Prints the stack trace of the <code>Exception</code> to the given
209      * PrintStream. If there is a root cause, the stack trace of the root
210      * <code>Exception</code> is printed right after.
211      *
212      * @param s PrintStream to print to
213      */

214     public void printStackTrace(PrintStream s) {
215         // Print the stack trace for this exception.
216
super.printStackTrace(s);
217
218         Throwable JavaDoc parent = this;
219         Throwable JavaDoc child;
220
221         // Print the stack trace for each nested exception.
222
while((child = getNestedException(parent)) != null) {
223             s.print("Caused by: ");
224             child.printStackTrace(s);
225             // Any nested JDOMException will print its own children,
226
// so we need to break out of here.
227
if (child instanceof JDOMException) {
228                 break;
229             }
230             parent = child;
231         }
232     }
233
234     /**
235      * Prints the stack trace of the <code>Exception</code> to the given
236      * PrintWriter. If there is a root cause, the stack trace of the root
237      * <code>Exception</code> is printed right after.
238      *
239      * @param w PrintWriter to print to
240      */

241     public void printStackTrace(PrintWriter w) {
242         // Print the stack trace for this exception.
243
super.printStackTrace(w);
244
245         Throwable JavaDoc parent = this;
246         Throwable JavaDoc child;
247
248         // Print the stack trace for each nested exception.
249
while((child = getNestedException(parent)) != null) {
250             w.print("Caused by: ");
251             child.printStackTrace(w);
252             // Any nested JDOMException will print its own children,
253
// so we need to break out of here.
254
if (child instanceof JDOMException) {
255                 break;
256             }
257             parent = child;
258         }
259     }
260
261     /**
262      * This will return the root cause <code>Throwable</code>, or null
263      * if one does not exist.
264      *
265      * @return <code>Throwable</code> - the wrapped <code>Throwable</code>.
266      */

267     public Throwable JavaDoc getCause() {
268         return cause;
269     }
270
271     // If this Throwable has a nested (child) exception, then we return it.
272
// Otherwise we return null.
273
private static Throwable JavaDoc getNestedException(Throwable JavaDoc parent) {
274         if (parent instanceof JDOMException) {
275             return ((JDOMException)parent).getCause();
276         }
277         
278         if (parent instanceof SAXException) {
279             return ((SAXException)parent).getException();
280         }
281         
282         if (parent instanceof SQLException) {
283             return ((SQLException)parent).getNextException();
284         }
285         
286         if (parent instanceof InvocationTargetException) {
287             return ((InvocationTargetException)parent).getTargetException();
288         }
289         
290         if (parent instanceof ExceptionInInitializerError JavaDoc) {
291             return ((ExceptionInInitializerError JavaDoc)parent).getException();
292         }
293         
294         if (parent instanceof RemoteException) {
295             return ((RemoteException)parent).detail;
296         }
297         
298         // These classes are not part of standard JDK 1.1 or 1.2, so we
299
// use reflection to access them.
300

301         Throwable JavaDoc nestedException = getNestedException(parent, "javax.naming.NamingException", "getRootCause");
302         if (nestedException != null) {
303             return nestedException;
304         }
305         
306         nestedException = getNestedException(parent, "javax.servlet.ServletException", "getRootCause");
307         if (nestedException != null) {
308             return nestedException;
309         }
310
311         return null;
312     }
313
314     // This method uses reflection to obtain the nest exception of a Throwable. We use reflection
315
// because the desired class may not exist in the currently-running VM.
316
private static Throwable JavaDoc getNestedException(
317                                  Throwable JavaDoc parent, String JavaDoc className, String JavaDoc methodName) {
318         try {
319             // See if this Throwable is of the desired type, by using isAssignableFrom().
320
Class JavaDoc testClass = Class.forName(className);
321             Class JavaDoc objectClass = parent.getClass();
322             if (testClass.isAssignableFrom(objectClass)) {
323                 // Use reflection to call the specified method.
324
Class JavaDoc[] argClasses = new Class JavaDoc[0];
325                 Method method = testClass.getMethod(methodName, argClasses);
326                 Object JavaDoc[] args = new Object JavaDoc[0];
327                 return (Throwable JavaDoc)method.invoke(parent, args);
328             }
329         }
330         catch(Exception JavaDoc ex) {
331             // Most likely, the desired class is not available in this VM. That's fine.
332
// Even if it's caused by something else, we don't want to display an error
333
// here, since we're already in the process of trying to display the original
334
// error - another error here will just confuse things.
335
}
336
337         return null;
338     }
339 }
340
Popular Tags