1 16 17 package org.apache.axis.types; 18 19 import java.io.IOException ; 20 import java.io.Serializable ; 21 22 58 public class URI implements Serializable { 59 60 66 public static class MalformedURIException extends IOException { 67 68 69 static final long serialVersionUID = -6695054834342951930L; 70 71 75 public MalformedURIException() { 76 super(); 77 } 78 79 85 public MalformedURIException(String p_msg) { 86 super(p_msg); 87 } 88 } 89 90 91 static final long serialVersionUID = 1601921774685357214L; 92 93 private static final byte [] fgLookupTable = new byte[128]; 94 95 98 99 100 private static final int RESERVED_CHARACTERS = 0x01; 102 103 105 private static final int MARK_CHARACTERS = 0x02; 106 107 108 private static final int SCHEME_CHARACTERS = 0x04; 109 110 112 private static final int USERINFO_CHARACTERS = 0x08; 113 114 115 private static final int ASCII_ALPHA_CHARACTERS = 0x10; 116 117 118 private static final int ASCII_DIGIT_CHARACTERS = 0x20; 119 120 121 private static final int ASCII_HEX_CHARACTERS = 0x40; 122 123 124 private static final int PATH_CHARACTERS = 0x80; 125 126 127 private static final int MASK_ALPHA_NUMERIC = ASCII_ALPHA_CHARACTERS | ASCII_DIGIT_CHARACTERS; 128 129 130 private static final int MASK_UNRESERVED_MASK = MASK_ALPHA_NUMERIC | MARK_CHARACTERS; 131 132 133 private static final int MASK_URI_CHARACTER = MASK_UNRESERVED_MASK | RESERVED_CHARACTERS; 134 135 136 private static final int MASK_SCHEME_CHARACTER = MASK_ALPHA_NUMERIC | SCHEME_CHARACTERS; 137 138 139 private static final int MASK_USERINFO_CHARACTER = MASK_UNRESERVED_MASK | USERINFO_CHARACTERS; 140 141 142 private static final int MASK_PATH_CHARACTER = MASK_UNRESERVED_MASK | PATH_CHARACTERS; 143 144 static { 145 for (int i = '0'; i <= '9'; ++i) { 147 fgLookupTable[i] |= ASCII_DIGIT_CHARACTERS | ASCII_HEX_CHARACTERS; 148 } 149 150 for (int i = 'A'; i <= 'F'; ++i) { 152 fgLookupTable[i] |= ASCII_ALPHA_CHARACTERS | ASCII_HEX_CHARACTERS; 153 fgLookupTable[i+0x00000020] |= ASCII_ALPHA_CHARACTERS | ASCII_HEX_CHARACTERS; 154 } 155 156 for (int i = 'G'; i <= 'Z'; ++i) { 158 fgLookupTable[i] |= ASCII_ALPHA_CHARACTERS; 159 fgLookupTable[i+0x00000020] |= ASCII_ALPHA_CHARACTERS; 160 } 161 162 fgLookupTable[';'] |= RESERVED_CHARACTERS; 164 fgLookupTable['/'] |= RESERVED_CHARACTERS; 165 fgLookupTable['?'] |= RESERVED_CHARACTERS; 166 fgLookupTable[':'] |= RESERVED_CHARACTERS; 167 fgLookupTable['@'] |= RESERVED_CHARACTERS; 168 fgLookupTable['&'] |= RESERVED_CHARACTERS; 169 fgLookupTable['='] |= RESERVED_CHARACTERS; 170 fgLookupTable['+'] |= RESERVED_CHARACTERS; 171 fgLookupTable['$'] |= RESERVED_CHARACTERS; 172 fgLookupTable[','] |= RESERVED_CHARACTERS; 173 fgLookupTable['['] |= RESERVED_CHARACTERS; 174 fgLookupTable[']'] |= RESERVED_CHARACTERS; 175 176 fgLookupTable['-'] |= MARK_CHARACTERS; 178 fgLookupTable['_'] |= MARK_CHARACTERS; 179 fgLookupTable['.'] |= MARK_CHARACTERS; 180 fgLookupTable['!'] |= MARK_CHARACTERS; 181 fgLookupTable['~'] |= MARK_CHARACTERS; 182 fgLookupTable['*'] |= MARK_CHARACTERS; 183 fgLookupTable['\''] |= MARK_CHARACTERS; 184 fgLookupTable['('] |= MARK_CHARACTERS; 185 fgLookupTable[')'] |= MARK_CHARACTERS; 186 187 fgLookupTable['+'] |= SCHEME_CHARACTERS; 189 fgLookupTable['-'] |= SCHEME_CHARACTERS; 190 fgLookupTable['.'] |= SCHEME_CHARACTERS; 191 192 fgLookupTable[';'] |= USERINFO_CHARACTERS; 194 fgLookupTable[':'] |= USERINFO_CHARACTERS; 195 fgLookupTable['&'] |= USERINFO_CHARACTERS; 196 fgLookupTable['='] |= USERINFO_CHARACTERS; 197 fgLookupTable['+'] |= USERINFO_CHARACTERS; 198 fgLookupTable['$'] |= USERINFO_CHARACTERS; 199 fgLookupTable[','] |= USERINFO_CHARACTERS; 200 201 fgLookupTable[';'] |= PATH_CHARACTERS; 203 fgLookupTable['/'] |= PATH_CHARACTERS; 204 fgLookupTable[':'] |= PATH_CHARACTERS; 205 fgLookupTable['@'] |= PATH_CHARACTERS; 206 fgLookupTable['&'] |= PATH_CHARACTERS; 207 fgLookupTable['='] |= PATH_CHARACTERS; 208 fgLookupTable['+'] |= PATH_CHARACTERS; 209 fgLookupTable['$'] |= PATH_CHARACTERS; 210 fgLookupTable[','] |= PATH_CHARACTERS; 211 } 212 213 214 private String m_scheme = null; 215 216 217 private String m_userinfo = null; 218 219 220 private String m_host = null; 221 222 223 private int m_port = -1; 224 225 226 private String m_regAuthority = null; 227 228 229 private String m_path = null; 230 231 233 private String m_queryString = null; 234 235 236 private String m_fragment = null; 237 238 private static boolean DEBUG = false; 239 240 243 public URI() { 244 } 245 246 252 public URI(URI p_other) { 253 initialize(p_other); 254 } 255 256 271 public URI(String p_uriSpec) throws MalformedURIException { 272 this((URI)null, p_uriSpec); 273 } 274 275 294 public URI(String p_uriSpec, boolean allowNonAbsoluteURI) throws MalformedURIException { 295 this((URI)null, p_uriSpec, allowNonAbsoluteURI); 296 } 297 298 310 public URI(URI p_base, String p_uriSpec) throws MalformedURIException { 311 initialize(p_base, p_uriSpec); 312 } 313 314 331 public URI(URI p_base, String p_uriSpec, boolean allowNonAbsoluteURI) throws MalformedURIException { 332 initialize(p_base, p_uriSpec, allowNonAbsoluteURI); 333 } 334 335 347 public URI(String p_scheme, String p_schemeSpecificPart) 348 throws MalformedURIException { 349 if (p_scheme == null || p_scheme.trim().length() == 0) { 350 throw new MalformedURIException( 351 "Cannot construct URI with null/empty scheme!"); 352 } 353 if (p_schemeSpecificPart == null || 354 p_schemeSpecificPart.trim().length() == 0) { 355 throw new MalformedURIException( 356 "Cannot construct URI with null/empty scheme-specific part!"); 357 } 358 setScheme(p_scheme); 359 setPath(p_schemeSpecificPart); 360 } 361 362 383 public URI(String p_scheme, String p_host, String p_path, 384 String p_queryString, String p_fragment) 385 throws MalformedURIException { 386 this(p_scheme, null, p_host, -1, p_path, p_queryString, p_fragment); 387 } 388 389 414 public URI(String p_scheme, String p_userinfo, 415 String p_host, int p_port, String p_path, 416 String p_queryString, String p_fragment) 417 throws MalformedURIException { 418 if (p_scheme == null || p_scheme.trim().length() == 0) { 419 throw new MalformedURIException("Scheme is required!"); 420 } 421 422 if (p_host == null) { 423 if (p_userinfo != null) { 424 throw new MalformedURIException( 425 "Userinfo may not be specified if host is not specified!"); 426 } 427 if (p_port != -1) { 428 throw new MalformedURIException( 429 "Port may not be specified if host is not specified!"); 430 } 431 } 432 433 if (p_path != null) { 434 if (p_path.indexOf('?') != -1 && p_queryString != null) { 435 throw new MalformedURIException( 436 "Query string cannot be specified in path and query string!"); 437 } 438 439 if (p_path.indexOf('#') != -1 && p_fragment != null) { 440 throw new MalformedURIException( 441 "Fragment cannot be specified in both the path and fragment!"); 442 } 443 } 444 445 setScheme(p_scheme); 446 setHost(p_host); 447 setPort(p_port); 448 setUserinfo(p_userinfo); 449 setPath(p_path); 450 setQueryString(p_queryString); 451 setFragment(p_fragment); 452 } 453 454 459 private void initialize(URI p_other) { 460 m_scheme = p_other.getScheme(); 461 m_userinfo = p_other.getUserinfo(); 462 m_host = p_other.getHost(); 463 m_port = p_other.getPort(); 464 m_regAuthority = p_other.getRegBasedAuthority(); 465 m_path = p_other.getPath(); 466 m_queryString = p_other.getQueryString(); 467 m_fragment = p_other.getFragment(); 468 } 469 470 488 private void initialize(URI p_base, String p_uriSpec, boolean allowNonAbsoluteURI) 489 throws MalformedURIException { 490 491 String uriSpec = p_uriSpec; 492 int uriSpecLen = (uriSpec != null) ? uriSpec.length() : 0; 493 494 if (p_base == null && uriSpecLen == 0) { 495 if (allowNonAbsoluteURI) { 496 m_path = ""; 497 return; 498 } 499 throw new MalformedURIException("Cannot initialize URI with empty parameters."); 500 } 501 502 if (uriSpecLen == 0) { 504 initialize(p_base); 505 return; 506 } 507 508 int index = 0; 509 510 int colonIdx = uriSpec.indexOf(':'); 512 if (colonIdx != -1) { 513 final int searchFrom = colonIdx - 1; 514 int slashIdx = uriSpec.lastIndexOf('/', searchFrom); 516 int queryIdx = uriSpec.lastIndexOf('?', searchFrom); 517 int fragmentIdx = uriSpec.lastIndexOf('#', searchFrom); 518 519 if (colonIdx == 0 || slashIdx != -1 || 520 queryIdx != -1 || fragmentIdx != -1) { 521 if (colonIdx == 0 || (p_base == null && fragmentIdx != 0 && !allowNonAbsoluteURI)) { 523 throw new MalformedURIException("No scheme found in URI."); 524 } 525 } 526 else { 527 initializeScheme(uriSpec); 528 index = m_scheme.length()+1; 529 530 if (colonIdx == uriSpecLen - 1 || uriSpec.charAt(colonIdx+1) == '#') { 532 throw new MalformedURIException("Scheme specific part cannot be empty."); 533 } 534 } 535 } 536 else if (p_base == null && uriSpec.indexOf('#') != 0 && !allowNonAbsoluteURI) { 537 throw new MalformedURIException("No scheme found in URI."); 538 } 539 540 if (((index+1) < uriSpecLen) && 550 (uriSpec.charAt(index) == '/' && uriSpec.charAt(index+1) == '/')) { 551 index += 2; 552 int startPos = index; 553 554 char testChar = '\0'; 556 while (index < uriSpecLen) { 557 testChar = uriSpec.charAt(index); 558 if (testChar == '/' || testChar == '?' || testChar == '#') { 559 break; 560 } 561 index++; 562 } 563 564 if (index > startPos) { 568 if (!initializeAuthority(uriSpec.substring(startPos, index))) { 571 index = startPos - 2; 572 } 573 } 574 else { 575 m_host = ""; 576 } 577 } 578 579 initializePath(uriSpec, index); 580 581 if (p_base != null) { 587 absolutize(p_base); 588 } 589 } 590 591 607 private void initialize(URI p_base, String p_uriSpec) 608 throws MalformedURIException { 609 610 String uriSpec = p_uriSpec; 611 int uriSpecLen = (uriSpec != null) ? uriSpec.length() : 0; 612 613 if (p_base == null && uriSpecLen == 0) { 614 throw new MalformedURIException( 615 "Cannot initialize URI with empty parameters."); 616 } 617 618 if (uriSpecLen == 0) { 620 initialize(p_base); 621 return; 622 } 623 624 int index = 0; 625 626 int colonIdx = uriSpec.indexOf(':'); 628 if (colonIdx != -1) { 629 final int searchFrom = colonIdx - 1; 630 int slashIdx = uriSpec.lastIndexOf('/', searchFrom); 632 int queryIdx = uriSpec.lastIndexOf('?', searchFrom); 633 int fragmentIdx = uriSpec.lastIndexOf('#', searchFrom); 634 635 if (colonIdx == 0 || slashIdx != -1 || 636 queryIdx != -1 || fragmentIdx != -1) { 637 if (colonIdx == 0 || (p_base == null && fragmentIdx != 0)) { 639 throw new MalformedURIException("No scheme found in URI."); 640 } 641 } 642 else { 643 initializeScheme(uriSpec); 644 index = m_scheme.length()+1; 645 646 if (colonIdx == uriSpecLen - 1 || uriSpec.charAt(colonIdx+1) == '#') { 648 throw new MalformedURIException("Scheme specific part cannot be empty."); 649 } 650 } 651 } 652 else if (p_base == null && uriSpec.indexOf('#') != 0) { 653 throw new MalformedURIException("No scheme found in URI."); 654 } 655 656 if (((index+1) < uriSpecLen) && 666 (uriSpec.charAt(index) == '/' && uriSpec.charAt(index+1) == '/')) { 667 index += 2; 668 int startPos = index; 669 670 char testChar = '\0'; 672 while (index < uriSpecLen) { 673 testChar = uriSpec.charAt(index); 674 if (testChar == '/' || testChar == '?' || testChar == '#') { 675 break; 676 } 677 index++; 678 } 679 680 if (index > startPos) { 684 if (!initializeAuthority(uriSpec.substring(startPos, index))) { 687 index = startPos - 2; 688 } 689 } 690 else { 691 m_host = ""; 692 } 693 } 694 695 initializePath(uriSpec, index); 696 697 if (p_base != null) { 703 absolutize(p_base); 704 } 705 } 706 707 712 public void absolutize(URI p_base) { 713 714 if (m_path.length() == 0 && m_scheme == null && 722 m_host == null && m_regAuthority == null) { 723 m_scheme = p_base.getScheme(); 724 m_userinfo = p_base.getUserinfo(); 725 m_host = p_base.getHost(); 726 m_port = p_base.getPort(); 727 m_regAuthority = p_base.getRegBasedAuthority(); 728 m_path = p_base.getPath(); 729 730 if (m_queryString == null) { 731 m_queryString = p_base.getQueryString(); 732 733 if (m_fragment == null) { 734 m_fragment = p_base.getFragment(); 735 } 736 } 737 return; 738 } 739 740 if (m_scheme == null) { 743 m_scheme = p_base.getScheme(); 744 } 745 else { 746 return; 747 } 748 749 if (m_host == null && m_regAuthority == null) { 752 m_userinfo = p_base.getUserinfo(); 753 m_host = p_base.getHost(); 754 m_port = p_base.getPort(); 755 m_regAuthority = p_base.getRegBasedAuthority(); 756 } 757 else { 758 return; 759 } 760 761 if (m_path.length() > 0 && 763 m_path.startsWith("/")) { 764 return; 765 } 766 767 String path = ""; 770 String basePath = p_base.getPath(); 771 772 if (basePath != null && basePath.length() > 0) { 774 int lastSlash = basePath.lastIndexOf('/'); 775 if (lastSlash != -1) { 776 path = basePath.substring(0, lastSlash+1); 777 } 778 } 779 else if (m_path.length() > 0) { 780 path = "/"; 781 } 782 783 path = path.concat(m_path); 785 786 int index = -1; 788 while ((index = path.indexOf("/./")) != -1) { 789 path = path.substring(0, index+1).concat(path.substring(index+3)); 790 } 791 792 if (path.endsWith("/.")) { 794 path = path.substring(0, path.length()-1); 795 } 796 797 index = 1; 800 int segIndex = -1; 801 String tempString = null; 802 803 while ((index = path.indexOf("/../", index)) > 0) { 804 tempString = path.substring(0, path.indexOf("/../")); 805 segIndex = tempString.lastIndexOf('/'); 806 if (segIndex != -1) { 807 if (!tempString.substring(segIndex).equals("..")) { 808 path = path.substring(0, segIndex+1).concat(path.substring(index+4)); 809 index = segIndex; 810 } 811 else { 812 index += 4; 813 } 814 } 815 else { 816 index += 4; 817 } 818 } 819 820 if (path.endsWith("/..")) { 823 tempString = path.substring(0, path.length()-3); 824 segIndex = tempString.lastIndexOf('/'); 825 if (segIndex != -1) { 826 path = path.substring(0, segIndex+1); 827 } 828 } 829 m_path = path; 830 } 831 832 840 private void initializeScheme(String p_uriSpec) 841 throws MalformedURIException { 842 int uriSpecLen = p_uriSpec.length(); 843 int index = 0; 844 String scheme = null; 845 char testChar = '\0'; 846 847 while (index < uriSpecLen) { 848 testChar = p_uriSpec.charAt(index); 849 if (testChar == ':' || testChar == '/' || 850 testChar == '?' || testChar == '#') { 851 break; 852 } 853 index++; 854 } 855 scheme = p_uriSpec.substring(0, index); 856 857 if (scheme.length() == 0) { 858 throw new MalformedURIException("No scheme found in URI."); 859 } 860 else { 861 setScheme(scheme); 862 } 863 } 864 865 874 private boolean initializeAuthority(String p_uriSpec) { 875 876 int index = 0; 877 int start = 0; 878 int end = p_uriSpec.length(); 879 880 char testChar = '\0'; 881 String userinfo = null; 882 883 if (p_uriSpec.indexOf('@', start) != -1) { 885 while (index < end) { 886 testChar = p_uriSpec.charAt(index); 887 if (testChar == '@') { 888 break; 889 } 890 index++; 891 } 892 userinfo = p_uriSpec.substring(start, index); 893 index++; 894 } 895 896 String host = null; 899 start = index; 900 boolean hasPort = false; 901 if (index < end) { 902 if (p_uriSpec.charAt(start) == '[') { 903 int bracketIndex = p_uriSpec.indexOf(']', start); 904 index = (bracketIndex != -1) ? bracketIndex : end; 905 if (index+1 < end && p_uriSpec.charAt(index+1) == ':') { 906 ++index; 907 hasPort = true; 908 } 909 else { 910 index = end; 911 } 912 } 913 else { 914 int colonIndex = p_uriSpec.lastIndexOf(':', end); 915 index = (colonIndex > start) ? colonIndex : end; 916 hasPort = (index != end); 917 } 918 } 919 host = p_uriSpec.substring(start, index); 920 int port = -1; 921 if (host.length() > 0) { 922 if (hasPort) { 924 index++; 925 start = index; 926 while (index < end) { 927 index++; 928 } 929 String portStr = p_uriSpec.substring(start, index); 930 if (portStr.length() > 0) { 931 939 try { 942 port = Integer.parseInt(portStr); 943 if (port == -1) --port; 944 } 945 catch (NumberFormatException nfe) { 946 port = -2; 947 } 948 } 949 } 950 } 951 952 if (isValidServerBasedAuthority(host, port, userinfo)) { 953 m_host = host; 954 m_port = port; 955 m_userinfo = userinfo; 956 return true; 957 } 958 else if (isValidRegistryBasedAuthority(p_uriSpec)) { 963 m_regAuthority = p_uriSpec; 964 return true; 965 } 966 return false; 967 } 968 969 980 private boolean isValidServerBasedAuthority(String host, int port, String userinfo) { 981 982 if (!isWellFormedAddress(host)) { 984 return false; 985 } 986 987 if (port < -1 || port > 65535) { 992 return false; 993 } 994 995 if (userinfo != null) { 997 int index = 0; 1000 int end = userinfo.length(); 1001 char testChar = '\0'; 1002 while (index < end) { 1003 testChar = userinfo.charAt(index); 1004 if (testChar == '%') { 1005 if (index+2 >= end || 1006 !isHex(userinfo.charAt(index+1)) || 1007 !isHex(userinfo.charAt(index+2))) { 1008 return false; 1009 } 1010 index += 2; 1011 } 1012 else if (!isUserinfoCharacter(testChar)) { 1013 return false; 1014 } 1015 ++index; 1016 } 1017 } 1018 return true; 1019 } 1020 1021 1028 private boolean isValidRegistryBasedAuthority(String authority) { 1029 int index = 0; 1030 int end = authority.length(); 1031 char testChar; 1032 1033 while (index < end) { 1034 testChar = authority.charAt(index); 1035 1036 if (testChar == '%') { 1038 if (index+2 >= end || 1039 !isHex(authority.charAt(index+1)) || 1040 !isHex(authority.charAt(index+2))) { 1041 return false; 1042 } 1043 index += 2; 1044 } 1045 else if (!isPathCharacter(testChar)) { 1048 return false; 1049 } 1050 ++index; 1051 } 1052 return true; 1053 } 1054 1055 1063 private void initializePath(String p_uriSpec, int p_nStartIndex) 1064 throws MalformedURIException { 1065 if (p_uriSpec == null) { 1066 throw new MalformedURIException( 1067 "Cannot initialize path from null string!"); 1068 } 1069 1070 int index = p_nStartIndex; 1071 int start = p_nStartIndex; 1072 int end = p_uriSpec.length(); 1073 char testChar = '\0'; 1074 1075 if (start < end) { 1077 if (getScheme() == null || p_uriSpec.charAt(start) == '/') { 1079 1080 while (index < end) { 1084 testChar = p_uriSpec.charAt(index); 1085 1086 if (testChar == '%') { 1088 if (index+2 >= end || 1089 !isHex(p_uriSpec.charAt(index+1)) || 1090 !isHex(p_uriSpec.charAt(index+2))) { 1091 throw new MalformedURIException( 1092 "Path contains invalid escape sequence!"); 1093 } 1094 index += 2; 1095 } 1096 else if (!isPathCharacter(testChar)) { 1099 if (testChar == '?' || testChar == '#') { 1100 break; 1101 } 1102 throw new MalformedURIException( 1103 "Path contains invalid character: " + testChar); 1104 } 1105 ++index; 1106 } 1107 } 1108 else { 1109 1110 while (index < end) { 1113 testChar = p_uriSpec.charAt(index); 1114 1115 if (testChar == '?' || testChar == '#') { 1116 break; 1117 } 1118 1119 if (testChar == '%') { 1121 if (index+2 >= end || 1122 !isHex(p_uriSpec.charAt(index+1)) || 1123 !isHex(p_uriSpec.charAt(index+2))) { 1124 throw new MalformedURIException( 1125 "Opaque part contains invalid escape sequence!"); 1126 } 1127 index += 2; 1128 } 1129 else if (!isURICharacter(testChar)) { 1135 throw new MalformedURIException( 1136 "Opaque part contains invalid character: " + testChar); 1137 } 1138 ++index; 1139 } 1140 } 1141 } 1142 m_path = p_uriSpec.substring(start, index); 1143 1144 if (testChar == '?') { 1146 index++; 1147 start = index; 1148 while (index < end) { 1149 testChar = p_uriSpec.charAt(index); 1150 if (testChar == '#') { 1151 break; 1152 } 1153 if (testChar == '%') { 1154 if (index+2 >= end || 1155 !isHex(p_uriSpec.charAt(index+1)) || 1156 !isHex(p_uriSpec.charAt(index+2))) { 1157 throw new MalformedURIException( 1158 "Query string contains invalid escape sequence!"); 1159 } 1160 index += 2; 1161 } 1162 else if (!isURICharacter(testChar)) { 1163 throw new MalformedURIException( 1164 "Query string contains invalid character: " + testChar); 1165 } 1166 index++; 1167 } 1168 m_queryString = p_uriSpec.substring(start, index); 1169 } 1170 1171 if (testChar == '#') { 1173 index++; 1174 start = index; 1175 while (index < end) { 1176 testChar = p_uriSpec.charAt(index); 1177 1178 if (testChar == '%') { 1179 if (index+2 >= end || 1180 !isHex(p_uriSpec.charAt(index+1)) || 1181 !isHex(p_uriSpec.charAt(index+2))) { 1182 throw new MalformedURIException( 1183 "Fragment contains invalid escape sequence!"); 1184 } 1185 index += 2; 1186 } 1187 else if (!isURICharacter(testChar)) { 1188 throw new MalformedURIException( 1189 "Fragment contains invalid character: "+testChar); 1190 } 1191 index++; 1192 } 1193 m_fragment = p_uriSpec.substring(start, index); 1194 } 1195 } 1196 1197 1202 public String getScheme() { 1203 return m_scheme; 1204 } 1205 1206 1212 public String getSchemeSpecificPart() { 1213 StringBuffer schemespec = new StringBuffer (); 1214 1215 if (m_host != null || m_regAuthority != null) { 1216 schemespec.append("//"); 1217 1218 if (m_host != null) { 1220 1221 if (m_userinfo != null) { 1222 schemespec.append(m_userinfo); 1223 schemespec.append('@'); 1224 } 1225 1226 schemespec.append(m_host); 1227 1228 if (m_port != -1) { 1229 schemespec.append(':'); 1230 schemespec.append(m_port); 1231 } 1232 } 1233 else { 1235 schemespec.append(m_regAuthority); 1236 } 1237 } 1238 1239 if (m_path != null) { 1240 schemespec.append((m_path)); 1241 } 1242 1243 if (m_queryString != null) { 1244 schemespec.append('?'); 1245 schemespec.append(m_queryString); 1246 } 1247 1248 if (m_fragment != null) { 1249 schemespec.append('#'); 1250 schemespec.append(m_fragment); 1251 } 1252 1253 return schemespec.toString(); 1254 } 1255 1256 1261 public String getUserinfo() { 1262 return m_userinfo; 1263 } 1264 1265 1270 public String getHost() { 1271 return m_host; 1272 } 1273 1274 1279 public int getPort() { 1280 return m_port; 1281 } 1282 1283 1288 public String getRegBasedAuthority() { 1289 return m_regAuthority; 1290 } 1291 1292 1306 public String getPath(boolean p_includeQueryString, 1307 boolean p_includeFragment) { 1308 StringBuffer pathString = new StringBuffer (m_path); 1309 1310 if (p_includeQueryString && m_queryString != null) { 1311 pathString.append('?'); 1312 pathString.append(m_queryString); 1313 } 1314 1315 if (p_includeFragment && m_fragment != null) { 1316 pathString.append('#'); 1317 pathString.append(m_fragment); 1318 } 1319 return pathString.toString(); 1320 } 1321 1322 1328 public String getPath() { 1329 return m_path; 1330 } 1331 1332 1339 public String getQueryString() { 1340 return m_queryString; 1341 } 1342 1343 1350 public String getFragment() { 1351 return m_fragment; 1352 } 1353 1354 1363 public void setScheme(String p_scheme) throws MalformedURIException { 1364 if (p_scheme == null) { 1365 throw new MalformedURIException( 1366 "Cannot set scheme from null string!"); 1367 } 1368 if (!isConformantSchemeName(p_scheme)) { 1369 throw new MalformedURIException("The scheme is not conformant."); 1370 } 1371 1372 m_scheme = p_scheme.toLowerCase(); 1373 } 1374 1375 1384 public void setUserinfo(String p_userinfo) throws MalformedURIException { 1385 if (p_userinfo == null) { 1386 m_userinfo = null; 1387 return; 1388 } 1389 else { 1390 if (m_host == null) { 1391 throw new MalformedURIException( 1392 "Userinfo cannot be set when host is null!"); 1393 } 1394 1395 int index = 0; 1398 int end = p_userinfo.length(); 1399 char testChar = '\0'; 1400 while (index < end) { 1401 testChar = p_userinfo.charAt(index); 1402 if (testChar == '%') { 1403 if (index+2 >= end || 1404 !isHex(p_userinfo.charAt(index+1)) || 1405 !isHex(p_userinfo.charAt(index+2))) { 1406 throw new MalformedURIException( 1407 "Userinfo contains invalid escape sequence!"); 1408 } 1409 } 1410 else if (!isUserinfoCharacter(testChar)) { 1411 throw new MalformedURIException( 1412 "Userinfo contains invalid character:"+testChar); 1413 } 1414 index++; 1415 } 1416 } 1417 m_userinfo = p_userinfo; 1418 } 1419 1420 1432 public void setHost(String p_host) throws MalformedURIException { 1433 if (p_host == null || p_host.length() == 0) { 1434 if (p_host != null) { 1435 m_regAuthority = null; 1436 } 1437 m_host = p_host; 1438 m_userinfo = null; 1439 m_port = -1; 1440 return; 1441 } 1442 else if (!isWellFormedAddress(p_host)) { 1443 throw new MalformedURIException("Host is not a well formed address!"); 1444 } 1445 m_host = p_host; 1446 m_regAuthority = null; 1447 } 1448 1449 1460 public void setPort(int p_port) throws MalformedURIException { 1461 if (p_port >= 0 && p_port <= 65535) { 1462 if (m_host == null) { 1463 throw new MalformedURIException( 1464 "Port cannot be set when host is null!"); 1465 } 1466 } 1467 else if (p_port != -1) { 1468 throw new MalformedURIException("Invalid port number!"); 1469 } 1470 m_port = p_port; 1471 } 1472 1473 1484 public void setRegBasedAuthority(String authority) 1485 throws MalformedURIException { 1486 1487 if (authority == null) { 1488 m_regAuthority = null; 1489 return; 1490 } 1491 else if (authority.length() < 1 || 1494 !isValidRegistryBasedAuthority(authority) || 1495 authority.indexOf('/') != -1) { 1496 throw new MalformedURIException("Registry based authority is not well formed."); 1497 } 1498 m_regAuthority = authority; 1499 m_host = null; 1500 m_userinfo = null; 1501 m_port = -1; 1502 } 1503 1504 1518 public void setPath(String p_path) throws MalformedURIException { 1519 if (p_path == null) { 1520 m_path = null; 1521 m_queryString = null; 1522 m_fragment = null; 1523 } 1524 else { 1525 initializePath(p_path, 0); 1526 } 1527 } 1528 1529 1542 public void appendPath(String p_addToPath) 1543 throws MalformedURIException { 1544 if (p_addToPath == null || p_addToPath.trim().length() == 0) { 1545 return; 1546 } 1547 1548 if (!isURIString(p_addToPath)) { 1549 throw new MalformedURIException( 1550 "Path contains invalid character!"); 1551 } 1552 1553 if (m_path == null || m_path.trim().length() == 0) { 1554 if (p_addToPath.startsWith("/")) { 1555 m_path = p_addToPath; 1556 } 1557 else { 1558 m_path = "/" + p_addToPath; 1559 } 1560 } 1561 else if (m_path.endsWith("/")) { 1562 if (p_addToPath.startsWith("/")) { 1563 m_path = m_path.concat(p_addToPath.substring(1)); 1564 } 1565 else { 1566 m_path = m_path.concat(p_addToPath); 1567 } 1568 } 1569 else { 1570 if (p_addToPath.startsWith("/")) { 1571 m_path = m_path.concat(p_addToPath); 1572 } 1573 else { 1574 m_path = m_path.concat("/" + p_addToPath); 1575 } 1576 } 1577 } 1578 1579 1590 public void setQueryString(String p_queryString) throws MalformedURIException { 1591 if (p_queryString == null) { 1592 m_queryString = null; 1593 } 1594 else if (!isGenericURI()) { 1595 throw new MalformedURIException( 1596 "Query string can only be set for a generic URI!"); 1597 } 1598 else if (getPath() == null) { 1599 throw new MalformedURIException( 1600 "Query string cannot be set when path is null!"); 1601 } 1602 else if (!isURIString(p_queryString)) { 1603 throw new MalformedURIException( 1604 "Query string contains invalid character!"); 1605 } 1606 else { 1607 m_queryString = p_queryString; 1608 } 1609 } 1610 1611 1622 public void setFragment(String p_fragment) throws MalformedURIException { 1623 if (p_fragment == null) { 1624 m_fragment = null; 1625 } 1626 else if (!isGenericURI()) { 1627 throw new MalformedURIException( 1628 "Fragment can only be set for a generic URI!"); 1629 } 1630 else if (getPath() == null) { 1631 throw new MalformedURIException( 1632 "Fragment cannot be set when path is null!"); 1633 } 1634 else if (!isURIString(p_fragment)) { 1635 throw new MalformedURIException( 1636 "Fragment contains invalid character!"); 1637 } 1638 else { 1639 m_fragment = p_fragment; 1640 } 1641 } 1642 1643 1651 public boolean equals(Object p_test) { 1652 if (p_test instanceof URI) { 1653 URI testURI = (URI) p_test; 1654 if (((m_scheme == null && testURI.m_scheme == null) || 1655 (m_scheme != null && testURI.m_scheme != null && 1656 m_scheme.equals(testURI.m_scheme))) && 1657 ((m_userinfo == null && testURI.m_userinfo == null) || 1658 (m_userinfo != null && testURI.m_userinfo != null && 1659 m_userinfo.equals(testURI.m_userinfo))) && 1660 ((m_regAuthority == null && testURI.m_regAuthority == null) || 1661 (m_regAuthority != null && testURI.m_regAuthority != null && 1662 m_regAuthority.equals(testURI.m_regAuthority))) && 1663 ((m_host == null && testURI.m_host == null) || 1664 (m_host != null && testURI.m_host != null && 1665 m_host.equals(testURI.m_host))) && 1666 m_port == testURI.m_port && 1667 ((m_path == null && testURI.m_path == null) || 1668 (m_path != null && testURI.m_path != null && 1669 m_path.equals(testURI.m_path))) && 1670 ((m_queryString == null && testURI.m_queryString == null) || 1671 (m_queryString != null && testURI.m_queryString != null && 1672 m_queryString.equals(testURI.m_queryString))) && 1673 ((m_fragment == null && testURI.m_fragment == null) || 1674 (m_fragment != null && testURI.m_fragment != null && 1675 m_fragment.equals(testURI.m_fragment)))) { 1676 return true; 1677 } 1678 } 1679 return false; 1680 } 1681 1682 1689 public int hashCode() { 1690 return toString().hashCode(); 1691 } 1692 1693 1698 public String toString() { 1699 StringBuffer uriSpecString = new StringBuffer (); 1700 1701 if (m_scheme != null) { 1702 uriSpecString.append(m_scheme); 1703 uriSpecString.append(':'); 1704 } 1705 uriSpecString.append(getSchemeSpecificPart()); 1706 return uriSpecString.toString(); 1707 } 1708 1709 1716 public boolean isGenericURI() { 1717 return (m_host != null); 1720 } 1721 1722 1728 public boolean isAbsoluteURI() { 1729 return (m_scheme != null); 1731 } 1732 1733 1740 public static boolean isConformantSchemeName(String p_scheme) { 1741 if (p_scheme == null || p_scheme.trim().length() == 0) { 1742 return false; 1743 } 1744 1745 if (!isAlpha(p_scheme.charAt(0))) { 1746 return false; 1747 } 1748 1749 char testChar; 1750 int schemeLength = p_scheme.length(); 1751 for (int i = 1; i < schemeLength; ++i) { 1752 testChar = p_scheme.charAt(i); 1753 if (!isSchemeCharacter(testChar)) { 1754 return false; 1755 } 1756 } 1757 1758 return true; 1759 } 1760 1761 1773 public static boolean isWellFormedAddress(String address) { 1774 if (address == null) { 1775 return false; 1776 } 1777 1778 int addrLength = address.length(); 1779 if (addrLength == 0) { 1780 return false; 1781 } 1782 1783 if (address.startsWith("[")) { 1785 return isWellFormedIPv6Reference(address); 1786 } 1787 1788 if (address.startsWith(".") || 1790 address.startsWith("-") || 1791 address.endsWith("-")) { 1792 return false; 1793 } 1794 1795 int index = address.lastIndexOf('.'); 1799 if (address.endsWith(".")) { 1800 index = address.substring(0, index).lastIndexOf('.'); 1801 } 1802 1803 if (index+1 < addrLength && isDigit(address.charAt(index+1))) { 1804 return isWellFormedIPv4Address(address); 1805 } 1806 else { 1807 1811 if (addrLength > 255) { 1815 return false; 1816 } 1817 1818 char testChar; 1821 int labelCharCount = 0; 1822 1823 for (int i = 0; i < addrLength; i++) { 1824 testChar = address.charAt(i); 1825 if (testChar == '.') { 1826 if (!isAlphanum(address.charAt(i-1))) { 1827 return false; 1828 } 1829 if (i+1 < addrLength && !isAlphanum(address.charAt(i+1))) { 1830 return false; 1831 } 1832 labelCharCount = 0; 1833 } 1834 else if (!isAlphanum(testChar) && testChar != '-') { 1835 return false; 1836 } 1837 else if (++labelCharCount > 63) { 1839 return false; 1840 } 1841 } 1842 } 1843 return true; 1844 } 1845 1846 1857 public static boolean isWellFormedIPv4Address(String address) { 1858 1859 int addrLength = address.length(); 1860 char testChar; 1861 int numDots = 0; 1862 int numDigits = 0; 1863 1864 for (int i = 0; i < addrLength; i++) { 1875 testChar = address.charAt(i); 1876 if (testChar == '.') { 1877 if ((i > 0 && !isDigit(address.charAt(i-1))) || 1878 (i+1 < addrLength && !isDigit(address.charAt(i+1)))) { 1879 return false; 1880 } 1881 numDigits = 0; 1882 if (++numDots > 3) { 1883 return false; 1884 } 1885 } 1886 else if (!isDigit(testChar)) { 1887 return false; 1888 } 1889 else if (++numDigits > 3) { 1892 return false; 1893 } 1894 else if (numDigits == 3) { 1896 char first = address.charAt(i-2); 1897 char second = address.charAt(i-1); 1898 if (!(first < '2' || 1899 (first == '2' && 1900 (second < '5' || 1901 (second == '5' && testChar <= '5'))))) { 1902 return false; 1903 } 1904 } 1905 } 1906 return (numDots == 3); 1907 } 1908 1909 1924 public static boolean isWellFormedIPv6Reference(String address) { 1925 1926 int addrLength = address.length(); 1927 int index = 1; 1928 int end = addrLength-1; 1929 1930 if (!(addrLength > 2 && address.charAt(0) == '[' 1932 && address.charAt(end) == ']')) { 1933 return false; 1934 } 1935 1936 int [] counter = new int[1]; 1938 1939 index = scanHexSequence(address, index, end, counter); 1941 if (index == -1) { 1942 return false; 1943 } 1944 else if (index == end) { 1946 return (counter[0] == 8); 1947 } 1948 1949 if (index+1 < end && address.charAt(index) == ':') { 1950 if (address.charAt(index+1) == ':') { 1951 if (++counter[0] > 8) { 1953 return false; 1954 } 1955 index += 2; 1956 if (index == end) { 1958 return true; 1959 } 1960 } 1961 else { 1965 return (counter[0] == 6) && 1966 isWellFormedIPv4Address(address.substring(index+1, end)); 1967 } 1968 } 1969 else { 1970 return false; 1971 } 1972 1973 int prevCount = counter[0]; 1975 index = scanHexSequence(address, index, end, counter); 1976 1977 return (index == end) || 1981 (index != -1 && isWellFormedIPv4Address( 1982 address.substring((counter[0] > prevCount) ? index+1 : index, end))); 1983 } 1984 1985 2000 private static int scanHexSequence (String address, int index, int end, int [] counter) { 2001 2002 char testChar; 2003 int numDigits = 0; 2004 int start = index; 2005 2006 for (; index < end; ++index) { 2010 testChar = address.charAt(index); 2011 if (testChar == ':') { 2012 if (numDigits > 0 && ++counter[0] > 8) { 2014 return -1; 2015 } 2016 if (numDigits == 0 || ((index+1 < end) && address.charAt(index+1) == ':')) { 2018 return index; 2019 } 2020 numDigits = 0; 2021 } 2022 else if (!isHex(testChar)) { 2025 if (testChar == '.' && numDigits < 4 && numDigits > 0 && counter[0] <= 6) { 2026 int back = index - numDigits - 1; 2027 return (back >= start) ? back : (back+1); 2028 } 2029 return -1; 2030 } 2031 else if (++numDigits > 4) { 2033 return -1; 2034 } 2035 } 2036 return (numDigits > 0 && ++counter[0] <= 8) ? end : -1; 2037 } 2038 2039 2040 2045 private static boolean isDigit(char p_char) { 2046 return p_char >= '0' && p_char <= '9'; 2047 } 2048 2049 2055 private static boolean isHex(char p_char) { 2056 return (p_char <= 'f' && (fgLookupTable[p_char] & ASCII_HEX_CHARACTERS) != 0); 2057 } 2058 2059 2064 private static boolean isAlpha(char p_char) { 2065 return ((p_char >= 'a' && p_char <= 'z') || (p_char >= 'A' && p_char <= 'Z' )); 2066 } 2067 2068 2073 private static boolean isAlphanum(char p_char) { 2074 return (p_char <= 'z' && (fgLookupTable[p_char] & MASK_ALPHA_NUMERIC) != 0); 2075 } 2076 2077 2083 private static boolean isReservedCharacter(char p_char) { 2084 return (p_char <= ']' && (fgLookupTable[p_char] & RESERVED_CHARACTERS) != 0); 2085 } 2086 2087 2092 private static boolean isUnreservedCharacter(char p_char) { 2093 return (p_char <= '~' && (fgLookupTable[p_char] & MASK_UNRESERVED_MASK) != 0); 2094 } 2095 2096 2102 private static boolean isURICharacter (char p_char) { 2103 return (p_char <= '~' && (fgLookupTable[p_char] & MASK_URI_CHARACTER) != 0); 2104 } 2105 2106 2111 private static boolean isSchemeCharacter (char p_char) { 2112 return (p_char <= 'z' && (fgLookupTable[p_char] & MASK_SCHEME_CHARACTER) != 0); 2113 } 2114 2115 2120 private static boolean isUserinfoCharacter (char p_char) { 2121 return (p_char <= 'z' && (fgLookupTable[p_char] & MASK_USERINFO_CHARACTER) != 0); 2122 } 2123 2124 2129 private static boolean isPathCharacter (char p_char) { 2130 return (p_char <= '~' && (fgLookupTable[p_char] & MASK_PATH_CHARACTER) != 0); 2131 } 2132 2133 2134 2141 private static boolean isURIString(String p_uric) { 2142 if (p_uric == null) { 2143 return false; 2144 } 2145 int end = p_uric.length(); 2146 char testChar = '\0'; 2147 for (int i = 0; i < end; i++) { 2148 testChar = p_uric.charAt(i); 2149 if (testChar == '%') { 2150 if (i+2 >= end || 2151 !isHex(p_uric.charAt(i+1)) || 2152 !isHex(p_uric.charAt(i+2))) { 2153 return false; 2154 } 2155 else { 2156 i += 2; 2157 continue; 2158 } 2159 } 2160 if (isURICharacter(testChar)) { 2161 continue; 2162 } 2163 else { 2164 return false; 2165 } 2166 } 2167 return true; 2168 } 2169} 2170 2171 | Popular Tags |