1 56 57 58 package com.sun.org.apache.xerces.internal.util; 59 60 import java.io.IOException ; 61 import java.io.Serializable ; 62 63 98 public class URI implements Serializable { 99 100 106 public static class MalformedURIException extends IOException { 107 108 112 public MalformedURIException() { 113 super(); 114 } 115 116 122 public MalformedURIException(String p_msg) { 123 super(p_msg); 124 } 125 } 126 127 private static final byte [] fgLookupTable = new byte[128]; 128 129 132 133 134 private static final int RESERVED_CHARACTERS = 0x01; 136 137 139 private static final int MARK_CHARACTERS = 0x02; 140 141 142 private static final int SCHEME_CHARACTERS = 0x04; 143 144 146 private static final int USERINFO_CHARACTERS = 0x08; 147 148 149 private static final int ASCII_ALPHA_CHARACTERS = 0x10; 150 151 152 private static final int ASCII_DIGIT_CHARACTERS = 0x20; 153 154 155 private static final int ASCII_HEX_CHARACTERS = 0x40; 156 157 158 private static final int PATH_CHARACTERS = 0x80; 159 160 161 private static final int MASK_ALPHA_NUMERIC = ASCII_ALPHA_CHARACTERS | ASCII_DIGIT_CHARACTERS; 162 163 164 private static final int MASK_UNRESERVED_MASK = MASK_ALPHA_NUMERIC | MARK_CHARACTERS; 165 166 167 private static final int MASK_URI_CHARACTER = MASK_UNRESERVED_MASK | RESERVED_CHARACTERS; 168 169 170 private static final int MASK_SCHEME_CHARACTER = MASK_ALPHA_NUMERIC | SCHEME_CHARACTERS; 171 172 173 private static final int MASK_USERINFO_CHARACTER = MASK_UNRESERVED_MASK | USERINFO_CHARACTERS; 174 175 176 private static final int MASK_PATH_CHARACTER = MASK_UNRESERVED_MASK | PATH_CHARACTERS; 177 178 static { 179 for (int i = '0'; i <= '9'; ++i) { 181 fgLookupTable[i] |= ASCII_DIGIT_CHARACTERS | ASCII_HEX_CHARACTERS; 182 } 183 184 for (int i = 'A'; i <= 'F'; ++i) { 186 fgLookupTable[i] |= ASCII_ALPHA_CHARACTERS | ASCII_HEX_CHARACTERS; 187 fgLookupTable[i+0x00000020] |= ASCII_ALPHA_CHARACTERS | ASCII_HEX_CHARACTERS; 188 } 189 190 for (int i = 'G'; i <= 'Z'; ++i) { 192 fgLookupTable[i] |= ASCII_ALPHA_CHARACTERS; 193 fgLookupTable[i+0x00000020] |= ASCII_ALPHA_CHARACTERS; 194 } 195 196 fgLookupTable[';'] |= RESERVED_CHARACTERS; 198 fgLookupTable['/'] |= RESERVED_CHARACTERS; 199 fgLookupTable['?'] |= RESERVED_CHARACTERS; 200 fgLookupTable[':'] |= RESERVED_CHARACTERS; 201 fgLookupTable['@'] |= RESERVED_CHARACTERS; 202 fgLookupTable['&'] |= RESERVED_CHARACTERS; 203 fgLookupTable['='] |= RESERVED_CHARACTERS; 204 fgLookupTable['+'] |= RESERVED_CHARACTERS; 205 fgLookupTable['$'] |= RESERVED_CHARACTERS; 206 fgLookupTable[','] |= RESERVED_CHARACTERS; 207 fgLookupTable['['] |= RESERVED_CHARACTERS; 208 fgLookupTable[']'] |= RESERVED_CHARACTERS; 209 210 fgLookupTable['-'] |= MARK_CHARACTERS; 212 fgLookupTable['_'] |= MARK_CHARACTERS; 213 fgLookupTable['.'] |= MARK_CHARACTERS; 214 fgLookupTable['!'] |= MARK_CHARACTERS; 215 fgLookupTable['~'] |= MARK_CHARACTERS; 216 fgLookupTable['*'] |= MARK_CHARACTERS; 217 fgLookupTable['\''] |= MARK_CHARACTERS; 218 fgLookupTable['('] |= MARK_CHARACTERS; 219 fgLookupTable[')'] |= MARK_CHARACTERS; 220 221 fgLookupTable['+'] |= SCHEME_CHARACTERS; 223 fgLookupTable['-'] |= SCHEME_CHARACTERS; 224 fgLookupTable['.'] |= SCHEME_CHARACTERS; 225 226 fgLookupTable[';'] |= USERINFO_CHARACTERS; 228 fgLookupTable[':'] |= USERINFO_CHARACTERS; 229 fgLookupTable['&'] |= USERINFO_CHARACTERS; 230 fgLookupTable['='] |= USERINFO_CHARACTERS; 231 fgLookupTable['+'] |= USERINFO_CHARACTERS; 232 fgLookupTable['$'] |= USERINFO_CHARACTERS; 233 fgLookupTable[','] |= USERINFO_CHARACTERS; 234 235 fgLookupTable[';'] |= PATH_CHARACTERS; 237 fgLookupTable['/'] |= PATH_CHARACTERS; 238 fgLookupTable[':'] |= PATH_CHARACTERS; 239 fgLookupTable['@'] |= PATH_CHARACTERS; 240 fgLookupTable['&'] |= PATH_CHARACTERS; 241 fgLookupTable['='] |= PATH_CHARACTERS; 242 fgLookupTable['+'] |= PATH_CHARACTERS; 243 fgLookupTable['$'] |= PATH_CHARACTERS; 244 fgLookupTable[','] |= PATH_CHARACTERS; 245 } 246 247 248 private String m_scheme = null; 249 250 251 private String m_userinfo = null; 252 253 254 private String m_host = null; 255 256 257 private int m_port = -1; 258 259 260 private String m_regAuthority = null; 261 262 263 private String m_path = null; 264 265 267 private String m_queryString = null; 268 269 270 private String m_fragment = null; 271 272 private static boolean DEBUG = false; 273 274 277 public URI() { 278 } 279 280 286 public URI(URI p_other) { 287 initialize(p_other); 288 } 289 290 305 public URI(String p_uriSpec) throws MalformedURIException { 306 this((URI)null, p_uriSpec); 307 } 308 309 321 public URI(URI p_base, String p_uriSpec) throws MalformedURIException { 322 initialize(p_base, p_uriSpec); 323 } 324 325 337 public URI(String p_scheme, String p_schemeSpecificPart) 338 throws MalformedURIException { 339 if (p_scheme == null || p_scheme.trim().length() == 0) { 340 throw new MalformedURIException( 341 "Cannot construct URI with null/empty scheme!"); 342 } 343 if (p_schemeSpecificPart == null || 344 p_schemeSpecificPart.trim().length() == 0) { 345 throw new MalformedURIException( 346 "Cannot construct URI with null/empty scheme-specific part!"); 347 } 348 setScheme(p_scheme); 349 setPath(p_schemeSpecificPart); 350 } 351 352 373 public URI(String p_scheme, String p_host, String p_path, 374 String p_queryString, String p_fragment) 375 throws MalformedURIException { 376 this(p_scheme, null, p_host, -1, p_path, p_queryString, p_fragment); 377 } 378 379 404 public URI(String p_scheme, String p_userinfo, 405 String p_host, int p_port, String p_path, 406 String p_queryString, String p_fragment) 407 throws MalformedURIException { 408 if (p_scheme == null || p_scheme.trim().length() == 0) { 409 throw new MalformedURIException("Scheme is required!"); 410 } 411 412 if (p_host == null) { 413 if (p_userinfo != null) { 414 throw new MalformedURIException( 415 "Userinfo may not be specified if host is not specified!"); 416 } 417 if (p_port != -1) { 418 throw new MalformedURIException( 419 "Port may not be specified if host is not specified!"); 420 } 421 } 422 423 if (p_path != null) { 424 if (p_path.indexOf('?') != -1 && p_queryString != null) { 425 throw new MalformedURIException( 426 "Query string cannot be specified in path and query string!"); 427 } 428 429 if (p_path.indexOf('#') != -1 && p_fragment != null) { 430 throw new MalformedURIException( 431 "Fragment cannot be specified in both the path and fragment!"); 432 } 433 } 434 435 setScheme(p_scheme); 436 setHost(p_host); 437 setPort(p_port); 438 setUserinfo(p_userinfo); 439 setPath(p_path); 440 setQueryString(p_queryString); 441 setFragment(p_fragment); 442 } 443 444 449 private void initialize(URI p_other) { 450 m_scheme = p_other.getScheme(); 451 m_userinfo = p_other.getUserinfo(); 452 m_host = p_other.getHost(); 453 m_port = p_other.getPort(); 454 m_regAuthority = p_other.getRegBasedAuthority(); 455 m_path = p_other.getPath(); 456 m_queryString = p_other.getQueryString(); 457 m_fragment = p_other.getFragment(); 458 } 459 460 476 private void initialize(URI p_base, String p_uriSpec) 477 throws MalformedURIException { 478 479 String uriSpec = p_uriSpec; 480 int uriSpecLen = (uriSpec != null) ? uriSpec.length() : 0; 481 482 if (p_base == null && uriSpecLen == 0) { 483 throw new MalformedURIException( 484 "Cannot initialize URI with empty parameters."); 485 } 486 487 if (uriSpecLen == 0) { 489 initialize(p_base); 490 return; 491 } 492 493 int index = 0; 494 495 int colonIdx = uriSpec.indexOf(':'); 499 if (colonIdx != -1) { 500 final int searchFrom = colonIdx - 1; 501 int slashIdx = uriSpec.lastIndexOf('/', searchFrom); 503 int queryIdx = uriSpec.lastIndexOf('?', searchFrom); 504 int fragmentIdx = uriSpec.lastIndexOf('#', searchFrom); 505 506 if (colonIdx < 2 || slashIdx != -1 || 507 queryIdx != -1 || fragmentIdx != -1) { 508 if (colonIdx == 0 || (p_base == null && fragmentIdx != 0)) { 510 throw new MalformedURIException("No scheme found in URI."); 511 } 512 } 513 else { 514 initializeScheme(uriSpec); 515 index = m_scheme.length()+1; 516 517 if (colonIdx == uriSpecLen - 1 || uriSpec.charAt(colonIdx+1) == '#') { 519 throw new MalformedURIException("Scheme specific part cannot be empty."); 520 } 521 } 522 } 523 else if (p_base == null && uriSpec.indexOf('#') != 0) { 524 throw new MalformedURIException("No scheme found in URI."); 525 } 526 527 if (((index+1) < uriSpecLen) && 537 (uriSpec.charAt(index) == '/' && uriSpec.charAt(index+1) == '/')) { 538 index += 2; 539 int startPos = index; 540 541 char testChar = '\0'; 543 while (index < uriSpecLen) { 544 testChar = uriSpec.charAt(index); 545 if (testChar == '/' || testChar == '?' || testChar == '#') { 546 break; 547 } 548 index++; 549 } 550 551 if (index > startPos) { 555 if (!initializeAuthority(uriSpec.substring(startPos, index))) { 558 index = startPos - 2; 559 } 560 } 561 else { 562 m_host = ""; 563 } 564 } 565 566 initializePath(uriSpec, index); 567 568 if (p_base != null) { 574 575 if (m_path.length() == 0 && m_scheme == null && 583 m_host == null && m_regAuthority == null) { 584 m_scheme = p_base.getScheme(); 585 m_userinfo = p_base.getUserinfo(); 586 m_host = p_base.getHost(); 587 m_port = p_base.getPort(); 588 m_regAuthority = p_base.getRegBasedAuthority(); 589 m_path = p_base.getPath(); 590 591 if (m_queryString == null) { 592 m_queryString = p_base.getQueryString(); 593 } 594 return; 595 } 596 597 if (m_scheme == null) { 600 m_scheme = p_base.getScheme(); 601 } 602 else { 603 return; 604 } 605 606 if (m_host == null && m_regAuthority == null) { 609 m_userinfo = p_base.getUserinfo(); 610 m_host = p_base.getHost(); 611 m_port = p_base.getPort(); 612 m_regAuthority = p_base.getRegBasedAuthority(); 613 } 614 else { 615 return; 616 } 617 618 if (m_path.length() > 0 && 620 m_path.startsWith("/")) { 621 return; 622 } 623 624 String path = ""; 627 String basePath = p_base.getPath(); 628 629 if (basePath != null && basePath.length() > 0) { 631 int lastSlash = basePath.lastIndexOf('/'); 632 if (lastSlash != -1) { 633 path = basePath.substring(0, lastSlash+1); 634 } 635 } 636 else if (m_path.length() > 0) { 637 path = "/"; 638 } 639 640 path = path.concat(m_path); 642 643 index = -1; 645 while ((index = path.indexOf("/./")) != -1) { 646 path = path.substring(0, index+1).concat(path.substring(index+3)); 647 } 648 649 if (path.endsWith("/.")) { 651 path = path.substring(0, path.length()-1); 652 } 653 654 index = 1; 657 int segIndex = -1; 658 String tempString = null; 659 660 while ((index = path.indexOf("/../", index)) > 0) { 661 tempString = path.substring(0, path.indexOf("/../")); 662 segIndex = tempString.lastIndexOf('/'); 663 if (segIndex != -1) { 664 if (!tempString.substring(segIndex).equals("..")) { 665 path = path.substring(0, segIndex+1).concat(path.substring(index+4)); 666 index = segIndex; 667 } 668 else 669 index += 4; 670 } 671 else 672 index += 4; 673 } 674 675 if (path.endsWith("/..")) { 678 tempString = path.substring(0, path.length()-3); 679 segIndex = tempString.lastIndexOf('/'); 680 if (segIndex != -1) { 681 path = path.substring(0, segIndex+1); 682 } 683 } 684 m_path = path; 685 } 686 } 687 688 696 private void initializeScheme(String p_uriSpec) 697 throws MalformedURIException { 698 int uriSpecLen = p_uriSpec.length(); 699 int index = 0; 700 String scheme = null; 701 char testChar = '\0'; 702 703 while (index < uriSpecLen) { 704 testChar = p_uriSpec.charAt(index); 705 if (testChar == ':' || testChar == '/' || 706 testChar == '?' || testChar == '#') { 707 break; 708 } 709 index++; 710 } 711 scheme = p_uriSpec.substring(0, index); 712 713 if (scheme.length() == 0) { 714 throw new MalformedURIException("No scheme found in URI."); 715 } 716 else { 717 setScheme(scheme); 718 } 719 } 720 721 730 private boolean initializeAuthority(String p_uriSpec) { 731 732 int index = 0; 733 int start = 0; 734 int end = p_uriSpec.length(); 735 736 char testChar = '\0'; 737 String userinfo = null; 738 739 if (p_uriSpec.indexOf('@', start) != -1) { 741 while (index < end) { 742 testChar = p_uriSpec.charAt(index); 743 if (testChar == '@') { 744 break; 745 } 746 index++; 747 } 748 userinfo = p_uriSpec.substring(start, index); 749 index++; 750 } 751 752 String host = null; 755 start = index; 756 boolean hasPort = false; 757 if (index < end) { 758 if (p_uriSpec.charAt(start) == '[') { 759 int bracketIndex = p_uriSpec.indexOf(']', start); 760 index = (bracketIndex != -1) ? bracketIndex : end; 761 if (index+1 < end && p_uriSpec.charAt(index+1) == ':') { 762 ++index; 763 hasPort = true; 764 } 765 else { 766 index = end; 767 } 768 } 769 else { 770 int colonIndex = p_uriSpec.lastIndexOf(':', end); 771 index = (colonIndex > start) ? colonIndex : end; 772 hasPort = (index != end); 773 } 774 } 775 host = p_uriSpec.substring(start, index); 776 int port = -1; 777 if (host.length() > 0) { 778 if (hasPort) { 780 index++; 781 start = index; 782 while (index < end) { 783 index++; 784 } 785 String portStr = p_uriSpec.substring(start, index); 786 if (portStr.length() > 0) { 787 795 try { 798 port = Integer.parseInt(portStr); 799 if (port == -1) --port; 800 } 801 catch (NumberFormatException nfe) { 802 port = -2; 803 } 804 } 805 } 806 } 807 808 if (isValidServerBasedAuthority(host, port, userinfo)) { 809 m_host = host; 810 m_port = port; 811 m_userinfo = userinfo; 812 return true; 813 } 814 else if (isValidRegistryBasedAuthority(p_uriSpec)) { 819 m_regAuthority = p_uriSpec; 820 return true; 821 } 822 return false; 823 } 824 825 836 private boolean isValidServerBasedAuthority(String host, int port, String userinfo) { 837 838 if (!isWellFormedAddress(host)) { 840 return false; 841 } 842 843 if (port < -1 || port > 65535) { 848 return false; 849 } 850 851 if (userinfo != null) { 853 int index = 0; 856 int end = userinfo.length(); 857 char testChar = '\0'; 858 while (index < end) { 859 testChar = userinfo.charAt(index); 860 if (testChar == '%') { 861 if (index+2 >= end || 862 !isHex(userinfo.charAt(index+1)) || 863 !isHex(userinfo.charAt(index+2))) { 864 return false; 865 } 866 index += 2; 867 } 868 else if (!isUserinfoCharacter(testChar)) { 869 return false; 870 } 871 ++index; 872 } 873 } 874 return true; 875 } 876 877 884 private boolean isValidRegistryBasedAuthority(String authority) { 885 int index = 0; 886 int end = authority.length(); 887 char testChar; 888 889 while (index < end) { 890 testChar = authority.charAt(index); 891 892 if (testChar == '%') { 894 if (index+2 >= end || 895 !isHex(authority.charAt(index+1)) || 896 !isHex(authority.charAt(index+2))) { 897 return false; 898 } 899 index += 2; 900 } 901 else if (!isPathCharacter(testChar)) { 904 return false; 905 } 906 ++index; 907 } 908 return true; 909 } 910 911 919 private void initializePath(String p_uriSpec, int p_nStartIndex) 920 throws MalformedURIException { 921 if (p_uriSpec == null) { 922 throw new MalformedURIException( 923 "Cannot initialize path from null string!"); 924 } 925 926 int index = p_nStartIndex; 927 int start = p_nStartIndex; 928 int end = p_uriSpec.length(); 929 char testChar = '\0'; 930 931 if (start < end) { 933 if (getScheme() == null || p_uriSpec.charAt(start) == '/') { 935 936 while (index < end) { 940 testChar = p_uriSpec.charAt(index); 941 942 if (testChar == '%') { 944 if (index+2 >= end || 945 !isHex(p_uriSpec.charAt(index+1)) || 946 !isHex(p_uriSpec.charAt(index+2))) { 947 throw new MalformedURIException( 948 "Path contains invalid escape sequence!"); 949 } 950 index += 2; 951 } 952 else if (!isPathCharacter(testChar)) { 955 if (testChar == '?' || testChar == '#') { 956 break; 957 } 958 throw new MalformedURIException( 959 "Path contains invalid character: " + testChar); 960 } 961 ++index; 962 } 963 } 964 else { 965 966 while (index < end) { 969 testChar = p_uriSpec.charAt(index); 970 971 if (testChar == '?' || testChar == '#') { 972 break; 973 } 974 975 if (testChar == '%') { 977 if (index+2 >= end || 978 !isHex(p_uriSpec.charAt(index+1)) || 979 !isHex(p_uriSpec.charAt(index+2))) { 980 throw new MalformedURIException( 981 "Opaque part contains invalid escape sequence!"); 982 } 983 index += 2; 984 } 985 else if (!isURICharacter(testChar)) { 991 throw new MalformedURIException( 992 "Opaque part contains invalid character: " + testChar); 993 } 994 ++index; 995 } 996 } 997 } 998 m_path = p_uriSpec.substring(start, index); 999 1000 if (testChar == '?') { 1002 index++; 1003 start = index; 1004 while (index < end) { 1005 testChar = p_uriSpec.charAt(index); 1006 if (testChar == '#') { 1007 break; 1008 } 1009 if (testChar == '%') { 1010 if (index+2 >= end || 1011 !isHex(p_uriSpec.charAt(index+1)) || 1012 !isHex(p_uriSpec.charAt(index+2))) { 1013 throw new MalformedURIException( 1014 "Query string contains invalid escape sequence!"); 1015 } 1016 index += 2; 1017 } 1018 else if (!isURICharacter(testChar)) { 1019 throw new MalformedURIException( 1020 "Query string contains invalid character: " + testChar); 1021 } 1022 index++; 1023 } 1024 m_queryString = p_uriSpec.substring(start, index); 1025 } 1026 1027 if (testChar == '#') { 1029 index++; 1030 start = index; 1031 while (index < end) { 1032 testChar = p_uriSpec.charAt(index); 1033 1034 if (testChar == '%') { 1035 if (index+2 >= end || 1036 !isHex(p_uriSpec.charAt(index+1)) || 1037 !isHex(p_uriSpec.charAt(index+2))) { 1038 throw new MalformedURIException( 1039 "Fragment contains invalid escape sequence!"); 1040 } 1041 index += 2; 1042 } 1043 else if (!isURICharacter(testChar)) { 1044 throw new MalformedURIException( 1045 "Fragment contains invalid character: "+testChar); 1046 } 1047 index++; 1048 } 1049 m_fragment = p_uriSpec.substring(start, index); 1050 } 1051 } 1052 1053 1058 public String getScheme() { 1059 return m_scheme; 1060 } 1061 1062 1068 public String getSchemeSpecificPart() { 1069 StringBuffer schemespec = new StringBuffer (); 1070 1071 if (m_host != null || m_regAuthority != null) { 1072 schemespec.append("//"); 1073 1074 if (m_host != null) { 1076 1077 if (m_userinfo != null) { 1078 schemespec.append(m_userinfo); 1079 schemespec.append('@'); 1080 } 1081 1082 schemespec.append(m_host); 1083 1084 if (m_port != -1) { 1085 schemespec.append(':'); 1086 schemespec.append(m_port); 1087 } 1088 } 1089 else { 1091 schemespec.append(m_regAuthority); 1092 } 1093 } 1094 1095 if (m_path != null) { 1096 schemespec.append((m_path)); 1097 } 1098 1099 if (m_queryString != null) { 1100 schemespec.append('?'); 1101 schemespec.append(m_queryString); 1102 } 1103 1104 if (m_fragment != null) { 1105 schemespec.append('#'); 1106 schemespec.append(m_fragment); 1107 } 1108 1109 return schemespec.toString(); 1110 } 1111 1112 1117 public String getUserinfo() { 1118 return m_userinfo; 1119 } 1120 1121 1126 public String getHost() { 1127 return m_host; 1128 } 1129 1130 1135 public int getPort() { 1136 return m_port; 1137 } 1138 1139 1144 public String getRegBasedAuthority() { 1145 return m_regAuthority; 1146 } 1147 1148 1162 public String getPath(boolean p_includeQueryString, 1163 boolean p_includeFragment) { 1164 StringBuffer pathString = new StringBuffer (m_path); 1165 1166 if (p_includeQueryString && m_queryString != null) { 1167 pathString.append('?'); 1168 pathString.append(m_queryString); 1169 } 1170 1171 if (p_includeFragment && m_fragment != null) { 1172 pathString.append('#'); 1173 pathString.append(m_fragment); 1174 } 1175 return pathString.toString(); 1176 } 1177 1178 1184 public String getPath() { 1185 return m_path; 1186 } 1187 1188 1195 public String getQueryString() { 1196 return m_queryString; 1197 } 1198 1199 1206 public String getFragment() { 1207 return m_fragment; 1208 } 1209 1210 1219 public void setScheme(String p_scheme) throws MalformedURIException { 1220 if (p_scheme == null) { 1221 throw new MalformedURIException( 1222 "Cannot set scheme from null string!"); 1223 } 1224 if (!isConformantSchemeName(p_scheme)) { 1225 throw new MalformedURIException("The scheme is not conformant."); 1226 } 1227 1228 m_scheme = p_scheme.toLowerCase(); 1229 } 1230 1231 1240 public void setUserinfo(String p_userinfo) throws MalformedURIException { 1241 if (p_userinfo == null) { 1242 m_userinfo = null; 1243 return; 1244 } 1245 else { 1246 if (m_host == null) { 1247 throw new MalformedURIException( 1248 "Userinfo cannot be set when host is null!"); 1249 } 1250 1251 int index = 0; 1254 int end = p_userinfo.length(); 1255 char testChar = '\0'; 1256 while (index < end) { 1257 testChar = p_userinfo.charAt(index); 1258 if (testChar == '%') { 1259 if (index+2 >= end || 1260 !isHex(p_userinfo.charAt(index+1)) || 1261 !isHex(p_userinfo.charAt(index+2))) { 1262 throw new MalformedURIException( 1263 "Userinfo contains invalid escape sequence!"); 1264 } 1265 } 1266 else if (!isUserinfoCharacter(testChar)) { 1267 throw new MalformedURIException( 1268 "Userinfo contains invalid character:"+testChar); 1269 } 1270 index++; 1271 } 1272 } 1273 m_userinfo = p_userinfo; 1274 } 1275 1276 1288 public void setHost(String p_host) throws MalformedURIException { 1289 if (p_host == null || p_host.length() == 0) { 1290 if (p_host != null) { 1291 m_regAuthority = null; 1292 } 1293 m_host = p_host; 1294 m_userinfo = null; 1295 m_port = -1; 1296 return; 1297 } 1298 else if (!isWellFormedAddress(p_host)) { 1299 throw new MalformedURIException("Host is not a well formed address!"); 1300 } 1301 m_host = p_host; 1302 m_regAuthority = null; 1303 } 1304 1305 1316 public void setPort(int p_port) throws MalformedURIException { 1317 if (p_port >= 0 && p_port <= 65535) { 1318 if (m_host == null) { 1319 throw new MalformedURIException( 1320 "Port cannot be set when host is null!"); 1321 } 1322 } 1323 else if (p_port != -1) { 1324 throw new MalformedURIException("Invalid port number!"); 1325 } 1326 m_port = p_port; 1327 } 1328 1329 1340 public void setRegBasedAuthority(String authority) 1341 throws MalformedURIException { 1342 1343 if (authority == null) { 1344 m_regAuthority = null; 1345 return; 1346 } 1347 else if (authority.length() < 1 || 1350 !isValidRegistryBasedAuthority(authority) || 1351 authority.indexOf('/') != -1) { 1352 throw new MalformedURIException("Registry based authority is not well formed."); 1353 } 1354 m_regAuthority = authority; 1355 m_host = null; 1356 m_userinfo = null; 1357 m_port = -1; 1358 } 1359 1360 1374 public void setPath(String p_path) throws MalformedURIException { 1375 if (p_path == null) { 1376 m_path = null; 1377 m_queryString = null; 1378 m_fragment = null; 1379 } 1380 else { 1381 initializePath(p_path, 0); 1382 } 1383 } 1384 1385 1398 public void appendPath(String p_addToPath) 1399 throws MalformedURIException { 1400 if (p_addToPath == null || p_addToPath.trim().length() == 0) { 1401 return; 1402 } 1403 1404 if (!isURIString(p_addToPath)) { 1405 throw new MalformedURIException( 1406 "Path contains invalid character!"); 1407 } 1408 1409 if (m_path == null || m_path.trim().length() == 0) { 1410 if (p_addToPath.startsWith("/")) { 1411 m_path = p_addToPath; 1412 } 1413 else { 1414 m_path = "/" + p_addToPath; 1415 } 1416 } 1417 else if (m_path.endsWith("/")) { 1418 if (p_addToPath.startsWith("/")) { 1419 m_path = m_path.concat(p_addToPath.substring(1)); 1420 } 1421 else { 1422 m_path = m_path.concat(p_addToPath); 1423 } 1424 } 1425 else { 1426 if (p_addToPath.startsWith("/")) { 1427 m_path = m_path.concat(p_addToPath); 1428 } 1429 else { 1430 m_path = m_path.concat("/" + p_addToPath); 1431 } 1432 } 1433 } 1434 1435 1446 public void setQueryString(String p_queryString) throws MalformedURIException { 1447 if (p_queryString == null) { 1448 m_queryString = null; 1449 } 1450 else if (!isGenericURI()) { 1451 throw new MalformedURIException( 1452 "Query string can only be set for a generic URI!"); 1453 } 1454 else if (getPath() == null) { 1455 throw new MalformedURIException( 1456 "Query string cannot be set when path is null!"); 1457 } 1458 else if (!isURIString(p_queryString)) { 1459 throw new MalformedURIException( 1460 "Query string contains invalid character!"); 1461 } 1462 else { 1463 m_queryString = p_queryString; 1464 } 1465 } 1466 1467 1478 public void setFragment(String p_fragment) throws MalformedURIException { 1479 if (p_fragment == null) { 1480 m_fragment = null; 1481 } 1482 else if (!isGenericURI()) { 1483 throw new MalformedURIException( 1484 "Fragment can only be set for a generic URI!"); 1485 } 1486 else if (getPath() == null) { 1487 throw new MalformedURIException( 1488 "Fragment cannot be set when path is null!"); 1489 } 1490 else if (!isURIString(p_fragment)) { 1491 throw new MalformedURIException( 1492 "Fragment contains invalid character!"); 1493 } 1494 else { 1495 m_fragment = p_fragment; 1496 } 1497 } 1498 1499 1507 public boolean equals(Object p_test) { 1508 if (p_test instanceof URI) { 1509 URI testURI = (URI) p_test; 1510 if (((m_scheme == null && testURI.m_scheme == null) || 1511 (m_scheme != null && testURI.m_scheme != null && 1512 m_scheme.equals(testURI.m_scheme))) && 1513 ((m_userinfo == null && testURI.m_userinfo == null) || 1514 (m_userinfo != null && testURI.m_userinfo != null && 1515 m_userinfo.equals(testURI.m_userinfo))) && 1516 ((m_host == null && testURI.m_host == null) || 1517 (m_host != null && testURI.m_host != null && 1518 m_host.equals(testURI.m_host))) && 1519 m_port == testURI.m_port && 1520 ((m_path == null && testURI.m_path == null) || 1521 (m_path != null && testURI.m_path != null && 1522 m_path.equals(testURI.m_path))) && 1523 ((m_queryString == null && testURI.m_queryString == null) || 1524 (m_queryString != null && testURI.m_queryString != null && 1525 m_queryString.equals(testURI.m_queryString))) && 1526 ((m_fragment == null && testURI.m_fragment == null) || 1527 (m_fragment != null && testURI.m_fragment != null && 1528 m_fragment.equals(testURI.m_fragment)))) { 1529 return true; 1530 } 1531 } 1532 return false; 1533 } 1534 1535 1540 public String toString() { 1541 StringBuffer uriSpecString = new StringBuffer (); 1542 1543 if (m_scheme != null) { 1544 uriSpecString.append(m_scheme); 1545 uriSpecString.append(':'); 1546 } 1547 uriSpecString.append(getSchemeSpecificPart()); 1548 return uriSpecString.toString(); 1549 } 1550 1551 1558 public boolean isGenericURI() { 1559 return (m_host != null); 1562 } 1563 1564 1571 public static boolean isConformantSchemeName(String p_scheme) { 1572 if (p_scheme == null || p_scheme.trim().length() == 0) { 1573 return false; 1574 } 1575 1576 if (!isAlpha(p_scheme.charAt(0))) { 1577 return false; 1578 } 1579 1580 char testChar; 1581 int schemeLength = p_scheme.length(); 1582 for (int i = 1; i < schemeLength; ++i) { 1583 testChar = p_scheme.charAt(i); 1584 if (!isSchemeCharacter(testChar)) { 1585 return false; 1586 } 1587 } 1588 1589 return true; 1590 } 1591 1592 1604 public static boolean isWellFormedAddress(String address) { 1605 if (address == null) { 1606 return false; 1607 } 1608 1609 int addrLength = address.length(); 1610 if (addrLength == 0) { 1611 return false; 1612 } 1613 1614 if (address.startsWith("[")) { 1616 return isWellFormedIPv6Reference(address); 1617 } 1618 1619 if (address.startsWith(".") || 1621 address.startsWith("-") || 1622 address.endsWith("-")) { 1623 return false; 1624 } 1625 1626 int index = address.lastIndexOf('.'); 1630 if (address.endsWith(".")) { 1631 index = address.substring(0, index).lastIndexOf('.'); 1632 } 1633 1634 if (index+1 < addrLength && isDigit(address.charAt(index+1))) { 1635 return isWellFormedIPv4Address(address); 1636 } 1637 else { 1638 1642 if (addrLength > 255) { 1646 return false; 1647 } 1648 1649 char testChar; 1652 int labelCharCount = 0; 1653 1654 for (int i = 0; i < addrLength; i++) { 1655 testChar = address.charAt(i); 1656 if (testChar == '.') { 1657 if (!isAlphanum(address.charAt(i-1))) { 1658 return false; 1659 } 1660 if (i+1 < addrLength && !isAlphanum(address.charAt(i+1))) { 1661 return false; 1662 } 1663 labelCharCount = 0; 1664 } 1665 else if (!isAlphanum(testChar) && testChar != '-') { 1666 return false; 1667 } 1668 else if (++labelCharCount > 63) { 1670 return false; 1671 } 1672 } 1673 } 1674 return true; 1675 } 1676 1677 1688 public static boolean isWellFormedIPv4Address(String address) { 1689 1690 int addrLength = address.length(); 1691 char testChar; 1692 int numDots = 0; 1693 int numDigits = 0; 1694 1695 for (int i = 0; i < addrLength; i++) { 1706 testChar = address.charAt(i); 1707 if (testChar == '.') { 1708 if ((i > 0 && !isDigit(address.charAt(i-1))) || 1709 (i+1 < addrLength && !isDigit(address.charAt(i+1)))) { 1710 return false; 1711 } 1712 numDigits = 0; 1713 if (++numDots > 3) { 1714 return false; 1715 } 1716 } 1717 else if (!isDigit(testChar)) { 1718 return false; 1719 } 1720 else if (++numDigits > 3) { 1723 return false; 1724 } 1725 else if (numDigits == 3) { 1727 char first = address.charAt(i-2); 1728 char second = address.charAt(i-1); 1729 if (!(first < '2' || 1730 (first == '2' && 1731 (second < '5' || 1732 (second == '5' && testChar <= '5'))))) { 1733 return false; 1734 } 1735 } 1736 } 1737 return (numDots == 3); 1738 } 1739 1740 1755 public static boolean isWellFormedIPv6Reference(String address) { 1756 1757 int addrLength = address.length(); 1758 int index = 1; 1759 int end = addrLength-1; 1760 1761 if (!(addrLength > 2 && address.charAt(0) == '[' 1763 && address.charAt(end) == ']')) { 1764 return false; 1765 } 1766 1767 int [] counter = new int[1]; 1769 1770 index = scanHexSequence(address, index, end, counter); 1772 if (index == -1) { 1773 return false; 1774 } 1775 else if (index == end) { 1777 return (counter[0] == 8); 1778 } 1779 1780 if (index+1 < end && address.charAt(index) == ':') { 1781 if (address.charAt(index+1) == ':') { 1782 if (++counter[0] > 8) { 1784 return false; 1785 } 1786 index += 2; 1787 if (index == end) { 1789 return true; 1790 } 1791 } 1792 else { 1796 return (counter[0] == 6) && 1797 isWellFormedIPv4Address(address.substring(index+1, end)); 1798 } 1799 } 1800 else { 1801 return false; 1802 } 1803 1804 int prevCount = counter[0]; 1806 index = scanHexSequence(address, index, end, counter); 1807 1808 return (index == end) || 1812 (index != -1 && isWellFormedIPv4Address( 1813 address.substring((counter[0] > prevCount) ? index+1 : index, end))); 1814 } 1815 1816 1831 private static int scanHexSequence (String address, int index, int end, int [] counter) { 1832 1833 char testChar; 1834 int numDigits = 0; 1835 int start = index; 1836 1837 for (; index < end; ++index) { 1841 testChar = address.charAt(index); 1842 if (testChar == ':') { 1843 if (numDigits > 0 && ++counter[0] > 8) { 1845 return -1; 1846 } 1847 if (numDigits == 0 || ((index+1 < end) && address.charAt(index+1) == ':')) { 1849 return index; 1850 } 1851 numDigits = 0; 1852 } 1853 else if (!isHex(testChar)) { 1856 if (testChar == '.' && numDigits < 4 && numDigits > 0 && counter[0] <= 6) { 1857 int back = index - numDigits - 1; 1858 return (back >= start) ? back : (back+1); 1859 } 1860 return -1; 1861 } 1862 else if (++numDigits > 4) { 1864 return -1; 1865 } 1866 } 1867 return (numDigits > 0 && ++counter[0] <= 8) ? end : -1; 1868 } 1869 1870 1871 1876 private static boolean isDigit(char p_char) { 1877 return p_char >= '0' && p_char <= '9'; 1878 } 1879 1880 1886 private static boolean isHex(char p_char) { 1887 return (p_char <= 'f' && (fgLookupTable[p_char] & ASCII_HEX_CHARACTERS) != 0); 1888 } 1889 1890 1895 private static boolean isAlpha(char p_char) { 1896 return ((p_char >= 'a' && p_char <= 'z') || (p_char >= 'A' && p_char <= 'Z' )); 1897 } 1898 1899 1904 private static boolean isAlphanum(char p_char) { 1905 return (p_char <= 'z' && (fgLookupTable[p_char] & MASK_ALPHA_NUMERIC) != 0); 1906 } 1907 1908 1914 private static boolean isReservedCharacter(char p_char) { 1915 return (p_char <= ']' && (fgLookupTable[p_char] & RESERVED_CHARACTERS) != 0); 1916 } 1917 1918 1923 private static boolean isUnreservedCharacter(char p_char) { 1924 return (p_char <= '~' && (fgLookupTable[p_char] & MASK_UNRESERVED_MASK) != 0); 1925 } 1926 1927 1933 private static boolean isURICharacter (char p_char) { 1934 return (p_char <= '~' && (fgLookupTable[p_char] & MASK_URI_CHARACTER) != 0); 1935 } 1936 1937 1942 private static boolean isSchemeCharacter (char p_char) { 1943 return (p_char <= 'z' && (fgLookupTable[p_char] & MASK_SCHEME_CHARACTER) != 0); 1944 } 1945 1946 1951 private static boolean isUserinfoCharacter (char p_char) { 1952 return (p_char <= 'z' && (fgLookupTable[p_char] & MASK_USERINFO_CHARACTER) != 0); 1953 } 1954 1955 1960 private static boolean isPathCharacter (char p_char) { 1961 return (p_char <= '~' && (fgLookupTable[p_char] & MASK_PATH_CHARACTER) != 0); 1962 } 1963 1964 1965 1972 private static boolean isURIString(String p_uric) { 1973 if (p_uric == null) { 1974 return false; 1975 } 1976 int end = p_uric.length(); 1977 char testChar = '\0'; 1978 for (int i = 0; i < end; i++) { 1979 testChar = p_uric.charAt(i); 1980 if (testChar == '%') { 1981 if (i+2 >= end || 1982 !isHex(p_uric.charAt(i+1)) || 1983 !isHex(p_uric.charAt(i+2))) { 1984 return false; 1985 } 1986 else { 1987 i += 2; 1988 continue; 1989 } 1990 } 1991 if (isURICharacter(testChar)) { 1992 continue; 1993 } 1994 else { 1995 return false; 1996 } 1997 } 1998 return true; 1999 } 2000} 2001 | Popular Tags |