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.morph.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 class NestableRuntimeException extends RuntimeException {
31  	private static final String NESTING_MESSAGE = "Nested Exception: ";
32  
33  	private Throwable cause;
34  
35  	/**
36  	 * Constructs a new exception with null as its detail message. The cause is
37  	 * not initialized, and may subsequently be initialized by a call to
38  	 * {@link net.sf.morph.util.NestableRuntimeException#initCause(Throwable)}.
39  	 */
40  	public NestableRuntimeException() {
41  		super();
42  	}
43  
44  	/**
45  	 * Constructs a new exception with the specified detail message. The cause
46  	 * is not initialized, and may subsequently be initialized by a call to
47  	 * {@link NestableRuntimeException#initCause(Throwable)}.
48  	 * 
49  	 * @param message
50  	 *            the detail message. The detail message is saved for later
51  	 *            retrieval by the {@link NestableRuntimeException#getCause()}
52  	 *            method.
53  	 */
54  	public NestableRuntimeException(String message) {
55  		super(message);
56  	}
57  
58  	/**
59  	 * Constructs a new exception with the specified detail message and cause.
60  	 * <br>
61  	 * <br>
62  	 * Note that the detail message associated with cause is not automatically
63  	 * incorporated in this exception's detail message.
64  	 * 
65  	 * @param message
66  	 *            the detail message (which is saved for later retrieval by the
67  	 *            {@link java.lang.Throwable#getMessage()}method).
68  	 * @param cause
69  	 *            the cause (which is saved for later retrieval by the
70  	 *            {@link NestableRuntimeException#getCause()}method). (A
71  	 *            <code>null</code> value is permitted, and indicates that the
72  	 *            cause is nonexistent or unknown.)
73  	 */
74  	public NestableRuntimeException(String message, Throwable cause) {
75  		super(message);
76  		this.cause = cause;
77  	}
78  
79  	/**
80  	 * Constructs a new exception with the specified cause and a detail message
81  	 * of <code>(cause==null ? null : cause.toString())</code> (which
82  	 * typically contains the class and detail message of cause). This
83  	 * constructor is useful for exceptions that are little more than wrappers
84  	 * for other throwables (for example, <a
85  	 * href="http://java.sun.com/j2se/1.4.1/docs/api/java/security/PrivilegedActionException.html">PrivilegedActionException
86  	 * </a>).
87  	 * 
88  	 * @param cause
89  	 *            the cause (which is saved for later retrieval by the
90  	 *            {@link NestableRuntimeException#getCause()}method). (A
91  	 *            <code>null</code> value is permitted, and indicates that the
92  	 *            cause is nonexistent or unknown.)
93  	 */
94  	public NestableRuntimeException(Throwable cause) {
95  		super();
96  		this.cause = cause;
97  	}
98  
99  	/**
100 	 * Initializes the cause of this throwable to the specified value. (The
101 	 * cause is the throwable that caused this throwable to get thrown.) <br>
102 	 * <br>
103 	 * This method can be called at most once. It is generally called from
104 	 * within the constructor, or immediately after creating the throwable. If
105 	 * this throwable was created with Throwable(Throwable) or
106 	 * Throwable(String,Throwable), this method cannot be called even once.
107 	 * 
108 	 * @param cause
109 	 *            the cause (which is saved for later retrieval by the
110 	 *            {@link NestableRuntimeException#getCause()}method). (A
111 	 *            <code>null</code> value is permitted, and indicates that the
112 	 *            cause is nonexistent or unknown.)
113 	 * @returns a reference to this Throwable instance.
114 	 */
115 	public void setCause(Throwable cause) {
116 		this.cause = cause;
117 	}
118 
119 	public Throwable getCause() {
120 		return this.cause;
121 	}
122 
123 	public void getMessage(StringBuffer sb) {
124 		sb.append(super.getMessage());
125 		sb.append("\n");
126 		if (cause != null) {
127 			sb.append(NESTING_MESSAGE);
128 			if (cause instanceof NestableRuntimeException) {
129 				NestableRuntimeException chainedCause = (NestableRuntimeException) cause;
130 				chainedCause.getMessage(sb);
131 			} else {
132 				sb.append(cause.getMessage());
133 			}
134 		}
135 	}
136 	
137 	public void printStackTrace() {
138 		printStackTrace(System.err);
139 	}
140 	
141 	/**
142 	 * @see java.lang.Throwable#printStackTrace(java.io.PrintStream)
143 	 */
144 	public void printStackTrace(PrintStream out) {
145 		super.printStackTrace(out);
146 
147 		if (!ClassUtils.isJdk14OrHigherPresent()) {
148 			Throwable t = getCause();
149 			if (t!=null) {
150 				out.println(NESTING_MESSAGE);
151 				t.printStackTrace(out);
152 			}
153 		}
154 	}
155 
156 	/**
157 	 * @see java.lang.Throwable#printStackTrace(java.io.PrintWriter)
158 	 */
159 	public void printStackTrace(PrintWriter out) {
160 		super.printStackTrace(out);
161 
162 		if (!ClassUtils.isJdk14OrHigherPresent()) {
163 			Throwable t = getCause();
164 			if (t!=null) {
165 				out.println(NESTING_MESSAGE);
166 				t.printStackTrace(out);
167 			}
168 		}
169 	}	
170 
171 }