KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > apache > avalon > framework > ExceptionUtil


1 /* ====================================================================
2  * The Apache Software License, Version 1.1
3  *
4  * Copyright (c) 1997-2003 The Apache Software Foundation. All rights
5  * reserved.
6  *
7  * Redistribution and use in source and binary forms, with or without
8  * modification, are permitted provided that the following conditions
9  * are met:
10  *
11  * 1. Redistributions of source code must retain the above copyright
12  * notice, this list of conditions and the following disclaimer.
13  *
14  * 2. Redistributions in binary form must reproduce the above copyright
15  * notice, this list of conditions and the following disclaimer in
16  * the documentation and/or other materials provided with the
17  * distribution.
18  *
19  * 3. The end-user documentation included with the redistribution,
20  * if any, must include the following acknowledgment:
21  * "This product includes software developed by the
22  * Apache Software Foundation (http://www.apache.org/)."
23  * Alternately, this acknowledgment may appear in the software
24  * itself, if and wherever such third-party acknowledgments
25  * normally appear.
26  *
27  * 4. The names "Jakarta", "Avalon", and "Apache Software Foundation"
28  * must not be used to endorse or promote products derived from this
29  * software without prior written permission. For written
30  * permission, please contact apache@apache.org.
31  *
32  * 5. Products derived from this software may not be called "Apache",
33  * nor may "Apache" appear in their name, without prior written
34  * permission of the Apache Software Foundation.
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 APACHE SOFTWARE FOUNDATION OR
40  * ITS 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  *
50  * This software consists of voluntary contributions made by many
51  * individuals on behalf of the Apache Software Foundation. For more
52  * information on the Apache Software Foundation, please see
53  * <http://www.apache.org/>.
54  */

55 package org.apache.avalon.framework;
56
57 import java.io.PrintWriter JavaDoc;
58 import java.io.StringWriter JavaDoc;
59 import java.lang.reflect.Method JavaDoc;
60 import java.util.StringTokenizer JavaDoc;
61
62 /**
63  * This class provides basic facilities for manipulating exceptions.
64  *
65  * Some exception handling stuff thieved from Turbine...
66  *
67  * @author <a HREF="mailto:dev@avalon.apache.org">Avalon Development Team</a>
68  * @version CVS $Revision: 1.22 $ $Date: 2003/02/11 15:58:37 $
69  */

