1 package org.apache.turbine.util;
2
3 /* ====================================================================
4 * The Apache Software License, Version 1.1
5 *
6 * Copyright (c) 2001 The Apache Software Foundation. All rights
7 * reserved.
8 *
9 * Redistribution and use in source and binary forms, with or without
10 * modification, are permitted provided that the following conditions
11 * are met:
12 *
13 * 1. Redistributions of source code must retain the above copyright
14 * notice, this list of conditions and the following disclaimer.
15 *
16 * 2. Redistributions in binary form must reproduce the above copyright
17 * notice, this list of conditions and the following disclaimer in
18 * the documentation and/or other materials provided with the
19 * distribution.
20 *
21 * 3. The end-user documentation included with the redistribution,
22 * if any, must include the following acknowledgment:
23 * "This product includes software developed by the
24 * Apache Software Foundation (http://www.apache.org/)."
25 * Alternately, this acknowledgment may appear in the software itself,
26 * if and wherever such third-party acknowledgments normally appear.
27 *
28 * 4. The names "Apache" and "Apache Software Foundation" and
29 * "Apache Turbine" must not be used to endorse or promote products
30 * derived from this software without prior written permission. For
31 * written permission, please contact apache@apache.org.
32 *
33 * 5. Products derived from this software may not be called "Apache",
34 * "Apache Turbine", nor may "Apache" appear in their name, without
35 * prior written permission of the Apache Software Foundation.
36 *
37 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
38 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
39 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
40 * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
41 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
42 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
43 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
44 * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
45 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
46 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
47 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
48 * SUCH DAMAGE.
49 * ====================================================================
50 *
51 * This software consists of voluntary contributions made by many
52 * individuals on behalf of the Apache Software Foundation. For more
53 * information on the Apache Software Foundation, please see
54 * <http://www.apache.org/>.
55 */
56
57 import java.io.OutputStream;
58 import java.io.PrintStream;
59 import java.io.PrintWriter;
60 import java.io.StringWriter;
61 import java.io.Writer;
62 import java.util.LinkedList;
63 import java.util.StringTokenizer;
64
65 /***
66 * The base class of all exceptions thrown by Turbine.
67 *
68 * It is intended to ease the debugging by carrying on the information
69 * about the exception which was caught and provoked throwing the
70 * current exception. Catching and rethrowing may occur multiple
71 * times, and provided that all exceptions except the first one
72 * are descendands of <code>TurbineException</code>, when the
73 * exception is finally printed out using any of the <code>
74 * printStackTrace()</code> methods, the stacktrace will contain
75 * the information about all exceptions thrown and caught on
76 * the way.
77 * <p> Running the following program
78 * <p><blockquote><pre>
79 * 1 import org.apache.turbine.util.TurbineException;
80 * 2
81 * 3 public class Test {
82 * 4 public static void main( String[] args ) {
83 * 5 try {
84 * 6 a();
85 * 7 } catch(Exception e) {
86 * 8 e.printStackTrace();
87 * 9 }
88 * 10 }
89 * 11
90 * 12 public static void a() throws Exception {
91 * 13 try {
92 * 14 b();
93 * 15 } catch(Exception e) {
94 * 16 throw new TurbineException("foo", e);
95 * 17 }
96 * 18 }
97 * 19
98 * 20 public static void b() throws Exception {
99 * 21 try {
100 * 22 c();
101 * 23 } catch(Exception e) {
102 * 24 throw new TurbineException("bar", e);
103 * 25 }
104 * 26 }
105 * 27
106 * 28 public static void c() throws Exception {
107 * 29 throw new Exception("baz");
108 * 30 }
109 * 31 }
110 * </pre></blockquote>
111 * <p>Yields the following stacktrace:
112 * <p><blockquote><pre>
113 * java.lang.Exception: baz: bar: foo
114 * at Test.c(Test.java:29)
115 * at Test.b(Test.java:22)
116 * rethrown as TurbineException: bar
117 * at Test.b(Test.java:24)
118 * at Test.a(Test.java:14)
119 * rethrown as TurbineException: foo
120 * at Test.a(Test.java:16)
121 * at Test.main(Test.java:6)
122 * </pre></blockquote><br>
123 *
124 * @author <a href="mailto:Rafal.Krzewski@e-point.pl">Rafal Krzewski</a>
125 */
126 public class TurbineException extends Exception
127 {
128 /***
129 * Holds the reference to the exception or error that caused
130 * this exception to be thrown.
131 */
132 private Throwable nested = null;
133
134 /***
135 * Constructs a new <code>TurbineException</code> without specified
136 * detail message.
137 */
138 public TurbineException()
139 {
140 super();
141 }
142
143 /***
144 * Constructs a new <code>TurbineException</code> with specified
145 * detail message.
146 *
147 * @param msg The error message.
148 */
149 public TurbineException(String msg)
150 {
151 super(msg);
152 }
153
154 /***
155 * Constructs a new <code>TurbineException</code> with specified
156 * nested <code>Throwable</code>.
157 *
158 * @param nested The exception or error that caused this exception
159 * to be thrown.
160 */
161 public TurbineException(Throwable nested)
162 {
163 super();
164 this.nested = nested;
165 }
166
167 /***
168 * Constructs a new <code>TurbineException</code> with specified
169 * detail message and nested <code>Throwable</code>.
170 *
171 * @param msg The error message.
172 * @param nested The exception or error that caused this exception
173 * to be thrown.
174 */
175 public TurbineException(String msg, Throwable nested)
176 {
177 super(msg);
178 this.nested = nested;
179 }
180
181 /***
182 * Returns the error message of this and any nested <code>Throwable</code>.
183 *
184 * @return The error message.
185 */
186 public String getMessage()
187 {
188 StringBuffer msg = new StringBuffer();
189 String ourMsg = super.getMessage();
190 if (ourMsg != null)
191 {
192 msg.append(ourMsg);
193 }
194 if (nested != null)
195 {
196 String nestedMsg = nested.getMessage();
197 if (nestedMsg != null)
198 {
199 if (ourMsg != null)
200 {
201 msg.append(": ");
202 }
203 msg.append(nestedMsg);
204 }
205
206 }
207 return (msg.length() > 0 ? msg.toString() : null);
208 }
209
210 /***
211 * Prints the stack trace of this exception the the standar error
212 * stream.
213 */
214 public void printStackTrace()
215 {
216 synchronized(System.err)
217 {
218 printStackTrace(System.err);
219 }
220 }
221
222 /***
223 * Prints the stack trace of this exception to the specified print stream.
224 *
225 * @param out <code>PrintStream</code> to use for output.
226 */
227 public void printStackTrace(PrintStream out)
228 {
229 synchronized(out)
230 {
231 PrintWriter pw = new PrintWriter(out, false);
232 printStackTrace(pw);
233 // Flush the PrintWriter before it's GC'ed.
234 pw.flush();
235 }
236 }
237
238 /***
239 * Prints the stack trace of this exception to the specified print writer.
240 *
241 * @param out <code>PrintWriter</code> to use for output.
242 */
243 public void printStackTrace(PrintWriter out)
244 {
245 synchronized(out)
246 {
247 printStackTrace(out, 0);
248 }
249 }
250
251 /***
252 * Prints the stack trace of this exception skiping a specified number
253 * of stack frames.
254 *
255 * @param out <code>PrintWriter</code> to use for output.
256 * @param skip The numbere of stack frames to skip.
257 */
258 public void printStackTrace(PrintWriter out, int skip)
259 {
260 String[] st = captureStackTrace();
261 if(nested != null)
262 {
263 if(nested instanceof TurbineException)
264 {
265 ((TurbineException)nested).printStackTrace(out, st.length - 2);
266 }
267 else if(nested instanceof TurbineRuntimeException)
268 {
269 ((TurbineRuntimeException)nested).printStackTrace(out, st.length - 2);
270 }
271 else
272 {
273 String[] nst = captureStackTrace(nested);
274 for(int i = 0; i < nst.length - st.length + 2; i++)
275 {
276 out.println(nst[i]);
277 }
278 }
279 out.print("rethrown as ");
280 }
281 for(int i=0; i<st.length - skip; i++)
282 {
283 out.println(st[i]);
284 }
285 }
286
287 /***
288 * Captures the stack trace associated with this exception.
289 *
290 * @return an array of Strings describing stack frames.
291 */
292 private String[] captureStackTrace()
293 {
294 StringWriter sw = new StringWriter();
295 super.printStackTrace(new PrintWriter(sw, true));
296 return splitStackTrace(sw.getBuffer().toString());
297 }
298
299 /***
300 * Captures the stack trace associated with a <code>Throwable</code>
301 * object.
302 *
303 * @param t The <code>Throwable</code>.
304 * @return An array of strings describing each stack frame.
305 */
306 private String[] captureStackTrace(Throwable t)
307 {
308 StringWriter sw = new StringWriter();
309 t.printStackTrace(new PrintWriter(sw, true));
310 return splitStackTrace(sw.getBuffer().toString());
311 }
312
313 /***
314 * Splits the stack trace given as a newline separated string
315 * into an array of stack frames.
316 *
317 * @param stackTrace The stack trace.
318 * @return An array of strings describing each stack frame.
319 */
320 private String[] splitStackTrace(String stackTrace)
321 {
322 String linebreak = System.getProperty("line.separator");
323 StringTokenizer st = new StringTokenizer(stackTrace, linebreak);
324 LinkedList list = new LinkedList();
325 while(st.hasMoreTokens())
326 {
327 list.add(st.nextToken());
328 }
329 return (String [])list.toArray(new String[] {});
330 }
331 }
This page was automatically generated by Maven