View Javadoc

1   /*
2    * Copyright 2004-2005 the original author or authors.
3    * 
4    * Licensed under the Apache License, Version 2.0 (the "License"); you may not
5    * use this file except in compliance with the License. You may obtain a copy of
6    * the License at
7    * 
8    * http://www.apache.org/licenses/LICENSE-2.0
9    * 
10   * Unless required by applicable law or agreed to in writing, software
11   * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
12   * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
13   * License for the specific language governing permissions and limitations under
14   * the License.
15   */
16  package net.sf.composite.util;
17  
18  import java.io.PrintStream;
19  import java.io.PrintWriter;
20  
21  /***
22   * A nestable runtime exception. Some documentation was copied directly from the
23   * documentation for the <a
24   * href="http://java.sun.com/j2se/1.4.1/docs/api/java/lang/Throwable.html">Throwable
25   * </a> class in the Java SE 1.4 API.
26   * 
27   * @author Matthew Sgarlata
28   * @since November 6, 2004
29   */
30  public abstract class NestableRuntimeException extends RuntimeException {
31  	
32  	private static final String NESTING_MESSAGE = "Nested Exception: ";
33  
34  	private Throwable cause;
35  
36  	/***
37  	 * Constructs a new exception with null as its detail message. The cause is
38  	 * not initialized, and may subsequently be initialized by a call to
39  	 * {@link net.sf.composite.util.NestableRuntimeException#initCause(Throwable)}.
40  	 */
41  	public NestableRuntimeException() {
42  		super();
43  	}
44  
45  	/***
46  	 * Constructs a new exception with the specified detail message. The cause
47  	 * is not initialized, and may subsequently be initialized by a call to
48  	 * {@link NestableRuntimeException#initCause(Throwable)}.
49  	 * 
50  	 * @param message
51  	 *            the detail message. The detail message is saved for later
52  	 *            retrieval by the {@link NestableRuntimeException#getCause()}
53  	 *            method.
54  	 */
55  	public NestableRuntimeException(String message) {
56  		super(message);
57  	}
58  
59  	/***
60  	 * Constructs a new exception with the specified detail message and cause.
61  	 * <br>
62  	 * <br>
63  	 * Note that the detail message associated with cause is not automatically
64  	 * incorporated in this exception's detail message.
65  	 * 
66  	 * @param message
67  	 *            the detail message (which is saved for later retrieval by the
68  	 *            {@link java.lang.Throwable#getMessage()}method).
69  	 * @param cause
70  	 *            the cause (which is saved for later retrieval by the
71  	 *            {@link NestableRuntimeException#getCause()}method). (A
72  	 *            <code>null</code> value is permitted, and indicates that the
73  	 *            cause is nonexistent or unknown.)
74  	 */
75  	public NestableRuntimeException(String message, Throwable cause) {
76  		super(message);
77  		this.cause = cause;
78  	}
79  
80  	/***
81  	 * Constructs a new exception with the specified cause and a detail message
82  	 * of <code>(cause==null ? null : cause.toString())</code> (which
83  	 * typically contains the class and detail message of cause). This
84  	 * constructor is useful for exceptions that are little more than wrappers
85  	 * for other throwables (for example, <a
86  	 * href="http://java.sun.com/j2se/1.4.1/docs/api/java/security/PrivilegedActionException.html">PrivilegedActionException
87  	 * </a>).
88  	 * 
89  	 * @param cause
90  	 *            the cause (which is saved for later retrieval by the
91  	 *            {@link NestableRuntimeException#getCause()}method). (A
92  	 *            <code>null</code> value is permitted, and indicates that the
93  	 *            cause is nonexistent or unknown.)
94  	 */
95  	public NestableRuntimeException(Throwable cause) {
96  		super();
97  		this.cause = cause;
98  	}
99  
100 	/***
101 	 * Initializes the cause of this throwable to the specified value. (The
102 	 * cause is the throwable that caused this throwable to get thrown.) <br>
103 	 * <br>
104 	 * This method can be called at most once. It is generally called from
105 	 * within the constructor, or immediately after creating the throwable. If
106 	 * this throwable was created with Throwable(Throwable) or
107 	 * Throwable(String,Throwable), this method cannot be called even once.
108 	 * 
109 	 * @param cause
110 	 *            the cause (which is saved for later retrieval by the
111 	 *            {@link NestableRuntimeException#getCause()}method). (A
112 	 *            <code>null</code> value is permitted, and indicates that the
113 	 *            cause is nonexistent or unknown.)
114 	 * @returns a reference to this Throwable instance.
115 	 */
116 	public void setCause(Throwable cause) {
117 		this.cause = cause;
118 	}
119 
120 	public Throwable getCause() {
121 		return this.cause;
122 	}
123 
124 	public void getMessage(StringBuffer sb) {
125 		sb.append(super.getMessage());
126 		sb.append("\n");
127 		if (cause != null) {
128 			sb.append(NESTING_MESSAGE);
129 			if (cause instanceof NestableRuntimeException) {
130 				NestableRuntimeException chainedCause = (NestableRuntimeException) cause;
131 				chainedCause.getMessage(sb);
132 			} else {
133 				sb.append(cause.getMessage());
134 			}
135 		}
136 	}
137 	
138 	public void printStackTrace() {
139 		printStackTrace(System.err);
140 	}
141 	
142 	/***
143 	 * @see java.lang.Throwable#printStackTrace(java.io.PrintStream)
144 	 */
145 	public void printStackTrace(PrintStream out) {
146 		super.printStackTrace(out);
147 
148 		if (!ClassUtils.isJdk14OrHigherPresent()) {
149 			Throwable t = getCause();
150 			if (t!=null) {
151 				out.println(NESTING_MESSAGE);
152 				t.printStackTrace(out);
153 			}
154 		}
155 	}
156 
157 	/***
158 	 * @see java.lang.Throwable#printStackTrace(java.io.PrintWriter)
159 	 */
160 	public void printStackTrace(PrintWriter out) {
161 		super.printStackTrace(out);
162 
163 		if (!ClassUtils.isJdk14OrHigherPresent()) {
164 			Throwable t = getCause();
165 			if (t!=null) {
166 				out.println(NESTING_MESSAGE);
167 				t.printStackTrace(out);
168 			}
169 		}
170 	}	
171 
172 }