1 19 20 package soot.toolkits.exceptions; 21 22 import soot.*; 23 import soot.jimple.*; 24 import soot.util.*; 25 import java.util.*; 26 27 81 82 public final class ThrowableSet { 83 84 private static final boolean INSTRUMENTING = true; 85 86 92 public static class Manager { 93 94 98 private final Map sizeToSets = new HashMap(); 99 100 103 public final ThrowableSet EMPTY; 104 105 109 final ThrowableSet ALL_THROWABLES; 110 111 116 final ThrowableSet VM_ERRORS; 117 118 124 final ThrowableSet RESOLVE_CLASS_ERRORS; 125 126 131 final ThrowableSet RESOLVE_FIELD_ERRORS; 132 133 138 final ThrowableSet RESOLVE_METHOD_ERRORS; 139 140 147 final ThrowableSet INITIALIZATION_ERRORS; 148 149 final RefType RUNTIME_EXCEPTION; 150 final RefType ARITHMETIC_EXCEPTION; 151 final RefType ARRAY_STORE_EXCEPTION; 152 final RefType CLASS_CAST_EXCEPTION; 153 final RefType ILLEGAL_MONITOR_STATE_EXCEPTION; 154 final RefType INDEX_OUT_OF_BOUNDS_EXCEPTION; 155 final RefType ARRAY_INDEX_OUT_OF_BOUNDS_EXCEPTION; 156 final RefType NEGATIVE_ARRAY_SIZE_EXCEPTION; 157 final RefType NULL_POINTER_EXCEPTION; 158 final RefType INSTANTIATION_ERROR; 159 160 private int registeredSets = 0; 162 private int addsOfRefType = 0; 163 private int addsOfAnySubType = 0; 164 private int addsOfSet = 0; 165 private int addsInclusionFromMap = 0; 166 private int addsInclusionFromMemo = 0; 167 private int addsInclusionFromSearch = 0; 168 private int addsInclusionInterrupted = 0; 169 private int addsExclusionWithSearch = 0; 170 private int addsExclusionWithoutSearch = 0; 171 private int removesOfAnySubType = 0; 172 private int removesFromMap = 0; 173 private int removesFromMemo = 0; 174 private int removesFromSearch = 0; 175 private int registrationCalls = 0; 176 private int catchableAsQueries = 0; 177 private int catchableAsFromMap = 0; 178 private int catchableAsFromSearch = 0; 179 180 187 public Manager( Singletons.Global g ) { 188 190 RUNTIME_EXCEPTION = 192 Scene.v().getRefType("java.lang.RuntimeException"); 193 ARITHMETIC_EXCEPTION = 194 Scene.v().getRefType("java.lang.ArithmeticException"); 195 ARRAY_STORE_EXCEPTION = 196 Scene.v().getRefType("java.lang.ArrayStoreException"); 197 CLASS_CAST_EXCEPTION = 198 Scene.v().getRefType("java.lang.ClassCastException"); 199 ILLEGAL_MONITOR_STATE_EXCEPTION = 200 Scene.v().getRefType("java.lang.IllegalMonitorStateException"); 201 INDEX_OUT_OF_BOUNDS_EXCEPTION = 202 Scene.v().getRefType("java.lang.IndexOutOfBoundsException"); 203 ARRAY_INDEX_OUT_OF_BOUNDS_EXCEPTION = 204 Scene.v().getRefType("java.lang.ArrayIndexOutOfBoundsException"); 205 NEGATIVE_ARRAY_SIZE_EXCEPTION = 206 Scene.v().getRefType("java.lang.NegativeArraySizeException"); 207 NULL_POINTER_EXCEPTION = 208 Scene.v().getRefType("java.lang.NullPointerException"); 209 210 INSTANTIATION_ERROR = 211 Scene.v().getRefType("java.lang.InstantiationError"); 212 213 EMPTY = registerSetIfNew(null, null); 214 215 Set allThrowablesSet = new HashSet(); 216 allThrowablesSet.add(AnySubType.v(Scene.v().getRefType("java.lang.Throwable"))); 217 ALL_THROWABLES = registerSetIfNew(allThrowablesSet, null); 218 219 Set vmErrorSet = new HashSet(); 220 vmErrorSet.add(Scene.v().getRefType("java.lang.InternalError")); 221 vmErrorSet.add(Scene.v().getRefType("java.lang.OutOfMemoryError")); 222 vmErrorSet.add(Scene.v().getRefType("java.lang.StackOverflowError")); 223 vmErrorSet.add(Scene.v().getRefType("java.lang.UnknownError")); 224 225 vmErrorSet.add(Scene.v().getRefType("java.lang.ThreadDeath")); 229 230 VM_ERRORS = registerSetIfNew(vmErrorSet, null); 231 232 Set resolveClassErrorSet = new HashSet(); 233 resolveClassErrorSet.add(Scene.v().getRefType("java.lang.ClassCircularityError")); 234 resolveClassErrorSet.add(AnySubType.v(Scene.v().getRefType("java.lang.ClassFormatError"))); 240 resolveClassErrorSet.add(Scene.v().getRefType("java.lang.IllegalAccessError")); 241 resolveClassErrorSet.add(Scene.v().getRefType("java.lang.IncompatibleClassChangeError")); 242 resolveClassErrorSet.add(Scene.v().getRefType("java.lang.LinkageError")); 243 resolveClassErrorSet.add(Scene.v().getRefType("java.lang.NoClassDefFoundError")); 244 resolveClassErrorSet.add(Scene.v().getRefType("java.lang.VerifyError")); 245 RESOLVE_CLASS_ERRORS = registerSetIfNew(resolveClassErrorSet, null); 246 247 Set resolveFieldErrorSet = new HashSet(resolveClassErrorSet); 248 resolveFieldErrorSet.add(Scene.v().getRefType("java.lang.NoSuchFieldError")); 249 RESOLVE_FIELD_ERRORS = registerSetIfNew(resolveFieldErrorSet, null); 250 251 Set resolveMethodErrorSet = new HashSet(resolveClassErrorSet); 252 resolveMethodErrorSet.add(Scene.v().getRefType("java.lang.AbstractMethodError")); 253 resolveMethodErrorSet.add(Scene.v().getRefType("java.lang.NoSuchMethodError")); 254 resolveMethodErrorSet.add(Scene.v().getRefType("java.lang.UnsatisfiedLinkError")); 255 RESOLVE_METHOD_ERRORS = registerSetIfNew(resolveMethodErrorSet, null); 256 257 Set initializationErrorSet = new HashSet(); 263 initializationErrorSet.add(AnySubType.v(Scene.v().getRefType("java.lang.Error"))); 264 INITIALIZATION_ERRORS = registerSetIfNew(initializationErrorSet, null); 265 } 266 267 268 273 public static Manager v() { 274 return G.v().soot_toolkits_exceptions_ThrowableSet_Manager(); 275 } 276 277 278 298 private ThrowableSet registerSetIfNew(Set include, Set exclude) { 299 if (INSTRUMENTING) { 300 registrationCalls++; 301 } 302 if (include == null) { 303 include = Collections.EMPTY_SET; 304 } 305 if (exclude == null) { 306 exclude = Collections.EMPTY_SET; 307 } 308 int size = include.size() + exclude.size(); 309 Integer sizeKey = new Integer (size); 310 311 List sizeList = (List) sizeToSets.get(sizeKey); 312 if (sizeList == null) { 313 sizeList = new LinkedList(); 314 sizeToSets.put(sizeKey, sizeList); 315 } 316 for (Iterator i = sizeList.iterator(); i.hasNext() ;) { 317 ThrowableSet set = (ThrowableSet) i.next(); 318 if (set.exceptionsIncluded.equals(include) 319 && set.exceptionsExcluded.equals(exclude)) { 320 return set; 321 } 322 } 323 if (INSTRUMENTING) { 324 registeredSets++; 325 } 326 ThrowableSet result = new ThrowableSet(include, exclude); 327 sizeList.add(result); 328 return result; 329 } 330 331 332 339 public String reportInstrumentation() { 340 int setCount = 0; 341 for (Iterator it = sizeToSets.values().iterator(); it.hasNext(); ) { 342 List sizeList = (List) it.next(); 343 setCount += sizeList.size(); 344 } 345 if (setCount != registeredSets) { 346 throw new IllegalStateException ("ThrowableSet.reportInstrumentation() assertion failure: registeredSets != list count"); 347 } 348 StringBuffer buf = new StringBuffer ("registeredSets: ") 349 .append(setCount) 350 .append("\naddsOfRefType: ") 351 .append(addsOfRefType) 352 .append("\naddsOfAnySubType: ") 353 .append(addsOfAnySubType) 354 .append("\naddsOfSet: ") 355 .append(addsOfSet) 356 .append("\naddsInclusionFromMap: ") 357 .append(addsInclusionFromMap) 358 .append("\naddsInclusionFromMemo: ") 359 .append(addsInclusionFromMemo) 360 .append("\naddsInclusionFromSearch: ") 361 .append(addsInclusionFromSearch) 362 .append("\naddsInclusionInterrupted: ") 363 .append(addsInclusionInterrupted) 364 .append("\naddsExclusionWithoutSearch: ") 365 .append(addsExclusionWithoutSearch) 366 .append("\naddsExclusionWithSearch: ") 367 .append(addsExclusionWithSearch) 368 .append("\nremovesOfAnySubType: ") 369 .append(removesOfAnySubType) 370 .append("\nremovesFromMap: ") 371 .append(removesFromMap) 372 .append("\nremovesFromMemo: ") 373 .append(removesFromMemo) 374 .append("\nremovesFromSearch: ") 375 .append(removesFromSearch) 376 .append("\nregistrationCalls: ") 377 .append(registrationCalls) 378 .append("\ncatchableAsQueries: ") 379 .append(catchableAsQueries) 380 .append("\ncatchableAsFromMap: ") 381 .append(catchableAsFromMap) 382 .append("\ncatchableAsFromSearch: ") 383 .append(catchableAsFromSearch) 384 .append('\n'); 385 return buf.toString(); 386 } 387 388 392 Map getSizeToSets() { 393 return Manager.v().sizeToSets; 394 } 395 } 396 397 398 public static class AlreadyHasExclusionsException extends IllegalStateException { 399 public AlreadyHasExclusionsException(String s) { 400 super(s); 401 } 402 } 403 404 405 408 private final Set exceptionsIncluded; 409 410 419 private final Set exceptionsExcluded; 420 421 432 private Map memoizedAdds; 433 434 private ThrowableSet getMemoizedAdds(Object key) { 435 if (memoizedAdds == null) { 436 memoizedAdds = new HashMap(); 437 } 438 return (ThrowableSet) memoizedAdds.get(key); 439 } 440 441 442 456 private ThrowableSet(Set include, Set exclude) { 457 exceptionsIncluded = Collections.unmodifiableSet(include); 458 exceptionsExcluded = Collections.unmodifiableSet(exclude); 459 } 465 466 467 503 public ThrowableSet add(RefType e) 504 throws ThrowableSet.AlreadyHasExclusionsException { 505 if (INSTRUMENTING) { 506 Manager.v().addsOfRefType++; 507 } 508 if (this.exceptionsIncluded.contains(e)) { 509 if (INSTRUMENTING) { 510 Manager.v().addsInclusionFromMap++; 511 Manager.v().addsExclusionWithoutSearch++; 512 } 513 return this; 514 } else { 515 ThrowableSet result = getMemoizedAdds(e); 516 if (result != null) { 517 if (INSTRUMENTING) { 518 Manager.v().addsInclusionFromMemo++; 519 Manager.v().addsExclusionWithoutSearch++; 520 } 521 return result; 522 } else { 523 if (INSTRUMENTING) { 524 Manager.v().addsInclusionFromSearch++; 525 if (exceptionsExcluded.size() != 0) { 526 Manager.v().addsExclusionWithSearch++; 527 } else { 528 Manager.v().addsExclusionWithoutSearch++; 529 } 530 } 531 FastHierarchy hierarchy = Scene.v().getOrMakeFastHierarchy(); 532 533 for (Iterator i = exceptionsExcluded.iterator(); i.hasNext(); ) { 534 RefType exclusionBase = ((AnySubType) i.next()).getBase(); 535 if (hierarchy.canStoreType(e, exclusionBase)) { 536 throw new AlreadyHasExclusionsException( 537 "ThrowableSet.add(RefType): adding" + e.toString() 538 + " to the set [ " + this.toString() 539 + "] where " + exclusionBase.toString() 540 + " is excluded."); 541 } 542 } 543 544 for (Iterator i = exceptionsIncluded.iterator(); i.hasNext() ; ) { 545 RefLikeType incumbent = (RefLikeType) i.next(); 546 if (incumbent instanceof AnySubType) { 547 RefType incumbentBase = ((AnySubType) incumbent).getBase(); 551 if (hierarchy.canStoreType(e, incumbentBase)) { 552 memoizedAdds.put(e, this); 553 return this; 554 } 555 } else if (! (incumbent instanceof RefType)) { 556 throw new IllegalStateException ("ThrowableSet.add(RefType): Set element " + 558 incumbent.toString() + 559 " is neither a RefType nor an AnySubType."); 560 } 561 } 562 Set resultSet = new HashSet(this.exceptionsIncluded); 563 resultSet.add(e); 564 result = Manager.v().registerSetIfNew(resultSet, 565 this.exceptionsExcluded); 566 memoizedAdds.put(e, result); 567 return result; 568 } 569 } 570 } 571 572 573 614 public ThrowableSet add(AnySubType e) 615 throws ThrowableSet.AlreadyHasExclusionsException { 616 if (INSTRUMENTING) { 617 Manager.v().addsOfAnySubType++; 618 } 619 620 ThrowableSet result = getMemoizedAdds(e); 621 if (result != null) { 622 if (INSTRUMENTING) { 623 Manager.v().addsInclusionFromMemo++; 624 Manager.v().addsExclusionWithoutSearch++; 625 } 626 return result; 627 } else { 628 FastHierarchy hierarchy = Scene.v().getOrMakeFastHierarchy(); 629 RefType newBase = e.getBase(); 630 631 if (INSTRUMENTING) { 632 if (exceptionsExcluded.size() != 0) { 633 Manager.v().addsExclusionWithSearch++; 634 } else { 635 Manager.v().addsExclusionWithoutSearch++; 636 } 637 } 638 for (Iterator i = exceptionsExcluded.iterator(); i.hasNext(); ) { 639 RefType exclusionBase = ((AnySubType) i.next()).getBase(); 640 if (hierarchy.canStoreType(newBase, exclusionBase) 641 || hierarchy.canStoreType(exclusionBase, newBase)) { 642 if (INSTRUMENTING) { 643 Manager.v().addsInclusionInterrupted++; 645 } 646 throw new AlreadyHasExclusionsException( 647 "ThrowableSet.add(" + e.toString() 648 + ") to the set [ " + this.toString() 649 + "] where " + exclusionBase.toString() 650 + " is excluded."); 651 } 652 } 653 654 if (this.exceptionsIncluded.contains(e)) { 655 if (INSTRUMENTING) { 656 Manager.v().addsInclusionFromMap++; 657 } 658 return this; 659 660 } else { 661 if (INSTRUMENTING) { 662 Manager.v().addsInclusionFromSearch++; 663 } 664 665 int changes = 0; 666 boolean addNewException = true; 667 Set resultSet = new HashSet(); 668 669 for (Iterator i = this.exceptionsIncluded.iterator(); i.hasNext() ; ) { 670 RefLikeType incumbent = (RefLikeType) i.next(); 671 if (incumbent instanceof RefType) { 672 if (hierarchy.canStoreType(incumbent, newBase)) { 673 changes++; 675 } else { 676 resultSet.add(incumbent); 677 } 678 } else if (incumbent instanceof AnySubType) { 679 RefType incumbentBase = ((AnySubType) incumbent).getBase(); 680 if (hierarchy.canStoreType(newBase, incumbentBase)) { 685 addNewException = false; 686 resultSet.add(incumbent); 687 } else if (hierarchy.canStoreType(incumbentBase, newBase)) { 688 changes++; 690 } else { 691 resultSet.add(incumbent); 692 } 693 } else { throw new IllegalStateException ("ThrowableSet.add(AnySubType): Set element " + 695 incumbent.toString() + 696 " is neither a RefType nor an AnySubType."); 697 } 698 } 699 if (addNewException) { 700 resultSet.add(e); 701 changes++; 702 } 703 if (changes > 0) { 704 result = Manager.v().registerSetIfNew(resultSet, 705 this.exceptionsExcluded); 706 } else { 707 result = this; 708 } 709 memoizedAdds.put(e, result); 710 return result; 711 } 712 } 713 } 714 715 716 731 public ThrowableSet add(ThrowableSet s) 732 throws ThrowableSet.AlreadyHasExclusionsException { 733 if (INSTRUMENTING) { 734 Manager.v().addsOfSet++; 735 } 736 if (exceptionsExcluded.size() > 0 || s.exceptionsExcluded.size() > 0) { 737 throw new AlreadyHasExclusionsException("ThrowableSet.Add(ThrowableSet): attempt to add to [" + this.toString() + "] after removals recorded."); 738 } 739 ThrowableSet result = getMemoizedAdds(s); 740 if (result == null) { 741 if (INSTRUMENTING) { 742 Manager.v().addsInclusionFromSearch++; 743 Manager.v().addsExclusionWithoutSearch++; 744 } 745 result = this.add(s.exceptionsIncluded); 746 memoizedAdds.put(s, result); 747 } else if (INSTRUMENTING) { 748 Manager.v().addsInclusionFromMemo++; 749 Manager.v().addsExclusionWithoutSearch++; 750 } 751 return result; 752 } 753 754 755 767 private ThrowableSet add(Set addedExceptions) { 768 Set resultSet = new HashSet(this.exceptionsIncluded); 769 int changes = 0; 770 FastHierarchy hierarchy = Scene.v().getOrMakeFastHierarchy(); 771 772 775 for (Iterator i = addedExceptions.iterator(); i.hasNext(); ) { 776 RefLikeType newType = (RefLikeType) i.next(); 777 if (! resultSet.contains(newType)) { 778 boolean addNewType = true; 779 if (newType instanceof RefType) { 780 for (Iterator j = resultSet.iterator(); j.hasNext(); ) { 781 RefLikeType incumbentType = (RefLikeType) j.next(); 782 if (incumbentType instanceof RefType) { 783 if (newType == incumbentType) { 784 throw new IllegalStateException ("ThrowableSet.add(Set): resultSet.contains() failed to screen duplicate RefType " 786 + newType); 787 } 788 } else if (incumbentType instanceof AnySubType) { 789 RefType incumbentBase = ((AnySubType) incumbentType).getBase(); 790 if (hierarchy.canStoreType(newType, incumbentBase)) { 791 addNewType = false; 793 } 794 } else { throw new IllegalStateException ("ThrowableSet.add(Set): incumbent Set element " 796 + incumbentType 797 + " is neither a RefType nor an AnySubType."); 798 } 799 } 800 } else if (newType instanceof AnySubType) { 801 RefType newBase = ((AnySubType) newType).getBase(); 802 for (Iterator j = resultSet.iterator(); j.hasNext(); ) { 803 RefLikeType incumbentType = (RefLikeType) j.next(); 804 if (incumbentType instanceof RefType) { 805 RefType incumbentBase = (RefType) incumbentType; 806 if (hierarchy.canStoreType(incumbentBase, newBase)) { 807 j.remove(); 808 changes++; 809 } 810 } else if (incumbentType instanceof AnySubType) { 811 RefType incumbentBase = ((AnySubType) incumbentType).getBase(); 812 if (newBase == incumbentBase) { 813 throw new IllegalStateException ("ThrowableSet.add(Set): resultSet.contains() failed to screen duplicate AnySubType " 815 + newBase); 816 } else if (hierarchy.canStoreType(incumbentBase, newBase)) { 817 j.remove(); 818 changes++; 819 } else if (hierarchy.canStoreType(newBase, incumbentBase)) { 820 addNewType = false; 822 } 823 } else { throw new IllegalStateException ("ThrowableSet.add(Set): old Set element " 825 + incumbentType 826 + " is neither a RefType nor an AnySubType."); 827 } 828 } 829 } else { throw new IllegalArgumentException ("ThrowableSet.add(Set): new Set element " 831 + newType 832 + " is neither a RefType nor an AnySubType."); 833 } 834 if (addNewType) { 835 changes++; 836 resultSet.add(newType); 837 } 838 } 839 } 840 841 ThrowableSet result = null; 842 if (changes > 0) { 843 result = Manager.v().registerSetIfNew(resultSet, 844 this.exceptionsExcluded); 845 } else { 846 result = this; 847 } 848 return result; 849 } 850 851 852 863 public boolean catchableAs(RefType catcher) { 864 if (INSTRUMENTING) { 865 Manager.v().catchableAsQueries++; 866 } 867 868 FastHierarchy h = Scene.v().getOrMakeFastHierarchy(); 869 870 if (exceptionsExcluded.size() > 0) { 871 if (INSTRUMENTING) { 872 Manager.v().catchableAsFromSearch++; 873 } 874 for (Iterator i = exceptionsExcluded.iterator(); i.hasNext(); ) { 875 AnySubType exclusion = (AnySubType) i.next(); 876 if (h.canStoreType(catcher, exclusion.getBase())) { 877 return false; 878 } 879 } 880 } 881 882 if (exceptionsIncluded.contains(catcher)) { 883 if (INSTRUMENTING) { 884 if (exceptionsExcluded.size() == 0) { 885 Manager.v().catchableAsFromMap++; 886 } else { 887 Manager.v().catchableAsFromSearch++; 888 } 889 } 890 return true; 891 } else { 892 if (INSTRUMENTING) { 893 if (exceptionsExcluded.size() == 0) { 894 Manager.v().catchableAsFromSearch++; 895 } 896 } 897 for (Iterator i = exceptionsIncluded.iterator(); i.hasNext(); ) { 898 RefLikeType thrownType = (RefLikeType) i.next(); 899 if (thrownType instanceof RefType) { 900 if (thrownType == catcher) { 901 throw new IllegalStateException ("ThrowableSet.catchableAs(RefType): exceptions.contains() failed to match contained RefType " 903 + catcher); 904 } else if (h.canStoreType(thrownType, catcher)) { 905 return true; 906 } 907 } else { 908 RefType thrownBase = ((AnySubType) thrownType).getBase(); 909 if (h.canStoreType(thrownBase, catcher) 912 || h.canStoreType(catcher, thrownBase)) { 913 return true; 914 } 915 } 916 } 917 return false; 918 } 919 } 920 921 922 935 public Pair whichCatchableAs(RefType catcher) { 936 if (INSTRUMENTING) { 937 Manager.v().removesOfAnySubType++; 938 } 939 940 FastHierarchy h = Scene.v().getOrMakeFastHierarchy(); 941 Set caughtIncluded = null; 942 Set caughtExcluded = null; 943 Set uncaughtIncluded = null; 944 Set uncaughtExcluded = null; 945 946 if (INSTRUMENTING) { 947 Manager.v().removesFromSearch++; 948 } 949 950 for (Iterator i = exceptionsExcluded.iterator(); i.hasNext(); ) { 951 AnySubType exclusion = (AnySubType) i.next(); 952 RefType exclusionBase = exclusion.getBase(); 953 if (h.canStoreType(catcher, exclusionBase)) { 954 return new Pair(ThrowableSet.Manager.v().EMPTY, this); 958 } else if (h.canStoreType(exclusionBase, catcher)) { 959 caughtExcluded = addExceptionToSet(exclusion, caughtExcluded); 964 } else { 965 uncaughtExcluded = addExceptionToSet(exclusion, uncaughtExcluded); 966 } 967 } 968 969 for (Iterator i = exceptionsIncluded.iterator(); i.hasNext(); ) { 970 RefLikeType inclusion = (RefLikeType) i.next(); 971 if (inclusion instanceof RefType) { 972 if (h.canStoreType(inclusion, catcher)) { 973 caughtIncluded = addExceptionToSet(inclusion, caughtIncluded); 974 } else { 975 uncaughtIncluded = addExceptionToSet(inclusion, uncaughtIncluded); 976 } 977 } else { 978 RefType base = ((AnySubType) inclusion).getBase(); 979 if (h.canStoreType(base, catcher)) { 980 caughtIncluded = 984 addExceptionToSet(inclusion, caughtIncluded); 985 } else if (h.canStoreType(catcher, base)) { 986 uncaughtIncluded 993 = addExceptionToSet(inclusion, uncaughtIncluded); 994 uncaughtExcluded 995 = addExceptionToSet(AnySubType.v(catcher), uncaughtExcluded); 996 caughtIncluded 997 = addExceptionToSet(AnySubType.v(catcher), caughtIncluded); 998 } else { 1002 uncaughtIncluded 1003 = addExceptionToSet(inclusion, uncaughtIncluded); 1004 } 1005 } 1006 } 1007 ThrowableSet caughtSet 1008 = Manager.v().registerSetIfNew(caughtIncluded, caughtExcluded); 1009 ThrowableSet uncaughtSet 1010 = Manager.v().registerSetIfNew(uncaughtIncluded, uncaughtExcluded); 1011 return new Pair(caughtSet, uncaughtSet); 1012 } 1013 1014 1015 1019 public static class Pair { 1020 private ThrowableSet caught; 1021 private ThrowableSet uncaught; 1022 1033 protected Pair(ThrowableSet caught, ThrowableSet uncaught) { 1034 this.caught = caught; 1035 this.uncaught = uncaught; 1036 } 1037 1038 1041 public ThrowableSet getCaught() { 1042 return caught; 1043 } 1044 1045 1048 public ThrowableSet getUncaught() { 1049 return uncaught; 1050 } 1051 1052 1065 public boolean equals(Object o) { 1066 if (o == this) { 1067 return true; 1068 } 1069 if (! (o instanceof Pair)) { 1070 return false; 1071 } 1072 Pair tsp = (Pair) o; 1073 if ( this.caught.equals(tsp.caught) 1074 && this.uncaught.equals(tsp.uncaught)) { 1075 return true; 1076 } 1077 return false; 1078 } 1079 1080 1081 public int hashCode() { 1082 int result = 31; 1083 result = 37 * result + caught.hashCode(); 1084 result = 37 * result + uncaught.hashCode(); 1085 return result; 1086 } 1087 } 1088 1089 1090 1103 private Set addExceptionToSet(RefLikeType e, Set set) { 1104 if (set == null) { 1105 set = new HashSet(); 1106 } 1107 set.add(e); 1108 return set; 1109 } 1110 1111 1112 1115 public String toString() { 1116 StringBuffer buffer = new StringBuffer (this.toBriefString()); 1117 buffer.append(":\n "); 1118 for (Iterator i = exceptionsIncluded.iterator(); i.hasNext(); ) { 1119 buffer.append('+'); 1120 Object o = i.next(); 1121 buffer.append(o == null ? "null" : o.toString()); 1122 } 1124 for (Iterator i = exceptionsExcluded.iterator(); i.hasNext(); ) { 1125 buffer.append('-'); 1126 buffer.append(i.next().toString()); 1127 } 1128 return buffer.toString(); 1129 } 1130 1131 1132 1136 public String toBriefString() { 1137 return super.toString(); 1138 } 1139 1140 1141 1153 private static Iterator sortedThrowableIterator(Collection coll) { 1154 if (coll.size() <= 1) { 1155 return coll.iterator(); 1156 } else { 1157 Object array[] = coll.toArray(); 1158 Arrays.sort(array, new ThrowableComparator()); 1159 return Arrays.asList(array).iterator(); 1160 } 1161 } 1162 1163 1164 1168 private static class ThrowableComparator implements java.util.Comparator { 1169 1170 private static RefType baseType(Object o) { 1171 if (o instanceof AnySubType) { 1172 return ((AnySubType) o).getBase(); 1173 } else { 1174 return (RefType) o; } 1176 } 1177 1178 public int compare(Object o1, Object o2) { 1179 RefType t1 = baseType(o1); 1180 RefType t2 = baseType(o2); 1181 if (t1.equals(t2)) { 1182 if (o1 instanceof AnySubType) { 1186 if (o2 instanceof AnySubType) { 1187 return 0; 1188 } else { 1189 return -1; 1190 } 1191 } else if (o2 instanceof AnySubType) { 1192 return 1; 1193 } else { 1194 return 0; 1195 } 1196 } else { 1197 return t1.toString().compareTo(t2.toString()); 1198 } 1199 } 1200 1201 public boolean equal(Object o1, Object o2) { 1202 return (o1.equals(o2)); 1203 } 1204 } 1205 1206 1207 1231 public String toAbbreviatedString() { 1232 return toAbbreviatedString(exceptionsIncluded, '+') 1233 + toAbbreviatedString(exceptionsExcluded, '-'); 1234 } 1235 1236 1237 1247 private String toAbbreviatedString(Set s, char connector) { 1248 final String JAVA_LANG = "java.lang."; 1249 final int JAVA_LANG_LENGTH = JAVA_LANG.length(); 1250 final String EXCEPTION = "Exception"; 1251 final int EXCEPTION_LENGTH = EXCEPTION.length(); 1252 1253 Collection vmErrorThrowables = ThrowableSet.Manager.v().VM_ERRORS.exceptionsIncluded; 1254 boolean containsAllVmErrors = s.containsAll(vmErrorThrowables); 1255 StringBuffer buf = new StringBuffer (); 1256 1257 if (containsAllVmErrors) { 1258 buf.append(connector); 1259 buf.append("vmErrors"); 1260 } 1261 1262 for (Iterator it = sortedThrowableIterator(s); it.hasNext(); ) { 1263 RefLikeType reflikeType = (RefLikeType) it.next(); 1264 RefType baseType = null; 1265 if (reflikeType instanceof RefType) { 1266 baseType = (RefType)reflikeType; 1267 if (vmErrorThrowables.contains(baseType) && containsAllVmErrors) { 1268 continue; } else { 1270 buf.append(connector); 1271 } 1272 } else if (reflikeType instanceof AnySubType) { 1273 buf.append(connector); 1274 buf.append('('); 1275 baseType = ((AnySubType)reflikeType).getBase(); 1276 } 1277 String typeName = baseType.toString(); 1278 if (typeName.startsWith(JAVA_LANG)) { 1279 typeName = typeName.substring(JAVA_LANG_LENGTH); 1280 } 1281 if (typeName.length() > EXCEPTION_LENGTH && 1282 typeName.endsWith(EXCEPTION)) { 1283 typeName = typeName.substring(0, typeName.length()-EXCEPTION_LENGTH); 1284 } 1285 buf.append(typeName); 1286 if (reflikeType instanceof AnySubType) { 1287 buf.append(')'); 1288 } 1289 } 1290 return buf.toString(); 1291 } 1292 1293 1294 1302 Collection typesIncluded() { 1303 return new AbstractCollection() { 1304 1305 public Iterator iterator() { 1306 return new Iterator() { 1307 private Iterator i = exceptionsIncluded.iterator(); 1308 1309 public boolean hasNext() { 1310 return i.hasNext(); 1311 } 1312 1313 public Object next() { 1314 return i.next(); 1315 } 1316 1317 public void remove() { 1318 throw new UnsupportedOperationException (); 1319 } 1320 }; 1321 } 1322 1323 public int size() { 1324 return exceptionsIncluded.size(); 1325 } 1326 }; 1327 } 1328 1329 1330 1338 Collection typesExcluded() { 1339 return new AbstractCollection() { 1340 1341 public Iterator iterator() { 1342 return new Iterator() { 1343 private Iterator i = exceptionsExcluded.iterator(); 1344 1345 public boolean hasNext() { 1346 return i.hasNext(); 1347 } 1348 1349 public Object next() { 1350 return i.next(); 1351 } 1352 1353 public void remove() { 1354 throw new UnsupportedOperationException (); 1355 } 1356 }; 1357 } 1358 1359 public int size() { 1360 return exceptionsExcluded.size(); 1361 } 1362 }; 1363 } 1364 1365 1366 1370 Map getMemoizedAdds() { 1371 if (memoizedAdds == null) { 1372 return Collections.EMPTY_MAP; 1373 } else { 1374 return Collections.unmodifiableMap(memoizedAdds); 1375 } 1376 } 1377} 1378 | Popular Tags |