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 }