001 /*
002 * Licensed to the Apache Software Foundation (ASF) under one
003 * or more contributor license agreements. See the NOTICE file
004 * distributed with this work for additional information
005 * regarding copyright ownership. The ASF licenses this file
006 * to you under the Apache License, Version 2.0 (the
007 * "License"); you may not use this file except in compliance
008 * with the License. You may obtain a copy of the License at
009 *
010 * http://www.apache.org/licenses/LICENSE-2.0
011 *
012 * Unless required by applicable law or agreed to in writing,
013 * software distributed under the License is distributed on an
014 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
015 * KIND, either express or implied. See the License for the
016 * specific language governing permissions and limitations
017 * under the License.
018 *
019 */
020 package org.apache.directory.shared.ldap.util;
021
022
023 import java.io.PrintStream;
024 import java.io.PrintWriter;
025
026
027 /**
028 * The base class of all exceptions which can contain other exceptions. It is
029 * intended to ease the debugging by carrying on the information about the
030 * exception which was caught and provoked throwing the current exception.
031 * Catching and rethrowing may occur multiple times, and provided that all
032 * exceptions except the first one are descendants of
033 * <code>NestedException</code>, when the exception is finally printed out
034 * using any of the <code>
035 * printStackTrace()</code> methods, the stack trace
036 * will contain the information about all exceptions thrown and caught on the
037 * way.
038 * <p>
039 * Running the following program
040 * <p>
041 * <blockquote>
042 *
043 * <pre>
044 * 1 import org.apache.commons.lang.exception.NestableException;
045 * 2
046 * 3 public class Test {
047 * 4 public static void main( String[] args ) {
048 * 5 try {
049 * 6 a();
050 * 7 } catch(Exception e) {
051 * 8 e.printStackTrace();
052 * 9 }
053 * 10 }
054 * 11
055 * 12 public static void a() throws Exception {
056 * 13 try {
057 * 14 b();
058 * 15 } catch(Exception e) {
059 * 16 throw new NestableException("foo", e);
060 * 17 }
061 * 18 }
062 * 19
063 * 20 public static void b() throws Exception {
064 * 21 try {
065 * 22 c();
066 * 23 } catch(Exception e) {
067 * 24 throw new NestableException("bar", e);
068 * 25 }
069 * 26 }
070 * 27
071 * 28 public static void c() throws Exception {
072 * 29 throw new Exception("baz");
073 * 30 }
074 * 31 }
075 * </pre>
076 *
077 * </blockquote>
078 * <p>
079 * Yields the following stack trace:
080 * <p>
081 * <blockquote>
082 *
083 * <pre>
084 * org.apache.commons.lang.exception.NestableException: foo
085 * at Test.a(Test.java:16)
086 * at Test.main(Test.java:6)
087 * Caused by: org.apache.commons.lang.exception.NestableException: bar
088 * at Test.b(Test.java:24)
089 * at Test.a(Test.java:14)
090 * ... 1 more
091 * Caused by: java.lang.Exception: baz
092 * at Test.c(Test.java:29)
093 * at Test.b(Test.java:22)
094 * ... 2 more
095 * </pre>
096 *
097 * </blockquote><br>
098 *
099 * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
100 */
101 public class NestableException extends Exception implements Nestable
102 {
103
104 static final long serialVersionUID = 3485795588970325053L;
105
106 /**
107 * The helper instance which contains much of the code which we delegate to.
108 */
109 protected NestableDelegate delegate = new NestableDelegate( this );
110
111 /**
112 * Holds the reference to the exception or error that caused this exception
113 * to be thrown.
114 */
115 private Throwable cause = null;
116
117
118 /**
119 * Constructs a new <code>NestableException</code> without specified
120 * detail message.
121 */
122 public NestableException()
123 {
124 super();
125 }
126
127
128 /**
129 * Constructs a new <code>NestableException</code> with specified detail
130 * message.
131 *
132 * @param msg
133 * The error message.
134 */
135 public NestableException(String msg)
136 {
137 super( msg );
138 }
139
140
141 /**
142 * Constructs a new <code>NestableException</code> with specified nested
143 * <code>Throwable</code>.
144 *
145 * @param cause
146 * the exception or error that caused this exception to be thrown
147 */
148 public NestableException(Throwable cause)
149 {
150 super();
151 this.cause = cause;
152 }
153
154
155 /**
156 * Constructs a new <code>NestableException</code> with specified detail
157 * message and nested <code>Throwable</code>.
158 *
159 * @param msg
160 * the error message
161 * @param cause
162 * the exception or error that caused this exception to be thrown
163 */
164 public NestableException(String msg, Throwable cause)
165 {
166 super( msg );
167 this.cause = cause;
168 }
169
170
171 public Throwable getCause()
172 {
173 return cause;
174 }
175
176
177 /**
178 * Returns the detail message string of this throwable. If it was created
179 * with a null message, returns the following: (cause==null ? null :
180 * cause.toString()).
181 */
182 public String getMessage()
183 {
184 if ( super.getMessage() != null )
185 {
186 return super.getMessage();
187 }
188 else if ( cause != null )
189 {
190 return cause.toString();
191 }
192 else
193 {
194 return null;
195 }
196 }
197
198
199 public String getMessage( int index )
200 {
201 if ( index == 0 )
202 {
203 return super.getMessage();
204 }
205 else
206 {
207 return delegate.getMessage( index );
208 }
209 }
210
211
212 public String[] getMessages()
213 {
214 return delegate.getMessages();
215 }
216
217
218 public Throwable getThrowable( int index )
219 {
220 return delegate.getThrowable( index );
221 }
222
223
224 public int getThrowableCount()
225 {
226 return delegate.getThrowableCount();
227 }
228
229
230 public Throwable[] getThrowables()
231 {
232 return delegate.getThrowables();
233 }
234
235
236 public int indexOfThrowable( Class type )
237 {
238 return delegate.indexOfThrowable( type, 0 );
239 }
240
241
242 public int indexOfThrowable( Class type, int fromIndex )
243 {
244 return delegate.indexOfThrowable( type, fromIndex );
245 }
246
247
248 public void printStackTrace()
249 {
250 delegate.printStackTrace();
251 }
252
253
254 public void printStackTrace( PrintStream out )
255 {
256 delegate.printStackTrace( out );
257 }
258
259
260 public void printStackTrace( PrintWriter out )
261 {
262 delegate.printStackTrace( out );
263 }
264
265
266 public final void printPartialStackTrace( PrintWriter out )
267 {
268 super.printStackTrace( out );
269 }
270
271 }