70 public final class ExceptionUtil
71 {
72     private static final String JavaDoc LINE_SEPARATOR = System.getProperty( "line.separator" );
73     private static final String JavaDoc GET_CAUSE_NAME = "getCause";
74     private static final Class JavaDoc[] GET_CAUSE_PARAMTYPES = new Class JavaDoc[ 0 ];
75
76     /**
77      * Private constructor to prevent instantiation.
78      */

79     private ExceptionUtil()
80     {
81     }
82
83     /**
84      * Generate string for specified exception and the cause of
85      * this exception (if any).
86      * @param throwable a <code>Throwable</code>
87      * @return the stack trace as a <code>String</code>
88      */

89     public static String JavaDoc printStackTrace( final Throwable JavaDoc throwable )
90     {
91         return printStackTrace( throwable, 0, true );
92     }
93
94     /**
95      * Generate string for specified exception and if printCascading
96      * is true will print all cascading exceptions.
97      * @param throwable a <code>Throwable</code>
98      * @param printCascading if <code>true</code> will print all cascading exceptions
99      * @return the stack trace as a <code>String</code>
100      */

101     public static String JavaDoc printStackTrace( final Throwable JavaDoc throwable,
102                                           final boolean printCascading )
103     {
104         return printStackTrace( throwable, 0, printCascading );
105     }
106
107     /**
108      * Serialize the specified <code>Throwable</code> to a string.
109      * Restrict the number of frames printed out to the specified depth.
110      * If the depth specified is <code>0</code> then all the frames are
111      * converted into a string.
112      * @param throwable a <code>Throwable</code>
113      * @param depth number of stack trace frames to show
114      * @return the stack trace as a <code>String</code>
115      */

116     public static String JavaDoc printStackTrace( final Throwable JavaDoc throwable, final int depth )
117     {
118         int dp = depth;
119         final String JavaDoc[] lines = captureStackTrace( throwable );
120
121         if( 0 == dp || dp > lines.length )
122         {
123             dp = lines.length;
124         }
125
126         final StringBuffer JavaDoc sb = new StringBuffer JavaDoc();
127
128         for( int i = 0; i < dp; i++ )
129         {
130             sb.append( lines[ i ] );
131             sb.append( LINE_SEPARATOR );
132         }
133
134         return sb.toString();
135     }
136
137     /**
138      * Generate exception string for specified exception to specified depth
139      * and all Cascading exceptions if printCascading is true.
140      * @param throwable a <code>Throwable</code>
141      * @param depth number of stack trace frames to show
142      * @param printCascading if <code>true</code> will print all cascading exceptions
143      * @return the stack trace as a <code>String</code>
144      */

145     public static String JavaDoc printStackTrace( final Throwable JavaDoc throwable,
146                                           final int depth,
147                                           final boolean printCascading )
148     {
149         return printStackTrace( throwable, depth, printCascading, true );
150     }
151
152     /**
153      * Generate exception string for specified exception to specified depth
154      * and all Cascading exceptions if printCascading is true. If useReflection
155      * is true then the method will also attempt to use reflection to find a
156      * method with signature <code>Throwable getCause()</code>. This makes
157      * it compatible with JDK1.4 mechanisms for nesting exceptions.
158      * @param throwable a <code>Throwable</code>
159      * @param depth number of stack trace frames to show
160      * @param printCascading if <code>true</code> will print all cascading exceptions
161      * @param useReflection if <code>true</code> will use reflection to handle JDK1.4
162      * nested exceptions
163      * @return the stack trace as a <code>String</code>
164      */

165     public static String JavaDoc printStackTrace( final Throwable JavaDoc throwable,
166                                           final int depth,
167                                           final boolean printCascading,
168                                           final boolean useReflection )
169     {
170         final String JavaDoc result = printStackTrace( throwable, depth );
171
172         if( !printCascading )
173         {
174             return result;
175         }
176         else
177         {
178             final StringBuffer JavaDoc sb = new StringBuffer JavaDoc();
179             sb.append( result );
180
181             Throwable JavaDoc cause = getCause( throwable, useReflection );
182
183             while( null != cause )
184             {
185                 sb.append( "rethrown from" );
186                 sb.append( LINE_SEPARATOR );
187                 sb.append( printStackTrace( cause, depth ) );
188
189                 cause = getCause( cause, useReflection );
190             }
191
192             return sb.toString();
193         }
194     }
195
196     /**
197      * Utility method to get cause of exception.
198      * @param throwable a <code>Throwable</code>
199      * @param useReflection if <code>true</code> will use reflection to handle JDK1.4
200      * nested exceptions
201      * @return cause of specified exception
202      */

203     public static Throwable JavaDoc getCause( final Throwable JavaDoc throwable,
204                                       final boolean useReflection )
205     {
206         if( throwable instanceof CascadingThrowable )
207         {
208             return ( (CascadingThrowable)throwable ).getCause();
209         }
210         else if( useReflection )
211         {
212             try
213             {
214                 final Class JavaDoc clazz = throwable.getClass();
215                 final Method JavaDoc method =
216                     clazz.getMethod( GET_CAUSE_NAME, GET_CAUSE_PARAMTYPES );
217                 return (Throwable JavaDoc)method.invoke( throwable, null );
218             }
219             catch( final Throwable JavaDoc t )
220             {
221                 return null;
222             }
223         }
224         else
225         {
226             return null;
227         }
228     }
229
230     /**
231      * Captures the stack trace associated with this exception.
232      *
233      * @param throwable a <code>Throwable</code>
234      * @return an array of Strings describing stack frames.
235      */

236     public static String JavaDoc[] captureStackTrace( final Throwable JavaDoc throwable )
237     {
238         final StringWriter JavaDoc sw = new StringWriter JavaDoc();
239         throwable.printStackTrace( new PrintWriter JavaDoc( sw, true ) );
240         return splitStringInternal( sw.toString(), LINE_SEPARATOR );
241     }
242
243     /**
244      * Splits the string on every token into an array of stack frames.
245      *
246      * @param string the string to split
247      * @param onToken the token to split on
248      * @return the resultant array
249      * @deprecated This is an internal utility method that should not be used
250      */

251     public static String JavaDoc[] splitString( final String JavaDoc string, final String JavaDoc onToken )
252     {
253         return splitStringInternal( string, onToken );
254     }
255
256     /**
257      * Splits the string on every token into an array of stack frames.
258      *
259      * @param string the string to split
260      * @param onToken the token to split on
261      * @return the resultant array
262      */

263     private static String JavaDoc[] splitStringInternal( final String JavaDoc string, final String JavaDoc onToken )
264     {
265         final StringTokenizer JavaDoc tokenizer = new StringTokenizer JavaDoc( string, onToken );
266         final String JavaDoc[] result = new String JavaDoc[ tokenizer.countTokens() ];
267
268         for( int i = 0; i < result.length; i++ )
269         {
270             result[ i ] = tokenizer.nextToken();
271         }
272
273         return result;
274     }
275 }
276
Popular Tags