1 54 package org.hibernate.exception; 55 56 import org.hibernate.util.ArrayHelper; 57 58 import java.io.PrintStream ; 59 import java.io.PrintWriter ; 60 import java.io.StringWriter ; 61 import java.lang.reflect.Field ; 62 import java.lang.reflect.InvocationTargetException ; 63 import java.lang.reflect.Method ; 64 import java.sql.SQLException ; 65 import java.util.ArrayList ; 66 import java.util.LinkedList ; 67 import java.util.List ; 68 import java.util.StringTokenizer ; 69 70 82 public final class ExceptionUtils { 83 84 private static final String LINE_SEPARATOR = System.getProperty( "line.separator" ); 85 86 92 static final String WRAPPED_MARKER = " [wrapped] "; 93 94 97 private static final String [] CAUSE_METHOD_NAMES = { 98 "getCause", 99 "getNextException", 100 "getTargetException", 101 "getException", 102 "getSourceException", 103 "getRootCause", 104 "getCausedByException", 105 "getNested" 106 }; 107 108 111 private static final Method THROWABLE_CAUSE_METHOD; 112 113 static { 114 Method getCauseMethod; 115 try { 116 getCauseMethod = Throwable .class.getMethod( "getCause", null ); 117 } 118 catch ( Exception e ) { 119 getCauseMethod = null; 120 } 121 THROWABLE_CAUSE_METHOD = getCauseMethod; 122 } 123 124 private ExceptionUtils() { 125 } 126 127 136 143 144 174 public static Throwable getCause(Throwable throwable) { 175 return getCause( throwable, CAUSE_METHOD_NAMES ); 176 } 177 178 195 public static Throwable getCause(Throwable throwable, String [] methodNames) { 196 if ( throwable == null ) { 197 return null; 198 } 199 Throwable cause = getCauseUsingWellKnownTypes( throwable ); 200 if ( cause == null ) { 201 if ( methodNames == null ) { 202 methodNames = CAUSE_METHOD_NAMES; 203 } 204 for ( int i = 0; i < methodNames.length; i++ ) { 205 String methodName = methodNames[i]; 206 if ( methodName != null ) { 207 cause = getCauseUsingMethodName( throwable, methodName ); 208 if ( cause != null ) { 209 break; 210 } 211 } 212 } 213 214 if ( cause == null ) { 215 cause = getCauseUsingFieldName( throwable, "detail" ); 216 } 217 } 218 return cause; 219 } 220 221 232 public static Throwable getRootCause(Throwable throwable) { 233 Throwable cause = getCause( throwable ); 234 if ( cause != null ) { 235 throwable = cause; 236 while ( ( throwable = getCause( throwable ) ) != null ) { 237 cause = throwable; 238 } 239 } 240 return cause; 241 } 242 243 253 private static Throwable getCauseUsingWellKnownTypes(Throwable throwable) { 254 if ( throwable instanceof Nestable ) { 255 return ( ( Nestable ) throwable ).getCause(); 256 } 257 else if ( throwable instanceof SQLException ) { 258 return ( ( SQLException ) throwable ).getNextException(); 259 } 260 else if ( throwable instanceof InvocationTargetException ) { 261 return ( ( InvocationTargetException ) throwable ).getTargetException(); 262 } 263 else { 264 return null; 265 } 266 } 267 268 275 private static Throwable getCauseUsingMethodName(Throwable throwable, String methodName) { 276 Method method = null; 277 try { 278 method = throwable.getClass().getMethod( methodName, null ); 279 } 280 catch ( NoSuchMethodException ignored ) { 281 } 282 catch ( SecurityException ignored ) { 283 } 284 285 if ( method != null && Throwable .class.isAssignableFrom( method.getReturnType() ) ) { 286 try { 287 return ( Throwable ) method.invoke( throwable, ArrayHelper.EMPTY_OBJECT_ARRAY ); 288 } 289 catch ( IllegalAccessException ignored ) { 290 } 291 catch ( IllegalArgumentException ignored ) { 292 } 293 catch ( InvocationTargetException ignored ) { 294 } 295 } 296 return null; 297 } 298 299 306 private static Throwable getCauseUsingFieldName(Throwable throwable, String fieldName) { 307 Field field = null; 308 try { 309 field = throwable.getClass().getField( fieldName ); 310 } 311 catch ( NoSuchFieldException ignored ) { 312 } 313 catch ( SecurityException ignored ) { 314 } 315 316 if ( field != null && Throwable .class.isAssignableFrom( field.getType() ) ) { 317 try { 318 return ( Throwable ) field.get( throwable ); 319 } 320 catch ( IllegalAccessException ignored ) { 321 } 322 catch ( IllegalArgumentException ignored ) { 323 } 324 } 325 return null; 326 } 327 328 337 public static boolean isThrowableNested() { 338 return ( THROWABLE_CAUSE_METHOD != null ); 339 } 340 341 350 public static boolean isNestedThrowable(Throwable throwable) { 351 if ( throwable == null ) { 352 return false; 353 } 354 355 if ( throwable instanceof Nestable ) { 356 return true; 357 } 358 else if ( throwable instanceof SQLException ) { 359 return true; 360 } 361 else if ( throwable instanceof InvocationTargetException ) { 362 return true; 363 } 364 else if ( isThrowableNested() ) { 365 return true; 366 } 367 368 Class cls = throwable.getClass(); 369 for ( int i = 0, isize = CAUSE_METHOD_NAMES.length; i < isize; i++ ) { 370 try { 371 Method method = cls.getMethod( CAUSE_METHOD_NAMES[i], null ); 372 if ( method != null && Throwable .class.isAssignableFrom( method.getReturnType() ) ) { 373 return true; 374 } 375 } 376 catch ( NoSuchMethodException ignored ) { 377 } 378 catch ( SecurityException ignored ) { 379 } 380 } 381 382 try { 383 Field field = cls.getField( "detail" ); 384 if ( field != null ) { 385 return true; 386 } 387 } 388 catch ( NoSuchFieldException ignored ) { 389 } 390 catch ( SecurityException ignored ) { 391 } 392 393 return false; 394 } 395 396 408 public static int getThrowableCount(Throwable throwable) { 409 int count = 0; 410 while ( throwable != null ) { 411 count++; 412 throwable = ExceptionUtils.getCause( throwable ); 413 } 414 return count; 415 } 416 417 430 public static Throwable [] getThrowables(Throwable throwable) { 431 List list = new ArrayList (); 432 while ( throwable != null ) { 433 list.add( throwable ); 434 throwable = ExceptionUtils.getCause( throwable ); 435 } 436 return ( Throwable [] ) list.toArray( new Throwable [list.size()] ); 437 } 438 439 452 public static int indexOfThrowable(Throwable throwable, Class type) { 453 return indexOfThrowable( throwable, type, 0 ); 454 } 455 456 473 public static int indexOfThrowable(Throwable throwable, Class type, int fromIndex) { 474 if ( throwable == null ) { 475 return -1; 476 } 477 if ( fromIndex < 0 ) { 478 fromIndex = 0; 479 } 480 Throwable [] throwables = ExceptionUtils.getThrowables( throwable ); 481 if ( fromIndex >= throwables.length ) { 482 return -1; 483 } 484 for ( int i = fromIndex; i < throwables.length; i++ ) { 485 if ( throwables[i].getClass().equals( type ) ) { 486 return i; 487 } 488 } 489 return -1; 490 } 491 492 508 public static void printRootCauseStackTrace(Throwable throwable) { 509 printRootCauseStackTrace( throwable, System.err ); 510 } 511 512 528 public static void printRootCauseStackTrace(Throwable throwable, PrintStream stream) { 529 if ( throwable == null ) { 530 return; 531 } 532 if ( stream == null ) { 533 throw new IllegalArgumentException ( "The PrintStream must not be null" ); 534 } 535 String trace[] = getRootCauseStackTrace( throwable ); 536 for ( int i = 0; i < trace.length; i++ ) { 537 stream.println( trace[i] ); 538 } 539 stream.flush(); 540 } 541 542 558 public static void printRootCauseStackTrace(Throwable throwable, PrintWriter writer) { 559 if ( throwable == null ) { 560 return; 561 } 562 if ( writer == null ) { 563 throw new IllegalArgumentException ( "The PrintWriter must not be null" ); 564 } 565 String trace[] = getRootCauseStackTrace( throwable ); 566 for ( int i = 0; i < trace.length; i++ ) { 567 writer.println( trace[i] ); 568 } 569 writer.flush(); 570 } 571 572 581 public static String [] getRootCauseStackTrace(Throwable throwable) { 582 if ( throwable == null ) { 583 return ArrayHelper.EMPTY_STRING_ARRAY; 584 } 585 Throwable throwables[] = getThrowables( throwable ); 586 int count = throwables.length; 587 ArrayList frames = new ArrayList (); 588 List nextTrace = getStackFrameList( throwables[count - 1] ); 589 for ( int i = count; --i >= 0; ) { 590 List trace = nextTrace; 591 if ( i != 0 ) { 592 nextTrace = getStackFrameList( throwables[i - 1] ); 593 removeCommonFrames( trace, nextTrace ); 594 } 595 if ( i == count - 1 ) { 596 frames.add( throwables[i].toString() ); 597 } 598 else { 599 frames.add( WRAPPED_MARKER + throwables[i].toString() ); 600 } 601 for ( int j = 0; j < trace.size(); j++ ) { 602 frames.add( trace.get( j ) ); 603 } 604 } 605 return ( String [] ) frames.toArray( new String [0] ); 606 } 607 608 616 public static void removeCommonFrames(List causeFrames, List wrapperFrames) { 617 if ( causeFrames == null || wrapperFrames == null ) { 618 throw new IllegalArgumentException ( "The List must not be null" ); 619 } 620 int causeFrameIndex = causeFrames.size() - 1; 621 int wrapperFrameIndex = wrapperFrames.size() - 1; 622 while ( causeFrameIndex >= 0 && wrapperFrameIndex >= 0 ) { 623 String causeFrame = ( String ) causeFrames.get( causeFrameIndex ); 626 String wrapperFrame = ( String ) wrapperFrames.get( wrapperFrameIndex ); 627 if ( causeFrame.equals( wrapperFrame ) ) { 628 causeFrames.remove( causeFrameIndex ); 629 } 630 causeFrameIndex--; 631 wrapperFrameIndex--; 632 } 633 } 634 635 643 public static String getStackTrace(Throwable throwable) { 644 StringWriter sw = new StringWriter (); 645 PrintWriter pw = new PrintWriter ( sw, true ); 646 throwable.printStackTrace( pw ); 647 return sw.getBuffer().toString(); 648 } 649 650 657 public static String getFullStackTrace(Throwable throwable) { 658 StringWriter sw = new StringWriter (); 659 PrintWriter pw = new PrintWriter ( sw, true ); 660 Throwable [] ts = getThrowables( throwable ); 661 for ( int i = 0; i < ts.length; i++ ) { 662 ts[i].printStackTrace( pw ); 663 if ( isNestedThrowable( ts[i] ) ) { 664 break; 665 } 666 } 667 return sw.getBuffer().toString(); 668 } 669 670 679 public static String [] getStackFrames(Throwable throwable) { 680 if ( throwable == null ) { 681 return ArrayHelper.EMPTY_STRING_ARRAY; 682 } 683 return getStackFrames( getStackTrace( throwable ) ); 684 } 685 686 692 static String [] getStackFrames(String stackTrace) { 693 String linebreak = LINE_SEPARATOR; 694 StringTokenizer frames = new StringTokenizer ( stackTrace, linebreak ); 695 List list = new LinkedList (); 696 while ( frames.hasMoreTokens() ) { 697 list.add( frames.nextToken() ); 698 } 699 return ( String [] ) list.toArray( new String [list.size()] ); 700 } 701 702 713 static List getStackFrameList(Throwable t) { 714 String stackTrace = getStackTrace( t ); 715 String linebreak = LINE_SEPARATOR; 716 StringTokenizer frames = new StringTokenizer ( stackTrace, linebreak ); 717 List list = new LinkedList (); 718 boolean traceStarted = false; 719 while ( frames.hasMoreTokens() ) { 720 String token = frames.nextToken(); 721 int at = token.indexOf( "at" ); 723 if ( at != -1 && token.substring( 0, at ).trim().length() == 0 ) { 724 traceStarted = true; 725 list.add( token ); 726 } 727 else if ( traceStarted ) { 728 break; 729 } 730 } 731 return list; 732 } 733 734 } 735 | Popular Tags |