1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31 package org.apache.commons.httpclient;
32
33 import java.io.IOException;
34 import java.io.ObjectInputStream;
35 import java.io.ObjectOutputStream;
36 import java.io.Serializable;
37 import java.util.Arrays;
38 import java.util.Locale;
39 import java.util.BitSet;
40 import java.util.Hashtable;
41
42 import org.apache.commons.codec.DecoderException;
43 import org.apache.commons.codec.net.URLCodec;
44 import org.apache.commons.httpclient.util.EncodingUtil;
45
46 /**
47 * The interface for the URI(Uniform Resource Identifiers) version of RFC 2396.
48 * This class has the purpose of supportting of parsing a URI reference to
49 * extend any specific protocols, the character encoding of the protocol to
50 * be transported and the charset of the document.
51 * <p>
52 * A URI is always in an "escaped" form, since escaping or unescaping a
53 * completed URI might change its semantics.
54 * <p>
55 * Implementers should be careful not to escape or unescape the same string
56 * more than once, since unescaping an already unescaped string might lead to
57 * misinterpreting a percent data character as another escaped character,
58 * or vice versa in the case of escaping an already escaped string.
59 * <p>
60 * In order to avoid these problems, data types used as follows:
61 * <p><blockquote><pre>
62 * URI character sequence: char
63 * octet sequence: byte
64 * original character sequence: String
65 * </pre></blockquote><p>
66 *
67 * So, a URI is a sequence of characters as an array of a char type, which
68 * is not always represented as a sequence of octets as an array of byte.
69 * <p>
70 *
71 * URI Syntactic Components
72 * <p><blockquote><pre>
73 * - In general, written as follows:
74 * Absolute URI = <scheme>:<scheme-specific-part>
75 * Generic URI = <scheme>://<authority><path>?<query>
76 *
77 * - Syntax
78 * absoluteURI = scheme ":" ( hier_part | opaque_part )
79 * hier_part = ( net_path | abs_path ) [ "?" query ]
80 * net_path = "//" authority [ abs_path ]
81 * abs_path = "/" path_segments
82 * </pre></blockquote><p>
83 *
84 * The following examples illustrate URI that are in common use.
85 * <pre>
86 * ftp://ftp.is.co.za/rfc/rfc1808.txt
87 * -- ftp scheme for File Transfer Protocol services
88 * gopher://spinaltap.micro.umn.edu/00/Weather/California/Los%20Angeles
89 * -- gopher scheme for Gopher and Gopher+ Protocol services
90 * http://www.math.uio.no/faq/compression-faq/part1.html
91 * -- http scheme for Hypertext Transfer Protocol services
92 * mailto:mduerst@ifi.unizh.ch
93 * -- mailto scheme for electronic mail addresses
94 * news:comp.infosystems.www.servers.unix
95 * -- news scheme for USENET news groups and articles
96 * telnet://melvyl.ucop.edu/
97 * -- telnet scheme for interactive services via the TELNET Protocol
98 * </pre>
99 * Please, notice that there are many modifications from URL(RFC 1738) and
100 * relative URL(RFC 1808).
101 * <p>
102 * <b>The expressions for a URI</b>
103 * <p><pre>
104 * For escaped URI forms
105 * - URI(char[]) // constructor
106 * - char[] getRawXxx() // method
107 * - String getEscapedXxx() // method
108 * - String toString() // method
109 * <p>
110 * For unescaped URI forms
111 * - URI(String) // constructor
112 * - String getXXX() // method
113 * </pre><p>
114 *
115 * @author <a href="mailto:jericho@apache.org">Sung-Gu</a>
116 * @author <a href="mailto:mbowler@GargoyleSoftware.com">Mike Bowler</a>
117 * @version $Revision: 564973 $ $Date: 2002/03/14 15:14:01
118 */
119 public class URI implements Cloneable, Comparable, Serializable {
120
121
122
123
124 /** Create an instance as an internal use */
125 protected URI() {
126 }
127
128 /**
129 * Construct a URI from a string with the given charset. The input string can
130 * be either in escaped or unescaped form.
131 *
132 * @param s URI character sequence
133 * @param escaped <tt>true</tt> if URI character sequence is in escaped form.
134 * <tt>false</tt> otherwise.
135 * @param charset the charset string to do escape encoding, if required
136 *
137 * @throws URIException If the URI cannot be created.
138 * @throws NullPointerException if input string is <code>null</code>
139 *
140 * @see #getProtocolCharset
141 *
142 * @since 3.0
143 */
144 public URI(String s, boolean escaped, String charset)
145 throws URIException, NullPointerException {
146 protocolCharset = charset;
147 parseUriReference(s, escaped);
148 }
149
150 /**
151 * Construct a URI from a string with the given charset. The input string can
152 * be either in escaped or unescaped form.
153 *
154 * @param s URI character sequence
155 * @param escaped <tt>true</tt> if URI character sequence is in escaped form.
156 * <tt>false</tt> otherwise.
157 *
158 * @throws URIException If the URI cannot be created.
159 * @throws NullPointerException if input string is <code>null</code>
160 *
161 * @see #getProtocolCharset
162 *
163 * @since 3.0
164 */
165 public URI(String s, boolean escaped)
166 throws URIException, NullPointerException {
167 parseUriReference(s, escaped);
168 }
169
170 /**
171 * Construct a URI as an escaped form of a character array with the given
172 * charset.
173 *
174 * @param escaped the URI character sequence
175 * @param charset the charset string to do escape encoding
176 * @throws URIException If the URI cannot be created.
177 * @throws NullPointerException if <code>escaped</code> is <code>null</code>
178 * @see #getProtocolCharset
179 *
180 * @deprecated Use #URI(String, boolean, String)
181 */
182 public URI(char[] escaped, String charset)
183 throws URIException, NullPointerException {
184 protocolCharset = charset;
185 parseUriReference(new String(escaped), true);
186 }
187
188
189 /**
190 * Construct a URI as an escaped form of a character array.
191 * An URI can be placed within double-quotes or angle brackets like
192 * "http://test.com/" and <http://test.com/>
193 *
194 * @param escaped the URI character sequence
195 * @throws URIException If the URI cannot be created.
196 * @throws NullPointerException if <code>escaped</code> is <code>null</code>
197 * @see #getDefaultProtocolCharset
198 *
199 * @deprecated Use #URI(String, boolean)
200 */
201 public URI(char[] escaped)
202 throws URIException, NullPointerException {
203 parseUriReference(new String(escaped), true);
204 }
205
206
207 /**
208 * Construct a URI from the given string with the given charset.
209 *
210 * @param original the string to be represented to URI character sequence
211 * It is one of absoluteURI and relativeURI.
212 * @param charset the charset string to do escape encoding
213 * @throws URIException If the URI cannot be created.
214 * @see #getProtocolCharset
215 *
216 * @deprecated Use #URI(String, boolean, String)
217 */
218 public URI(String original, String charset) throws URIException {
219 protocolCharset = charset;
220 parseUriReference(original, false);
221 }
222
223
224 /**
225 * Construct a URI from the given string.
226 * <p><blockquote><pre>
227 * URI-reference = [ absoluteURI | relativeURI ] [ "#" fragment ]
228 * </pre></blockquote><p>
229 * An URI can be placed within double-quotes or angle brackets like
230 * "http://test.com/" and <http://test.com/>
231 *
232 * @param original the string to be represented to URI character sequence
233 * It is one of absoluteURI and relativeURI.
234 * @throws URIException If the URI cannot be created.
235 * @see #getDefaultProtocolCharset
236 *
237 * @deprecated Use #URI(String, boolean)
238 */
239 public URI(String original) throws URIException {
240 parseUriReference(original, false);
241 }
242
243
244 /**
245 * Construct a general URI from the given components.
246 * <p><blockquote><pre>
247 * URI-reference = [ absoluteURI | relativeURI ] [ "#" fragment ]
248 * absoluteURI = scheme ":" ( hier_part | opaque_part )
249 * opaque_part = uric_no_slash *uric
250 * </pre></blockquote><p>
251 * It's for absolute URI = <scheme>:<scheme-specific-part>#
252 * <fragment>.
253 *
254 * @param scheme the scheme string
255 * @param schemeSpecificPart scheme_specific_part
256 * @param fragment the fragment string
257 * @throws URIException If the URI cannot be created.
258 * @see #getDefaultProtocolCharset
259 */
260 public URI(String scheme, String schemeSpecificPart, String fragment)
261 throws URIException {
262
263
264 if (scheme == null) {
265 throw new URIException(URIException.PARSING, "scheme required");
266 }
267 char[] s = scheme.toLowerCase().toCharArray();
268 if (validate(s, URI.scheme)) {
269 _scheme = s;
270 } else {
271 throw new URIException(URIException.PARSING, "incorrect scheme");
272 }
273 _opaque = encode(schemeSpecificPart, allowed_opaque_part,
274 getProtocolCharset());
275
276 _is_opaque_part = true;
277 _fragment = fragment == null ? null : fragment.toCharArray();
278 setURI();
279 }
280
281
282 /**
283 * Construct a general URI from the given components.
284 * <p><blockquote><pre>
285 * URI-reference = [ absoluteURI | relativeURI ] [ "#" fragment ]
286 * absoluteURI = scheme ":" ( hier_part | opaque_part )
287 * relativeURI = ( net_path | abs_path | rel_path ) [ "?" query ]
288 * hier_part = ( net_path | abs_path ) [ "?" query ]
289 * </pre></blockquote><p>
290 * It's for absolute URI = <scheme>:<path>?<query>#<
291 * fragment> and relative URI = <path>?<query>#<fragment
292 * >.
293 *
294 * @param scheme the scheme string
295 * @param authority the authority string
296 * @param path the path string
297 * @param query the query string
298 * @param fragment the fragment string
299 * @throws URIException If the new URI cannot be created.
300 * @see #getDefaultProtocolCharset
301 */
302 public URI(String scheme, String authority, String path, String query,
303 String fragment) throws URIException {
304
305
306 StringBuffer buff = new StringBuffer();
307 if (scheme != null) {
308 buff.append(scheme);
309 buff.append(':');
310 }
311 if (authority != null) {
312 buff.append("//");
313 buff.append(authority);
314 }
315 if (path != null) {
316 if ((scheme != null || authority != null)
317 && !path.startsWith("/")) {
318 throw new URIException(URIException.PARSING,
319 "abs_path requested");
320 }
321 buff.append(path);
322 }
323 if (query != null) {
324 buff.append('?');
325 buff.append(query);
326 }
327 if (fragment != null) {
328 buff.append('#');
329 buff.append(fragment);
330 }
331 parseUriReference(buff.toString(), false);
332 }
333
334
335 /**
336 * Construct a general URI from the given components.
337 *
338 * @param scheme the scheme string
339 * @param userinfo the userinfo string
340 * @param host the host string
341 * @param port the port number
342 * @throws URIException If the new URI cannot be created.
343 * @see #getDefaultProtocolCharset
344 */
345 public URI(String scheme, String userinfo, String host, int port)
346 throws URIException {
347
348 this(scheme, userinfo, host, port, null, null, null);
349 }
350
351
352 /**
353 * Construct a general URI from the given components.
354 *
355 * @param scheme the scheme string
356 * @param userinfo the userinfo string
357 * @param host the host string
358 * @param port the port number
359 * @param path the path string
360 * @throws URIException If the new URI cannot be created.
361 * @see #getDefaultProtocolCharset
362 */
363 public URI(String scheme, String userinfo, String host, int port,
364 String path) throws URIException {
365
366 this(scheme, userinfo, host, port, path, null, null);
367 }
368
369
370 /**
371 * Construct a general URI from the given components.
372 *
373 * @param scheme the scheme string
374 * @param userinfo the userinfo string
375 * @param host the host string
376 * @param port the port number
377 * @param path the path string
378 * @param query the query string
379 * @throws URIException If the new URI cannot be created.
380 * @see #getDefaultProtocolCharset
381 */
382 public URI(String scheme, String userinfo, String host, int port,
383 String path, String query) throws URIException {
384
385 this(scheme, userinfo, host, port, path, query, null);
386 }
387
388
389 /**
390 * Construct a general URI from the given components.
391 *
392 * @param scheme the scheme string
393 * @param userinfo the userinfo string
394 * @param host the host string
395 * @param port the port number
396 * @param path the path string
397 * @param query the query string
398 * @param fragment the fragment string
399 * @throws URIException If the new URI cannot be created.
400 * @see #getDefaultProtocolCharset
401 */
402 public URI(String scheme, String userinfo, String host, int port,
403 String path, String query, String fragment) throws URIException {
404
405 this(scheme, (host == null) ? null
406 : ((userinfo != null) ? userinfo + '@' : "") + host
407 + ((port != -1) ? ":" + port : ""), path, query, fragment);
408 }
409
410
411 /**
412 * Construct a general URI from the given components.
413 *
414 * @param scheme the scheme string
415 * @param host the host string
416 * @param path the path string
417 * @param fragment the fragment string
418 * @throws URIException If the new URI cannot be created.
419 * @see #getDefaultProtocolCharset
420 */
421 public URI(String scheme, String host, String path, String fragment)
422 throws URIException {
423
424 this(scheme, host, path, null, fragment);
425 }
426
427
428 /**
429 * Construct a general URI with the given relative URI string.
430 *
431 * @param base the base URI
432 * @param relative the relative URI string
433 * @throws URIException If the new URI cannot be created.
434 *
435 * @deprecated Use #URI(URI, String, boolean)
436 */
437 public URI(URI base, String relative) throws URIException {
438 this(base, new URI(relative));
439 }
440
441
442 /**
443 * Construct a general URI with the given relative URI string.
444 *
445 * @param base the base URI
446 * @param relative the relative URI string
447 * @param escaped <tt>true</tt> if URI character sequence is in escaped form.
448 * <tt>false</tt> otherwise.
449 *
450 * @throws URIException If the new URI cannot be created.
451 *
452 * @since 3.0
453 */
454 public URI(URI base, String relative, boolean escaped) throws URIException {
455 this(base, new URI(relative, escaped));
456 }
457
458
459 /**
460 * Construct a general URI with the given relative URI.
461 * <p><blockquote><pre>
462 * URI-reference = [ absoluteURI | relativeURI ] [ "#" fragment ]
463 * relativeURI = ( net_path | abs_path | rel_path ) [ "?" query ]
464 * </pre></blockquote><p>
465 * Resolving Relative References to Absolute Form.
466 *
467 * <strong>Examples of Resolving Relative URI References</strong>
468 *
469 * Within an object with a well-defined base URI of
470 * <p><blockquote><pre>
471 * http://a/b/c/d;p?q
472 * </pre></blockquote><p>
473 * the relative URI would be resolved as follows:
474 *
475 * Normal Examples
476 *
477 * <p><blockquote><pre>
478 * g:h = g:h
479 * g = http://a/b/c/g
480 * ./g = http://a/b/c/g
481 * g/ = http://a/b/c/g/
482 * /g = http://a/g
483 * //g = http://g
484 * ?y = http://a/b/c/?y
485 * g?y = http://a/b/c/g?y
486 * #s = (current document)#s
487 * g#s = http://a/b/c/g#s
488 * g?y#s = http://a/b/c/g?y#s
489 * ;x = http://a/b/c/;x
490 * g;x = http://a/b/c/g;x
491 * g;x?y#s = http://a/b/c/g;x?y#s
492 * . = http://a/b/c/
493 * ./ = http://a/b/c/
494 * .. = http://a/b/
495 * ../ = http://a/b/
496 * ../g = http://a/b/g
497 * ../.. = http://a/
498 * ../../ = http://a/
499 * ../../g = http://a/g
500 * </pre></blockquote><p>
501 *
502 * Some URI schemes do not allow a hierarchical syntax matching the
503 * <hier_part> syntax, and thus cannot use relative references.
504 *
505 * @param base the base URI
506 * @param relative the relative URI
507 * @throws URIException If the new URI cannot be created.
508 */
509 public URI(URI base, URI relative) throws URIException {
510
511 if (base._scheme == null) {
512 throw new URIException(URIException.PARSING, "base URI required");
513 }
514 if (base._scheme != null) {
515 this._scheme = base._scheme;
516 this._authority = base._authority;
517 this._is_net_path = base._is_net_path;
518 }
519 if (base._is_opaque_part || relative._is_opaque_part) {
520 this._scheme = base._scheme;
521 this._is_opaque_part = base._is_opaque_part
522 || relative._is_opaque_part;
523 this._opaque = relative._opaque;
524 this._fragment = relative._fragment;
525 this.setURI();
526 return;
527 }
528 boolean schemesEqual = Arrays.equals(base._scheme,relative._scheme);
529 if (relative._scheme != null
530 && (!schemesEqual || relative._authority != null)) {
531 this._scheme = relative._scheme;
532 this._is_net_path = relative._is_net_path;
533 this._authority = relative._authority;
534 if (relative._is_server) {
535 this._is_server = relative._is_server;
536 this._userinfo = relative._userinfo;
537 this._host = relative._host;
538 this._port = relative._port;
539 } else if (relative._is_reg_name) {
540 this._is_reg_name = relative._is_reg_name;
541 }
542 this._is_abs_path = relative._is_abs_path;
543 this._is_rel_path = relative._is_rel_path;
544 this._path = relative._path;
545 } else if (base._authority != null && relative._scheme == null) {
546 this._is_net_path = base._is_net_path;
547 this._authority = base._authority;
548 if (base._is_server) {
549 this._is_server = base._is_server;
550 this._userinfo = base._userinfo;
551 this._host = base._host;
552 this._port = base._port;
553 } else if (base._is_reg_name) {
554 this._is_reg_name = base._is_reg_name;
555 }
556 }
557 if (relative._authority != null) {
558 this._is_net_path = relative._is_net_path;
559 this._authority = relative._authority;
560 if (relative._is_server) {
561 this._is_server = relative._is_server;
562 this._userinfo = relative._userinfo;
563 this._host = relative._host;
564 this._port = relative._port;
565 } else if (relative._is_reg_name) {
566 this._is_reg_name = relative._is_reg_name;
567 }
568 this._is_abs_path = relative._is_abs_path;
569 this._is_rel_path = relative._is_rel_path;
570 this._path = relative._path;
571 }
572
573 if (relative._authority == null
574 && (relative._scheme == null || schemesEqual)) {
575 if ((relative._path == null || relative._path.length == 0)
576 && relative._query == null) {
577
578
579 this._path = base._path;
580 this._query = base._query;
581 } else {
582 this._path = resolvePath(base._path, relative._path);
583 }
584 }
585
586 if (relative._query != null) {
587 this._query = relative._query;
588 }
589
590 if (relative._fragment != null) {
591 this._fragment = relative._fragment;
592 }
593 this.setURI();
594
595
596 parseUriReference(new String(_uri), true);
597 }
598
599
600
601 /** Version ID for serialization */
602 static final long serialVersionUID = 604752400577948726L;
603
604
605 /**
606 * Cache the hash code for this URI.
607 */
608 protected int hash = 0;
609
610
611 /**
612 * This Uniform Resource Identifier (URI).
613 * The URI is always in an "escaped" form, since escaping or unescaping
614 * a completed URI might change its semantics.
615 */
616 protected char[] _uri = null;
617
618
619 /**
620 * The charset of the protocol used by this URI instance.
621 */
622 protected String protocolCharset = null;
623
624
625 /**
626 * The default charset of the protocol. RFC 2277, 2396
627 */
628 protected static String defaultProtocolCharset = "UTF-8";
629
630
631 /**
632 * The default charset of the document. RFC 2277, 2396
633 * The platform's charset is used for the document by default.
634 */
635 protected static String defaultDocumentCharset = null;
636 protected static String defaultDocumentCharsetByLocale = null;
637 protected static String defaultDocumentCharsetByPlatform = null;
638
639 static {
640 Locale locale = Locale.getDefault();
641
642 if (locale != null) {
643 defaultDocumentCharsetByLocale =
644 LocaleToCharsetMap.getCharset(locale);
645
646 defaultDocumentCharset = defaultDocumentCharsetByLocale;
647 }
648
649 try {
650 defaultDocumentCharsetByPlatform = System.getProperty("file.encoding");
651 } catch (SecurityException ignore) {
652 }
653 if (defaultDocumentCharset == null) {
654
655 defaultDocumentCharset = defaultDocumentCharsetByPlatform;
656 }
657 }
658
659
660 /**
661 * The scheme.
662 */
663 protected char[] _scheme = null;
664
665
666 /**
667 * The opaque.
668 */
669 protected char[] _opaque = null;
670
671
672 /**
673 * The authority.
674 */
675 protected char[] _authority = null;
676
677
678 /**
679 * The userinfo.
680 */
681 protected char[] _userinfo = null;
682
683
684 /**
685 * The host.
686 */
687 protected char[] _host = null;
688
689
690 /**
691 * The port.
692 */
693 protected int _port = -1;
694
695
696 /**
697 * The path.
698 */
699 protected char[] _path = null;
700
701
702 /**
703 * The query.
704 */
705 protected char[] _query = null;
706
707
708 /**
709 * The fragment.
710 */
711 protected char[] _fragment = null;
712
713
714 /**
715 * The root path.
716 */
717 protected static final char[] rootPath = { '/' };
718
719
720
721 /**
722 * The percent "%" character always has the reserved purpose of being the
723 * escape indicator, it must be escaped as "%25" in order to be used as
724 * data within a URI.
725 */
726 protected static final BitSet percent = new BitSet(256);
727
728 static {
729 percent.set('%');
730 }
731
732
733 /**
734 * BitSet for digit.
735 * <p><blockquote><pre>
736 * digit = "0" | "1" | "2" | "3" | "4" | "5" | "6" | "7" |
737 * "8" | "9"
738 * </pre></blockquote><p>
739 */
740 protected static final BitSet digit = new BitSet(256);
741
742 static {
743 for (int i = '0'; i <= '9'; i++) {
744 digit.set(i);
745 }
746 }
747
748
749 /**
750 * BitSet for alpha.
751 * <p><blockquote><pre>
752 * alpha = lowalpha | upalpha
753 * </pre></blockquote><p>
754 */
755 protected static final BitSet alpha = new BitSet(256);
756
757 static {
758 for (int i = 'a'; i <= 'z'; i++) {
759 alpha.set(i);
760 }
761 for (int i = 'A'; i <= 'Z'; i++) {
762 alpha.set(i);
763 }
764 }
765
766
767 /**
768 * BitSet for alphanum (join of alpha & digit).
769 * <p><blockquote><pre>
770 * alphanum = alpha | digit
771 * </pre></blockquote><p>
772 */
773 protected static final BitSet alphanum = new BitSet(256);
774
775 static {
776 alphanum.or(alpha);
777 alphanum.or(digit);
778 }
779
780
781 /**
782 * BitSet for hex.
783 * <p><blockquote><pre>
784 * hex = digit | "A" | "B" | "C" | "D" | "E" | "F" |
785 * "a" | "b" | "c" | "d" | "e" | "f"
786 * </pre></blockquote><p>
787 */
788 protected static final BitSet hex = new BitSet(256);
789
790 static {
791 hex.or(digit);
792 for (int i = 'a'; i <= 'f'; i++) {
793 hex.set(i);
794 }
795 for (int i = 'A'; i <= 'F'; i++) {
796 hex.set(i);
797 }
798 }
799
800
801 /**
802 * BitSet for escaped.
803 * <p><blockquote><pre>
804 * escaped = "%" hex hex
805 * </pre></blockquote><p>
806 */
807 protected static final BitSet escaped = new BitSet(256);
808
809 static {
810 escaped.or(percent);
811 escaped.or(hex);
812 }
813
814
815 /**
816 * BitSet for mark.
817 * <p><blockquote><pre>
818 * mark = "-" | "_" | "." | "!" | "~" | "*" | "'" |
819 * "(" | ")"
820 * </pre></blockquote><p>
821 */
822 protected static final BitSet mark = new BitSet(256);
823
824 static {
825 mark.set('-');
826 mark.set('_');
827 mark.set('.');
828 mark.set('!');
829 mark.set('~');
830 mark.set('*');
831 mark.set('\'');
832 mark.set('(');
833 mark.set(')');
834 }
835
836
837 /**
838 * Data characters that are allowed in a URI but do not have a reserved
839 * purpose are called unreserved.
840 * <p><blockquote><pre>
841 * unreserved = alphanum | mark
842 * </pre></blockquote><p>
843 */
844 protected static final BitSet unreserved = new BitSet(256);
845
846 static {
847 unreserved.or(alphanum);
848 unreserved.or(mark);
849 }
850
851
852 /**
853 * BitSet for reserved.
854 * <p><blockquote><pre>
855 * reserved = ";" | "/" | "?" | ":" | "@" | "&" | "=" | "+" |
856 * "$" | ","
857 * </pre></blockquote><p>
858 */
859 protected static final BitSet reserved = new BitSet(256);
860
861 static {
862 reserved.set(';');
863 reserved.set('/');
864 reserved.set('?');
865 reserved.set(':');
866 reserved.set('@');
867 reserved.set('&');
868 reserved.set('=');
869 reserved.set('+');
870 reserved.set('$');
871 reserved.set(',');
872 }
873
874
875 /**
876 * BitSet for uric.
877 * <p><blockquote><pre>
878 * uric = reserved | unreserved | escaped
879 * </pre></blockquote><p>
880 */
881 protected static final BitSet uric = new BitSet(256);
882
883 static {
884 uric.or(reserved);
885 uric.or(unreserved);
886 uric.or(escaped);
887 }
888
889
890 /**
891 * BitSet for fragment (alias for uric).
892 * <p><blockquote><pre>
893 * fragment = *uric
894 * </pre></blockquote><p>
895 */
896 protected static final BitSet fragment = uric;
897
898
899 /**
900 * BitSet for query (alias for uric).
901 * <p><blockquote><pre>
902 * query = *uric
903 * </pre></blockquote><p>
904 */
905 protected static final BitSet query = uric;
906
907
908 /**
909 * BitSet for pchar.
910 * <p><blockquote><pre>
911 * pchar = unreserved | escaped |
912 * ":" | "@" | "&" | "=" | "+" | "$" | ","
913 * </pre></blockquote><p>
914 */
915 protected static final BitSet pchar = new BitSet(256);
916
917 static {
918 pchar.or(unreserved);
919 pchar.or(escaped);
920 pchar.set(':');
921 pchar.set('@');
922 pchar.set('&');
923 pchar.set('=');
924 pchar.set('+');
925 pchar.set('$');
926 pchar.set(',');
927 }
928
929
930 /**
931 * BitSet for param (alias for pchar).
932 * <p><blockquote><pre>
933 * param = *pchar
934 * </pre></blockquote><p>
935 */
936 protected static final BitSet param = pchar;
937
938
939 /**
940 * BitSet for segment.
941 * <p><blockquote><pre>
942 * segment = *pchar *( ";" param )
943 * </pre></blockquote><p>
944 */
945 protected static final BitSet segment = new BitSet(256);
946
947 static {
948 segment.or(pchar);
949 segment.set(';');
950 segment.or(param);
951 }
952
953
954 /**
955 * BitSet for path segments.
956 * <p><blockquote><pre>
957 * path_segments = segment *( "/" segment )
958 * </pre></blockquote><p>
959 */
960 protected static final BitSet path_segments = new BitSet(256);
961
962 static {
963 path_segments.set('/');
964 path_segments.or(segment);
965 }
966
967
968 /**
969 * URI absolute path.
970 * <p><blockquote><pre>
971 * abs_path = "/" path_segments
972 * </pre></blockquote><p>
973 */
974 protected static final BitSet abs_path = new BitSet(256);
975
976 static {
977 abs_path.set('/');
978 abs_path.or(path_segments);
979 }
980
981
982 /**
983 * URI bitset for encoding typical non-slash characters.
984 * <p><blockquote><pre>
985 * uric_no_slash = unreserved | escaped | ";" | "?" | ":" | "@" |
986 * "&" | "=" | "+" | "$" | ","
987 * </pre></blockquote><p>
988 */
989 protected static final BitSet uric_no_slash = new BitSet(256);
990
991 static {
992 uric_no_slash.or(unreserved);
993 uric_no_slash.or(escaped);
994 uric_no_slash.set(';');
995 uric_no_slash.set('?');
996 uric_no_slash.set(';');
997 uric_no_slash.set('@');
998 uric_no_slash.set('&');
999 uric_no_slash.set('=');
1000 uric_no_slash.set('+');
1001 uric_no_slash.set('$');
1002 uric_no_slash.set(',');
1003 }
1004
1005
1006 /**
1007 * URI bitset that combines uric_no_slash and uric.
1008 * <p><blockquote><pre>
1009 * opaque_part = uric_no_slash *uric
1010 * </pre></blockquote><p>
1011 */
1012 protected static final BitSet opaque_part = new BitSet(256);
1013
1014 static {
1015
1016 opaque_part.or(uric_no_slash);
1017 opaque_part.or(uric);
1018 }
1019
1020
1021 /**
1022 * URI bitset that combines absolute path and opaque part.
1023 * <p><blockquote><pre>
1024 * path = [ abs_path | opaque_part ]
1025 * </pre></blockquote><p>
1026 */
1027 protected static final BitSet path = new BitSet(256);
1028
1029 static {
1030 path.or(abs_path);
1031 path.or(opaque_part);
1032 }
1033
1034
1035 /**
1036 * Port, a logical alias for digit.
1037 */
1038 protected static final BitSet port = digit;
1039
1040
1041 /**
1042 * Bitset that combines digit and dot fo IPv$address.
1043 * <p><blockquote><pre>
1044 * IPv4address = 1*digit "." 1*digit "." 1*digit "." 1*digit
1045 * </pre></blockquote><p>
1046 */
1047 protected static final BitSet IPv4address = new BitSet(256);
1048
1049 static {
1050 IPv4address.or(digit);
1051 IPv4address.set('.');
1052 }
1053
1054
1055 /**
1056 * RFC 2373.
1057 * <p><blockquote><pre>
1058 * IPv6address = hexpart [ ":" IPv4address ]
1059 * </pre></blockquote><p>
1060 */
1061 protected static final BitSet IPv6address = new BitSet(256);
1062
1063 static {
1064 IPv6address.or(hex);
1065 IPv6address.set(':');
1066 IPv6address.or(IPv4address);
1067 }
1068
1069
1070 /**
1071 * RFC 2732, 2373.
1072 * <p><blockquote><pre>
1073 * IPv6reference = "[" IPv6address "]"
1074 * </pre></blockquote><p>
1075 */
1076 protected static final BitSet IPv6reference = new BitSet(256);
1077
1078 static {
1079 IPv6reference.set('[');
1080 IPv6reference.or(IPv6address);
1081 IPv6reference.set(']');
1082 }
1083
1084
1085 /**
1086 * BitSet for toplabel.
1087 * <p><blockquote><pre>
1088 * toplabel = alpha | alpha *( alphanum | "-" ) alphanum
1089 * </pre></blockquote><p>
1090 */
1091 protected static final BitSet toplabel = new BitSet(256);
1092
1093 static {
1094 toplabel.or(alphanum);
1095 toplabel.set('-');
1096 }
1097
1098
1099 /**
1100 * BitSet for domainlabel.
1101 * <p><blockquote><pre>
1102 * domainlabel = alphanum | alphanum *( alphanum | "-" ) alphanum
1103 * </pre></blockquote><p>
1104 */
1105 protected static final BitSet domainlabel = toplabel;
1106
1107
1108 /**
1109 * BitSet for hostname.
1110 * <p><blockquote><pre>
1111 * hostname = *( domainlabel "." ) toplabel [ "." ]
1112 * </pre></blockquote><p>
1113 */
1114 protected static final BitSet hostname = new BitSet(256);
1115
1116 static {
1117 hostname.or(toplabel);
1118
1119 hostname.set('.');
1120 }
1121
1122
1123 /**
1124 * BitSet for host.
1125 * <p><blockquote><pre>
1126 * host = hostname | IPv4address | IPv6reference
1127 * </pre></blockquote><p>
1128 */
1129 protected static final BitSet host = new BitSet(256);
1130
1131 static {
1132 host.or(hostname);
1133
1134 host.or(IPv6reference);
1135 }
1136
1137
1138 /**
1139 * BitSet for hostport.
1140 * <p><blockquote><pre>
1141 * hostport = host [ ":" port ]
1142 * </pre></blockquote><p>
1143 */
1144 protected static final BitSet hostport = new BitSet(256);
1145
1146 static {
1147 hostport.or(host);
1148 hostport.set(':');
1149 hostport.or(port);
1150 }
1151
1152
1153 /**
1154 * Bitset for userinfo.
1155 * <p><blockquote><pre>
1156 * userinfo = *( unreserved | escaped |
1157 * ";" | ":" | "&" | "=" | "+" | "$" | "," )
1158 * </pre></blockquote><p>
1159 */
1160 protected static final BitSet userinfo = new BitSet(256);
1161
1162 static {
1163 userinfo.or(unreserved);
1164 userinfo.or(escaped);
1165 userinfo.set(';');
1166 userinfo.set(':');
1167 userinfo.set('&');
1168 userinfo.set('=');
1169 userinfo.set('+');
1170 userinfo.set('$');
1171 userinfo.set(',');
1172 }
1173
1174
1175 /**
1176 * BitSet for within the userinfo component like user and password.
1177 */
1178 public static final BitSet within_userinfo = new BitSet(256);
1179
1180 static {
1181 within_userinfo.or(userinfo);
1182 within_userinfo.clear(';');
1183 within_userinfo.clear(':');
1184 within_userinfo.clear('@');
1185 within_userinfo.clear('?');
1186 within_userinfo.clear('/');
1187 }
1188
1189
1190 /**
1191 * Bitset for server.
1192 * <p><blockquote><pre>
1193 * server = [ [ userinfo "@" ] hostport ]
1194 * </pre></blockquote><p>
1195 */
1196 protected static final BitSet server = new BitSet(256);
1197
1198 static {
1199 server.or(userinfo);
1200 server.set('@');
1201 server.or(hostport);
1202 }
1203
1204
1205 /**
1206 * BitSet for reg_name.
1207 * <p><blockquote><pre>
1208 * reg_name = 1*( unreserved | escaped | "$" | "," |
1209 * ";" | ":" | "@" | "&" | "=" | "+" )
1210 * </pre></blockquote><p>
1211 */
1212 protected static final BitSet reg_name = new BitSet(256);
1213
1214 static {
1215 reg_name.or(unreserved);
1216 reg_name.or(escaped);
1217 reg_name.set('$');
1218 reg_name.set(',');
1219 reg_name.set(';');
1220 reg_name.set(':');
1221 reg_name.set('@');
1222 reg_name.set('&');
1223 reg_name.set('=');
1224 reg_name.set('+');
1225 }
1226
1227
1228 /**
1229 * BitSet for authority.
1230 * <p><blockquote><pre>
1231 * authority = server | reg_name
1232 * </pre></blockquote><p>
1233 */
1234 protected static final BitSet authority = new BitSet(256);
1235
1236 static {
1237 authority.or(server);
1238 authority.or(reg_name);
1239 }
1240
1241
1242 /**
1243 * BitSet for scheme.
1244 * <p><blockquote><pre>
1245 * scheme = alpha *( alpha | digit | "+" | "-" | "." )
1246 * </pre></blockquote><p>
1247 */
1248 protected static final BitSet scheme = new BitSet(256);
1249
1250 static {
1251 scheme.or(alpha);
1252 scheme.or(digit);
1253 scheme.set('+');
1254 scheme.set('-');
1255 scheme.set('.');
1256 }
1257
1258
1259 /**
1260 * BitSet for rel_segment.
1261 * <p><blockquote><pre>
1262 * rel_segment = 1*( unreserved | escaped |
1263 * ";" | "@" | "&" | "=" | "+" | "$" | "," )
1264 * </pre></blockquote><p>
1265 */
1266 protected static final BitSet rel_segment = new BitSet(256);
1267
1268 static {
1269 rel_segment.or(unreserved);
1270 rel_segment.or(escaped);
1271 rel_segment.set(';');
1272 rel_segment.set('@');
1273 rel_segment.set('&');
1274 rel_segment.set('=');
1275 rel_segment.set('+');
1276 rel_segment.set('$');
1277 rel_segment.set(',');
1278 }
1279
1280
1281 /**
1282 * BitSet for rel_path.
1283 * <p><blockquote><pre>
1284 * rel_path = rel_segment [ abs_path ]
1285 * </pre></blockquote><p>
1286 */
1287 protected static final BitSet rel_path = new BitSet(256);
1288
1289 static {
1290 rel_path.or(rel_segment);
1291 rel_path.or(abs_path);
1292 }
1293
1294
1295 /**
1296 * BitSet for net_path.
1297 * <p><blockquote><pre>
1298 * net_path = "//" authority [ abs_path ]
1299 * </pre></blockquote><p>
1300 */
1301 protected static final BitSet net_path = new BitSet(256);
1302
1303 static {
1304 net_path.set('/');
1305 net_path.or(authority);
1306 net_path.or(abs_path);
1307 }
1308
1309
1310 /**
1311 * BitSet for hier_part.
1312 * <p><blockquote><pre>
1313 * hier_part = ( net_path | abs_path ) [ "?" query ]
1314 * </pre></blockquote><p>
1315 */
1316 protected static final BitSet hier_part = new BitSet(256);
1317
1318 static {
1319 hier_part.or(net_path);
1320 hier_part.or(abs_path);
1321
1322 hier_part.or(query);
1323 }
1324
1325
1326 /**
1327 * BitSet for relativeURI.
1328 * <p><blockquote><pre>
1329 * relativeURI = ( net_path | abs_path | rel_path ) [ "?" query ]
1330 * </pre></blockquote><p>
1331 */
1332 protected static final BitSet relativeURI = new BitSet(256);
1333
1334 static {
1335 relativeURI.or(net_path);
1336 relativeURI.or(abs_path);
1337 relativeURI.or(rel_path);
1338
1339 relativeURI.or(query);
1340 }
1341
1342
1343 /**
1344 * BitSet for absoluteURI.
1345 * <p><blockquote><pre>
1346 * absoluteURI = scheme ":" ( hier_part | opaque_part )
1347 * </pre></blockquote><p>
1348 */
1349 protected static final BitSet absoluteURI = new BitSet(256);
1350
1351 static {
1352 absoluteURI.or(scheme);
1353 absoluteURI.set(':');
1354 absoluteURI.or(hier_part);
1355 absoluteURI.or(opaque_part);
1356 }
1357
1358
1359 /**
1360 * BitSet for URI-reference.
1361 * <p><blockquote><pre>
1362 * URI-reference = [ absoluteURI | relativeURI ] [ "#" fragment ]
1363 * </pre></blockquote><p>
1364 */
1365 protected static final BitSet URI_reference = new BitSet(256);
1366
1367 static {
1368 URI_reference.or(absoluteURI);
1369 URI_reference.or(relativeURI);
1370 URI_reference.set('#');
1371 URI_reference.or(fragment);
1372 }
1373
1374
1375
1376
1377 /**
1378 * BitSet for control.
1379 */
1380 public static final BitSet control = new BitSet(256);
1381
1382 static {
1383 for (int i = 0; i <= 0x1F; i++) {
1384 control.set(i);
1385 }
1386 control.set(0x7F);
1387 }
1388
1389 /**
1390 * BitSet for space.
1391 */
1392 public static final BitSet space = new BitSet(256);
1393
1394 static {
1395 space.set(0x20);
1396 }
1397
1398
1399 /**
1400 * BitSet for delims.
1401 */
1402 public static final BitSet delims = new BitSet(256);
1403
1404 static {
1405 delims.set('<');
1406 delims.set('>');
1407 delims.set('#');
1408 delims.set('%');
1409 delims.set('"');
1410 }
1411
1412
1413 /**
1414 * BitSet for unwise.
1415 */
1416 public static final BitSet unwise = new BitSet(256);
1417
1418 static {
1419 unwise.set('{');
1420 unwise.set('}');
1421 unwise.set('|');
1422 unwise.set('\\');
1423 unwise.set('^');
1424 unwise.set('[');
1425 unwise.set(']');
1426 unwise.set('`');
1427 }
1428
1429
1430 /**
1431 * Disallowed rel_path before escaping.
1432 */
1433 public static final BitSet disallowed_rel_path = new BitSet(256);
1434
1435 static {
1436 disallowed_rel_path.or(uric);
1437 disallowed_rel_path.andNot(rel_path);
1438 }
1439
1440
1441 /**
1442 * Disallowed opaque_part before escaping.
1443 */
1444 public static final BitSet disallowed_opaque_part = new BitSet(256);
1445
1446 static {
1447 disallowed_opaque_part.or(uric);
1448 disallowed_opaque_part.andNot(opaque_part);
1449 }
1450
1451
1452
1453 /**
1454 * Those characters that are allowed for the authority component.
1455 */
1456 public static final BitSet allowed_authority = new BitSet(256);
1457
1458 static {
1459 allowed_authority.or(authority);
1460 allowed_authority.clear('%');
1461 }
1462
1463
1464 /**
1465 * Those characters that are allowed for the opaque_part.
1466 */
1467 public static final BitSet allowed_opaque_part = new BitSet(256);
1468
1469 static {
1470 allowed_opaque_part.or(opaque_part);
1471 allowed_opaque_part.clear('%');
1472 }
1473
1474
1475 /**
1476 * Those characters that are allowed for the reg_name.
1477 */
1478 public static final BitSet allowed_reg_name = new BitSet(256);
1479
1480 static {
1481 allowed_reg_name.or(reg_name);
1482
1483 allowed_reg_name.clear('%');
1484 }
1485
1486
1487 /**
1488 * Those characters that are allowed for the userinfo component.
1489 */
1490 public static final BitSet allowed_userinfo = new BitSet(256);
1491
1492 static {
1493 allowed_userinfo.or(userinfo);
1494
1495 allowed_userinfo.clear('%');
1496 }
1497
1498
1499 /**
1500 * Those characters that are allowed for within the userinfo component.
1501 */
1502 public static final BitSet allowed_within_userinfo = new BitSet(256);
1503
1504 static {
1505 allowed_within_userinfo.or(within_userinfo);
1506 allowed_within_userinfo.clear('%');
1507 }
1508
1509
1510 /**
1511 * Those characters that are allowed for the IPv6reference component.
1512 * The characters '[', ']' in IPv6reference should be excluded.
1513 */
1514 public static final BitSet allowed_IPv6reference = new BitSet(256);
1515
1516 static {
1517 allowed_IPv6reference.or(IPv6reference);
1518
1519 allowed_IPv6reference.clear('[');
1520 allowed_IPv6reference.clear(']');
1521 }
1522
1523
1524 /**
1525 * Those characters that are allowed for the host component.
1526 * The characters '[', ']' in IPv6reference should be excluded.
1527 */
1528 public static final BitSet allowed_host = new BitSet(256);
1529
1530 static {
1531 allowed_host.or(hostname);
1532 allowed_host.or(allowed_IPv6reference);
1533 }
1534
1535
1536 /**
1537 * Those characters that are allowed for the authority component.
1538 */
1539 public static final BitSet allowed_within_authority = new BitSet(256);
1540
1541 static {
1542 allowed_within_authority.or(server);
1543 allowed_within_authority.or(reg_name);
1544 allowed_within_authority.clear(';');
1545 allowed_within_authority.clear(':');
1546 allowed_within_authority.clear('@');
1547 allowed_within_authority.clear('?');
1548 allowed_within_authority.clear('/');
1549 }
1550
1551
1552 /**
1553 * Those characters that are allowed for the abs_path.
1554 */
1555 public static final BitSet allowed_abs_path = new BitSet(256);
1556
1557 static {
1558 allowed_abs_path.or(abs_path);
1559
1560 allowed_abs_path.andNot(percent);
1561 allowed_abs_path.clear('+');
1562 }
1563
1564
1565 /**
1566 * Those characters that are allowed for the rel_path.
1567 */
1568 public static final BitSet allowed_rel_path = new BitSet(256);
1569
1570 static {
1571 allowed_rel_path.or(rel_path);
1572 allowed_rel_path.clear('%');
1573 allowed_rel_path.clear('+');
1574 }
1575
1576
1577 /**
1578 * Those characters that are allowed within the path.
1579 */
1580 public static final BitSet allowed_within_path = new BitSet(256);
1581
1582 static {
1583 allowed_within_path.or(abs_path);
1584 allowed_within_path.clear('/');
1585 allowed_within_path.clear(';');
1586 allowed_within_path.clear('=');
1587 allowed_within_path.clear('?');
1588 }
1589
1590
1591 /**
1592 * Those characters that are allowed for the query component.
1593 */
1594 public static final BitSet allowed_query = new BitSet(256);
1595
1596 static {
1597 allowed_query.or(uric);
1598 allowed_query.clear('%');
1599 }
1600
1601
1602 /**
1603 * Those characters that are allowed within the query component.
1604 */
1605 public static final BitSet allowed_within_query = new BitSet(256);
1606
1607 static {
1608 allowed_within_query.or(allowed_query);
1609 allowed_within_query.andNot(reserved);
1610 }
1611
1612
1613 /**
1614 * Those characters that are allowed for the fragment component.
1615 */
1616 public static final BitSet allowed_fragment = new BitSet(256);
1617
1618 static {
1619 allowed_fragment.or(uric);
1620 allowed_fragment.clear('%');
1621 }
1622
1623
1624
1625
1626
1627
1628
1629 protected boolean _is_hier_part;
1630 protected boolean _is_opaque_part;
1631
1632
1633 protected boolean _is_net_path;
1634 protected boolean _is_abs_path;
1635 protected boolean _is_rel_path;
1636
1637
1638 protected boolean _is_reg_name;
1639 protected boolean _is_server;
1640
1641
1642 protected boolean _is_hostname;
1643 protected boolean _is_IPv4address;
1644 protected boolean _is_IPv6reference;
1645
1646
1647
1648 /**
1649 * Encodes URI string.
1650 *
1651 * This is a two mapping, one from original characters to octets, and
1652 * subsequently a second from octets to URI characters:
1653 * <p><blockquote><pre>
1654 * original character sequence->octet sequence->URI character sequence
1655 * </pre></blockquote><p>
1656 *
1657 * An escaped octet is encoded as a character triplet, consisting of the
1658 * percent character "%" followed by the two hexadecimal digits
1659 * representing the octet code. For example, "%20" is the escaped
1660 * encoding for the US-ASCII space character.
1661 * <p>
1662 * Conversion from the local filesystem character set to UTF-8 will
1663 * normally involve a two step process. First convert the local character
1664 * set to the UCS; then convert the UCS to UTF-8.
1665 * The first step in the process can be performed by maintaining a mapping
1666 * table that includes the local character set code and the corresponding
1667 * UCS code.
1668 * The next step is to convert the UCS character code to the UTF-8 encoding.
1669 * <p>
1670 * Mapping between vendor codepages can be done in a very similar manner
1671 * as described above.
1672 * <p>
1673 * The only time escape encodings can allowedly be made is when a URI is
1674 * being created from its component parts. The escape and validate methods
1675 * are internally performed within this method.
1676 *
1677 * @param original the original character sequence
1678 * @param allowed those characters that are allowed within a component
1679 * @param charset the protocol charset
1680 * @return URI character sequence
1681 * @throws URIException null component or unsupported character encoding
1682 */
1683
1684 protected static char[] encode(String original, BitSet allowed,
1685 String charset) throws URIException {
1686 if (original == null) {
1687 throw new IllegalArgumentException("Original string may not be null");
1688 }
1689 if (allowed == null) {
1690 throw new IllegalArgumentException("Allowed bitset may not be null");
1691 }
1692 byte[] rawdata = URLCodec.encodeUrl(allowed, EncodingUtil.getBytes(original, charset));
1693 return EncodingUtil.getAsciiString(rawdata).toCharArray();
1694 }
1695
1696 /**
1697 * Decodes URI encoded string.
1698 *
1699 * This is a two mapping, one from URI characters to octets, and
1700 * subsequently a second from octets to original characters:
1701 * <p><blockquote><pre>
1702 * URI character sequence->octet sequence->original character sequence
1703 * </pre></blockquote><p>
1704 *
1705 * A URI must be separated into its components before the escaped
1706 * characters within those components can be allowedly decoded.
1707 * <p>
1708 * Notice that there is a chance that URI characters that are non UTF-8
1709 * may be parsed as valid UTF-8. A recent non-scientific analysis found
1710 * that EUC encoded Japanese words had a 2.7% false reading; SJIS had a
1711 * 0.0005% false reading; other encoding such as ASCII or KOI-8 have a 0%
1712 * false reading.
1713 * <p>
1714 * The percent "%" character always has the reserved purpose of being
1715 * the escape indicator, it must be escaped as "%25" in order to be used
1716 * as data within a URI.
1717 * <p>
1718 * The unescape method is internally performed within this method.
1719 *
1720 * @param component the URI character sequence
1721 * @param charset the protocol charset
1722 * @return original character sequence
1723 * @throws URIException incomplete trailing escape pattern or unsupported
1724 * character encoding
1725 */
1726 protected static String decode(char[] component, String charset)
1727 throws URIException {
1728 if (component == null) {
1729 throw new IllegalArgumentException("Component array of chars may not be null");
1730 }
1731 return decode(new String(component), charset);
1732 }
1733
1734 /**
1735 * Decodes URI encoded string.
1736 *
1737 * This is a two mapping, one from URI characters to octets, and
1738 * subsequently a second from octets to original characters:
1739 * <p><blockquote><pre>
1740 * URI character sequence->octet sequence->original character sequence
1741 * </pre></blockquote><p>
1742 *
1743 * A URI must be separated into its components before the escaped
1744 * characters within those components can be allowedly decoded.
1745 * <p>
1746 * Notice that there is a chance that URI characters that are non UTF-8
1747 * may be parsed as valid UTF-8. A recent non-scientific analysis found
1748 * that EUC encoded Japanese words had a 2.7% false reading; SJIS had a
1749 * 0.0005% false reading; other encoding such as ASCII or KOI-8 have a 0%
1750 * false reading.
1751 * <p>
1752 * The percent "%" character always has the reserved purpose of being
1753 * the escape indicator, it must be escaped as "%25" in order to be used
1754 * as data within a URI.
1755 * <p>
1756 * The unescape method is internally performed within this method.
1757 *
1758 * @param component the URI character sequence
1759 * @param charset the protocol charset
1760 * @return original character sequence
1761 * @throws URIException incomplete trailing escape pattern or unsupported
1762 * character encoding
1763 *
1764 * @since 3.0
1765 */
1766 protected static String decode(String component, String charset)
1767 throws URIException {
1768 if (component == null) {
1769 throw new IllegalArgumentException("Component array of chars may not be null");
1770 }
1771 byte[] rawdata = null;
1772 try {
1773 rawdata = URLCodec.decodeUrl(EncodingUtil.getAsciiBytes(component));
1774 } catch (DecoderException e) {
1775 throw new URIException(e.getMessage());
1776 }
1777 return EncodingUtil.getString(rawdata, charset);
1778 }
1779 /**
1780 * Pre-validate the unescaped URI string within a specific component.
1781 *
1782 * @param component the component string within the component
1783 * @param disallowed those characters disallowed within the component
1784 * @return if true, it doesn't have the disallowed characters
1785 * if false, the component is undefined or an incorrect one
1786 */
1787 protected boolean prevalidate(String component, BitSet disallowed) {
1788
1789 if (component == null) {
1790 return false;
1791 }
1792 char[] target = component.toCharArray();
1793 for (int i = 0; i < target.length; i++) {
1794 if (disallowed.get(target[i])) {
1795 return false;
1796 }
1797 }
1798 return true;
1799 }
1800
1801
1802 /**
1803 * Validate the URI characters within a specific component.
1804 * The component must be performed after escape encoding. Or it doesn't
1805 * include escaped characters.
1806 *
1807 * @param component the characters sequence within the component
1808 * @param generous those characters that are allowed within a component
1809 * @return if true, it's the correct URI character sequence
1810 */
1811 protected boolean validate(char[] component, BitSet generous) {
1812
1813 return validate(component, 0, -1, generous);
1814 }
1815
1816
1817 /**
1818 * Validate the URI characters within a specific component.
1819 * The component must be performed after escape encoding. Or it doesn't
1820 * include escaped characters.
1821 * <p>
1822 * It's not that much strict, generous. The strict validation might be
1823 * performed before being called this method.
1824 *
1825 * @param component the characters sequence within the component
1826 * @param soffset the starting offset of the given component
1827 * @param eoffset the ending offset of the given component
1828 * if -1, it means the length of the component
1829 * @param generous those characters that are allowed within a component
1830 * @return if true, it's the correct URI character sequence
1831 */
1832 protected boolean validate(char[] component, int soffset, int eoffset,
1833 BitSet generous) {
1834
1835 if (eoffset == -1) {
1836 eoffset = component.length - 1;
1837 }
1838 for (int i = soffset; i <= eoffset; i++) {
1839 if (!generous.get(component[i])) {
1840 return false;
1841 }
1842 }
1843 return true;
1844 }
1845
1846
1847 /**
1848 * In order to avoid any possilbity of conflict with non-ASCII characters,
1849 * Parse a URI reference as a <code>String</code> with the character
1850 * encoding of the local system or the document.
1851 * <p>
1852 * The following line is the regular expression for breaking-down a URI
1853 * reference into its components.
1854 * <p><blockquote><pre>
1855 * ^(([^:/?#]+):)?(//([^/?#]*))?([^?#]*)(\?([^#]*))?(#(.*))?
1856 * 12 3 4 5 6 7 8 9
1857 * </pre></blockquote><p>
1858 * For example, matching the above expression to
1859 * http://jakarta.apache.org/ietf/uri/#Related
1860 * results in the following subexpression matches:
1861 * <p><blockquote><pre>
1862 * $1 = http:
1863 * scheme = $2 = http
1864 * $3 = //jakarta.apache.org
1865 * authority = $4 = jakarta.apache.org
1866 * path = $5 = /ietf/uri/
1867 * $6 = <undefined>
1868 * query = $7 = <undefined>
1869 * $8 = #Related
1870 * fragment = $9 = Related
1871 * </pre></blockquote><p>
1872 *
1873 * @param original the original character sequence
1874 * @param escaped <code>true</code> if <code>original</code> is escaped
1875 * @throws URIException If an error occurs.
1876 */
1877 protected void parseUriReference(String original, boolean escaped)
1878 throws URIException {
1879
1880
1881 if (original == null) {
1882 throw new URIException("URI-Reference required");
1883 }
1884
1885
1886
1887
1888 String tmp = original.trim();
1889
1890
1891
1892
1893
1894 int length = tmp.length();
1895
1896
1897
1898
1899 if (length > 0) {
1900 char[] firstDelimiter = { tmp.charAt(0) };
1901 if (validate(firstDelimiter, delims)) {
1902 if (length >= 2) {
1903 char[] lastDelimiter = { tmp.charAt(length - 1) };
1904 if (validate(lastDelimiter, delims)) {
1905 tmp = tmp.substring(1, length - 1);
1906 length = length - 2;
1907 }
1908 }
1909 }
1910 }
1911
1912
1913
1914
1915 int from = 0;
1916
1917
1918
1919
1920 boolean isStartedFromPath = false;
1921 int atColon = tmp.indexOf(':');
1922 int atSlash = tmp.indexOf('/');
1923 if ((atColon <= 0 && !tmp.startsWith("//"))
1924 || (atSlash >= 0 && atSlash < atColon)) {
1925 isStartedFromPath = true;
1926 }
1927
1928
1929
1930
1931
1932
1933
1934 int at = indexFirstOf(tmp, isStartedFromPath ? "/?#" : ":/?#", from);
1935 if (at == -1) {
1936 at = 0;
1937 }
1938
1939
1940
1941
1942
1943
1944
1945
1946
1947 if (at > 0 && at < length && tmp.charAt(at) == ':') {
1948 char[] target = tmp.substring(0, at).toLowerCase().toCharArray();
1949 if (validate(target, scheme)) {
1950 _scheme = target;
1951 } else {
1952 throw new URIException("incorrect scheme");
1953 }
1954 from = ++at;
1955 }
1956
1957
1958
1959
1960
1961
1962
1963
1964
1965
1966 _is_net_path = _is_abs_path = _is_rel_path = _is_hier_part = false;
1967 if (0 <= at && at < length && tmp.charAt(at) == '/') {
1968
1969 _is_hier_part = true;
1970 if (at + 2 < length && tmp.charAt(at + 1) == '/'
1971 && !isStartedFromPath) {
1972
1973 int next = indexFirstOf(tmp, "/?#", at + 2);
1974 if (next == -1) {
1975 next = (tmp.substring(at + 2).length() == 0) ? at + 2
1976 : tmp.length();
1977 }
1978 parseAuthority(tmp.substring(at + 2, next), escaped);
1979 from = at = next;
1980
1981 _is_net_path = true;
1982 }
1983 if (from == at) {
1984
1985 _is_abs_path = true;
1986 }
1987 }
1988
1989
1990
1991
1992
1993
1994
1995
1996
1997 if (from < length) {
1998
1999 int next = indexFirstOf(tmp, "?#", from);
2000 if (next == -1) {
2001 next = tmp.length();
2002 }
2003 if (!_is_abs_path) {
2004 if (!escaped
2005 && prevalidate(tmp.substring(from, next), disallowed_rel_path)
2006 || escaped
2007 && validate(tmp.substring(from, next).toCharArray(), rel_path)) {
2008
2009 _is_rel_path = true;
2010 } else if (!escaped
2011 && prevalidate(tmp.substring(from, next), disallowed_opaque_part)
2012 || escaped
2013 && validate(tmp.substring(from, next).toCharArray(), opaque_part)) {
2014
2015 _is_opaque_part = true;
2016 } else {
2017
2018 _path = null;
2019 }
2020 }
2021 String s = tmp.substring(from, next);
2022 if (escaped) {
2023 setRawPath(s.toCharArray());
2024 } else {
2025 setPath(s);
2026 }
2027 at = next;
2028 }
2029
2030
2031 String charset = getProtocolCharset();
2032
2033
2034
2035
2036
2037
2038
2039
2040
2041 if (0 <= at && at + 1 < length && tmp.charAt(at) == '?') {
2042 int next = tmp.indexOf('#', at + 1);
2043 if (next == -1) {
2044 next = tmp.length();
2045 }
2046 if (escaped) {
2047 _query = tmp.substring(at + 1, next).toCharArray();
2048 if (!validate(_query, uric)) {
2049 throw new URIException("Invalid query");
2050 }
2051 } else {
2052 _query = encode(tmp.substring(at + 1, next), allowed_query, charset);
2053 }
2054 at = next;
2055 }
2056
2057
2058
2059
2060
2061
2062
2063
2064
2065 if (0 <= at && at + 1 <= length && tmp.charAt(at) == '#') {
2066 if (at + 1 == length) {
2067 _fragment = "".toCharArray();
2068 } else {
2069 _fragment = (escaped) ? tmp.substring(at + 1).toCharArray()
2070 : encode(tmp.substring(at + 1), allowed_fragment, charset);
2071 }
2072 }
2073
2074
2075 setURI();
2076 }
2077
2078
2079 /**
2080 * Get the earlier index that to be searched for the first occurrance in
2081 * one of any of the given string.
2082 *
2083 * @param s the string to be indexed
2084 * @param delims the delimiters used to index
2085 * @return the earlier index if there are delimiters
2086 */
2087 protected int indexFirstOf(String s, String delims) {
2088 return indexFirstOf(s, delims, -1);
2089 }
2090
2091
2092 /**
2093 * Get the earlier index that to be searched for the first occurrance in
2094 * one of any of the given string.
2095 *
2096 * @param s the string to be indexed
2097 * @param delims the delimiters used to index
2098 * @param offset the from index
2099 * @return the earlier index if there are delimiters
2100 */
2101 protected int indexFirstOf(String s, String delims, int offset) {
2102 if (s == null || s.length() == 0) {
2103 return -1;
2104 }
2105 if (delims == null || delims.length() == 0) {
2106 return -1;
2107 }
2108
2109 if (offset < 0) {
2110 offset = 0;
2111 } else if (offset > s.length()) {
2112 return -1;
2113 }
2114
2115 int min = s.length();
2116 char[] delim = delims.toCharArray();
2117 for (int i = 0; i < delim.length; i++) {
2118 int at = s.indexOf(delim[i], offset);
2119 if (at >= 0 && at < min) {
2120 min = at;
2121 }
2122 }
2123 return (min == s.length()) ? -1 : min;
2124 }
2125
2126
2127 /**
2128 * Get the earlier index that to be searched for the first occurrance in
2129 * one of any of the given array.
2130 *
2131 * @param s the character array to be indexed
2132 * @param delim the delimiter used to index
2133 * @return the ealier index if there are a delimiter
2134 */
2135 protected int indexFirstOf(char[] s, char delim) {
2136 return indexFirstOf(s, delim, 0);
2137 }
2138
2139
2140 /**
2141 * Get the earlier index that to be searched for the first occurrance in
2142 * one of any of the given array.
2143 *
2144 * @param s the character array to be indexed
2145 * @param delim the delimiter used to index
2146 * @param offset The offset.
2147 * @return the ealier index if there is a delimiter
2148 */
2149 protected int indexFirstOf(char[] s, char delim, int offset) {
2150 if (s == null || s.length == 0) {
2151 return -1;
2152 }
2153
2154 if (offset < 0) {
2155 offset = 0;
2156 } else if (offset > s.length) {
2157 return -1;
2158 }
2159 for (int i = offset; i < s.length; i++) {
2160 if (s[i] == delim) {
2161 return i;
2162 }
2163 }
2164 return -1;
2165 }
2166
2167
2168 /**
2169 * Parse the authority component.
2170 *
2171 * @param original the original character sequence of authority component
2172 * @param escaped <code>true</code> if <code>original</code> is escaped
2173 * @throws URIException If an error occurs.
2174 */
2175 protected void parseAuthority(String original, boolean escaped)
2176 throws URIException {
2177
2178
2179 _is_reg_name = _is_server =
2180 _is_hostname = _is_IPv4address = _is_IPv6reference = false;
2181
2182
2183 String charset = getProtocolCharset();
2184
2185 boolean hasPort = true;
2186 int from = 0;
2187 int next = original.indexOf('@');
2188 if (next != -1) {
2189
2190 _userinfo = (escaped) ? original.substring(0, next).toCharArray()
2191 : encode(original.substring(0, next), allowed_userinfo,
2192 charset);
2193 from = next + 1;
2194 }
2195 next = original.indexOf('[', from);
2196 if (next >= from) {
2197 next = original.indexOf(']', from);
2198 if (next == -1) {
2199 throw new URIException(URIException.PARSING, "IPv6reference");
2200 } else {
2201 next++;
2202 }
2203
2204 _host = (escaped) ? original.substring(from, next).toCharArray()
2205 : encode(original.substring(from, next), allowed_IPv6reference,
2206 charset);
2207
2208 _is_IPv6reference = true;
2209 } else {
2210 next = original.indexOf(':', from);
2211 if (next == -1) {
2212 next = original.length();
2213 hasPort = false;
2214 }
2215
2216 _host = original.substring(from, next).toCharArray();
2217 if (validate(_host, IPv4address)) {
2218
2219 _is_IPv4address = true;
2220 } else if (validate(_host, hostname)) {
2221
2222 _is_hostname = true;
2223 } else {
2224
2225 _is_reg_name = true;
2226 }
2227 }
2228 if (_is_reg_name) {
2229
2230 _is_server = _is_hostname = _is_IPv4address =
2231 _is_IPv6reference = false;
2232
2233 if (escaped) {
2234 _authority = original.toCharArray();
2235 if (!validate(_authority, reg_name)) {
2236 throw new URIException("Invalid authority");
2237 }
2238 } else {
2239 _authority = encode(original, allowed_reg_name, charset);
2240 }
2241 } else {
2242 if (original.length() - 1 > next && hasPort
2243 && original.charAt(next) == ':') {
2244 from = next + 1;
2245 try {
2246 _port = Integer.parseInt(original.substring(from));
2247 } catch (NumberFormatException error) {
2248 throw new URIException(URIException.PARSING,
2249 "invalid port number");
2250 }
2251 }
2252
2253 StringBuffer buf = new StringBuffer();
2254 if (_userinfo != null) {
2255 buf.append(_userinfo);
2256 buf.append('@');
2257 }
2258 if (_host != null) {
2259 buf.append(_host);
2260 if (_port != -1) {
2261 buf.append(':');
2262 buf.append(_port);
2263 }
2264 }
2265 _authority = buf.toString().toCharArray();
2266
2267 _is_server = true;
2268 }
2269 }
2270
2271
2272 /**
2273 * Once it's parsed successfully, set this URI.
2274 *
2275 * @see #getRawURI
2276 */
2277 protected void setURI() {
2278
2279 StringBuffer buf = new StringBuffer();
2280
2281 if (_scheme != null) {
2282 buf.append(_scheme);
2283 buf.append(':');
2284 }
2285 if (_is_net_path) {
2286 buf.append("//");
2287 if (_authority != null) {
2288 buf.append(_authority);
2289 }
2290 }
2291 if (_opaque != null && _is_opaque_part) {
2292 buf.append(_opaque);
2293 } else if (_path != null) {
2294
2295 if (_path.length != 0) {
2296 buf.append(_path);
2297 }
2298 }
2299 if (_query != null) {
2300 buf.append('?');
2301 buf.append(_query);
2302 }
2303
2304 _uri = buf.toString().toCharArray();
2305 hash = 0;
2306 }
2307
2308
2309
2310
2311 /**
2312 * Tell whether or not this URI is absolute.
2313 *
2314 * @return true iif this URI is absoluteURI
2315 */
2316 public boolean isAbsoluteURI() {
2317 return (_scheme != null);
2318 }
2319
2320
2321 /**
2322 * Tell whether or not this URI is relative.
2323 *
2324 * @return true iif this URI is relativeURI
2325 */
2326 public boolean isRelativeURI() {
2327 return (_scheme == null);
2328 }
2329
2330
2331 /**
2332 * Tell whether or not the absoluteURI of this URI is hier_part.
2333 *
2334 * @return true iif the absoluteURI is hier_part
2335 */
2336 public boolean isHierPart() {
2337 return _is_hier_part;
2338 }
2339
2340
2341 /**
2342 * Tell whether or not the absoluteURI of this URI is opaque_part.
2343 *
2344 * @return true iif the absoluteURI is opaque_part
2345 */
2346 public boolean isOpaquePart() {
2347 return _is_opaque_part;
2348 }
2349
2350
2351 /**
2352 * Tell whether or not the relativeURI or heir_part of this URI is net_path.
2353 * It's the same function as the has_authority() method.
2354 *
2355 * @return true iif the relativeURI or heir_part is net_path
2356 * @see #hasAuthority
2357 */
2358 public boolean isNetPath() {
2359 return _is_net_path || (_authority != null);
2360 }
2361
2362
2363 /**
2364 * Tell whether or not the relativeURI or hier_part of this URI is abs_path.
2365 *
2366 * @return true iif the relativeURI or hier_part is abs_path
2367 */
2368 public boolean isAbsPath() {
2369 return _is_abs_path;
2370 }
2371
2372
2373 /**
2374 * Tell whether or not the relativeURI of this URI is rel_path.
2375 *
2376 * @return true iif the relativeURI is rel_path
2377 */
2378 public boolean isRelPath() {
2379 return _is_rel_path;
2380 }
2381
2382
2383 /**
2384 * Tell whether or not this URI has authority.
2385 * It's the same function as the is_net_path() method.
2386 *
2387 * @return true iif this URI has authority
2388 * @see #isNetPath
2389 */
2390 public boolean hasAuthority() {
2391 return (_authority != null) || _is_net_path;
2392 }
2393
2394 /**
2395 * Tell whether or not the authority component of this URI is reg_name.
2396 *
2397 * @return true iif the authority component is reg_name
2398 */
2399 public boolean isRegName() {
2400 return _is_reg_name;
2401 }
2402
2403
2404 /**
2405 * Tell whether or not the authority component of this URI is server.
2406 *
2407 * @return true iif the authority component is server
2408 */
2409 public boolean isServer() {
2410 return _is_server;
2411 }
2412
2413
2414 /**
2415 * Tell whether or not this URI has userinfo.
2416 *
2417 * @return true iif this URI has userinfo
2418 */
2419 public boolean hasUserinfo() {
2420 return (_userinfo != null);
2421 }
2422
2423
2424 /**
2425 * Tell whether or not the host part of this URI is hostname.
2426 *
2427 * @return true iif the host part is hostname
2428 */
2429 public boolean isHostname() {
2430 return _is_hostname;
2431 }
2432
2433
2434 /**
2435 * Tell whether or not the host part of this URI is IPv4address.
2436 *
2437 * @return true iif the host part is IPv4address
2438 */
2439 public boolean isIPv4address() {
2440 return _is_IPv4address;
2441 }
2442
2443
2444 /**
2445 * Tell whether or not the host part of this URI is IPv6reference.
2446 *
2447 * @return true iif the host part is IPv6reference
2448 */
2449 public boolean isIPv6reference() {
2450 return _is_IPv6reference;
2451 }
2452
2453
2454 /**
2455 * Tell whether or not this URI has query.
2456 *
2457 * @return true iif this URI has query
2458 */
2459 public boolean hasQuery() {
2460 return (_query != null);
2461 }
2462
2463
2464 /**
2465 * Tell whether or not this URI has fragment.
2466 *
2467 * @return true iif this URI has fragment
2468 */
2469 public boolean hasFragment() {
* @return true iif the relativeURI is rel_path
2438 < name="2450" href="#2450">24502360 *ring(from, next).toCharArray()
*ring(from, ne5o="2465" 6f="#2376">2376 * @return true iif the relativeU)89">> * TellJ }
2387 6">2336 pub(from heme "#2420">2420 ref="#22064me="21>23365tiveUrue iif the ref="#22064me="21>23365tiveUrue iif the ref="#22064me="21>23365tiveUrue iif the 2373ref="#22064me="21>23365tiveUrue iif the <() {
2437 *7I is net_path.="2379" href="#2379">2312 * Tell wheth1>23365tive2387" 9>2465 * Tell name 2426 2465 <365tive2387" 9>2465 l48rel_p9me="2387" href="#2387">2387 l48re1M =666ame="/a> this URI is I3365tiveUru> g>);
isef="#s rel_path
249ef="6="#2324">23399 re {
2437 > 2452
233ef="#2398">2a> 2" href="#23 "21>21891="2333" href="#2333">2333 *="2272" href="#2272">2272 ef="#2399">7124r4rn true 4 73759" hrerel_p 4 _is_seris URI is rel_path.
2375 *
2376 * @return true iif the relativeURI is rel_pnot the aut4 4 href0s I3365tiveUru> g>) 5c " hreI3365tiveUru"23827href="79th
t5942399 publa nam4stron38 ef="#29 hre.233e2I is relativ2405 /9ame="2375" href6200ame="2363" href="#2363"396" a @trong>null) |847n2e="2285" hreifnull) |)pem>
239y 23912396" href="#23me="25return2286 buf.append("//");
249ef="6="#2324">23399 re {
2437 7ef="#2377">2ss="st8rRI is IPname="2376"href="#2450"em> * this URI is server." hreI33652 }
"//");
2415 454 hrei4799ame="2375" href6200ame="2363" href="#2lI0760rst7k"#2395">2391239Io/str> 48="#24m="#2374">231239Io/str> 48="#24m="#2374">231239Io/str> 48="name="2421"ref="#2401"> 2391239Io/str> 48="#24m70>233e2I is relativ2452
2396 81
6!0"#2ef="# {
243lr3bs_path<6valid authority")
233t#2248">2248 > " hreI3365tiveUru"23827href="79th
" hreI33652 [C1ref="#22064me="21>23365tlhref=28- 5 is Iis URI has t);
2312n8="#2429">24402"leref="79th
2267 name="2405" hre9Io/str> 48="#oei4799ame="2375" href3');
re24m70>233e2I is r
242#2347">2347!8Ang>return name="2405" hre9Io/str> uthor+347!m70> r
21em>/*
public boolean hasUserin 648="#/a> e="strong> hasUserin 2360 }
2267 name="2405" hre9Io/str> 48="#oei4799ame="2375" href3');
re24m70>233e2I8em> F1b
2 F1n:48 is hostname5446">2446 *
2396 *
242#2347">2347!8Ang>retn222a> 347">2347! *
<=8 hr96" h=e24mg};
955> * @return
F1berinf a name58e * @return
F50" href="#2430">2425m *
<92f="#229 u a name58e<1435">24352396 #222314 }
24ng>re233uC 21262126
ne34x name="2446> isIPv4address() {
2440 11ne34x name="2446> isIPv4address() {
92760pum05/a> <2375" href="#2375">23755e947! o c6tRry249m1rel_pnot the a> pub#22>ifm/a> 955> >245602href="#2436">2436u a name7> F50" href="]5624402"leref="2n9227 href="#2trong>return _is_IPv4address;
2441 }
246967 name=7oerin};
955> >245602href="#2436">2436243aS65uf.append(_name="e02href="#2436">2436246966799">718URI is server.
2172 * @param escaped <code>true
public booI is IPv6re-396" href="#2396">rel2375"69i 2,whether or not this U54> e="2402" href="#24
2436
< 51w=7oerin};
955> >s U54> e=" 5ref="#2370">2370 }
67namref="# 9a namref="#2396">2396 #2228ance in
2142 a> 6e-396" href() {
:
is> 0 24404]956 * @re2348m>
me="2302" href="#2302">2302 }
b 1">2275 9" hreN9f="#ng> (_schemehref="#2459"="#21trong>if boo]e4">ongv6renul3p8d317nr #haa65ref=" 1">2>boolong>public<|| (_authority n0server./strong> 6""#d F50"7oerin e="2387" href="#2387"2me7>n4>
2142 a> 6ron9 #2228ance in
2435 -9 #2228ance /**229e=7oerin};
955> >245602href="#2436">2436m>
* @return truen
* 52228arongance in 64me="21>23365tiveUru72href. iif the ra>*
42">2142 a> 6ron9 #2228ance in
24404]956 * @re2348m>
me="2302" href="#2302">2302 }
2272 1">2>boolon92me7>n hrOname="2178" href="#2178">2178
<=8 hr96" h=e26 re6ro6t,6 /9ame="2 "#2436"escapedem>
62363"6== -1) {
2uf.append(_s is/{@link URI is hostname67k"#2395">236123966782I8em7, ic em>
228671 -1) {
2N Poame40append(_s {
<2t of this URI is hostname6end(224 * @ry compo"i6> is> ss=em>
[] escapedem>
6""#2440">6 name="2253"6href=674m>
uf.append(_s,2N Poame40append(_s f="#2452">246 * this URI6is se6753" href*/
em>
buf.app"#2317">2317<6448">" hreI36652 6792">2292 2310">23#2317">2317<64272 re6d nam67a name="2386" href="#260ame="2363" 6ref="67 *
261239I68387 6="#24m70>23362I is68is URI has authority
81
24c> typ8" h201"246,a 6="2440,="#2467">,ity
683 authority
20 ,ef7" 9>24652435
2
< 231em>
rong>puescape= this therel_pn435">2435 * this URI6e="2168hether or not > /9ame="2 "#2436"escapedem>
687 -1) {
2uf.append(_s is/{@link URI is hostname6 name58e6 688
955> >245602#a> em>
68="#o6427 * @return true ii6turn 6 name6ostname
24y compo"i6> is> Escapedem>
2336 * 6 public2370">2rn 4m70>2../../../../org/F1beri/324"ons/http="#237/uf.append(_s.html">uf.append(_sstronf="#2452">246g>public 69 > 67 nam6="2406
2317<65449" "#2#746>2 632 2310">23#2317">2317<646 6 *<692228ance /**242#2346">23469n};
955> >245662 name58e 69
F50" hre6="#2469n truen
26352435 702405" hre9Io/str> uthor+347!m70>7ority
<7 nam670799">718URI is se36 uthor+347!m70>7o2ity
<7 2am67072 /tringBuffer buf47{
2373 * @rub(f="dress,>[] class=em>
next &&15oname=7oerin91 ;2429" href=7{5/**7e9N7ef="]56244027leref7>
2435 243aS65uf7appen712405" hre9Io/str> uthor+347!m70>7#2|9i#2469">746976799">718URI is se36 uthor+347!m70>7hserveh69" h7e72">7172 /tringBuffer buf47h
224 he relativEscapedem>
next &&15oname=7oerin91 i2365 *
?7 r:te.
3#2317">2317<7rority conem7
/**
7e9N7in};
955>7>s U571
21471a name=ee="2="#2435"2435 uthor+347!m70>7 }
718URI is se36 uthor+347!m70>7 serveh69" h7ng>b 72uf.append(_s is/{@link #de,URI} fails URI is hostname7 72n _is_r/tringBuffer buf47"2me7>n4>
224 he relativem>
2uf.append(_s "2429" href=7">2435 -7 725> next &&15oname=7oerin91 i2365 *
?7 r:tde,URIn ,2429" href=7"s server.7e=7oe72642" href="#2142">2142tiv rel_pns URI2" hr3#2317">2317<72href="#24367>24367292">2292"#2345">23457amN5em> 7 @ret72> Buffer buf47@return trus7729 public boolean isOpaquePart() {
23365tiveUr772hre7> */
serveh69" h7 a> 67on9 #2228ance 35"
2370 }
_is_abs_path;
<7/>2435 -7 7em class="comment" 2394 <7e="2393" hre7="#237{
24/s7 {
[] class=459" href="#2459">2459<7fmN5em> 72437<738> next &&15oname=7oerin91
#2317">2317<7freturn trus7Autho73"#2303">2303 7 href="#238772me7>7e="2377" href="#237! *
<=7 hr9<741"2377" href="#237!serveh69" h7is Ii74> _uri = buf.toString().t72
2307
<75718URI is se36
_is_abs_path;
<72">2322 7em246746 class="comment" 2394 <7tPatro 77759" 74 Tell whether or not this URI has72272 re7usme 7482242">224 he relativEscaped459" href="#2459">2459<77437749 boolean hasQuery() {
2365 *
?7 r:te.
2317<7
2477 > 7 2420 7 true iif t7not t75
718URI is se36 <**
_is_abs_path;
<7mPatro 77m|7a 757 name="2359" hre#2370">2uf.append(_s is/{@link #de,URI} fails URI is hostname7m272 re7759" 758 class="comment" 2394 <72272 7ef="#7527 * @return true ii7m>
224 he relativ459" href="2370">2uf.append(_s "2429" href=7@return true7iif t761 boolean hasQuery() {
2365 *
?7 r:tde,URIn2142tiv rel_pns URI2" hr3#2317">2317<7t 240ame="2419" 7tame="2453" 7 _is_765"#2452">249ef="6="#2324">23399 re {
2437 7ef="#2377">2ss="st8rRI is IPnam23="2"#24 @return true ii7me="2452" hr77e9N7 *="2272" href="#2272"7<272 re7ro6t,76 * 72363"769">2400 * b
<=8 hr96" h=e277k"#2395">2371239677272me="server-b 6="2222222222=="#2467"> |
20 |
20< 9>2465 <365tive2387" 77return true7">228771Ang>retn222a> 347"
<=8 hr96" h=e27end( 48="36 <"#24 @return true ii7 name="2253"7href=7 re 2394 <7 * this URI7is se77m>
[] class=a> f="#2459">2459<7448">" hreI37652 7792">2292 15oname=7oerin91 2317<74272 re7d nam77a name="2386" href="#270ame="2363" 7ref="77 *
271239I78387 7="#24m70>23372I is78is URI has authority
81*783">2400 * b
<=8 hr96" h=e27>
|
20 |
20< 9>2465 <365tive2387" 7> * this URI7e="2178 c6tRry347"
<=8 hr96" h=e27m, next).toC7nd( /**
7 7" href="#2426">24262370">2uf.append(_s is/{@link #de,URI} fails URI is hostname7hre9Io/str> 78="#o7836">24362394 <7turn 7 name79_name="e02href="* @return true ii7t"#24m70>2337 * 7 pu he relativa> f="2370">2uf.append(_s "2429" href=7g>public 7922">2292 15oname=ifstrong> hasQ 6="2sHostname() {
2317<75449" "#2#747>2 732 }&15oname=urn<91 2317<75, next).toC7">23479642" href="#2186" href="#272 name58e 7992">2292"#2345">23457> F50" hre7="#2479> Buffer buf47e58e<1435">2735249ef="6="#2324">23399 re {
2437 7ef="#2377">2ss="st8rRI is IPnam23="22440 @return true ii8name="2452778> 80387 8ority
<8 nam680is URI has authority
<8 2am6802*
<8 3am6803">2400 eboolean-e="2440="24"6="hrxt>2dme=from= <>2a>4"6="hthis U5be22" href="me="2465" hr8{4
2435 718URI is se36 <2440 @return true ii8n7" h55 F50877eri80/a> * Teif -1etPatref=648=0" h35hre440his U454 #2365">s U454 ##"246-ba242465relat of this>2
* @return true ii85">243aS65uf8appen81stname
24i>22459<8#2|9i#2469">8469811 boolean ha_2440;2459">2459<8#2ity
<8e72">81/strong> _is_hostname;8h
2451 8s IPv6re-3968 href814"#2452">249ef="6="#2324">23399 re {
2437 7ef="#2377">2ss="st8rRI is IPnam23="22ath @return true ii8552451 8s4" h55 F508m>
955>8>s U58> e=" 5ref="S5"21481a name=ee="2="#24"#2436"escapedPath <2ath >231239Io/streturn @return true ii84404]956 8 @re2820href="#2426">24262370">2uf.append(_s this theerro Ulass= tebope the 23384g @return true ii842|9i#2469">8ame="82799">718URI is se3
<8ng>b 8272 /tringBuffer buf48 82#2242">224 * @ry compo"i6> is> ss=Pathm * @rub(f="dress,>[] escapedPath="2370">2uf.append(_s "2429" href=8"2me7>n4>
next &&15oname=ifstrong> hasescapedPath 2365 * || escapedPath.length 2360="#2459">2459<8">2435 -8 8252459<8"s server.8e=7oe82642" href="#2142">2310">23#2317">2317<82href="#24368>24368272317<82mref="#23968 @ret82842" href="#2186" href="#28@return trus8829 23399 rremovsQuery" href="#24402"fi<2375" href="#23758arongance in8/em228ean haescapedPath 2rremovsng>) |)pI4402"fi<2sescapedPath3#2317">2317<8>23365tiveUr872hre8312">2292 15oname=ifstrong> hasQis_net_2ath || Qis_abs_2ath="#2459">2459<8>serveh69" h8 a> 68322459<8>/strong> /**<83342" href="#2142">21423p8d317nr #haa65ref=" 1">2>boolong>public2../../../../org/F1beri/324"ons/http="#237/uf.append(_s.html">uf.append(_sstro(uf.append(_s.PARSING,2459">2459<8>2me7>n4>
214242">2142 a> 6ron92435 -8 835 has!validatesescapedPath, abs_2ath=="#2459">2459<8>href="#24368#237083742" href="#2142">21423p8d317nr #haa65ref=" 1">2>boolong>public2../../../../org/F1beri/324"ons/http="#237/uf.append(_s.html">uf.append(_sstro(uf.append(_s.ESCAPING,2459">2459<8>mref="#239682437<83842" href="#2142">214242">2142 a> 6ron9836 2459<8! *
<=8 hr9<841 }&15oname=urn<91 hasQis_rel_2ath="#2459">2459<8!serveh69" h8is Ii8422459<8!/strong> 2459<8n true iif t8ress(84442" href="#2142">21423p8d317nr #haa65ref=" 1">2>boolong>public2../../../../org/F1beri/324"ons/http="#237/uf.append(_s.html">uf.append(_sstro(uf.append(_s.PARSING,2 a> 6ron9publi2ath0ong
2322 8em2468468tPatro 78759" 84742" href="#2142">2142&& !validatesescapedPath, at, -1etabs_2ath=" 6""#2440">8tmref="#23968usme 84842" href="#2142">2142|| ane! * 0 && !validatesescapedPath, 0,#-1etrel_se) |)pg="#2459">2459<8nreturn trus84378493" href*/
21423p8d317nr #haa65ref=" 1">2>boolong>public2../../../../org/F1beri/324"ons/http="#237/uf.append(_s.html">uf.append(_sstro(uf.append(_s.ESCAPING,2459">2459<8thi#23952if 8h3w 85142" href="#2142">214242">2142 a> 6ron9248522459<8 true iif t8not t854 }&15oname=urn<91 hasQis_oparet_2art="#2459">2459<8name="2453" 82420<8558me="2452" hr8f="#285642" href="#2142">2142&& !validatesescapedPath, 1,#-1eturicg="#2459">2459<8mPatro 78m|7a 85742" href="#2142">21423p8d317nr #haa65ref=" 1">2>boolong>public2../../../../org/F1beri/324"ons/http="#237/uf.append(_s.html">uf.append(_sstro(uf.append(_s.ESCAPING,2459">2459<8m272 re8759" 85842" href="#2142">214242"> a> 6ron9
2459<8@return true8iif t861 }&15oname=urn<91 2>boolong>public2../../../../org/F1beri/324"ons/http="#237/uf.append(_s.html">uf.append(_sstro(uf.append(_s.PARSING,2 a> 6ron9publi2ath0ong
2310">23#2317">2317<8tame="2453" 8 _is_862228ance /**7e9N87e9N8<272 re8ro6t,86n truen
82363"869">2400 S5"23812396872405" hre9Io/str> uthor+347!m70>87return true8">228871 -1) {
24262370">2uf.append(_s this theerro Ulass= tebope the 23384g @return true ii8me="server-b8sed n87399">718URI is se3
24y compo"i6> is> EscapedPathmame="24escapedPath="2370">2uf.append(_s "2429" href=8ing(0,5ef="#8402"l876> next &&15oname=ifstrong> hasescapedPath 2365 *="#2459">2459<8448">" hreI38652 8772317<84272 re8d nam87842" href="#2142">2310">23#2317">2317<80ame="2363" 8ref="8792317<84m="#2374">281239I88042" href="#2186" href="#28="#24m70>23382I is881 231ss=PathmescapedPath.to URIArrayhr3#2317">2317<8a> 81 _is_hostname;8="# {
88451">2451 8> 2451 8> * this URI8e="21885 truen
/9ame="2 S5"88elativ8 88 /9ame="2 "#2436"path <2ath hes2thtringBuffer buf48hre9Io/str> 88="#o88= -1) {
2uf.append(_s rom inng>publlyUlas" href="#onlnamaveh69" hre72"8turn 8 name89_name="e02href="#3 2338 * 89rong>pub(72333public 892tname
24y compo"i6> is> Pathmame="24path="2370">2uf.append(_s "2429" href=8g"# {
2451 85449" "#2#748>2 89 > next &&15oname=ifstrong> haspath 2365 * || path.lengthhe a> 0="#2459">2459<8g * this URI8 *<8952317<85, next).toC8">23489642" href="#2142">2310">23#2317">2317<82 name58e 8972317<8> F50" hre8="#2489842" href="#2186" href="#28e58e<1435">2835 23399 r",ref="on"#24 908m>
ame="243/stron = tiv rel_pns URI2" hr; F1n:489n1me="2452779>1 901"2377" href="#239o2ity
<9 2am69022">2292 15oname=ifstrong> hasQis_net_2ath || Qis_abs_2ath="#2459">2459<9o3ity
<9 3am6903
<9 4am6904 }&15oname=urn<91 hasQis_rel_2ath="#2459">2459<9{52459<9n7" h55 F50977eri90723399 rne246 08#238 F1n:489n8" h55 F50978eri90842" href="#2142">21423p8d317nr #haa65ref=" 1">2>boolong>public2../../../../org/F1beri/324"ons/http="#237/uf.append(_s.html">uf.append(_sstro(uf.append(_s.PARSING,2459">2459<9n9" h55 F50979eri90942" href="#2142">214242">2142 a> 6ron9publirelativ <2ath0ong
243aS65uf9appen91094699112459<9#2ity
<9e72">91242" href="#2142">2142buf<.append(e" 6ron(0,#an),hasUowed_rel_2ath,2459">2459<9h
214242">214222223/strongname="2="#243954ity
<9 href91442" href="#2142">2142buf<.append(e" 6ron(an),hasUowed_abs_2ath,me="2="#243955214242">214222223/strongname="2="#243956955>9>s U591742" href="#2142">2142buf<.append(e"2396918214919 2317<94404]956 9 @re2948m>
}&15oname=urn<91 hasQis_oparet_2art="#2459">2459<942|9i#2469">9ame="9303" href*/
2317<942ity
<9ng>b 92242" href="#2142">buf. n01" (0,#e" 6ron(0,#1)eturic_no_sm> h,23/strongname="2="#2439 92342" href="#2142">buf. n01" (1,#e" 6ron(1)eturic,23/strongname="2="#2439<4ity
<9name=92142" href="#2142">_oparet = buf.to" href7).to URIArrayhr#2317">2317<9452>boolong>public2../../../../org/F1beri/324"ons/http="#237/uf.append(_s.html">uf.append(_sstro(uf.append(_s.PARSING,2 a> 6ron9publi2ath0ong
243692723#2317">2317<9@return trus992"#2303">2303 9arongance in9/em229 name="2367" href=9>23365tiveUr972hre931"2377" href="#239>serveh69" h9 a> 693> _uri = buf.toString().t9>/strong> /**<9em>5440">24404]956ResolvsQueryba4ity
<9e="2393="2307" href="#2307">2307
<9/>2435 -9 9em class="comment" #2436"ba231239Io/arrayiif the ba2307
<9/s server.9="#23936 /9ame="2 "#2436"hrlPath a >231239Io/arrayiif the hrlPath307">2307
<9/href="#24369#237093/a> * Tell whethe mref="#239692437<93 href="#2426">24262370">2uf.append(_s no more highIo/2ath le24l namb return trus9Autho9327 * @return true ii9 href="#238792me7>94stname
* @rub(f="dress,>[] resolvsPathm * @rub(f="dress,>[] ba[] relPath)urn true ii9 23365tiveUr9 hr9<94public2370">2rn 4m70>2../../../../org/F1beri/324"ons/http="#237/uf.append(_s.html">uf.append(_sstronf="#2452">249!serveh69" h9is Ii94 > 9!/strong> 23399 rREMINDME:tpaths/arerne246
<9ress(94442" href="#21ame="24ba *
?7 a> 6ron90ong
2317<95 > 9!s server.9em24694623399 r_2ath = bu994emp94">2394 <9tPatro 79759" 9472">2292 15oname=ifstrong> hashrlPath 2365 * || hrlPath.length 2360="#2459">2459<9tmref="#23969usme 94842" href="#2142">rong>boolean hanormalize7ba2317<95return trus94379493" href*/ hashrlPath[0]2=Ho'/'="#2459">2459<9
rong>boolean hanormalize7relPath)#2317">2317<9thi#23952if 9h3w 951 }&15oname=urn<91 249522459<9 2459<9
4ity
<9not t95442" href="#2142">2142ba 6ron(0,#an +#1).to URIArrayhr#2317">2317<9name="2453" 92420<955ame="2Buf2142+ hrlPath.lengthr#2317">2317<9nmref="#23969759" 95842" href="#2142">buf<.append(sane!= -1="?=ba 6ron(0,#an +#1)r:te.a> a> 6ron9/0ong
2317<9m>
rong>boolean hanormalize7buf<.to" href7).to URIArrayhr)#2317">2317<9mhi#23952if 9iif t961 }2317">2317<9m {
_is_hostname;9t 2451 9tiveUru"23829href=900">240ame="2419" 9tame="2453" 9 _is_965 truen
retn222a> 35"2olle8=(_s,2 h mark ('/'=hthis U5bebuf.toString().t9*>2dme=with at/ <"6=tr>231239Io/if the 2ath hes2th.buf.toString().t92400 buf.toString().t97k"#2395">2391239697272me="server"#2436"path <2athbuf.toString().t97hi#23952if 9">22897799">718URI is se36 24262370">2uf.append(_s no hierarchy le24lbuf.toString().t97 _is_r/tringBuffer buf49 name="2253"9href=974tname
* @rub(f="dress,>[] class=Cur natHierPathm * @rub(f="dress,>[] path="2370">2uf.append(_s "2429" href=9 * this URI9is se975/a> > 9ing(0,5ef="#9402"l976> next &&15oname=ifstrong> hasQis_oparet_2art="#2459">2459<9448">" hreI39652 9772>boolong>public2../../../../org/F1beri/324"ons/http="#237/uf.append(_s.html">uf.append(_sstro(uf.append(_s.PARSING,2 a> 6ron9 re9d nam97842" href="#2186" href="#290ame="2363" 9ref="979> next &&15oname=ifstrong> haspath 2365 *="#2459">2459<94m="#2374">291239I9802>boolong>public2../../../../org/F1beri/324"ons/http="#237/uf.append(_s.html">uf.append(_sstro(uf.append(_s.PARSING,2 a> 6ron923392I is981 }2317">2317<9a> 8198o]e4">ongv6renul3p8d31i>22459<9> ongv6renul3p8d31i>22459<9> * this URI9e="21985> next &&15oname=ifstrong> has"6=tr=360="#2459">2459<9m, next).toC9nd(rong>boolean harootPath;2459">2459<9a name58e9873" href*/ hasfirst != "6=tr&& "6=tr!= -1="#2459">2459<9 name58e9 98842" href="#2142">rong>boolean habuf<.sub> 6ron(0,#"6=t).to URIArrayhr#2317">2317<9hre9Io/str> 98="#o989 }2317">2317<9turn 9 name99023399 rFIXME:tit = bu994a #2469">24onU454 ##"246 sisp @return true ii9t"#24m70>2339 * 991 boolean hapath;2459">2459<9g>public 99/strong> _is_hostname;9g"# {
2451 95449" "#2#749>2 990">240ame="2419" 9g * this URI9 *<995 truen
234998Ang>retn222a> 35" 99elativ F50" hre9="#24998370">2370 }
29352uf.append(_s is/{@link #class=Cur natHierPathmub(f[])} fails.buf.toString().30name="2452730nam>30na _is_r/tringBuffer buf30n1me="2452730n1m>30n1ref="#23m4/s7 {
[] class=Cur natHierPathm="2370">2uf.append(_s "2429" href30n2me="2452730n2m>30n2 boolean hasQpath 2365 *
?7 r:tclass=Cur natHierPathm_pathname="2="#2430n3me="2452730n3m>30nolean30n4]e4">oame="2419"30n5me="2452730n5m>30n5/a> > 30n6me="2452730n6m>30n6s URI has authority
30na> #2228ance in< @return true i30n9me="2452730n9m>30n999">718URI is se36 3010 -1) {
2uf.append(_s is/{@link #class=Cur natHierPathmub(f[])} fails.buf.toString().3011me="245273011m>3011 _is_r/tringBuffer buf3012me="245273012m>30122242">224 he relativEscapedCur natHierPathm="2370">2uf.append(_s "2429" href3013me="245273013m>301o]e4">ongv6renul3p8d31ub(f="dress,>[] path = tivss=Cur natHierPathm=ame="2="#243014me="245273014m>301 > next &&15oname=7oerin91 *
?7 r:tstname() a name="2313" hrefspathname="2="#243015me="245273015m>3012228ance /**3016/**301
301n truen
301a name=ee="2="#2435"3022405" hre9Io/str> uthor+347!m703021me="245273021m>302799">718URI is se36 302uf.append(_s is/{@link #class=Cur natHierPathmub(f[])} fails.buf.toString().3023me="245273023m>302399">718URI is se3 3024 _is_r/tringBuffer buf3025me="245273025m>3025RI has tn he relativCur natHierPathm="2370">2uf.append(_s "2429" href3026me="245273026m>3026]e4">ongv6renul3p8d31ub(f="dress,>[] path = tivss=Cur natHierPathm=ame="2="#243027me="245273027m>3027> next &&15oname=7oerin91 *
?7 r:tt,,URIn2ath,2tiv rel_pns URI2" hr3#2317">23173028me="245273028m>3028228ance /**302930 name="2367" href30 1me="245273031m>30> */
2me="245273032m>30on9 #2228ance 35"30g>return _is_abs_path;
30g4me="245273034m>30#2370">2370 }
30em class="comment" 2370">2uf.append(_s is/{@link #class=Cur natHierPathmub(f[])} fails.buf.toString().3036me="245273036m>30{
3037"#2452">24/s7 {
[] class=AbovsHierPathm="2370">2uf.append(_s "2429" href3038me="245273038m>3038> next &&15oname=ub(f="dress,>[] path = tivss=Cur natHierPathm=ame="2="#243039me="245273039m>3039> next &&15oname=7oerin91 *
?7 r:ttivss=Cur natHierPathmpathname="2="#24304ame="24527304am>3040228ance /**3041"2377" href="#23042me="245273042m>304 > 3043me="245273043m>3043 */
3045return _is_abs_path;
3046me="245273046m>3046370">2370 }
3047 class="comment" 2370">2uf.append(_s is/{@link #class=Cur natHierPathmub(f[])} fails.buf.toString().3048me="245273048m>30482uf.append(_s "2429" href305ame="24527305am>305042" href="#2115oname=ub(f="dress,>[] path = tivss=ebovsHierPathm=ame="2="#243051me="245273051m>3051> next &&15oname=7oerin91 *
?7 r:tstname() a name="2313" hrefspathname="2="#243052me="245273052m>3052228ance /**3053/a> > 3054me="245273054m>3054/a> > 3055me="245273055m>3055 */
3057return _is_abs_path;
3058me="245273058m>3058370">2370 }
305= -1) {
2uf.append(_s is/{@link #class=Cur natHierPathmub(f[])} fails.buf.toString().306ame="24527306am>306099">718URI is se3 3061 _is_r/tringBuffer buf3062me="245273062m>30622242">224 he relativebovsHierPathm="2370">2uf.append(_s "2429" href3063me="245273063m>306342" href="#2115oname=ub(f="dress,>[] path = tivss=ebovsHierPathm=ame="2="#243064me="245273064m>3064> next &&15oname=7oerin91 *
?7 r:tt,,URIn2ath,2tiv rel_pns URI2" hr3#2317">23173065me="245273065m>3062228ance /**3066ref="#2452">7e93067me="245273067m>306
306n truen
306a name=ee="2="#2435"307272me="server * b
<=8 hr96" h=e3071me="245273071m>307799">718URI is se path 222222222==[tabs_2ath | oparet_2art ]>
<=8 hr96" h=e3072me="245273072m>3072href="#2426">242347"
<=8 hr96" h=e3073me="245273073m>307>return _is_abs_path;
3074me="245273074m>3072370">2370 }
307m>
3076ref="#23m4/s7 {
[] class=Pathm=""2429" href3077me="245273077m>30792">2292 15oname=7oerin91 23173078me="245273078m>3078228ance /**3079308name="2367" href3081me="245273081m>308 */
3083">2400 * b
<=8 hr96" h=e3084me="245273084m>308sa nam>
<=8 hr96" h=e3085me="245273085m>308 c6tRry tabs_2ath 22222=="/"34path_se) |)ps >
<=8 hr96" h=e3086me="245273086m>3086 /9ame="2 oparet_2art 22==uric_no_sm> h *uric>
<=8 hr96" h=e3087me="245273087m>30 * Te347"
<=8 hr96" h=e3088me="245273088m>308a> #2228ance in< @return true i3089me="245273089m>308999">718URI is se36 30 pu he relativEscapedPathm=""2429" href3092me="245273092m>30922">2292 15oname=ub(f="dress,>[] path = tivss=Pathm=ame="2="#243093me="245273093m>3093> next &&15oname=7oerin91 *
?7 r:tstname() a name="2313" hrefspathname="2="#243094me="245273094m>309 > next &a /**3095/a> > 3096me="245273096m>3096ref="#2452">7e93097me="245273097m>3097 */
3099">2400 * b
<=8 hr96" h=e31name="2452731nam>3100a nam>
<=8 hr96" h=e31n1me="2452731n1m>3101Ang>retn222a> 347"
<=8 hr96" h=e3102me="2452731n2m>310299">718URI is se36 <2ath hes2thtringBuffer buf31n3me="2452731n3m>3103">2400 62370">2uf.append(_s is/{@link #de,URI} fails.tringBuffer buf31n4me="2452731n4m>310499">718URI is se3 310m>
3106strong>pu he relativPathm="2370">2uf.append(_s " urn true i31n7me="2452731n7m>31072">2292 15oname=ub(f="dress,>[] path = tivss=Pathm=ame="2="#2431n8me="2452731n8m>3108> next &&15oname=7oerin91 *
?7 r:tt,,URIn2ath,2tiv rel_pns URI2" hr3#2317">231731n9me="2452731n9m>310"#2303">2303 311ame="24527311am>311name="2367" href3111me="245273111m>3111ame="2367" href3112me="245273112m>311> _uri = buf.toString().3113me="245273113m>3113 name=ee="2="#2435" if the 2ath.tringBuffer buf3114me="245273114m>311="2307" href="#2307">2307
3115me="245273115m>3115370">2370 }
307">2307
3116me="245273116m>311
24/s7 {
[] class=Nr bm=""2429" href3118me="245273118m>3118> next &&15oname=ifstrong> hasQpath 2365 *="#"2367" href3119me="245273119m>31192317312ame="24527312am>312042" href="#2186" href="#3121me="245273121m>3121ame="2367" href3122me="245273122m>3122]e4">ongv6renul3p8d31i>223173123me="245273123m>3123> next &&15oname=forstrong> hasul3p8d31i>215oname=ifstrong> hasQpath[i]2=Ho'/'="#2459">24593125me="245273125m>312542" href="#2142">2142anef=i +#1#2317">23173126me="245273126m>312642" href="#2142">21423p8d31breaka name="2#2317">23173127me="245273127m>3127312842" href="#2186" href="#3129me="245273129m>3129]e4">ongv6renul3p8d31i>22317313ame="24527313am>313042" href="#2115oname=ub(f="dress,>[] ba = " 1">2>boolong>public[len]#2317">23173131me="245273131m>31312">2292 System.arraycopy(_2ath,2at, ba, 0,#len3#2317">231731>2me="245273132m>3132 boolean haba#2317">231731>3me="245273133m>313olean3134/a> > 3135me="245273135m>3135/a> > 3136me="245273136m>3136s URI has authority
3137 _is_r435" if the 2ath.tringBuffer buf3138me="245273138m>313a> #2228ance in< @return true i3139me="245273139m>313999">718URI is se36 hes2thtringBuffer buf314ame="24527314am>314a _is_r/tringBuffer buf3141me="245273141m>314pu he relativEscapedNr bm=""2429" href3142me="245273142m>314242" href="#2115oname=ub(f="dress,>[] ba = class=Nr bm=#2317">23173143me="245273143m>3143> next &&15oname=7oerin91 =365 *
?7 r:tstname() a name="2313" hrefsba=#2317">23173144me="245273144m>314 > next &a /**3145/a> > 3146me="245273146m>3146/a> > 3147me="245273147m>3147 */
if the 2ath.tringBuffer buf3149me="245273149m>3149> #2228ance in< @return true i315ame="24527315am>315099">718URI is se36 hes2thtringBuffer buf3151me="245273151m>3151">2400 62370">2uf.append(_s inngmplete trail="24escape 2attern or une="2440="tringBuffer buf3152me="245273152m>315299">718URI is se>231239Io/ this th8#238 F1n:48<3153me="245273153m>315399">718URI is se3 3154 _is_r/tringBuffer buf3155me="245273155m>3155RI has tn he relativNr bm="2370">2uf.append(_s "2429" href3156me="245273156m>315642" href="#2115oname=ub(f="dress,>[] ba = class=Nr bm=#2317">23173157me="245273157m>3157> next &&15oname=7oerin91 =365 *
?7 r:tt,,URInclass=Nr bm=,2317">23173158me="245273158m>315842" href="#2142">2142tiv rel_pns URI2" hr3#2317">23173159me="245273159m>315"#2303">2303 316ame="24527316am>316name="2367" href3161me="245273161m>3161"#2452">249ef="6="#2324">23399 re {
2437 7ef="#2377">2ss="st8rR23="22athn 23query >
<=8 hr96" h=e3162me="245273162m>3162ame="2367" href3163me="245273163m>3163 */
3166370">2370 }
31relativ316n truen * @rub(f="dress,>[] class=PathQuerym=""2429" href3169me="245273169m>31693170> next &&15oname=ifstrong> hasQpath 2365 *r&& _query 2365 *="#2459">24593171me="245273171m>317123173172me="245273172m>317242" href="#2186" href="#3173me="245273173m>317342" href="#21ame="2Buf23173174me="245273174m>3174> next &&15oname=ifstrong> hasQpath !365 *="#2459">24593175me="245273175m>3175317642" href="#2186" href="#3177me="245273177m>31772">2292 15oname=ifstrong> has_query !365 *="#2459">24593178me="245273178m>317842" href="#2142">buf<.append('?'name="2="#243179me="245273179m>3179318042" href="#2186" href="#3181me="245273181m>3181> next &&15oname=7oerin91 23173182me="245273182m>318/strong> _is_hostname3183me="245273183m>318451">2451 3184me="245273184m>3184/a> > 3185me="245273185m>3185 truen
3186 _is_r435"
<=8 hr96" h=e3188me="245273188m>318899">718URI is se36 he relativEscapedPathQuerym=""2429" href3191me="245273191m>3191 booub(f="dress,>[] rs=PathQuery = tivss=PathQuerym=#2317">23173192me="245273192m>3192 boolean hasrs=PathQuery =365 *
?7 r:tstname() a name="2313" hrefsrs=PathQuery=#2317">23173193me="245273193m>319olean3194/a> > 3195me="245273195m>3195/a> > 3196me="245273196m>3196s URI has authority
319a> #2228ance in< @return true i3199me="245273199m>319999">718URI is se36 <2ath 23query hes2th.tringBuffer buf32name="2452732nam>3200">2400 62370">2uf.append(_s inngmplete trail="24escape 2attern or une="2440="tringBuffer buf32n1me="2452732n1m>3201Ang>retn222a> >231239Io/ this th8#238 F1n:48<3202me="2452732n2m>320299">718URI is se3 320n _is_r/tringBuffer buf3204me="2452732n4m>3204strong>pu he relativPathQuerym="2370">2uf.append(_s "2429" href32n5me="2452732n5m>3205 booub(f="dress,>[] rs=PathQuery = tivss=PathQuerym=#2317">231732n6me="2452732n6m>3206 boolean hasrs=PathQuery =365 *
?7 r:tt,,URInrs=PathQuery,2317">231732n7me="2452732n7m>320742" href="#2142">2142tiv rel_pns URI2" hr3#2317">231732n8me="2452732n8m>3208228ance /**3209321023399 re {
2437 7ef="#2377">2ss="st8rRss="st8rR23="2query >
<=8 hr96" h=e3211me="245273211m>3211ame="2367" href3212me="245273212m>321> _uri = buf.toString().3213me="245273213m>3213 name=ee="2="#24S5"2307
3215me="245273215m>3215 -1) {
2307
3216me="245273216m>3216href="#2426">24262370">2uf.append(_s scaped6queryss= tvalid307">2307
3217me="245273217m>321elativ3218tname
24y compo"i6> is> ss=Querymrong>booub(f="dress,>[] escapedQuery="2370">2uf.append(_s "2429" href3219me="245273219m>3219> next &&15oname=ifstrong> hasescapedQuery =365 * || escapedQuery.length 2360="#2459">2459322ame="24527322am>3226 23173221me="245273221m>32303" href*/
23#2317">23173232me="245273222m>322223173223me="245273223m>322342" href="#2186" href="#3224me="245273224m>322142" href="#2149ef="6="#2324">23399 rremovsQuery" href="#idf="ifiertringBuffer buf3225me="245273225m>322542" href="#21escapedQuery =rremovsF href="Idf="ifiersescapedQuery3#2317">23173236me="245273226m>3226> next &&15oname=ifstrong> has!validatesescapedQuery,6query)="#2459">24593227me="245273227m>32272>boolong>public2../../../../org/F1beri/324"ons/http="#237/uf.append(_s.html">uf.append(_sstro(uf.append(_s.ESCAPING,2459">24593228me="245273228m>322842" href="#2142">214242"> a> 6ron9322942" href="#2186" href="#323ame="24527323am>323042" href="#21_query 2 escapedQuery#2317">23173231me="245273231m>323142" href="#212310">23#2317">23173232me="245273232m>323/strong> _is_hostname32>3me="245273233m>323451">2451 32g4me="245273234m>3234/a> > 3235me="245273235m>3235 truen
3236">2400 S5"323elativ3238 -1) {
<=8 hr96" h=e3239me="245273239m>3239href="#2426">24262370">2uf.append(_s scaped6queryss= tvalid307">2307
324ame="24527324am>324a _is_r/tringBuffer buf3241me="245273241m>3241tname
24y compo"i6> is> EscapedQuerymame="24escapedQuery="2370">2uf.append(_s "2429" href3242me="245273242m>3242> next &&15oname=ifstrong> hasescapedQuery =365 *="#2459">24593243me="245273243m>3243 23173244me="245273244m>32443" href*/
23#2317">23173245me="245273245m>324523173246me="245273246m>324642" href="#2186" href="#3247me="245273247m>32472">2292 > ss=QuerymescapedQuery.to URIArrayhr)#2317">23173248me="245273248m>3248228ance /**32493250325 */
718URI is seS5"2400 * tringBuffer buf3254me="245273254m>3254 _is_r When a6query hes2th>2231239IostringBuffer buf3255me="245273255m>3255 -1) {
2dme=to use in= this thee 2400 * tringBuffer buf3258me="245273258m>3258370">2370 3="2addid(_salnAPIsthe <454 #pecialnpurpose us="24byhe 231239Ios used in= bertebol_pns/arerimpleef="ed in= bertebol_pnstringBuffer buf326ame="24527326am>326099">718URI is seem> es inheri"ed from ,URI>uf.
. So23384g.tringBuffer buf3262me="245273262m>3262lativ3263 -1) {
2uf.append(_s inngmplete trail="24escape 2attern or une="2440="tringBuffer buf3265me="245273265m>3265return >231239Io/ this th8#238 F1n:48<3266me="245273266m>3266370">2370 24y compo"i6> is> Querymame="24query="2370">2uf.append(_s "2429" href3269me="245273269m>3269> next &&15oname=ifstrong> hasquery =365 * || query.lengthhe a> 0="#2459">2459327ame="24527327am>3276 *
?7 r:tquery.to URIArrayhr#2317">23173271me="245273271m>32703" href*/
23#2317">23173272me="245273272m>327223173273me="245273273m>327342" href="#2186" href="#3274me="245273274m>3274> next &&> ss=Queryme"23173275me="245273275m>3272228ance /**3276/a> > 3277me="245273277m>3277/a> > 3278me="245273278m>327n truen
327a name=ee="2="#2435" uthor+347!m703281me="245273281m>3281370">2370 }
2307
3282me="245273282m>3282/tringBuffer buf3283me="245273283m>328o]e4">ongvm/s7 {
[] class=Querym=""2429" href3284me="245273284m>3284> next &&15oname=7oerin91 23173285me="245273285m>3282228ance /**3286/a> > 3287me="245273287m>3287/a> > 3288me="245273288m>328n truen
3289 _is_r435" uthor+347!m703291me="245273291m>329199">718URI is se36
<=8 hr96" h=e3292me="245273292m>3292/tringBuffer buf3293me="245273293m>3293strong>pu he relativEscapedQuerym=""2429" href3294me="245273294m>3294> next &&15oname=7oerin91 *
?7 r:tstname() a name="2313" hrefs_queryname="2="#243295me="245273295m>3292228ance /**3296ref="#2452">7e93297me="245273297m>3297/a> > 3298me="245273298m>329n truen
3299 _is_r435" uthor+347!m7033n1me="2452733n1m>330199">718URI is se36 2uf.append(_s inngmplete trail="24escape 2attern or une="2440="tringBuffer buf33n3me="2452733n3m>3303">2400 >231239Io/ this th8#238 F1n:48<3304me="2452733n4m>330499">718URI is se3 330m>
3306strong>pu he relativQuerym="2370">2uf.append(_s "2429" href33n7me="2452733n7m>3307> next &&15oname=7oerin91 *
?7 r:tt,,URIn_query,6tiv rel_pns URI2" hr3;2429" href33n8me="2452733n8m>3308228ance /**3309331023399 re {
2437 7ef="#2377">2ss="st8rRss="st 3="2" href="# @return true i3311me="245273311m>3311ame="2367" href3312me="245273312m>331> _uri = buf.toString().3313me="245273313m>3313 name=ee="2="#24S5"331="2307" href="#2307">2307
3315me="245273315m>3315 -1) {
2307
3316me="245273316m>3316href="#2426">24262370">2uf.append(_s scaped6" href="#s= tvalid307">2307
3317me="245273317m>331elativ3318tname
24y compo"i6> is> ss=F href="mrong>booub(f="dress,>[] escapedF href="="2370">2uf.append(_s "2429" href3319me="245273319m>3319> next &&15oname=ifstrong> hasescapedF href="<=365 * || escapedF href=".length 2360="#2459">2459332ame="24527332am>3326
h f=0#2317">23173332me="245273322m>332223173323me="245273323m>332342" href="#2186" href="#3324me="245273324m>3324> next &&15oname=ifstrong> has!validatesescapedF href=",6" href=")="#2459">24593325me="245273325m>33252>boolong>public2../../../../org/F1beri/324"ons/http="#237/uf.append(_s.html">uf.append(_sstro(uf.append(_s.ESCAPING,2459">24593336me="245273326m>332642" href="#2142">214242"> a> 6ron93327332842" href="#21_" href="#= escapedF href=";2429" href3329me="245273329m>332942" href="#21h> h f=0#2317">2317333ame="24527333am>3330228ance /**3331ame="2367" href3332me="245273332m>3332ame="2367" href3333me="245273333m>3333 */
2370 S5"3335return _is_abs_path;
3336me="245273336m>3336 /9ame="2 "#2436"escapedF href="3337href="#2426">24262370">2uf.append(_s scaped6" href="#s= tvalid307">2307
3338me="245273338m>333824y compo"i6> is> EscapedF href="mame="24escapedF href="="2370">2uf.append(_s "2429" href334ame="24527334am>3340> next &&15oname=ifstrong> hasescapedF href="<=365 *="#2459">24593341me="245273341m>3341 23173342me="245273342m>33423" href*/
h f=0#2317">23173343me="245273343m>334323173344me="245273344m>33443" href*//**334523173346me="245273346m>334642" href= /**3347/a> > 3348me="245273348m>3348228anem> > 3349me="245273349m>33493" href*/<>
718URI is seS5"3351">2400 tringBuffer buf3352me="245273352m>335299">718URI is se"#2436"f href="3353">2400 62370">2uf.append(_s is/> 3355RI has tn 2428">24y compo"i6> is> F href="mame="24f href="="2370">2uf.append(_s "2429" href3356me="245273356m>3356> next &&15oname=ifstrong> hasf href="<=365 * || f href=".lengthhe a> 0="#2459">24593357me="245273357m>335742" href="#2142">_" href="#= sf href="<=365 *
?7 r:tf href=".to URIArrayhr#2317">23173358me="245273358m>335842" href="#2142">h> h f=0#2317">23173359me="245273359m>33592317336ame="24527336am>336042" href="#2186" href="#3361me="245273361m>3361 _" href="#= e"336242" href="#21h> h f=0#2317">23173363me="245273363m>336olean3300">240ame="2419"3305me="245273365m>3365">240ame="2419"3306me="245273366m>3366s URI has authority
336 * * tringBuffer buf3369me="245273369m>336a name=ee="2="#243="2opd(_saln" href="#idf="ifier>22uf., but is osten usedtringBuffer buf337ame="24527337am>337272me="serveri 3372href="#2426">2423="2"ormat 23interp7oea=(_s=os/" href="#idf="ifiers is depend">24ontringBuffer buf3373me="245273373m>337>return2370 * tringBuffer buf3375me="245273375m>337m>
2337672me="serveri t>2dme=he <7oerieval< 23e 2tringBuffer buf3377me="245273377m>3377 name=ee="2="#24he 337a> #2228ance in< @return true i3379me="245273379m>3379370">2370 }
2307
338ame="24527338am>338a _is_r/tringBuffer buf3381me="245273381m>3381ref="#23m4/s7 {
[] class=F href="m="#2459">24593382me="245273382m>3382 boolean ha_f href="#2317">23173383me="245273383m>338olean3384/a> > 3385me="245273385m>3385">240ame="2419"3386me="245273386m>3386s URI has authority
338a> #2228ance in< @return true i3389me="245273389m>338999">718URI is se36 339a _is_r/tringBuffer buf3391me="245273391m>33 pu he relativEscapedF href="m="#2459">24593392me="245273392m>3392 boolean has_f href="<=365 *
?7 r:tstname() a name="2313" hrefs_f href="=#2317">23173393me="245273393m>339olean3394/a> > 3395me="245273395m>3395/a> > 3396me="245273396m>3396s URI has authority
339a> #2228ance in< @return true i3399me="245273399m>339999">718URI is se36 <" href="#hes2th _is_abs_path;
34name="2452734nam>3400">2400 62370">2uf.append(_s inngmplete trail="24escape 2attern or une="2440="tringBuffer buf34n1me="2452734n1m>3401Ang>retn222a> >231239Io/ this th8#238 F1n:48<3402me="2452734n2m>340299">718URI is se3 340n _is_r/tringBuffer buf3404me="2452734n4m>3404strong>pu he relativF href="m="2370">2uf.append(_s "2429" href34n5me="2452734n5m>3405 boolean has_f href="<=365 *
?7 r:tt,,URIn_f href=",2429" href34n6me="2452734n6m>340642" href="#2142">2142tiv rel_pns URI2" hr3#2317">231734n7me="2452734n7m>3407> next &a}2317">231734n8me="2452734n8m>3408228anem> > 34n9me="2452734n9m>340923399 re {
2437 7ef="#2377">2ss="st8rRss="st8r Util=ties >
<=8 hr96" h=e341ame="24527341am>341name="2367" href3411me="245273411m>341 */
718URI is seRemovsQuery" href="#idf="ifier if the given ngmpon237.ame="2368" href3413me="245273413m>341>return _is_abs_path;
3414me="245273414m>341499">718URI is se"#2436"ngmpon237 2370 }
24/s7 {
* @rub(f="dress,>[] removsF href="Idf="ifiers * @rub(f="dress,>[] cgmpon237="#2459">24593418me="245273418m>3418> next &&15oname=ifstrong> hascgmpon237 2365 *="#"2367" href3419me="245273419m>34192317342ame="24527342am>342042" href="#2186" href="#3421me="245273421m>3421]e4">ongv6renul3p8d31i>23422> next &&15oname=ifstrong> has"astI2dmx != -1="#2459">24593423me="245273423m>3423>>>>>>>>"astI2dmx).to URIArrayhr#2317">23173425me="245273425m>34253426 boolean hacgmpon237#2317">23173427me="245273427m>3427> next &a}2317">23173428me="245273428m>3428228anem> > 3429me="245273429m>34293430 */
2400 * Algorithm taken from uf.2370 rn 4m70>2http://www.F1beri.org/~fiels th/uri/rev-2002/issues.html." tartiv="alexandria_uri">http://www.F1beri.org/~fiels th/uri/rev-2002/issues.html.370"ame="2368" href3435me="245273435m>3435return _is_abs_path;
3436me="245273436m>3436 /9ame="2 "#2436"2ath <2ath to normalize _is_abs_path;
3437me="245273437m>3437href="#2426">2426 }
3438 -1) {
2uf.append(_s no morsQhigher<2ath le24l to bthnormalizedbuf.toString().3439me="245273439m>3439lativ3440"#2452">24/s7 {
* @rub(f="dress,>[] normalize(15oname=ub(f="dress,>[] path="2370">2uf.append(_s "2429" href3441me="245273441m>3441"2377" href="#23442me="245273442m>3442> next &&15oname=ifstrong> haspath 2365 *="#"2367" href3443me="245273443m>344323173444me="245273444m>34443" href*//**3445/a> > 3446me="245273446m>344642" href="#21he relanormalized6=tstname() a name="2313" hrefspathname="2="#243447me="245273447m>3447/a> > 3448me="245273448m>344842" href="#2149ef="6="#2324">23399 rIf the buf2459345ame="24527345am>3456 3451> next &&}&15oname=else91 hasnormalized.startsWith( a> 6ron924593452me="245273452m>3452 3453> next &&}&15oname=else91 hasnormalized.startsWith( a> 6ron924593454me="245273454m>3454 34553456ref="#2452">7e93457me="245273457m>3457> next &&19ef="6="#2324">23399 rAll occur e"ongv6renul3p8d31i>23459> next &&15oname=while91 a> 6ron9/./"ong
2459346ame="24527346am>3466 3461 86" href="#3462me="245273462m>3462ame="2367" href3463me="245273463m>346342" href="#2119ef="6="#2324">23399 rIf the buf24593405me="245273465m>3465 3466 86" href="#3467me="245273467m>346
3468]e4">ongv6renul3p8d31i>234693470> next &&19ef="6="#2324">23399 rAll occur e"/../" in the buf23399 r 23 se) |)p> arerngmplete 2ath he) |)ps,/areriterativelyrreplacedone="2368" href3472me="245273472m>347223399 rwith "/" in orda from left to right until no matchrela2attern remains.ame="2368" href3473me="245273473m>347342" href="#2119ef="6="#2324">23399 rIf the buf/..", tha"#2347423399 rwith "/". Note tha"# se) |)p> may be empty.ame="2368" href3475me="245273475m>3475> next &&15oname=while91 a> 6ron9/../"ong
24593476me="245273476m>347642" href="#2142">15oname=i>2347742" href="#2142">15oname=ifstrong> hassm> hI2dmx >> 0="#2459">24593478me="245273478m>347842" href="#2142">2142normalized6=tnormalized.subhes2th(0,#sm> hI2dmx) +tnormalized.subhes2th(i2dmx + 3name="2="#243479me="245273479m>34792459348ame="24527348am>348042" href="#2142">2142startI2dmx = i2dmx + 3;1422459">24593481me="245273481m>3481348242" href="#2186" href="#3483me="245273483m>3483> next &&15oname=ifstrong> hasnormalized.endsWith( a> 6ron9/.."ong
24593484me="245273484m>348442" href="#2142">15oname=i>2348542" href="#2142">15oname=ifstrong> hassm> hI2dmx >> 0="#2459">24593486me="245273486m>348642" href="#2142">2142normalized6=tnormalized.subhes2th(0,#sm> hI2dmx +#1name="2="#243487me="245273487m>3487348842" href="#2186" href="#3489me="245273489m>34893490> next &&19ef="6="#2324">23399 rAll p"24ixes os " se) |)p>/../" in the buf23399 r 23 se) |)p> arerngmplete 2ath he) |)ps,/areriterativelyrreplacedone="2368" href3492me="245273492m>349223399 rwith "/" in orda from left to right until no matchrela2attern remains.ame="2368" href3493me="245273493m>349342" href="#2119ef="6="#2324">23399 rIf the buf/..", tha"#2349423399 rwith "/". Note tha"# se) |)p> may be empty.ame="2368" href3495me="245273495m>3495> next &&15oname=while91 a> 6ron9/../"ong
24593496me="245273496m>349642" href="#2142">15oname=i>2349742" href="#2142">15oname=ifstrong> hassm> hI2dmx >> 0="#2459">24593498me="245273498m>349842" href="#2142">21423p8d31breaka name="2#2317">23173499me="245273499m>3499245935name="2452735nam>350042" href="#2142">2142normalized6=tnormalized.subhes2th(i2dmx + 3name="2="#2435n1me="2452735n1m>3501350242" href="#2186" href="#35n3me="2452735n3m>3503> next &&15oname=ifstrong> hasnormalized.endsWith( a> 6ron9/.."ong
24593504me="2452735n4m>350442" href="#2142">15oname=i>2350542" href="#2142">15oname=ifstrong> hassm> hI2dmx 0="#2459">245935n6me="2452735n6m>350642" href="#2142">2142normalized6=t a> 6ron9/"ong
3507350842" href="#2186" href="#35n9me="2452735n9m>35093510 boolean hanormalized.to URIArrayhr#2317">23173511me="245273511m>351 */351235133514 */
2370 Normalizes <2ath 2art os/this)uf.. Normaliza=(_s=23516href="#2426">242uf.s=with > 3519 -1) {
2uf.append(_s no morsQhigher<2ath le24l to bthnormalizedbuf.toString().352ame="24527352am>35209 #2228ance ame="2368" href3521me="245273521m>352199">718URI is se3 3523RI has tn 2428">24y compo"i6> isnormalize(="2370">2uf.append(_s "2429" href3524me="245273524m>3524> next &&15oname=ifstrong> hasisAbsPath()="#2459">24593525me="245273525m>3525352642" href="#2142">2310">23#2317">23173527me="245273527m>35273528228ance /**35293530353 */
353499">718URI is se"#2436"firs"#the firs"#>231239Io/array _is_abs_path;
3535me="245273535m>3535 -1) {
231239Io/array _is_abs_path;
3536me="245273536m>3536370">2370 }
353elativ3538"#2452">24/s7 {
* @rbooleantrdress,> equals(15oname=ub(f="dress,>[] firs", * @rub(f="dress,>[] #eco 2="#2459">24593539me="245273539m>35393540> next &&15oname=ifstrong> hasfirs"#2365 *r&& #eco 23=365 *="#2459">24593541me="245273541m>354123173542me="245273542m>354242" href="#2186" href="#3543me="245273543m>3543> next &&15oname=ifstrong> hasfirs"#2365 *r|| #eco 23=365 *="#2459">24593544me="245273544m>354423173545me="245273545m>354542" href="#2186" href="#3546me="245273546m>3546> next &&15oname=ifstrong> hasfirs".length != #eco 2.length="#2459">24593547me="245273547m>354723173548me="245273548m>354842" href="#2186" href="#3549me="245273549m>3549> next &&15oname="orstrong> hasul3p8d31i>22459355ame="24527355am>3556 hasfirs"[i] != #eco 2[i]="#2459">24593551me="245273551m>355142" href="#2142">21423p8d317oerin91 23173552me="245273552m>3552 355342" href="#2186" href="#3554me="245273554m>3554> next &&15oname=7oerin91 23173555me="245273555m>3552228ance /**3556ref="#2452">7e93557me="245273557m>3557ref="#2452">7e93558me="245273558m>355n truen
355= -1) {
uthor+347!m703561me="245273561m>3561 _is_rr##2436"obj#> uthor+347!m703562me="245273562m>3562370">2370 }
356n _is_r/tringBuffer buf3564me="245273564m>3564RI has tn 2428">24booleantrdress,> equals(Objec0#obj="#2459">24593505me="245273565m>3565">240ame="2419"3506me="245273566m>3566 19ef="6="#2324">23399 rnormalize< 23ees"# bertcgmpon237stringBuffer buf3567me="245273567m>35672">2292 15oname=ifstrong> hasobj#=365 ="#2459">24593568me="245273568m>356823173509me="245273569m>356942" href="#2186" href="#357ame="24527357am>3570> next &&15oname=ifstrong> has!sobj#i>23384gof)uf.)="#2459">24593571me="245273571m>357123173572me="245273572m>357242" href="#2186" href="#3573me="245273573m>357342" href="#211n 4m70>2../../../../org/F1beri/324"ons/http="#237/uf..html">uf.42" hanother#= suf.)#obj#2317">23173574me="245273574m>357423399 rserime> uthor+347!m703575me="245273575m>3575> next &&15oname=ifstrong> has!equals(_serime, another._serime)="#2459">24593576me="245273576m>357642" href="#2142">15oname=7oerin91 23173577me="245273577m>3577357842" href="#2149ef="6="#2324">23399 ris_opaque_2art or 2<_hier_2art? < 23opaque> uthor+347!m703579me="245273579m>3579> next &&15oname=ifstrong> has!equals(_opaque, another._opaque)="#2459">2459358ame="24527358am>358042" href="#2142">15oname=7oerin91 23173581me="245273581m>3581 86" href="#3582me="245273582m>358242" href="#2149ef="6="#2324">23399 ris_hier_2art> uthor+347!m703583me="245273583m>358342" href="#2119ef="6="#2324">23399 rhas_authority _is_abs_path;
3584me="245273584m>3584> next &&15oname=ifstrong> has!equals(_authority, another._authority)="#2459">24593585me="245273585m>358542" href="#2142">15oname=7oerin91 23173586me="245273586m>3586 86" href="#3587me="245273587m>3587> next &&19ef="6="#2324">23399 r2athbuf.toString().3588me="245273588m>3588> next &&15oname=ifstrong> has!equals(_2ath, another._pathn="#2459">24593589me="245273589m>358942" href="#2142">15oname=7oerin91 2317359ame="24527359am>359042" href="#2186" href="#3591me="245273591m>35903" href*/23399 rhas_query307">2307
3592me="245273592m>3592> next &&15oname=ifstrong> has!equals(_query,6another._query)="#2459">24593593me="245273593m>359342" href="#2142">15oname=7oerin91 23173594me="245273594m>359442" href="#2186" href="#3595me="245273595m>3595> next &&19ef="6="#2324">23399 rhas_" href="? 3596> next &&15oname=ifstrong> has!equals(_f href=",6another._" href=")="#2459">24593597me="245273597m>359723173598me="245273598m>359842" href="#2186" href="#3599me="245273599m>3599> next &&15oname=7oerin91 231736name="2452736nam>3600228ance /**3601"2377" href="#23602me="2452736n2m>360223399 re {
2437 7ef="#2377">2ss="st8rRss="s Serializa=(_stringBuffer buf36n3me="2452736n3m>3603"2377" href="#23604me="2452736n4m>3604 */
2t os/this)uf..ame="2368" href36n6me="2452736n6m>3606405" hre9Io/str> uthor+347!m7036n7me="2452736n7m>3607 _is_rr##2436"oos uthor+347!m7036n8me="2452736n8m>3608 -1) {
2IOappend(_s is/> 24/s7 {
2428">24y compo"i6> iswri"eObjec0(Objec0Outpu"Seseam"oos)Buffer buf3611me="245273611m>36103" href*/2IOappend(_s {Buffer buf3612me="245273612m>3612361342" href="#21oos.defaultWri"eObjec0(3#2317">23173614me="245273614m>3614 *//**361536163617"#2452">24>
3619 -1) {
uthor+347!m703621me="245273621m>362199">718URI is se32370">2C"6="NotFoundappend(_s is/one if the em> es specified in=the> uthor+347!m703622me="245273622m>3622 inpu"#heseam#cans= tb"2"ound.tringBuffer buf3623me="245273623m>3623 -1) {
2IOappend(_s is/> 3625"#2452">24/s7 {
2428">24y compo"i6> isseadObjec0(Objec0Inpu"Seseam"ois)Buffer buf3626me="245273626m>362642" href="#212370">2C"6="NotFoundappend(_s,2IOappend(_s {Buffer buf3627me="245273627m>3627ref="#2452">7e93628me="245273628m>362842" href="#21ois.defaultReadObjec0(3#2317">23173629me="245273629m>362942" href= /**3630363 */
f="6="#2324">23399 re {
2437 7ef="#2377">2ss="st8rRss="st8r- H> h ,URIbuf.toString().3632me="245273632m>3632ame="2367" href3633me="245273633m>3633 */
718URI is seR}
h ,URIthe <45is)uf..ame="2368" href3635me="245273635m>3635return _is_abs_path;
3636me="245273636m>3636370">2370 }
,URItvaluIthe <45is)uf. _is_abs_path;
3637me="245273637m>363elativ3638tname
24i>224593639me="245273639m>3639> next &&15oname=ifstrong> hash> h f> 0="#2459">2459364ame="24527364am>364042" href="#2142">15oname=ub(f="dress,>[] c = _uri#2317">23173641me="245273641m>364124593642me="245273642m>36423" href*/
hasul3p8d31i>224593643me="245273643m>3643 h f=31 h> h + c[i]#2317">23173644me="245273644m>364142" href="#2142">>>>> /**3645364642" href="#2142">c = _f href="#2317">23173647me="245273647m>364724593648me="245273648m>36483" href*/
hasul3p8d31i>224593649me="245273649m>3649 h f=31 h> h + c[i]#2317">2317365ame="24527365am>365042" href="#2142">>>>> /**3651365242" href="#2186" href="#3653me="245273653m>3653> next &&15oname=7oerin91 h#2317">23173654me="245273654m>3654 *//**3655365623399 re {
2437 7ef="#2377">2ss="st8rRss="st8r Cgmparis_s=ame="2368" href3657me="245273657m>3657ref="#2452">7e93658me="245273658m>365n truen
365= -1) {
uthor+347!m703661me="245273661m>3661 _is_rr##2436"obj# 2370 }
2C"6="Castappend(_s not)uf.=arg69">2tringBuffer buf3605me="245273665m>366m>
3666tname
24i>22C"6="Castappend(_s #2459">24593667me="245273667m>366
3668]e4">ongv6renun 4m70>2../../../../org/F1beri/324"ons/http="#237/uf..html">uf.42" hanother#= suf.)#obj#2317">23173609me="245273669m>3669> next &&15oname=ifstrong> has!equals(_authority, another.class=Authorityhr33"#"2367" href367ame="24527367am>367042" href="#2142">15oname=7oerin91 3671 86" href="#3672me="245273672m>3672 boolean hato" hrefs).ngmpareTo(another.to" hrefs)3#2317">23173673me="245273673m>367olean3674/a> > 3675me="245273675m>3675> next &am>
f="6="#2324">23399 re {
2437 7ef="#2377">2ss="st8rRss="st8r-st8r Clon2 @return true i3676me="245273676m>3676/a> > 3677me="245273677m>3677"#2452">24>
3679370">2370 the usehrefo ngmpon237. Notice at uerywhole uf.-re368a _is_r the usehrefo ngmpon237 ngunld s= tb"2gotten a" href /,URI>.tringBuffer buf3681me="245273681m>3681* * tringBuffer buf3682me="245273682m>368n9 #2228ance To1copy uf. /,URI>2400 >gmpon237,#it2307
3685me="245273685m>3685370">2370 }
23384g307">2307
3686me="245273686m>368
24sync370nizedbu href="#Objec0#clone(="2370">2C"oneNotS="2440="append(_s #2459">24593688me="245273688m>3688228anem> > 3689me="245273689m>368942" href="#21un 4m70>2../../../../org/F1beri/324"ons/http="#237/uf..html">uf.42" hi>23384g#= suf.)#2428">24superstrong> h.clone(=#2317">2317369ame="24527369am>369036903" href*/23384g._uri = _uri#2317">23173692me="245273692m>3692> next &&i>23384g._serime = _serime#2317">23173693me="245273693m>369342" href="#21i>23384g._opaque = _opaque#2317">23173694me="245273694m>369442" href="#21i>23384g._authorityt= _authority#2317">23173695me="245273695m>3695> next &&i>23384g._usehrefo = _usehrefo#2317">23173696me="245273696m>3696> next &&i>23384g._hos"#2 _hos"#2317">23173697me="245273697m>369723173698me="245273698m>369842" href="#21i>23384g._2ath 2s_2ath#2317">23173699me="245273699m>3699> next &&i>23384g._query = _query#2317">231737name="2452737nam>370042" href="#21i>23384g._" href="#= _f href="#2317">231737n1me="2452737n1m>37003" href*/23399 rthe eURI2" to do4escape this ththe <45is)i>23384g307">2307
3702me="2452737n2m>3702> next &&i>23384g.prel_pns URI2" #= prel_pns URI2" #2317">231737n3me="2452737n3m>370342" href="#2119ef="6="#2324">23399 rflags307">2307
3704me="2452737n4m>370442" href="#21i>23384g._is_hier_2art#= _is_hier_2art#2317">231737n5me="2452737n5m>370542" href="#21i>23384g._is_opaque_2art = _is_opaque_2art#2317">231737n6me="2452737n6m>370642" href="#21i>23384g._is_net_2ath 2s_is_net_2ath#2317">231737n7me="2452737n7m>370742" href="#21i>23384g._is_abs_2ath 2s_is_abs_2ath#2317">231737n8me="2452737n8m>370842" href="#21i>23384g._is_rel_2ath 2s_is_rel_2ath#2317">231737n9me="2452737n9m>370942" href="#21i>23384g._is_reg_">23 2s_is_reg_">23#2317">2317371ame="24527371am>371042" href="#21i>23384g._is_sehver#= _is_sehver#2317">23173711me="245273711m>371142" href="#21i>23384g._is_hos"">23 2s_is_hos"">23#2317">23173712me="245273712m>371242" href="#21i>23384g._is_IPv4address 2s_is_IPv4address#2317">23173713me="245273713m>371342" href="#21i>23384g._is_IPv6re23173714me="245273714m>3714/a> > 3715me="245273715m>3715 boolean hai>23384g#2317">23173716me="245273716m>371642" href= /**3717/a> > 3718me="245273718m>3718> next &am>
f="6="#2324">23399 re {
2437 7ef="#2377">2ss="st8rRss="st8*37193720 */
718URI is seI"#cantb"2gotten 2220uf.3>231239Io/seque84g.eI"'shpaw-escaped.ame="2368" href3722me="245273722m>3722 Fe <45e purpose if the prel_pns to bthtrans2440=",#it3724 _is_reI"#2372572me="serveri t>2dme=to bthseclea.eIn 2articular, the use os/>2p6="word2dme=eppendtringBuffer buf3727me="245273727m>372772me="serveri 2dme=to bttringBuffer buf3728me="245273728m>372a> #2228ance in< e="242.ame="2368" href3729me="245273729m>3729* * tringBuffer buf373ame="24527373am>373a _is_r When you want to ge"# bert2art os/the usehrefo, you neme=to use the> uthor+347!m703731me="245273731m>3731Ang>retn222a> specific)methods in the specific)ufL.eI" depend uthor+347!m703732me="245273732m>37on9 #2228ance> uthor+347!m703733me="245273733m>3733">2400 6 }
231239Io/seque84g> uthor+347!m703734me="245273734m>3734 _is_r/tringBuffer buf3735me="245273735m>3735ref="#23m4/s7 {
[] class=0">23 #2459">24593736me="245273736m>3736 boolean ha_uri#2317">23173737me="245273737m>3737> next &a}2317">23173738me="245273738m>3738228anem> > 3739me="245273739m>37393740 */
718URI is seI"#cantb"2gotten 2220uf.3>231239Io/seque84g.eI"'shescaped.ame="2368" href3742me="245273742m>3742 Fe <45e purpose if the prel_pns to bthtrans2440=",#it374499">718URI is se36 374m>
3746strong>pu he relativEscaped0">23 #2459">24593747me="245273747m>3747 boolean has_uri =365 *
?7 r:tstname() a name="2313" hrefs_uri=#2317">23173748me="245273748m>3748228ance /**37493750375 */
718URI is seI"#cantb"2gotten 2220uf.3>231239Io/seque84g.ame="2368" href3753me="245273753m>375>return _is_abs_path;
3754me="245273754m>375499">718URI is se36 3755">2400 62370">2uf.append(_s inngmplete trail="24escape 2attern or une="2440="tringBuffer buf3756me="245273756m>3756Ang>retn222a> >231239Io/ this th8#238 F1n:48<3757me="245273757m>375799">718URI is se3 3758>
3759> next &a he relativ0">23 2370">2uf.append(_s "2429" href376ame="24527376am>3760 boolean has_uri =365 *
?7 r:tt,,URIn_uri,2tiv rel_pns URI2" hr3#2317">23173761me="245273761m>376 */3762ame="2367" href3763me="245273763m>3763ame="2367" href3764me="245273764m>3764 */
231239Io/seque84g.ame="2368" href3706me="245273766m>3766405" hre9Io/str> uthor+347!m703767me="245273767m>3767">2400 6 }
231239Io/seque84g> uthor+347!m703768me="245273768m>3768>
3769ref="#23m4/s7 {
[] class=0">Re2459377ame="24527377am>3770> next &&15oname=ifstrong> has_f href="<=365 *
#"2367" href3771me="245273771m>377123173772me="245273772m>377242" href="#2186" href="#3773me="245273773m>3773> next &&15oname=ifstrong> has_uri =365 *
#"2367" href3774me="245273774m>377423173775me="245273775m>377542" href="#2186" href="#3776me="245273776m>3776 19ef="6="#2324">23399 rif6_uri != m> r&& 6_f href=" != m> @return true i3777me="245273777m>3777 a> 6ron9#"ong
23173778me="245273778m>3778 boolean hauriRe23173779me="245273779m>377942" href= /**378037813782 */
2400 35" 6ron.ame="2368" href3784me="245273784m>378="2307" href="#2307">2307
3785me="245273785m>378599">718URI is se36 6ron307">2307
3786me="245273786m>378
Re24593788me="245273788m>3788> next &&15oname=ub(f="dress,>[] uriReRe23173789me="245273789m>3789> next &&15oname=7oerin91 *
?7 r:tstname() a name="2313" hrefsuriRe2317379ame="24527379am>3790228ance /**37913792ame="2367" href3793me="245273793m>3793 */
2400 35" 6ron.ame="2368" href3795me="245273795m>3795return _is_abs_path;
3796me="245273796m>379699">718URI is se36 6ron307">2307
3797me="245273797m>3797">2400 62370">2uf.append(_s If {@l="km t,,URI} fails.ame="2368" href3798me="245273798m>3798>
3799> next &a he relativ0">Re2uf.append(_s "2429" href38name="2452738nam>3800> next &&15oname=ub(f="dress,>[] uriReRe231738n1me="2452738n1m>3801> next &&15oname=7oerin91 *
?7 r:tt,,URInuriRe231738n2me="2452738n2m>380242" href="#2142">2142tiv rel_pns URI2" hr3#2317">231738n3me="2452738n3m>380olean3804/a> > 38n5me="2452738n5m>3805/a> > 38n6me="2452738n6m>3806 */
6ron.ame="2368" href38n8me="2452738n8m>3808 -1) {
3809lativ2400 >gmpon237 like rn 4m70>2http://jakarta.F1beri.org/" tartiv="alexandria_uri">http://jakarta.F1beri.org/">240by3454 #ecuritytreason.ame="2368" href3811me="245273811m>381199">718URI is seBut6the uf.-re2400 In other#words, this)uf.= 23any its subem> es must s= texpose the> uthor+347!m703814me="245273814m>3814href="#2426">242uf.-re uthor+347!m703815me="245273815m>3815370">2370 rn 4m70>2http://useh:p6="word@hos"2440/res 6rc0="_zon2. br" tartiv="alexandria_uri">http://useh:p6="word@hos"2440/res 6rc0="_zon2. br370" tringBuffer buf3816me="245273816m>3816href="#2426">242Ithmeans at ueryAPI ="#237 pregra4">r38209 #2228ance #6 382199">718URI is se3 3822/tringBuffer buf3823me="245273823m>3823RI has tn he relato" hrefs) "2429" href3824me="245273824m>3824> next &&15oname=7oerin91 23#2317">23173825me="245273825m>3822228ance /**3826/a> > 3827me="245273827m>3827ref="#2452">7e93828me="245273828m>3828> next &am>
f="6="#2324">23399 re {
2437 7ef="#2377">2ss="st8rRss="st8*Inn"r2="6="tringBuffer buf3829me="245273829m>38293830 */
3831Ang>retn222a> The eURI2" -eURngedrnormal operation torrepresent to bthrequirme=totringBuffer buf3832me="245273832m>38on9 #2228ance alert=to use <45e f239# 3834RI has tn 2428">24statie="dress,> * @ru"6="trdress,> Default URI2" CURngedr15oname=ext>2d"trdress,> Runtimeappend(_s "2429" href3835me="245273835m>3835/a> > 3836me="245273836m>3836 19ef="6="#2324">23399 ra name137">2437 7ef="#2377">2ss="st8rRss="st8*condreuctor"tringBuffer buf3837me="245273837m>3837ref="#2452">7e93838me="245273838m>383842" href="#2149e2s.ame="2368" href384ame="24527384am>3840 -1) {
ame="2368" href3841me="245273841m>384199">718URI is _is_rr##2436"reasonCURI# 3842384>return3844> next &&15oname=a name="dress,> Default URI2" CURngedsul3p8d31i>215oname=superstrong> h(reason)#2317">23173846me="245273846m>384642" href="#2142">15oname=this *.reason#=areason#2317">23173847me="245273847m>384723173848me="245273848m>384842" href="#2186" href="#3849me="245273849m>38493850 19ef="6="#2324">23399 ra name137">2437 7ef="#2377">2ss="st8rRss="st8st8*condra37stringBuffer buf3851me="245273851m>3851385242" href="#2149e3853> next &&15oname=a name="dress,> 2428">24statie="dress,> * @rfisal8" href="#2428">24i>23854/a> > 3855me="245273855m>385542" href="#2149e 2428">24statie="dress,> * @rfisal8" href="#2428">24i>23857ref="#2452">7e93858me="245273858m>385842" href="#2149e 2428">24statie="dress,> * @rfisal8" href="#2428">24i>238603861 19ef="6="#2324">23399 ra name137">2437 7ef="#2377">2ss="st8rRshi>23384g#variablestringBuffer buf3862me="245273862m>3862ame="2367" href3863me="245273863m>386342" href="#2149e3864> next &&15oname=arivate="dress,> 2428">24i>23865">240ame="2419"3806me="245273866m>3866 19e38672">2292 15oname=arivate="dress,> he relareasoname="2="#243868me="245273868m>3868">240ame="2419"3809me="245273869m>3869> next &&1>
f="6="#2324">23399 re {
2437 7ef="#2377">2ss="st8rRss="st8*methodstringBuffer buf387ame="24527387am>3870387142" href="#2149e3875return3876> next &&15oname=a name="dress,> 2428">24i>2387842" href="#2186" href="#3879me="245273879m>3879388042" href="#2149e3885> next &&15oname=a name="dress,> he relativseasons) "2429" href3886me="245273886m>388638873888228anem> > 3889me="245273889m>388942" href= /**389038913892 */
3893">2400 A mapprelato determinI# <(somew at arbitrarily) p"24errme=eURI2" he 2400 given localI._ S="24403895return" * tringBuffer buf3896me="245273896m>389699">718URI is seT 2400 wri"ten by Jason3Hun9Io/[jhun9Io/at acm.org]= 23used 2428">24statie="dress,> * @ru"6="trdress,> LocalITo URI2" Map "2429" href39name="2452739nam>39003901 19e 2428">24statie="dress,> * @rfisal8" href="#H> htable LOCALE_TO_CHARSET_MAP;urn true i39n3me="2452739n3m>3903> next &&15oname=statie="dress,> "2429" href39n4me="2452739n4m>3904 htable23#2317">231739n5me="2452739n5m>390542" href="#2142">LOCALE_TO_CHARSET_MAP.put( a> 6ron9 a> 6ron9231739n6me="2452739n6m>390642" href="#2142">LOCALE_TO_CHARSET_MAP.put( a> 6ron9 a> 6ron9231739n7me="2452739n7m>390742" href="#2142">LOCALE_TO_CHARSET_MAP.put( a> 6ron9 a> 6ron9231739n8me="2452739n8m>390842" href="#2142">LOCALE_TO_CHARSET_MAP.put( a> 6ron9 a> 6ron9231739n9me="2452739n9m>390942" href="#2142">LOCALE_TO_CHARSET_MAP.put( a> 6ron9 a> 6ron92317391ame="24527391am>391042" href="#2142">LOCALE_TO_CHARSET_MAP.put( a> 6ron9 a> 6ron923173911me="245273911m>391142" href="#2142">LOCALE_TO_CHARSET_MAP.put( a> 6ron9 a> 6ron923173912me="245273912m>391242" href="#2142">LOCALE_TO_CHARSET_MAP.put( a> 6ron9 a> 6ron923173913me="245273913m>391342" href="#2142">LOCALE_TO_CHARSET_MAP.put( a> 6ron9 a> 6ron923173914me="245273914m>391442" href="#2142">LOCALE_TO_CHARSET_MAP.put( a> 6ron9 a> 6ron923173915me="245273915m>391542" href="#2142">LOCALE_TO_CHARSET_MAP.put( a> 6ron9 a> 6ron923173916me="245273916m>391642" href="#2142">LOCALE_TO_CHARSET_MAP.put( a> 6ron9 a> 6ron923173917me="245273917m>391742" href="#2142">LOCALE_TO_CHARSET_MAP.put( a> 6ron9 a> 6ron923173918me="245273918m>391842" href="#2142">LOCALE_TO_CHARSET_MAP.put( a> 6ron9 a> 6ron923173919me="245273919m>391942" href="#2142">LOCALE_TO_CHARSET_MAP.put( a> 6ron9 a> 6ron92317392ame="24527392am>392042" href="#2142">LOCALE_TO_CHARSET_MAP.put( a> 6ron9 a> 6ron923173921me="245273921m>392142" href="#2142">LOCALE_TO_CHARSET_MAP.put( a> 6ron9 a> 6ron923173922me="245273922m>392242" href="#2142">LOCALE_TO_CHARSET_MAP.put( a> 6ron9 a> 6ron923173923me="245273923m>392342" href="#2142">LOCALE_TO_CHARSET_MAP.put( a> 6ron9 a> 6ron923173924me="245273924m>392442" href="#2142">LOCALE_TO_CHARSET_MAP.put( a> 6ron9 a> 6ron923173925me="245273925m>392542" href="#2142">LOCALE_TO_CHARSET_MAP.put( a> 6ron9 a> 6ron923173926me="245273926m>392642" href="#2142">LOCALE_TO_CHARSET_MAP.put( a> 6ron9 a> 6ron923173927me="245273927m>392742" href="#2142">LOCALE_TO_CHARSET_MAP.put( a> 6ron9 a> 6ron923173928me="245273928m>392842" href="#2142">LOCALE_TO_CHARSET_MAP.put( a> 6ron9 a> 6ron923173929me="245273929m>392942" href="#2142">LOCALE_TO_CHARSET_MAP.put( a> 6ron9 a> 6ron92317393ame="24527393am>393042" href="#2142">LOCALE_TO_CHARSET_MAP.put( a> 6ron9 a> 6ron923173931me="245273931m>393142" href="#2142">LOCALE_TO_CHARSET_MAP.put( a> 6ron9 a> 6ron923173932me="245273932m>393242" href="#2142">LOCALE_TO_CHARSET_MAP.put( a> 6ron9 a> 6ron923173933me="245273933m>393342" href="#2142">LOCALE_TO_CHARSET_MAP.put( a> 6ron9 a> 6ron923173934me="245273934m>393442" href="#2142">LOCALE_TO_CHARSET_MAP.put( a> 6ron9 a> 6ron923173935me="245273935m>393542" href="#2142">LOCALE_TO_CHARSET_MAP.put( a> 6ron9 a> 6ron923173936me="245273936m>393642" href="#2142">LOCALE_TO_CHARSET_MAP.put( a> 6ron9 a> 6ron923173937me="245273937m>393742" href="#2142">LOCALE_TO_CHARSET_MAP.put( a> 6ron9 a> 6ron923173938me="245273938m>393842" href="#2142">LOCALE_TO_CHARSET_MAP.put( a> 6ron9 a> 6ron923173939me="245273939m>393942" href="#2142">LOCALE_TO_CHARSET_MAP.put( a> 6ron9 a> 6ron92317394ame="24527394am>394042" href="#2142">LOCA