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.PrintStream;
58 import java.io.PrintWriter;
59 import java.io.StringWriter;
60 import java.util.LinkedList;
61 import java.util.StringTokenizer;
62
63 /***
64 * The base class of all exceptions thrown by Turbine.
65 *
66 * It is intended to ease the debugging by carrying on the information
67 * about the exception which was caught and provoked throwing the
68 * current exception. Catching and rethrowing may occur multiple
69 * times, and provided that all exceptions except the first one
70 * are descendands of <code>TurbineException</code>, when the
71 * exception is finally printed out using any of the <code>
72 * printStackTrace()</code> methods, the stacktrace will contain
73 * the information about all exceptions thrown and caught on
74 * the way.
75 * <p> Running the following program
76 * <p><blockquote><pre>
77 * 1 import org.apache.turbine.util.TurbineException;
78 * 2
79 * 3 public class Test {
80 * 4 public static void main( String[] args ) {
81 * 5 try {
82 * 6 a();
83 * 7 } catch(Exception e) {
84 * 8 e.printStackTrace();
85 * 9 }
86 * 10 }
87 * 11
88 * 12 public static void a() throws Exception {
89 * 13 try {
90 * 14 b();
91 * 15 } catch(Exception e) {
92 * 16 throw new TurbineException("foo", e);
93 * 17 }
94 * 18 }
95 * 19
96 * 20 public static void b() throws Exception {
97 * 21 try {
98 * 22 c();
99 * 23 } catch(Exception e) {
100 * 24 throw new TurbineException("bar", e);
101 * 25 }
102 * 26 }
103 * 27
104 * 28 public static void c() throws Exception {
105 * 29 throw new Exception("baz");
106 * 30 }
107 * 31 }
108 * </pre></blockquote>
109 * <p>Yields the following stacktrace:
110 * <p><blockquote><pre>
111 * java.lang.Exception: baz: bar: foo
112 * at Test.c(Test.java:29)
113 * at Test.b(Test.java:22)
114 * rethrown as TurbineException: bar
115 * at Test.b(Test.java:24)
116 * at Test.a(Test.java:14)
117 * rethrown as TurbineException: foo
118 * at Test.a(Test.java:16)
119 * at Test.main(Test.java:6)
120 * </pre></blockquote><br>
121 *
122 * @author <a href="mailto:Rafal.Krzewski@e-point.pl">Rafal Krzewski</a>
123 */
124 public class TurbineException extends Exception
125 {
126 /***
127 * Holds the reference to the exception or error that caused
128 * this exception to be thrown.
129 */
130 private Throwable nested = null;
131
132 /***
133 * Constructs a new <code>TurbineException</code> without specified
134 * detail message.
135 */
136 public TurbineException()
137 {
138 super();
139 }
140
141 /***
142 * Constructs a new <code>TurbineException</code> with specified
143 * detail message.
144 *
145 * @param msg The error message.
146 */
147 public TurbineException(String msg)
148 {
149 super(msg);
150 }
151
152 /***
153 * Constructs a new <code>TurbineException</code> with specified
154 * nested <code>Throwable</code>.
155 *
156 * @param nested The exception or error that caused this exception
157 * to be thrown.
158 */
159 public TurbineException(Throwable nested)
160 {
161 super();
162 this.nested = nested;
163 }
164
165 /***
166 * Constructs a new <code>TurbineException</code> with specified
167 * detail message and nested <code>Throwable</code>.
168 *
169 * @param msg The error message.
170 * @param nested The exception or error that caused this exception
171 * to be thrown.
172 */
173 public TurbineException(String msg, Throwable nested)
174 {
175 super(msg);
176 this.nested = nested;
177 }
178
179 /***
180 * Returns the error message of this and any nested <code>Throwable</code>.
181 *
182 * @return The error message.
183 */
184 public String getMessage()
185 {
186 StringBuffer msg = new StringBuffer();
187 String ourMsg = super.getMessage();
188 if (ourMsg != null)
189 {
190 msg.append(ourMsg);
191 }
192 if (nested != null)
193 {
194 String nestedMsg = nested.getMessage();
195 if (nestedMsg != null)
196 {
197 if (ourMsg != null)
198 {
199 msg.append(": ");
200 }
201 msg.append(nestedMsg);
202 }
203
204 }
205 return (msg.length() > 0 ? msg.toString() : null);
206 }
207
208 /***
209 * Prints the stack trace of this exception the the standar error
210 * stream.
211 */
212 public void printStackTrace()
213 {
214 synchronized (System.err)
215 {
216 printStackTrace(System.err);
217 }
218 }
219
220 /***
221 * Prints the stack trace of this exception to the specified print stream.
222 *
223 * @param out <code>PrintStream</code> to use for output.
224 */
225 public void printStackTrace(PrintStream out)
226 {
227 synchronized (out)
228 {
229 PrintWriter pw = new PrintWriter(out, false);
230 printStackTrace(pw);
231 // Flush the PrintWriter before it's GC'ed.
232 pw.flush();
233 }
234 }
235
236 /***
237 * Prints the stack trace of this exception to the specified print writer.
238 *
239 * @param out <code>PrintWriter</code> to use for output.
240 */
241 public void printStackTrace(PrintWriter out)
242 {
243 synchronized (out)
244 {
245 printStackTrace(out, 0);
246 }
247 }
248
249 /***
250 * Prints the stack trace of this exception skiping a specified number
251 * of stack frames.
252 *
253 * @param out <code>PrintWriter</code> to use for output.
254 * @param skip The numbere of stack frames to skip.
255 */
256 public void printStackTrace(PrintWriter out, int skip)
257 {
258 String[] st = captureStackTrace();
259 if (nested != null)
260 {
261 if (nested instanceof TurbineException)
262 {
263 ((TurbineException)nested).printStackTrace(out, st.length - 2);
264 }
265 else if (nested instanceof TurbineRuntimeException)
266 {
267 ((TurbineRuntimeException)nested).printStackTrace(out, st.length - 2);
268 }
269 else
270 {
271 String[] nst = captureStackTrace(nested);
272 for(int i = 0; i < nst.length - st.length + 2; i++)
273 {
274 out.println(nst[i]);
275 }
276 }
277 out.print("rethrown as ");
278 }
279 for (int i = 0; i < st.length - skip; i++)
280 {
281 out.println(st[i]);
282 }
283 }
284
285 /***
286 * Captures the stack trace associated with this exception.
287 *
288 * @return an array of Strings describing stack frames.
289 */
290 private String[] captureStackTrace()
291 {
292 StringWriter sw = new StringWriter();
293 super.printStackTrace(new PrintWriter(sw, true));
294 return splitStackTrace(sw.getBuffer().toString());
295 }
296
297 /***
298 * Captures the stack trace associated with a <code>Throwable</code>
299 * object.
300 *
301 * @param t The <code>Throwable</code>.
302 * @return An array of strings describing each stack frame.
303 */
304 private String[] captureStackTrace(Throwable t)
305 {
306 StringWriter sw = new StringWriter();
307 t.printStackTrace(new PrintWriter(sw, true));
308 return splitStackTrace(sw.getBuffer().toString());
309 }
310
311 /***
312 * Splits the stack trace given as a newline separated string
313 * into an array of stack frames.
314 *
315 * @param stackTrace The stack trace.
316 * @return An array of strings describing each stack frame.
317 */
318 private String[] splitStackTrace(String stackTrace)
319 {
320 String linebreak = System.getProperty("line.separator");
321 StringTokenizer st = new StringTokenizer(stackTrace, linebreak);
322 LinkedList list = new LinkedList();
323 while (st.hasMoreTokens())
324 {
325 list.add(st.nextToken());
326 }
327 return (String []) list.toArray(new String[] {});
328 }
329 }
This page was automatically generated by Maven