KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > enhydra > zeus > ZeusException


1 /*
2  * Enhydra Java Application Server Project
3  *
4  * The contents of this file are subject to the Enhydra Public License
5  * Version 1.1 (the "License"); you may not use this file except in
6  * compliance with the License. You may obtain a copy of the License on
7  * the Enhydra web site ( http://www.enhydra.org/ ).
8  *
9  * Software distributed under the License is distributed on an "AS IS"
10  * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
11  * the License for the specific terms governing rights and limitations
12  * under the License.
13  *
14  * The Initial Developer of the Enhydra Application Server is Lutris
15  * Technologies, Inc. The Enhydra Application Server and portions created
16  * by Lutris Technologies, Inc. are Copyright Lutris Technologies, Inc.
17  * All Rights Reserved.
18  */

19 package org.enhydra.zeus;
20
21 import java.io.PrintStream JavaDoc;
22 import java.io.PrintWriter JavaDoc;
23 import java.lang.ExceptionInInitializerError JavaDoc;
24 import java.lang.reflect.Method JavaDoc;
25 import java.lang.reflect.InvocationTargetException JavaDoc;
26 import java.rmi.RemoteException JavaDoc;
27
28 // SAX imports
29
import org.xml.sax.SAXException JavaDoc;
30
31 /**
32  * <p>
33  * <code>ZeusException</code> is the top level
34  * <code>Exception</code> that Zeus classes
35  * can throw. It's subclasses add specificity to the
36  * problems that can occur using Zeus, but this single
37  * <code>Exception</code> can be caught to handle all
38  * Zeus specific problems.
39  * </p>
40  *
41  * @author Brett McLaughlin
42  */

