1 21 package proguard.classfile.util; 22 23 import proguard.classfile.*; 24 25 import java.util.*; 26 27 33 public class ClassUtil 34 { 35 private static final String EMPTY_STRING = ""; 36 37 private static final InternalTypeEnumeration internalTypeEnumeration = new InternalTypeEnumeration(); 38 private static final ExternalTypeEnumeration externalTypeEnumeration = new ExternalTypeEnumeration(); 39 40 41 46 public static void checkMagicNumber(int magicNumber) throws UnsupportedOperationException 47 { 48 if (magicNumber != ClassConstants.MAGIC) 49 { 50 throw new UnsupportedOperationException ("Invalid magic number ["+Integer.toHexString(magicNumber)+"] in class"); 51 } 52 } 53 54 55 61 public static int internalClassVersion(int majorVersion, int minorVersion) 62 { 63 return (majorVersion << 16) | minorVersion; 64 } 65 66 67 72 public static int internalMajorClassVersion(int classVersion) 73 { 74 return classVersion >>> 16; 75 } 76 77 78 83 public static int internalMinorClassVersion(int classVersion) 84 { 85 return classVersion & 0xffff; 86 } 87 88 89 94 public static int internalClassVersion(String classVersion) 95 { 96 return 97 classVersion.equals(ClassConstants.EXTERNAL_CLASS_VERSION_1_0) || 98 classVersion.equals(ClassConstants.EXTERNAL_CLASS_VERSION_1_1) ? ClassConstants.INTERNAL_CLASS_VERSION_1_0 : 99 classVersion.equals(ClassConstants.EXTERNAL_CLASS_VERSION_1_2) ? ClassConstants.INTERNAL_CLASS_VERSION_1_2 : 100 classVersion.equals(ClassConstants.EXTERNAL_CLASS_VERSION_1_3) ? ClassConstants.INTERNAL_CLASS_VERSION_1_3 : 101 classVersion.equals(ClassConstants.EXTERNAL_CLASS_VERSION_1_4) ? ClassConstants.INTERNAL_CLASS_VERSION_1_4 : 102 classVersion.equals(ClassConstants.EXTERNAL_CLASS_VERSION_1_5_ALIAS) || 103 classVersion.equals(ClassConstants.EXTERNAL_CLASS_VERSION_1_5) ? ClassConstants.INTERNAL_CLASS_VERSION_1_5 : 104 classVersion.equals(ClassConstants.EXTERNAL_CLASS_VERSION_1_6_ALIAS) || 105 classVersion.equals(ClassConstants.EXTERNAL_CLASS_VERSION_1_6) ? ClassConstants.INTERNAL_CLASS_VERSION_1_6 : 106 0; 107 } 108 109 110 115 public static String externalClassVersion(int classVersion) 116 { 117 switch (classVersion) 118 { 119 case ClassConstants.INTERNAL_CLASS_VERSION_1_0: return ClassConstants.EXTERNAL_CLASS_VERSION_1_0; 120 case ClassConstants.INTERNAL_CLASS_VERSION_1_2: return ClassConstants.EXTERNAL_CLASS_VERSION_1_2; 121 case ClassConstants.INTERNAL_CLASS_VERSION_1_3: return ClassConstants.EXTERNAL_CLASS_VERSION_1_3; 122 case ClassConstants.INTERNAL_CLASS_VERSION_1_4: return ClassConstants.EXTERNAL_CLASS_VERSION_1_4; 123 case ClassConstants.INTERNAL_CLASS_VERSION_1_5: return ClassConstants.EXTERNAL_CLASS_VERSION_1_5; 124 case ClassConstants.INTERNAL_CLASS_VERSION_1_6: return ClassConstants.EXTERNAL_CLASS_VERSION_1_6; 125 default: return null; 126 } 127 } 128 129 130 135 public static void checkVersionNumbers(int classVersion) throws UnsupportedOperationException 136 { 137 if (classVersion < ClassConstants.INTERNAL_CLASS_VERSION_1_0 || 138 classVersion > ClassConstants.INTERNAL_CLASS_VERSION_1_6) 139 { 140 throw new UnsupportedOperationException ("Unsupported version number ["+ 141 internalMajorClassVersion(classVersion)+"."+ 142 internalMinorClassVersion(classVersion)+"] for class format"); 143 } 144 } 145 146 147 154 public static String internalClassName(String externalClassName) 155 { 156 return externalClassName.replace(ClassConstants.EXTERNAL_PACKAGE_SEPARATOR, 157 ClassConstants.INTERNAL_PACKAGE_SEPARATOR); 158 } 159 160 161 169 public static String externalFullClassDescription(int accessFlags, 170 String internalClassName) 171 { 172 return externalClassAccessFlags(accessFlags) + 173 externalClassName(internalClassName); 174 } 175 176 177 184 public static String externalClassName(String internalClassName) 185 { 186 return internalClassName.replace(ClassConstants.INTERNAL_PACKAGE_SEPARATOR, 190 ClassConstants.EXTERNAL_PACKAGE_SEPARATOR); 191 } 192 193 194 202 public static String externalShortClassName(String externalClassName) 203 { 204 int index = externalClassName.lastIndexOf(ClassConstants.EXTERNAL_PACKAGE_SEPARATOR); 205 return externalClassName.substring(index+1); 206 } 207 208 209 216 public static boolean isInternalArrayType(String internalType) 217 { 218 return internalType.length() > 1 && 219 internalType.charAt(0) == ClassConstants.INTERNAL_TYPE_ARRAY; 220 } 221 222 223 229 public static int internalArrayTypeDimensionCount(String internalType) 230 { 231 int dimensions = 0; 232 while (internalType.charAt(dimensions) == ClassConstants.INTERNAL_TYPE_ARRAY) 233 { 234 dimensions++; 235 } 236 237 return dimensions; 238 } 239 240 241 251 public static boolean isInternalArrayInterfaceName(String internalClassName) 252 { 253 return ClassConstants.INTERNAL_NAME_JAVA_LANG_OBJECT.equals(internalClassName) || 254 ClassConstants.INTERNAL_NAME_JAVA_LANG_CLONEABLE.equals(internalClassName) || 255 ClassConstants.INTERNAL_NAME_JAVA_IO_SERIALIZABLE.equals(internalClassName); 256 } 257 258 259 267 public static boolean isInternalPrimitiveType(char internalType) 268 { 269 return internalType == ClassConstants.INTERNAL_TYPE_BOOLEAN || 270 internalType == ClassConstants.INTERNAL_TYPE_BYTE || 271 internalType == ClassConstants.INTERNAL_TYPE_CHAR || 272 internalType == ClassConstants.INTERNAL_TYPE_SHORT || 273 internalType == ClassConstants.INTERNAL_TYPE_INT || 274 internalType == ClassConstants.INTERNAL_TYPE_FLOAT || 275 internalType == ClassConstants.INTERNAL_TYPE_LONG || 276 internalType == ClassConstants.INTERNAL_TYPE_DOUBLE; 277 } 278 279 280 287 public static boolean isInternalCategory2Type(String internalType) 288 { 289 return internalType.length() == 1 && 290 (internalType.charAt(0) == ClassConstants.INTERNAL_TYPE_LONG || 291 internalType.charAt(0) == ClassConstants.INTERNAL_TYPE_DOUBLE); 292 } 293 294 295 303 public static boolean isInternalClassType(String internalType) 304 { 305 int length = internalType.length(); 306 return length > 1 && 307 internalType.charAt(length-1) == ClassConstants.INTERNAL_TYPE_CLASS_END; 309 } 310 311 312 319 public static String internalTypeFromClassName(String internalClassName) 320 { 321 return internalArrayTypeFromClassName(internalClassName, 0); 322 } 323 324 325 335 public static String internalArrayTypeFromClassName(String internalClassName, 336 int dimensionCount) 337 { 338 StringBuffer buffer = new StringBuffer (internalClassName.length() + dimensionCount + 2); 339 340 for (int dimension = 0; dimension < dimensionCount; dimension++) 341 { 342 buffer.append(ClassConstants.INTERNAL_TYPE_ARRAY); 343 } 344 345 return buffer.append(ClassConstants.INTERNAL_TYPE_CLASS_START) 346 .append(internalClassName) 347 .append(ClassConstants.INTERNAL_TYPE_CLASS_END) 348 .toString(); 349 } 350 351 352 361 public static String internalTypeFromArrayType(String internalArrayType) 362 { 363 int index = internalArrayType.lastIndexOf(ClassConstants.INTERNAL_TYPE_ARRAY); 364 return internalArrayType.substring(index+1); 365 } 366 367 368 379 public static String internalClassNameFromClassType(String internalClassType) 380 { 381 return isInternalClassType(internalClassType) ? 382 internalClassType.substring(internalClassType.indexOf(ClassConstants.INTERNAL_TYPE_CLASS_START)+1, 383 internalClassType.length()-1) : 384 internalClassType; 385 } 386 387 388 398 public static String internalClassNameFromType(String internalClassType) 399 { 400 if (!isInternalClassType(internalClassType)) 401 { 402 return null; 403 } 404 405 if (isInternalArrayType(internalClassType)) 407 { 408 internalClassType = internalTypeFromArrayType(internalClassType); 409 } 410 411 return internalClassNameFromClassType(internalClassType); 412 } 413 414 415 422 public static String internalMethodReturnType(String internalMethodDescriptor) 423 { 424 int index = internalMethodDescriptor.indexOf(ClassConstants.INTERNAL_METHOD_ARGUMENTS_CLOSE); 425 return internalMethodDescriptor.substring(index + 1); 426 } 427 428 429 436 public static int internalMethodParameterCount(String internalMethodDescriptor) 437 { 438 internalTypeEnumeration.setDescriptor(internalMethodDescriptor); 439 440 int counter = 0; 441 while (internalTypeEnumeration.hasMoreTypes()) 442 { 443 internalTypeEnumeration.nextType(); 444 445 counter++; 446 } 447 448 return counter; 449 } 450 451 452 461 public static int internalMethodParameterSize(String internalMethodDescriptor) 462 { 463 internalTypeEnumeration.setDescriptor(internalMethodDescriptor); 464 465 int size = 0; 466 while (internalTypeEnumeration.hasMoreTypes()) 467 { 468 String internalType = internalTypeEnumeration.nextType(); 469 470 size += internalTypeSize(internalType); 471 } 472 473 return size; 474 } 475 476 477 486 public static int internalTypeSize(String internalType) 487 { 488 if (internalType.length() == 1) 489 { 490 char internalPrimitiveType = internalType.charAt(0); 491 if (internalPrimitiveType == ClassConstants.INTERNAL_TYPE_LONG || 492 internalPrimitiveType == ClassConstants.INTERNAL_TYPE_DOUBLE) 493 { 494 return 2; 495 } 496 else if (internalPrimitiveType == ClassConstants.INTERNAL_TYPE_VOID) 497 { 498 return 0; 499 } 500 } 501 502 return 1; 503 } 504 505 506 515 public static String internalType(String externalType) 516 { 517 int dimensionCount = externalArrayTypeDimensionCount(externalType); 519 if (dimensionCount > 0) 520 { 521 externalType = externalType.substring(0, externalType.length() - dimensionCount * ClassConstants.EXTERNAL_TYPE_ARRAY.length()); 522 } 523 524 char internalTypeChar = 526 externalType.equals(ClassConstants.EXTERNAL_TYPE_VOID ) ? 527 ClassConstants.INTERNAL_TYPE_VOID : 528 externalType.equals(ClassConstants.EXTERNAL_TYPE_BOOLEAN) ? 529 ClassConstants.INTERNAL_TYPE_BOOLEAN : 530 externalType.equals(ClassConstants.EXTERNAL_TYPE_BYTE ) ? 531 ClassConstants.INTERNAL_TYPE_BYTE : 532 externalType.equals(ClassConstants.EXTERNAL_TYPE_CHAR ) ? 533 ClassConstants.INTERNAL_TYPE_CHAR : 534 externalType.equals(ClassConstants.EXTERNAL_TYPE_SHORT ) ? 535 ClassConstants.INTERNAL_TYPE_SHORT : 536 externalType.equals(ClassConstants.EXTERNAL_TYPE_INT ) ? 537 ClassConstants.INTERNAL_TYPE_INT : 538 externalType.equals(ClassConstants.EXTERNAL_TYPE_FLOAT ) ? 539 ClassConstants.INTERNAL_TYPE_FLOAT : 540 externalType.equals(ClassConstants.EXTERNAL_TYPE_LONG ) ? 541 ClassConstants.INTERNAL_TYPE_LONG : 542 externalType.equals(ClassConstants.EXTERNAL_TYPE_DOUBLE ) ? 543 ClassConstants.INTERNAL_TYPE_DOUBLE : 544 externalType.equals("%" ) ? 545 '%' : 546 (char)0; 547 548 String internalType = 549 internalTypeChar != 0 ? ("" + internalTypeChar) : 550 (ClassConstants.INTERNAL_TYPE_CLASS_START + 551 internalClassName(externalType) + 552 ClassConstants.INTERNAL_TYPE_CLASS_END); 553 554 for (int count = 0; count < dimensionCount; count++) 556 { 557 internalType = ClassConstants.INTERNAL_TYPE_ARRAY + internalType; 558 } 559 560 return internalType; 561 } 562 563 564 570 public static int externalArrayTypeDimensionCount(String externalType) 571 { 572 int dimensions = 0; 573 int length = ClassConstants.EXTERNAL_TYPE_ARRAY.length(); 574 int offset = externalType.length() - length; 575 while (externalType.regionMatches(offset, 576 ClassConstants.EXTERNAL_TYPE_ARRAY, 577 0, 578 length)) 579 { 580 dimensions++; 581 offset -= length; 582 } 583 584 return dimensions; 585 } 586 587 588 597 public static String externalType(String internalType) 598 { 599 int dimensionCount = internalArrayTypeDimensionCount(internalType); 601 if (dimensionCount > 0) 602 { 603 internalType = internalType.substring(dimensionCount); 604 } 605 606 char internalTypeChar = internalType.charAt(0); 608 609 String externalType = 610 internalTypeChar == ClassConstants.INTERNAL_TYPE_VOID ? 611 ClassConstants.EXTERNAL_TYPE_VOID : 612 internalTypeChar == ClassConstants.INTERNAL_TYPE_BOOLEAN ? 613 ClassConstants.EXTERNAL_TYPE_BOOLEAN : 614 internalTypeChar == ClassConstants.INTERNAL_TYPE_BYTE ? 615 ClassConstants.EXTERNAL_TYPE_BYTE : 616 internalTypeChar == ClassConstants.INTERNAL_TYPE_CHAR ? 617 ClassConstants.EXTERNAL_TYPE_CHAR : 618 internalTypeChar == ClassConstants.INTERNAL_TYPE_SHORT ? 619 ClassConstants.EXTERNAL_TYPE_SHORT : 620 internalTypeChar == ClassConstants.INTERNAL_TYPE_INT ? 621 ClassConstants.EXTERNAL_TYPE_INT : 622 internalTypeChar == ClassConstants.INTERNAL_TYPE_FLOAT ? 623 ClassConstants.EXTERNAL_TYPE_FLOAT : 624 internalTypeChar == ClassConstants.INTERNAL_TYPE_LONG ? 625 ClassConstants.EXTERNAL_TYPE_LONG : 626 internalTypeChar == ClassConstants.INTERNAL_TYPE_DOUBLE ? 627 ClassConstants.EXTERNAL_TYPE_DOUBLE : 628 internalTypeChar == '%' ? 629 "%" : 630 internalTypeChar == ClassConstants.INTERNAL_TYPE_CLASS_START ? 631 externalClassName(internalType.substring(1, internalType.indexOf(ClassConstants.INTERNAL_TYPE_CLASS_END))) : 632 null; 633 634 if (externalType == null) 635 { 636 throw new IllegalArgumentException ("Unknown type ["+internalType+"]"); 637 } 638 639 for (int count = 0; count < dimensionCount; count++) 641 { 642 externalType = externalType + ClassConstants.EXTERNAL_TYPE_ARRAY; 643 } 644 645 return externalType; 646 } 647 648 649 657 public static boolean isInternalMethodDescriptor(String internalDescriptor) 658 { 659 return internalDescriptor.charAt(0) == ClassConstants.INTERNAL_METHOD_ARGUMENTS_OPEN; 660 } 661 662 663 672 public static boolean isExternalMethodNameAndArguments(String externalMemberNameAndArguments) 673 { 674 return externalMemberNameAndArguments.indexOf(ClassConstants.EXTERNAL_METHOD_ARGUMENTS_OPEN) > 0; 675 } 676 677 678 684 public static String externalMethodName(String externalMethodNameAndArguments) 685 { 686 externalTypeEnumeration.setDescriptor(externalMethodNameAndArguments); 687 return externalTypeEnumeration.methodName(); 688 } 689 690 691 701 public static String internalMethodDescriptor(String externalReturnType, 702 String externalMethodNameAndArguments) 703 { 704 StringBuffer internalMethodDescriptor = new StringBuffer (); 705 internalMethodDescriptor.append(ClassConstants.INTERNAL_METHOD_ARGUMENTS_OPEN); 706 707 externalTypeEnumeration.setDescriptor(externalMethodNameAndArguments); 708 while (externalTypeEnumeration.hasMoreTypes()) 709 { 710 internalMethodDescriptor.append(internalType(externalTypeEnumeration.nextType())); 711 } 712 713 internalMethodDescriptor.append(ClassConstants.INTERNAL_METHOD_ARGUMENTS_CLOSE); 714 internalMethodDescriptor.append(internalType(externalReturnType)); 715 716 return internalMethodDescriptor.toString(); 717 } 718 719 720 730 public static String internalMethodDescriptor(String externalReturnType, 731 List externalArguments) 732 { 733 StringBuffer internalMethodDescriptor = new StringBuffer (); 734 internalMethodDescriptor.append(ClassConstants.INTERNAL_METHOD_ARGUMENTS_OPEN); 735 736 for (int index = 0; index < externalArguments.size(); index++) 737 { 738 internalMethodDescriptor.append(internalType((String )externalArguments.get(index))); 739 } 740 741 internalMethodDescriptor.append(ClassConstants.INTERNAL_METHOD_ARGUMENTS_CLOSE); 742 internalMethodDescriptor.append(internalType(externalReturnType)); 743 744 return internalMethodDescriptor.toString(); 745 } 746 747 748 758 public static String externalFullFieldDescription(int accessFlags, 759 String fieldName, 760 String internalFieldDescriptor) 761 { 762 return externalFieldAccessFlags(accessFlags) + 763 externalType(internalFieldDescriptor) + 764 " " + 765 fieldName; 766 } 767 768 769 783 public static String externalFullMethodDescription(String internalClassName, 784 int accessFlags, 785 String internalMethodName, 786 String internalMethodDescriptor) 787 { 788 return externalMethodAccessFlags(accessFlags) + 789 externalMethodReturnTypeAndName(internalClassName, 790 internalMethodName, 791 internalMethodDescriptor) + 792 ClassConstants.EXTERNAL_METHOD_ARGUMENTS_OPEN + 793 externalMethodArguments(internalMethodDescriptor) + 794 ClassConstants.EXTERNAL_METHOD_ARGUMENTS_CLOSE; 795 } 796 797 798 804 public static String externalClassAccessFlags(int accessFlags) 805 { 806 return externalClassAccessFlags(accessFlags, ""); 807 } 808 809 810 817 public static String externalClassAccessFlags(int accessFlags, String prefix) 818 { 819 if (accessFlags == 0) 820 { 821 return EMPTY_STRING; 822 } 823 824 StringBuffer string = new StringBuffer (50); 825 826 if ((accessFlags & ClassConstants.INTERNAL_ACC_PUBLIC) != 0) 827 { 828 string.append(prefix).append(ClassConstants.EXTERNAL_ACC_PUBLIC).append(" "); 829 } 830 if ((accessFlags & ClassConstants.INTERNAL_ACC_FINAL) != 0) 831 { 832 string.append(prefix).append(ClassConstants.EXTERNAL_ACC_FINAL).append(" "); 833 } 834 if ((accessFlags & ClassConstants.INTERNAL_ACC_INTERFACE) != 0) 835 { 836 string.append(prefix).append(ClassConstants.EXTERNAL_ACC_INTERFACE).append(" "); 837 } 838 else if ((accessFlags & ClassConstants.INTERNAL_ACC_ABSTRACT) != 0) 839 { 840 string.append(prefix).append(ClassConstants.EXTERNAL_ACC_ABSTRACT).append(" "); 841 } 842 843 return string.toString(); 844 } 845 846 847 853 public static String externalFieldAccessFlags(int accessFlags) 854 { 855 return externalFieldAccessFlags(accessFlags, ""); 856 } 857 858 859 866 public static String externalFieldAccessFlags(int accessFlags, String prefix) 867 { 868 if (accessFlags == 0) 869 { 870 return EMPTY_STRING; 871 } 872 873 StringBuffer string = new StringBuffer (50); 874 875 if ((accessFlags & ClassConstants.INTERNAL_ACC_PUBLIC) != 0) 876 { 877 string.append(prefix).append(ClassConstants.EXTERNAL_ACC_PUBLIC).append(" "); 878 } 879 if ((accessFlags & ClassConstants.INTERNAL_ACC_PRIVATE) != 0) 880 { 881 string.append(prefix).append(ClassConstants.EXTERNAL_ACC_PRIVATE).append(" "); 882 } 883 if ((accessFlags & ClassConstants.INTERNAL_ACC_PROTECTED) != 0) 884 { 885 string.append(prefix).append(ClassConstants.EXTERNAL_ACC_PROTECTED).append(" "); 886 } 887 if ((accessFlags & ClassConstants.INTERNAL_ACC_STATIC) != 0) 888 { 889 string.append(prefix).append(ClassConstants.EXTERNAL_ACC_STATIC).append(" "); 890 } 891 if ((accessFlags & ClassConstants.INTERNAL_ACC_FINAL) != 0) 892 { 893 string.append(prefix).append(ClassConstants.EXTERNAL_ACC_FINAL).append(" "); 894 } 895 if ((accessFlags & ClassConstants.INTERNAL_ACC_VOLATILE) != 0) 896 { 897 string.append(prefix).append(ClassConstants.EXTERNAL_ACC_VOLATILE).append(" "); 898 } 899 if ((accessFlags & ClassConstants.INTERNAL_ACC_TRANSIENT) != 0) 900 { 901 string.append(prefix).append(ClassConstants.EXTERNAL_ACC_TRANSIENT).append(" "); 902 } 903 904 return string.toString(); 905 } 906 907 908 914 public static String externalMethodAccessFlags(int accessFlags) 915 { 916 return externalMethodAccessFlags(accessFlags, ""); 917 } 918 919 920 927 public static String externalMethodAccessFlags(int accessFlags, String prefix) 928 { 929 if (accessFlags == 0) 930 { 931 return EMPTY_STRING; 932 } 933 934 StringBuffer string = new StringBuffer (50); 935 936 if ((accessFlags & ClassConstants.INTERNAL_ACC_PUBLIC) != 0) 937 { 938 string.append(prefix).append(ClassConstants.EXTERNAL_ACC_PUBLIC).append(" "); 939 } 940 if ((accessFlags & ClassConstants.INTERNAL_ACC_PRIVATE) != 0) 941 { 942 string.append(prefix).append(ClassConstants.EXTERNAL_ACC_PRIVATE).append(" "); 943 } 944 if ((accessFlags & ClassConstants.INTERNAL_ACC_PROTECTED) != 0) 945 { 946 string.append(prefix).append(ClassConstants.EXTERNAL_ACC_PROTECTED).append(" "); 947 } 948 if ((accessFlags & ClassConstants.INTERNAL_ACC_STATIC) != 0) 949 { 950 string.append(prefix).append(ClassConstants.EXTERNAL_ACC_STATIC).append(" "); 951 } 952 if ((accessFlags & ClassConstants.INTERNAL_ACC_FINAL) != 0) 953 { 954 string.append(prefix).append(ClassConstants.EXTERNAL_ACC_FINAL).append(" "); 955 } 956 if ((accessFlags & ClassConstants.INTERNAL_ACC_SYNCHRONIZED) != 0) 957 { 958 string.append(prefix).append(ClassConstants.EXTERNAL_ACC_SYNCHRONIZED).append(" "); 959 } 960 if ((accessFlags & ClassConstants.INTERNAL_ACC_NATIVE) != 0) 961 { 962 string.append(prefix).append(ClassConstants.EXTERNAL_ACC_NATIVE).append(" "); 963 } 964 if ((accessFlags & ClassConstants.INTERNAL_ACC_ABSTRACT) != 0) 965 { 966 string.append(prefix).append(ClassConstants.EXTERNAL_ACC_ABSTRACT).append(" "); 967 } 968 if ((accessFlags & ClassConstants.INTERNAL_ACC_STRICT) != 0) 969 { 970 string.append(prefix).append(ClassConstants.EXTERNAL_ACC_STRICT).append(" "); 971 } 972 973 return string.toString(); 974 } 975 976 977 984 public static String externalMethodReturnType(String internalMethodDescriptor) 985 { 986 return externalType(internalMethodReturnType(internalMethodDescriptor)); 987 } 988 989 990 1004 private static String externalMethodReturnTypeAndName(String internalClassName, 1005 String internalMethodName, 1006 String internalMethodDescriptor) 1007 { 1008 return internalMethodName.equals(ClassConstants.INTERNAL_METHOD_NAME_INIT) ? 1009 externalShortClassName(externalClassName(internalClassName)) : 1010 (externalMethodReturnType(internalMethodDescriptor) + 1011 " " + 1012 internalMethodName); 1013 } 1014 1015 1016 1024 public static String externalMethodArguments(String internalMethodDescriptor) 1025 { 1026 StringBuffer externalMethodNameAndArguments = new StringBuffer (); 1027 1028 internalTypeEnumeration.setDescriptor(internalMethodDescriptor); 1029 while (internalTypeEnumeration.hasMoreTypes()) 1030 { 1031 externalMethodNameAndArguments.append(externalType(internalTypeEnumeration.nextType())); 1032 if (internalTypeEnumeration.hasMoreTypes()) 1033 { 1034 externalMethodNameAndArguments.append(ClassConstants.EXTERNAL_METHOD_ARGUMENTS_SEPARATOR); 1035 } 1036 } 1037 1038 return externalMethodNameAndArguments.toString(); 1039 } 1040 1041 1042 1049 public static String internalPackageName(String internalClassName) 1050 { 1051 String internalPackagePrefix = internalPackagePrefix(internalClassName); 1052 int length = internalPackagePrefix.length(); 1053 return length > 0 ? 1054 internalPackagePrefix.substring(0, length - 1) : 1055 ""; 1056 } 1057 1058 1059 1066 public static String internalPackagePrefix(String internalClassName) 1067 { 1068 return internalClassName.substring(0, internalClassName.lastIndexOf(ClassConstants.INTERNAL_PACKAGE_SEPARATOR, 1069 internalClassName.length() - 2) + 1); 1070 } 1071 1072 1073 1080 public static String externalPackageName(String externalClassName) 1081 { 1082 String externalPackagePrefix = externalPackagePrefix(externalClassName); 1083 int length = externalPackagePrefix.length(); 1084 return length > 0 ? 1085 externalPackagePrefix.substring(0, length - 1) : 1086 ""; 1087 } 1088 1089 1090 1097 public static String externalPackagePrefix(String externalClassName) 1098 { 1099 return externalClassName.substring(0, externalClassName.lastIndexOf(ClassConstants.EXTERNAL_PACKAGE_SEPARATOR, 1100 externalClassName.length() - 2) + 1); 1101 } 1102} 1103 | Popular Tags |