| 1 31 32 package org.apache.commons.httpclient; 33 34 import java.io.IOException ; 35 import java.io.ObjectInputStream ; 36 import java.io.ObjectOutputStream ; 37 import java.io.Serializable ; 38 import java.io.UnsupportedEncodingException ; 39 import java.util.Locale ; 40 import java.util.BitSet ; 41 import java.util.Hashtable ; 42 import java.net.URL ; 43 44 117 public class URI implements Cloneable , Comparable , Serializable { 118 119 120 122 123 protected URI() { 124 } 125 126 127 137 public URI(char[] escaped, String charset) 138 throws URIException, NullPointerException { 139 protocolCharset = charset; 140 parseUriReference(new String (escaped), true); 141 } 142 143 144 154 public URI(char[] escaped) 155 throws URIException, NullPointerException { 156 parseUriReference(new String (escaped), true); 157 } 158 159 160 169 public URI(String original, String charset) throws URIException { 170 protocolCharset = charset; 171 parseUriReference(original, false); 172 } 173 174 175 188 public URI(String original) throws URIException { 189 parseUriReference(original, false); 190 } 191 192 193 201 public URI(URL url) throws URIException { 202 this(url.toString()); 203 } 204 205 206 222 public URI(String scheme, String schemeSpecificPart, String fragment) 223 throws URIException { 224 225 if (scheme == null) { 227 throw new URIException(URIException.PARSING, "scheme required"); 228 } 229 char[] s = scheme.toLowerCase().toCharArray(); 230 if (validate(s, URI.scheme)) { 231 _scheme = s; } else { 233 throw new URIException(URIException.PARSING, "incorrect scheme"); 234 } 235 _opaque = encode(schemeSpecificPart, allowed_opaque_part, 236 getProtocolCharset()); 237 _is_opaque_part = true; 239 _fragment = fragment.toCharArray(); 240 241 setURI(); 242 } 243 244 245 265 public URI(String scheme, String authority, String path, String query, 266 String fragment) throws URIException { 267 268 StringBuffer buff = new StringBuffer (); 270 if (scheme != null) { 271 buff.append(scheme); 272 buff.append(':'); 273 } 274 if (authority != null) { 275 buff.append("//"); 276 buff.append(authority); 277 } 278 if (path != null) { if ((scheme != null || authority != null) 280 && !path.startsWith("/")) { 281 throw new URIException(URIException.PARSING, 282 "abs_path requested"); 283 } 284 buff.append(path); 285 } 286 if (query != null) { 287 buff.append('?'); 288 buff.append(query); 289 } 290 if (fragment != null) { 291 buff.append('#'); 292 buff.append(fragment); 293 } 294 parseUriReference(buff.toString(), false); 295 } 296 297 298 308 public URI(String scheme, String userinfo, String host, int port) 309 throws URIException { 310 311 this(scheme, userinfo, host, port, null, null, null); 312 } 313 314 315 326 public URI(String scheme, String userinfo, String host, int port, 327 String path) throws URIException { 328 329 this(scheme, userinfo, host, port, path, null, null); 330 } 331 332 333 345 public URI(String scheme, String userinfo, String host, int port, 346 String path, String query) throws URIException { 347 348 this(scheme, userinfo, host, port, path, query, null); 349 } 350 351 352 365 public URI(String scheme, String userinfo, String host, int port, 366 String path, String query, String fragment) throws URIException { 367 368 this(scheme, (host == null) ? null 369 : ((userinfo != null) ? userinfo + '@' : "") + host 370 + ((port != -1) ? ":" + port : ""), path, query, fragment); 371 } 372 373 374 384 public URI(String scheme, String host, String path, String fragment) 385 throws URIException { 386 387 this(scheme, host, path, null, fragment); 388 } 389 390 391 398 public URI(URI base, String relative) throws URIException { 399 this(base, new URI(relative)); 400 } 401 402 403 453 public URI(URI base, URI relative) throws URIException { 454 455 if (base._scheme == null) { 456 throw new URIException(URIException.PARSING, "base URI required"); 457 } 458 if (base._scheme != null) { 459 this._scheme = base._scheme; 460 this._authority = base._authority; 461 } 462 if (base._is_opaque_part || relative._is_opaque_part) { 463 this._scheme = base._scheme; 464 this._is_opaque_part = base._is_opaque_part 465 || relative._is_opaque_part; 466 this._opaque = relative._opaque; 467 this._fragment = relative._fragment; 468 this.setURI(); 469 return; 470 } 471 if (relative._scheme != null) { 472 this._scheme = relative._scheme; 473 this._is_net_path = relative._is_net_path; 474 this._authority = relative._authority; 475 if (relative._is_server) { 476 this._is_server = relative._is_server; 477 this._userinfo = relative._userinfo; 478 this._host = relative._host; 479 this._port = relative._port; 480 } else if (relative._is_reg_name) { 481 this._is_reg_name = relative._is_reg_name; 482 } 483 this._is_abs_path = relative._is_abs_path; 484 this._is_rel_path = relative._is_rel_path; 485 this._path = relative._path; 486 } else if (base._authority != null && relative._scheme == null) { 487 this._is_net_path = base._is_net_path; 488 this._authority = base._authority; 489 if (base._is_server) { 490 this._is_server = base._is_server; 491 this._userinfo = base._userinfo; 492 this._host = base._host; 493 this._port = base._port; 494 } else if (base._is_reg_name) { 495 this._is_reg_name = base._is_reg_name; 496 } 497 } 498 if (relative._authority != null) { 499 this._is_net_path = relative._is_net_path; 500 this._authority = relative._authority; 501 if (relative._is_server) { 502 this._is_server = relative._is_server; 503 this._userinfo = relative._userinfo; 504 this._host = relative._host; 505 this._port = relative._port; 506 } else if (relative._is_reg_name) { 507 this._is_reg_name = relative._is_reg_name; 508 } 509 this._is_abs_path = relative._is_abs_path; 510 this._is_rel_path = relative._is_rel_path; 511 this._path = relative._path; 512 } 513 if (relative._scheme == null && relative._authority == null) { 515 if ((relative._path == null || relative._path.length == 0) 516 && relative._query == null) { 517 this._path = base._path; 520 this._query = base._query; 521 } else { 522 this._path = resolvePath(base._path, relative._path); 523 } 524 } 525 if (relative._query != null) { 527 this._query = relative._query; 528 } 529 if (relative._fragment != null) { 531 this._fragment = relative._fragment; 532 } 533 this.setURI(); 534 parseUriReference(new String (_uri), true); 537 } 538 539 541 542 static final long serialVersionUID = 604752400577948726L; 543 544 545 548 protected int hash = 0; 549 550 551 556 protected char[] _uri = null; 557 558 559 562 protected String protocolCharset = null; 563 564 565 568 protected static String defaultProtocolCharset = "UTF-8"; 569 570 571 575 protected static String defaultDocumentCharset = null; 576 protected static String defaultDocumentCharsetByLocale = null; 577 protected static String defaultDocumentCharsetByPlatform = null; 578 static { 580 Locale locale = Locale.getDefault(); 581 if (locale != null) { 583 defaultDocumentCharsetByLocale = 584 LocaleToCharsetMap.getCharset(locale); 585 defaultDocumentCharset = defaultDocumentCharsetByLocale; 587 } 588 try { 590 defaultDocumentCharsetByPlatform = System.getProperty("file.encoding"); 591 } catch(SecurityException ignore) { 592 } 593 if (defaultDocumentCharset == null) { 594 defaultDocumentCharset = defaultDocumentCharsetByPlatform; 596 } 597 } 598 599 600 603 protected char[] _scheme = null; 604 605 606 609 protected char[] _opaque = null; 610 611 612 615 protected char[] _authority = null; 616 617 618 621 protected char[] _userinfo = null; 622 623 624 627 protected char[] _host = null; 628 629 630 633 protected int _port = -1; 634 635 636 639 protected char[] _path = null; 640 641 642 645 protected char[] _query = null; 646 647 648 651 protected char[] _fragment = null; 652 653 654 657 protected static char[] rootPath = { '/' }; 658 659 661 666 protected static final BitSet percent = new BitSet (256); 667 static { 669 percent.set('%'); 670 } 671 672 673 680 protected static final BitSet digit = new BitSet (256); 681 static { 683 for (int i = '0'; i <= '9'; i++) { 684 digit.set(i); 685 } 686 } 687 688 689 695 protected static final BitSet alpha = new BitSet (256); 696 static { 698 for (int i = 'a'; i <= 'z'; i++) { 699 alpha.set(i); 700 } 701 for (int i = 'A'; i <= 'Z'; i++) { 702 alpha.set(i); 703 } 704 } 705 706 707 713 protected static final BitSet alphanum = new BitSet (256); 714 static { 716 alphanum.or(alpha); 717 alphanum.or(digit); 718 } 719 720 721 728 protected static final BitSet hex = new BitSet (256); 729 static { 731 hex.or(digit); 732 for (int i = 'a'; i <= 'f'; i++) { 733 hex.set(i); 734 } 735 for (int i = 'A'; i <= 'F'; i++) { 736 hex.set(i); 737 } 738 } 739 740 741 747 protected static final BitSet escaped = new BitSet (256); 748 static { 750 escaped.or(percent); 751 escaped.or(hex); 752 } 753 754 755 762 protected static final BitSet mark = new BitSet (256); 763 static { 765 mark.set('-'); 766 mark.set('_'); 767 mark.set('.'); 768 mark.set('!'); 769 mark.set('~'); 770 mark.set('*'); 771 mark.set('\''); 772 mark.set('('); 773 mark.set(')'); 774 } 775 776 777 784 protected static final BitSet unreserved = new BitSet (256); 785 static { 787 unreserved.or(alphanum); 788 unreserved.or(mark); 789 } 790 791 792 799 protected static final BitSet reserved = new BitSet (256); 800 static { 802 reserved.set(';'); 803 reserved.set('/'); 804 reserved.set('?'); 805 reserved.set(':'); 806 reserved.set('@'); 807 reserved.set('&'); 808 reserved.set('='); 809 reserved.set('+'); 810 reserved.set('$'); 811 reserved.set(','); 812 } 813 814 815 821 protected static final BitSet uric = new BitSet (256); 822 static { 824 uric.or(reserved); 825 uric.or(unreserved); 826 uric.or(escaped); 827 } 828 829 830 836 protected static final BitSet fragment = uric; 837 838 839 845 protected static final BitSet query = uric; 846 847 848 855 protected static final BitSet pchar = new BitSet (256); 856 static { 858 pchar.or(unreserved); 859 pchar.or(escaped); 860 pchar.set(':'); 861 pchar.set('@'); 862 pchar.set('&'); 863 pchar.set('='); 864 pchar.set('+'); 865 pchar.set('$'); 866 pchar.set(','); 867 } 868 869 870 876 protected static final BitSet param = pchar; 877 878 879 885 protected static final BitSet segment = new BitSet (256); 886 static { 888 segment.or(pchar); 889 segment.set(';'); 890 segment.or(param); 891 } 892 893 894 900 protected static final BitSet path_segments = new BitSet (256); 901 static { 903 path_segments.set('/'); 904 path_segments.or(segment); 905 } 906 907 908 914 protected static final BitSet abs_path = new BitSet (256); 915 static { 917 abs_path.set('/'); 918 abs_path.or(path_segments); 919 } 920 921 922 929 protected static final BitSet uric_no_slash = new BitSet (256); 930 static { 932 uric_no_slash.or(unreserved); 933 uric_no_slash.or(escaped); 934 uric_no_slash.set(';'); 935 uric_no_slash.set('?'); 936 uric_no_slash.set(';'); 937 uric_no_slash.set('@'); 938 uric_no_slash.set('&'); 939 uric_no_slash.set('='); 940 uric_no_slash.set('+'); 941 uric_no_slash.set('$'); 942 uric_no_slash.set(','); 943 } 944 945 946 |