43 public class ZeusException extends Exception JavaDoc {
44
45     /** A wrapped <code>Throwable</code> */
46     protected Throwable JavaDoc cause;
47
48     /**
49      * <p>
50      * This will create an <code>Exception</code>.
51      * </p>
52      */

53     public ZeusException() {
54         super("An exception occurred in Zeus processing.");
55     }
56
57     /**
58      * <p>
59      * This will create an <code>Exception</code> with the given message.
60      * </p>
61      *
62      * @param message <code>String</code> message indicating
63      * the problem that occurred.
64      */

65     public ZeusException(String JavaDoc message) {
66         super(message);
67     }
68
69     /**
70      * <p>
71      * This will create an <code>Exception</code> with the given message
72      * and wrap another <code>Exception</code>. This is useful when
73      * the originating <code>Exception</code> should be held on to.
74      * </p>
75      *
76      * @param message <code>String</code> message indicating
77      * the problem that occurred.
78      * @param cause <code>Throwable</code> that caused this
79      * to be thrown.
80      */

81     public ZeusException(String JavaDoc message, Throwable JavaDoc cause) {
82         super(message);
83         this.cause = cause;
84     }
85
86     /**
87      * <p>
88      * Intializes the cause of this exception to be the specified value.
89      * </p>
90      * @param cause <code>Throwable</code> that caused this
91      * to be thrown.
92      */

93     public Throwable JavaDoc initCause(Throwable JavaDoc cause) {
94         this.cause = cause;
95         return cause;
96     }
97
98     /**
99      * <p>
100      * This returns the message for the <code>Exception</code>. If
101      * there are one or more nested exceptions, their messages
102      * are appended.
103      * </p>
104      *
105      * @return <code>String</code> - message for <code>Exception</code>.
106      */

107     public String JavaDoc getMessage() {
108         // Get this exception's message.
109
String JavaDoc msg = super.getMessage();
110
111         Throwable JavaDoc parent = this;
112         Throwable JavaDoc child;
113         
114         // Look for nested exceptions.
115
while((child = getNestedException(parent)) != null) {
116             // Get the child's message.
117
String JavaDoc msg2 = child.getMessage();
118             
119             /**
120              * Special case: If a SAXException has no message of its own,
121              * but has a nested exception, then it returns the nested
122              * exception's message as its message. We don't want to add
123              * that message twice.
124              */

125             if (child instanceof SAXException JavaDoc) {
126                 Throwable JavaDoc grandchild = ((SAXException JavaDoc)child).getException();
127                 /**
128                  * If the SAXException tells us that it's message is identical
129                  * to its nested exception's message, then we skip it, so
130                  * we don't add it twice.
131                  */

132                 if ((grandchild != null) &&
133                     (msg2 != null) &&
134                     (msg2.equals(grandchild.getMessage()))) {
135                     msg2 = null;
136                 }
137             }
138
139             // If we found a message for the child exception, we append it.
140
if (msg2 != null) {
141                 if (msg != null) {
142                     msg += ": " + msg2;
143                 } else {
144                     msg = msg2;
145                 }
146             }
147
148             /**
149              * Any nested ZeusException will append its own children,
150              * so we need to break out of here.
151              */

152             if (child instanceof ZeusException) {
153                 break;
154             }
155             parent = child;
156         }
157
158         // Return the completed message.
159
return msg;
160     }
161
162     /**
163      * <p>
164      * This prints the stack trace of the <code>Exception</code>. If
165      * there is a root cause, the stack trace of the root
166      * <code>Exception</code> is printed right after.
167      * </p>
168      */

169     public void printStackTrace() {
170         // Print the stack trace for this exception.
171
super.printStackTrace();
172
173         Throwable JavaDoc parent = this;
174         Throwable JavaDoc child;
175
176         // Print the stack trace for each nested exception.
177
while((child = getNestedException(parent)) != null) {
178             if (child != null) {
179                 System.err.print("Caused by: ");
180                 child.printStackTrace();
181                 /**
182                  * Any nested ZeusException will print its own children,
183                  * so we need to break out of here.
184                  */

185                 if (child instanceof ZeusException) {
186                     break;
187                 }
188                 parent = child;
189             }
190         }
191     }
192
193     /**
194      * <p>
195      * This prints the stack trace of the <code>Exception</code> to the given
196      * PrintStream. If there is a root cause, the stack trace of the root
197      * <code>Exception</code> is printed right after.
198      * </p>
199      */

200     public void printStackTrace(PrintStream JavaDoc s) {
201         // Print the stack trace for this exception.
202
super.printStackTrace(s);
203
204         Throwable JavaDoc parent = this;
205         Throwable JavaDoc child;
206
207         // Print the stack trace for each nested exception.
208
while((child = getNestedException(parent)) != null) {
209             if (child != null) {
210                 System.err.print("Caused by: ");
211                 child.printStackTrace(s);
212                 /**
213                  * Any nested ZeusException will print its own children,
214                  * so we need to break out of here.
215                  */

216                 if (child instanceof ZeusException) {
217                     break;
218                 }
219                 parent = child;
220             }
221         }
222     }
223
224     /**
225      * <p>
226      * This prints the stack trace of the <code>Exception</code> to the given
227      * PrintWriter. If there is a root cause, the stack trace of the root
228      * <code>Exception</code> is printed right after.
229      * </p>
230      */

231     public void printStackTrace(PrintWriter JavaDoc w) {
232         // Print the stack trace for this exception.
233
super.printStackTrace(w);
234
235         Throwable JavaDoc parent = this;
236         Throwable JavaDoc child;
237
238         // Print the stack trace for each nested exception.
239
while((child = getNestedException(parent)) != null) {
240             if (child != null) {
241                 System.err.print("Caused by: ");
242                 child.printStackTrace(w);
243                 /**
244                  * Any nested JDOMException will print its own children,
245                  * so we need to break out of here.
246                  */

247                 if (child instanceof ZeusException) {
248                     break;
249                 }
250                 parent = child;
251             }
252         }
253     }
254
255     /**
256      * <p>
257      * This will return the root cause <code>Throwable</code>, or null
258      * if one does not exist.
259      * </p>
260      *
261      * @return <code>Throwable</code> - the wrapped <code>Throwable</code>.
262      */

263     public Throwable JavaDoc getCause() {
264         return cause;
265     }
266
267     /**
268      * <p>
269      * This returns any nested exceptions from the supplied
270      * <code>Throwable</code> object. If there is no nested exception,
271      * then <code>null</code> is returned.
272      * </p>
273      *
274      * @param parent <code>Throwable</code> to check for nested exceptions
275      * @return <code>Throwable</code> - the nested exception, or null
276      */

277     private static Throwable JavaDoc getNestedException(Throwable JavaDoc parent) {
278         if (parent instanceof ZeusException) {
279             return ((ZeusException)parent).getCause();
280         }
281         
282         if (parent instanceof SAXException JavaDoc) {
283             return ((SAXException JavaDoc)parent).getException();
284         }
285         
286         if (parent instanceof InvocationTargetException JavaDoc) {
287             return ((InvocationTargetException JavaDoc)parent).getTargetException();
288         }
289         
290         if (parent instanceof ExceptionInInitializerError JavaDoc) {
291             return ((ExceptionInInitializerError JavaDoc)parent).getException();
292         }
293         
294         if (parent instanceof RemoteException JavaDoc) {
295             return ((RemoteException JavaDoc)parent).detail;
296         }
297         
298         /**
299          * These classes are not part of standard JDK 1.1 or 1.2, so we
300          * use reflection to access them.
301          */

302         Throwable JavaDoc nestedException = getNestedException(parent,
303             "javax.naming.NamingException", "getRootCause");
304         if (nestedException != null) {
305             return nestedException;
306         }
307
308         return null;
309     }
310
311     /**
312      * <p>
313      * This method uses reflection to obtain the nested exception of a
314      * <code>Throwable</code>. We use reflection because the desired class
315      * may not exist in the currently-running VM.
316      * </p>
317      *
318      * @param parent <code>Throwable</code> to check for nested exceptions
319      * @param className the class of the exception to look for
320      * @param methodName the method to check for a root cause with
321      * @return <code>Throwable</code> - the nested exception, or null
322      */

323     private static Throwable JavaDoc getNestedException(Throwable JavaDoc parent,
324                                                 String JavaDoc className,
325                                                 String JavaDoc methodName) {
326         try {
327             /**
328              * See if this Throwable is of the desired type,
329              * by using isAssignableFrom().
330              */

331             Class JavaDoc testClass = Class.forName(className);
332             Class JavaDoc objectClass = parent.getClass();
333             if (testClass.isAssignableFrom(objectClass)) {
334                 // Use reflection to call the specified method.
335
Class JavaDoc[] argClasses = new Class JavaDoc[0];
336                 Method JavaDoc method = testClass.getMethod(methodName, argClasses);
337                 Object JavaDoc[] args = new Object JavaDoc[0];
338                 return (Throwable JavaDoc)method.invoke(parent, args);
339             }
340         }
341         catch(Exception JavaDoc ex) {
342             /**
343              * Most likely, the desired class is not available in this VM.
344              * That's fine. Even if it's caused by something else, we
345              * don't want to display an error here, since we're already
346              * in the process of trying to display the original
347              * error - another error here will just confuse things.
348              */

349         }
350
351         return null;
352     }
353 }
354
Popular Tags