1 54 package org.hibernate.exception; 55 56 import java.io.PrintStream ; 57 import java.io.PrintWriter ; 58 import java.io.Serializable ; 59 import java.io.StringWriter ; 60 import java.util.ArrayList ; 61 import java.util.Arrays ; 62 import java.util.Collections ; 63 import java.util.Iterator ; 64 import java.util.List ; 65 66 84 public class NestableDelegate implements Serializable { 85 86 89 private static final String MUST_BE_THROWABLE = 90 "The Nestable implementation passed to the NestableDelegate(Nestable) " 91 + "constructor must extend java.lang.Throwable"; 92 93 98 private Throwable nestable = null; 99 100 106 private static boolean topDown = true; 107 108 114 private static boolean trimStackFrames = true; 115 116 124 public NestableDelegate(Nestable nestable) { 125 if ( nestable instanceof Throwable ) { 126 this.nestable = ( Throwable ) nestable; 127 } 128 else { 129 throw new IllegalArgumentException ( MUST_BE_THROWABLE ); 130 } 131 } 132 133 146 public String getMessage(int index) { 147 Throwable t = this.getThrowable( index ); 148 if ( Nestable.class.isInstance( t ) ) { 149 return ( ( Nestable ) t ).getMessage( 0 ); 150 } 151 else { 152 return t.getMessage(); 153 } 154 } 155 156 169 public String getMessage(String baseMsg) { 170 StringBuffer msg = new StringBuffer (); 171 if ( baseMsg != null ) { 172 msg.append( baseMsg ); 173 } 174 175 Throwable nestedCause = ExceptionUtils.getCause( this.nestable ); 176 if ( nestedCause != null ) { 177 String causeMsg = nestedCause.getMessage(); 178 if ( causeMsg != null ) { 179 if ( baseMsg != null ) { 180 msg.append( ": " ); 181 } 182 msg.append( causeMsg ); 183 } 184 185 } 186 return ( msg.length() > 0 ? msg.toString() : null ); 187 } 188 189 200 public String [] getMessages() { 201 Throwable [] throwables = this.getThrowables(); 202 String [] msgs = new String [throwables.length]; 203 for ( int i = 0; i < throwables.length; i++ ) { 204 msgs[i] = Nestable.class.isInstance( throwables[i] ) ? 205 ( ( Nestable ) throwables[i] ).getMessage( 0 ) : 206 throwables[i].getMessage(); 207 } 208 return msgs; 209 } 210 211 223 public Throwable getThrowable(int index) { 224 if ( index == 0 ) { 225 return this.nestable; 226 } 227 Throwable [] throwables = this.getThrowables(); 228 return throwables[index]; 229 } 230 231 238 public int getThrowableCount() { 239 return ExceptionUtils.getThrowableCount( this.nestable ); 240 } 241 242 250 public Throwable [] getThrowables() { 251 return ExceptionUtils.getThrowables( this.nestable ); 252 } 253 254 270 public int indexOfThrowable(Class type, int fromIndex) { 271 if ( fromIndex < 0 ) { 272 throw new IndexOutOfBoundsException ( "The start index was out of bounds: " + fromIndex ); 273 } 274 Throwable [] throwables = ExceptionUtils.getThrowables( this.nestable ); 275 if ( fromIndex >= throwables.length ) { 276 throw new IndexOutOfBoundsException ( "The start index was out of bounds: " 277 + fromIndex + " >= " + throwables.length ); 278 } 279 for ( int i = fromIndex; i < throwables.length; i++ ) { 280 if ( throwables[i].getClass().equals( type ) ) { 281 return i; 282 } 283 } 284 return -1; 285 } 286 287 291 public void printStackTrace() { 292 printStackTrace( System.err ); 293 } 294 295 302 public void printStackTrace(PrintStream out) { 303 synchronized ( out ) { 304 PrintWriter pw = new PrintWriter ( out, false ); 305 printStackTrace( pw ); 306 pw.flush(); 308 } 309 } 310 311 322 public void printStackTrace(PrintWriter out) { 323 Throwable throwable = this.nestable; 324 if ( ExceptionUtils.isThrowableNested() ) { 326 if ( throwable instanceof Nestable ) { 327 ( ( Nestable ) throwable ).printPartialStackTrace( out ); 328 } 329 else { 330 throwable.printStackTrace( out ); 331 } 332 return; 333 } 334 335 List stacks = new ArrayList (); 337 while ( throwable != null ) { 338 String [] st = getStackFrames( throwable ); 339 stacks.add( st ); 340 throwable = ExceptionUtils.getCause( throwable ); 341 } 342 343 String separatorLine = "Caused by: "; 345 if ( !topDown ) { 346 separatorLine = "Rethrown as: "; 347 Collections.reverse( stacks ); 348 } 349 350 if ( trimStackFrames ) trimStackFrames( stacks ); 352 353 synchronized ( out ) { 354 for ( Iterator iter = stacks.iterator(); iter.hasNext(); ) { 355 String [] st = ( String [] ) iter.next(); 356 for ( int i = 0, len = st.length; i < len; i++ ) { 357 out.println( st[i] ); 358 } 359 if ( iter.hasNext() ) out.print( separatorLine ); 360 } 361 } 362 } 363 364 373 protected String [] getStackFrames(Throwable t) { 374 StringWriter sw = new StringWriter (); 375 PrintWriter pw = new PrintWriter ( sw, true ); 376 377 if ( t instanceof Nestable ) { 379 ( ( Nestable ) t ).printPartialStackTrace( pw ); 380 } 381 else { 382 t.printStackTrace( pw ); 383 } 384 return ExceptionUtils.getStackFrames( sw.getBuffer().toString() ); 385 } 386 387 395 protected void trimStackFrames(List stacks) { 396 for ( int size = stacks.size(), i = size - 1; i > 0; i-- ) { 397 String [] curr = ( String [] ) stacks.get( i ); 398 String [] next = ( String [] ) stacks.get( i - 1 ); 399 400 List currList = new ArrayList ( Arrays.asList( curr ) ); 401 List nextList = new ArrayList ( Arrays.asList( next ) ); 402 ExceptionUtils.removeCommonFrames( currList, nextList ); 403 404 int trimmed = curr.length - currList.size(); 405 if ( trimmed > 0 ) { 406 currList.add( "\t... " + trimmed + " more" ); 407 stacks.set( i, 408 currList.toArray( new String [currList.size()] ) ); 409 } 410 } 411 } 412 } 413 | Popular Tags |