View Javadoc

1   /*
2    * $HeadURL: https://svn.apache.org/repos/asf/jakarta/httpcomponents/oac.hc3x/tags/HTTPCLIENT_3_1/src/java/org/apache/commons/httpclient/URI.java $
3    * $Revision: 564973 $
4    * $Date: 2007-08-11 22:51:47 +0200 (Sat, 11 Aug 2007) $
5    *
6    * ====================================================================
7    *
8    *  Licensed to the Apache Software Foundation (ASF) under one or more
9    *  contributor license agreements.  See the NOTICE file distributed with
10   *  this work for additional information regarding copyright ownership.
11   *  The ASF licenses this file to You under the Apache License, Version 2.0
12   *  (the "License"); you may not use this file except in compliance with
13   *  the License.  You may obtain a copy of the License at
14   *
15   *      http://www.apache.org/licenses/LICENSE-2.0
16   *
17   *  Unless required by applicable law or agreed to in writing, software
18   *  distributed under the License is distributed on an "AS IS" BASIS,
19   *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
20   *  See the License for the specific language governing permissions and
21   *  limitations under the License.
22   * ====================================================================
23   *
24   * This software consists of voluntary contributions made by many
25   * individuals on behalf of the Apache Software Foundation.  For more
26   * information on the Apache Software Foundation, please see
27   * <http://www.apache.org/>.
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 = &lt;scheme&gt:&lt;scheme-specific-part&gt;
75   *   Generic URI = &lt;scheme&gt;://&lt;authority&gt;&lt;path&gt;?&lt;query&gt;
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     // ----------------------------------------------------------- Constructors
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 &lt;http://test.com/&gt;
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 &lt;http://test.com/&gt;
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 = &lt;scheme&gt;:&lt;scheme-specific-part&gt;#
252      * &lt;fragment&gt;.
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         // validate and contruct the URI character sequence
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; // is_absoluteURI
270         } else {
271             throw new URIException(URIException.PARSING, "incorrect scheme");
272         }
273         _opaque = encode(schemeSpecificPart, allowed_opaque_part,
274                 getProtocolCharset());
275         // Set flag
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 = &lt;scheme&gt;:&lt;path&gt;?&lt;query&gt;#&lt;
291      * fragment&gt; and relative URI = &lt;path&gt;?&lt;query&gt;#&lt;fragment
292      * &gt;.
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         // validate and contruct the URI character sequence
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) {  // accept empty path
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         // resolve the path and query if necessary
573         if (relative._authority == null 
574             && (relative._scheme == null || schemesEqual)) {
575             if ((relative._path == null || relative._path.length == 0)
576                 && relative._query == null) {
577                 // handle a reference to the current document, see RFC 2396 
578                 // section 5.2 step 2
579                 this._path = base._path;
580                 this._query = base._query;
581             } else {
582                 this._path = resolvePath(base._path, relative._path);
583             }
584         }
585         // base._query removed
586         if (relative._query != null) {
587             this._query = relative._query;
588         }
589         // base._fragment removed
590         if (relative._fragment != null) {
591             this._fragment = relative._fragment;
592         }
593         this.setURI();
594         // reparse the newly built URI, this will ensure that all flags are set correctly.
595         // TODO there must be a better way to do this
596         parseUriReference(new String(_uri), true);
597     }
598 
599     // --------------------------------------------------- Instance Variables
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     // Static initializer for defaultDocumentCharset
639     static {
640         Locale locale = Locale.getDefault();
641         // in order to support backward compatiblity
642         if (locale != null) {
643             defaultDocumentCharsetByLocale =
644                 LocaleToCharsetMap.getCharset(locale);
645             // set the default document charset
646             defaultDocumentCharset = defaultDocumentCharsetByLocale;
647         }
648         // in order to support platform encoding
649         try {
650             defaultDocumentCharsetByPlatform = System.getProperty("file.encoding");
651         } catch (SecurityException ignore) {
652         }
653         if (defaultDocumentCharset == null) {
654             // set the default document charset
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     // ---------------------- Generous characters for each component validation
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     // Static initializer for percent
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     // Static initializer for digit
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     // Static initializer for alpha
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 &amp; digit).
769      * <p><blockquote><pre>
770      *  alphanum      = alpha | digit
771      * </pre></blockquote><p>
772      */
773     protected static final BitSet alphanum = new BitSet(256);
774     // Static initializer for alphanum
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     // Static initializer for hex
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     // Static initializer for escaped
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     // Static initializer for mark
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     // Static initializer for unreserved
846     static {
847         unreserved.or(alphanum);
848         unreserved.or(mark);
849     }
850 
851 
852     /**
853      * BitSet for reserved.
854      * <p><blockquote><pre>
855      * reserved      = ";" | "/" | "?" | ":" | "@" | "&amp;" | "=" | "+" |
856      *                 "$" | ","
857      * </pre></blockquote><p>
858      */
859     protected static final BitSet reserved = new BitSet(256);
860     // Static initializer for reserved
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     // Static initializer for uric
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      *                 ":" | "@" | "&amp;" | "=" | "+" | "$" | ","
913      * </pre></blockquote><p>
914      */
915     protected static final BitSet pchar = new BitSet(256);
916     // Static initializer for pchar
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     // Static initializer for segment
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     // Static initializer for path_segments
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     // Static initializer for abs_path
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      *                 "&amp;" | "=" | "+" | "$" | ","
987      * </pre></blockquote><p>
988      */
989     protected static final BitSet uric_no_slash = new BitSet(256);
990     // Static initializer for uric_no_slash
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     // Static initializer for opaque_part
1014     static {
1015         // it's generous. because first character must not include a slash
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     // Static initializer for path
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     // Static initializer for IPv4address
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     // Static initializer for IPv6address reference
1063     static {
1064         IPv6address.or(hex); // hexpart
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     // Static initializer for IPv6reference
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     // Static initializer for toplabel
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     // Static initializer for hostname
1116     static {
1117         hostname.or(toplabel);
1118         // hostname.or(domainlabel);
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     // Static initializer for host
1131     static {
1132         host.or(hostname);
1133         // host.or(IPv4address);
1134         host.or(IPv6reference); // IPv4address
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     // Static initializer for hostport
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      *                    ";" | ":" | "&amp;" | "=" | "+" | "$" | "," )
1158      * </pre></blockquote><p>
1159      */
1160     protected static final BitSet userinfo = new BitSet(256);
1161     // Static initializer for userinfo
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     // Static initializer for within_userinfo
1180     static {
1181         within_userinfo.or(userinfo);
1182         within_userinfo.clear(';'); // reserved within authority
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     // Static initializer for server
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      *                     ";" | ":" | "@" | "&amp;" | "=" | "+" )
1210      * </pre></blockquote><p>
1211      */
1212     protected static final BitSet reg_name = new BitSet(256);
1213     // Static initializer for reg_name
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     // Static initializer for authority
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     // Static initializer for scheme
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      *                     ";" | "@" | "&amp;" | "=" | "+" | "$" | "," )
1264      * </pre></blockquote><p>
1265      */
1266     protected static final BitSet rel_segment = new BitSet(256);
1267     // Static initializer for rel_segment
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     // Static initializer for rel_path
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     // Static initializer for net_path
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     // Static initializer for hier_part
1318     static {
1319         hier_part.or(net_path);
1320         hier_part.or(abs_path);
1321         // hier_part.set('?'); aleady included
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     // Static initializer for relativeURI
1334     static {
1335         relativeURI.or(net_path);
1336         relativeURI.or(abs_path);
1337         relativeURI.or(rel_path);
1338         // relativeURI.set('?'); aleady included
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     // Static initializer for absoluteURI
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     // Static initializer for URI_reference
1367     static {
1368         URI_reference.or(absoluteURI);
1369         URI_reference.or(relativeURI);
1370         URI_reference.set('#');
1371         URI_reference.or(fragment);
1372     }
1373 
1374     // ---------------------------- Characters disallowed within the URI syntax
1375     // Excluded US-ASCII Characters are like control, space, delims and unwise
1376 
1377     /**
1378      * BitSet for control.
1379      */
1380     public static final BitSet control = new BitSet(256);
1381     // Static initializer for control
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     // Static initializer for space
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     // Static initializer for delims
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     // Static initializer for unwise
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     // Static initializer for disallowed_rel_path
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     // Static initializer for disallowed_opaque_part
1446     static {
1447         disallowed_opaque_part.or(uric);
1448         disallowed_opaque_part.andNot(opaque_part);
1449     }
1450 
1451     // ----------------------- Characters allowed within and for each component
1452 
1453     /**
1454      * Those characters that are allowed for the authority component.
1455      */
1456     public static final BitSet allowed_authority = new BitSet(256);
1457     // Static initializer for allowed_authority
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     // Static initializer for allowed_opaque_part 
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     // Static initializer for allowed_reg_name 
1480     static {
1481         allowed_reg_name.or(reg_name);
1482         // allowed_reg_name.andNot(percent);
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     // Static initializer for allowed_userinfo
1492     static {
1493         allowed_userinfo.or(userinfo);
1494         // allowed_userinfo.andNot(percent);
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     // Static initializer for allowed_within_userinfo
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     // Static initializer for allowed_IPv6reference
1516     static {
1517         allowed_IPv6reference.or(IPv6reference);
1518         // allowed_IPv6reference.andNot(unwise);
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     // Static initializer for allowed_host
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     // Static initializer for allowed_within_authority
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     // Static initializer for allowed_abs_path
1557     static {
1558         allowed_abs_path.or(abs_path);
1559         // allowed_abs_path.set('/');  // aleady included
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     // Static initializer for allowed_rel_path
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     // Static initializer for allowed_within_path
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     // Static initializer for allowed_query
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     // Static initializer for allowed_within_query
1607     static {
1608         allowed_within_query.or(allowed_query);
1609         allowed_within_query.andNot(reserved); // excluded '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     // Static initializer for allowed_fragment
1618     static {
1619         allowed_fragment.or(uric);
1620         allowed_fragment.clear('%');
1621     }
1622 
1623     // ------------------------------------------- Flags for this URI-reference
1624 
1625     // TODO: Figure out what all these variables are for and provide javadoc
1626 
1627     // URI-reference = [ absoluteURI | relativeURI ] [ "#" fragment ]
1628     // absoluteURI   = scheme ":" ( hier_part | opaque_part )
1629     protected boolean _is_hier_part;
1630     protected boolean _is_opaque_part;
1631     // relativeURI   = ( net_path | abs_path | rel_path ) [ "?" query ] 
1632     // hier_part     = ( net_path | abs_path ) [ "?" query ]
1633     protected boolean _is_net_path;
1634     protected boolean _is_abs_path;
1635     protected boolean _is_rel_path;
1636     // net_path      = "//" authority [ abs_path ] 
1637     // authority     = server | reg_name
1638     protected boolean _is_reg_name;
1639     protected boolean _is_server;  // = _has_server
1640     // server        = [ [ userinfo "@" ] hostport ]
1641     // host          = hostname | IPv4address | IPv6reference
1642     protected boolean _is_hostname;
1643     protected boolean _is_IPv4address;
1644     protected boolean _is_IPv6reference;
1645 
1646     // ------------------------------------------ Character and escape encoding
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         // prevalidate the given component by disallowed characters
1789         if (component == null) {
1790             return false; // undefined
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         // validate each component by generous characters
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         // validate each component by generous characters
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         // validate and contruct the URI character sequence
1881         if (original == null) {
1882             throw new URIException("URI-Reference required");
1883         }
1884 
1885         /* @
1886          *  ^(([^:/?#]+):)?(//([^/?#]*))?([^?#]*)(\?([^#]*))?(#(.*))?
1887          */
1888         String tmp = original.trim();
1889         
1890         /*
1891          * The length of the string sequence of characters.
1892          * It may not be equal to the length of the byte array.
1893          */
1894         int length = tmp.length();
1895 
1896         /*
1897          * Remove the delimiters like angle brackets around an URI.
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          * The starting index
1914          */
1915         int from = 0;
1916 
1917         /*
1918          * The test flag whether the URI is started from the path component.
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          * <p><blockquote><pre>
1930          *     @@@@@@@@
1931          *  ^(([^:/?#]+):)?(//([^/?#]*))?([^?#]*)(\?([^#]*))?(#(.*))?
1932          * </pre></blockquote><p>
1933          */
1934         int at = indexFirstOf(tmp, isStartedFromPath ? "/?#" : ":/?#", from);
1935         if (at == -1) { 
1936             at = 0;
1937         }
1938 
1939         /*
1940          * Parse the scheme.
1941          * <p><blockquote><pre>
1942          *  scheme    =  $2 = http
1943          *              @
1944          *  ^(([^:/?#]+):)?(//([^/?#]*))?([^?#]*)(\?([^#]*))?(#(.*))?
1945          * </pre></blockquote><p>
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          * Parse the authority component.
1959          * <p><blockquote><pre>
1960          *  authority =  $4 = jakarta.apache.org
1961          *                  @@
1962          *  ^(([^:/?#]+):)?(//([^/?#]*))?([^?#]*)(\?([^#]*))?(#(.*))?
1963          * </pre></blockquote><p>
1964          */
1965         // Reset flags
1966         _is_net_path = _is_abs_path = _is_rel_path = _is_hier_part = false;
1967         if (0 <= at && at < length && tmp.charAt(at) == '/') {
1968             // Set flag
1969             _is_hier_part = true;
1970             if (at + 2 < length && tmp.charAt(at + 1) == '/' 
1971                 && !isStartedFromPath) {
1972                 // the temporary index to start the search from
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                 // Set flag
1981                 _is_net_path = true;
1982             }
1983             if (from == at) {
1984                 // Set flag
1985                 _is_abs_path = true;
1986             }
1987         }
1988 
1989         /*
1990          * Parse the path component.
1991          * <p><blockquote><pre>
1992          *  path      =  $5 = /ietf/uri/
1993          *                                @@@@@@
1994          *  ^(([^:/?#]+):)?(//([^/?#]*))?([^?#]*)(\?([^#]*))?(#(.*))?
1995          * </pre></blockquote><p>
1996          */
1997         if (from < length) {
1998             // rel_path = rel_segment [ abs_path ]
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                     // Set flag
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                     // Set flag
2015                     _is_opaque_part = true;
2016                 } else {
2017                     // the path component may be empty
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         // set the charset to do escape encoding
2031         String charset = getProtocolCharset();
2032 
2033         /*
2034          * Parse the query component.
2035          * <p><blockquote><pre>
2036          *  query     =  $7 = <undefined>
2037          *                                        @@@@@@@@@
2038          *  ^(([^:/?#]+):)?(//([^/?#]*))?([^?#]*)(\?([^#]*))?(#(.*))?
2039          * </pre></blockquote><p>
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          * Parse the fragment component.
2059          * <p><blockquote><pre>
2060          *  fragment  =  $9 = Related
2061          *                                                   @@@@@@@@
2062          *  ^(([^:/?#]+):)?(//([^/?#]*))?([^?#]*)(\?([^#]*))?(#(.*))?
2063          * </pre></blockquote><p>
2064          */
2065         if (0 <= at && at + 1 <= length && tmp.charAt(at) == '#') {
2066             if (at + 1 == length) { // empty fragment
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         // set this URI.
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         // check boundaries
2109         if (offset < 0) {
2110             offset = 0;
2111         } else if (offset > s.length()) {
2112             return -1;
2113         }
2114         // s is never null
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         // check boundaries
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         // Reset flags
2179         _is_reg_name = _is_server =
2180         _is_hostname = _is_IPv4address = _is_IPv6reference = false;
2181 
2182         // set the charset to do escape encoding
2183         String charset = getProtocolCharset();
2184 
2185         boolean hasPort = true;
2186         int from = 0;
2187         int next = original.indexOf('@');
2188         if (next != -1) { // neither -1 and 0
2189             // each protocol extented from URI supports the specific userinfo
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             // In IPv6reference, '[', ']' should be excluded
2204             _host = (escaped) ? original.substring(from, next).toCharArray() 
2205                 : encode(original.substring(from, next), allowed_IPv6reference,
2206                         charset);
2207             // Set flag
2208             _is_IPv6reference = true;
2209         } else { // only for !_is_IPv6reference
2210             next = original.indexOf(':', from);
2211             if (next == -1) {
2212                 next = original.length();
2213                 hasPort = false;
2214             }
2215             // REMINDME: it doesn't need the pre-validation
2216             _host = original.substring(from, next).toCharArray();
2217             if (validate(_host, IPv4address)) {
2218                 // Set flag
2219                 _is_IPv4address = true;
2220             } else if (validate(_host, hostname)) {
2221                 // Set flag
2222                 _is_hostname = true;
2223             } else {
2224                 // Set flag
2225                 _is_reg_name = true;
2226             }
2227         }
2228         if (_is_reg_name) {
2229             // Reset flags for a server-based naming authority
2230             _is_server = _is_hostname = _is_IPv4address =
2231             _is_IPv6reference = false;
2232             // set a registry-based naming authority
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) == ':') { // not empty
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             // set a server-based naming authority
2253             StringBuffer buf = new StringBuffer();
2254             if (_userinfo != null) { // has_userinfo
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             // Set flag
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         // set _uri
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) { // has_authority
2288                 buf.append(_authority);
2289             }
2290         }
2291         if (_opaque != null && _is_opaque_part) {
2292             buf.append(_opaque);
2293         } else if (_path != null) {
2294             // _is_hier_part or _is_relativeURI
2295             if (_path.length != 0) {
2296                 buf.append(_path);
2297             }
2298         }
2299         if (_query != null) { // has_query
2300             buf.append('?');
2301             buf.append(_query);
2302         }
2303         // ignore the fragment identifier
2304         _uri = buf.toString().toCharArray();
2305         hash = 0;
2306     }
2307 
2308     // ----------------------------------------------------------- Test methods
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             // 1m|7a na2351">2351     "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     }

2469    name=7oerin};
955> >245602href="#2436">2436243aS65uf.append(_name="e02href="#2436">24362469718URI is server.
2172      * @param escaped <code>true
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. 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


      * 64me="21>23365tiveUru72href. iif the ra>*
42">2142    a> 6ron9 #2228ance in
24404]956    * @re2348m>
     me="2302" href="#2302">2302         }
22722>boolon92me7>n hrOname="2178" href="#2178">2178         // Res2ther or not the host part of thisame="2178" h2>
23707641tivet15oname=7oerin91346" href="#2345f="#2m>
67namre9 re {
2437  me="248ref="#2370">23701"246El6is Ulass= this the ra>* boolean hasAuthority() {
n2" href="#2452">2336     pub(from hes2thtringBuffer buf47!  *
<=8 hr9pub(72333  is23/7is Iis URI has tn2452 
     /4/a>      * @return true iif t1ress()/em>

2322 7e9NetPatro     73759" hre6      *="2272" href="#2272">2272  retusme == *   >91#2318   
233ef="#2398">2a>   2"+"#243/67namre9 re {
24372a>  href="#2452">24     pub(f8m  iif the 23384g> is/**
  k45/em>
pub(f8m  i1i    r or not thi#23952if th3w    1y() {
245>2388     36     <5m>   >91#2318   hes2thtringBuffer buf47         // In 5name="2453" 52420<555RI has tn245me="2452" hr5f="#2556ref="#23me="25return (_schemehresHostname() {
245mPatro     73m|7a 5292">2292      ? png> (_schemehre="#2452">245m272  ret759" 5ame="2293" href="#2:6t,>     /4/a>      * @retur2272    5ef="#55"#2303">2303      5m>
      5@return true5iif t5>
         _uri = buf.toString().t5>) 5c 
2415 454 #2469">2  i1i    r or not tiveUru"23825href=500">2400          * @re2348m>
) |5 _is_5et_path;
231239Io/strs,    <5m>   >91#2318     = bu994simplnamaveh69" hre72"{9     /9ame="2 
 BIDIamaveh69" hre72"{9272    52363"5== -1) {
2312n8="#242t3dif235123965782I8em7, ic 64me="21" href="#2285">228571y() {
     e="strong> hasUserin  2360     }
225me="server-b5sed n57 hre9Io/str> 48="#oei4799ame="2375" href3');
re24m70>233e2I8em>   F1b
2307 
<5  * this URI5is se57m>
2396      *
retn222a>   347">2347!  *
<=8 hr96" h=e25448">" hreI35652  57  * @return
    F1berinf a name58e      * @return
 2425m    *
<92f="#229 u a na50ame="2363" 5ref="57a namref="#2396">2396 #222314  }
251239I58272me="server-based nam5n2126 812126
2ne34x namEUC-KR46> isIPv4address() ="# {
58f="#2440">2440       11ne34x name="2446> isIPv4address() {> ref="#220645e="2158         c6tRry249m1rel_pnot the a>     pub#22>ifmDOCU auT2441     }

2469    name=7oerin};
9a name58e582n9227 href="#2trong>return _is_IPv4ad name58e5 588
955> >245602href="#2436">2436u a name7>   F50" hrhre9Io/str> 58="#o5836">24362436718URI is server.
public 5972      * @param escaped 7    nam5="24059a name=" is IPv6refe6not thserveh57     * @re2348",ref="ong>public booI i5449" "#2#745>2   59#2396">rel2375"69i   2,whether or not this U54>  e="2402" href="#24  5   *<59hether or not > 242#2345">23459ame=">245602href="#2436">24362 59  e="  5ref="#2370">2370     }
67namref="#     9a n>   F50" hre5="#245turn true iif the host part is IPv5e58e<1435">2535    a>     6e-396" href() {
:
 is>    0 2ne34x naame="243/strong> 6""#2440">6name="2452776>    608m>
     me="2302" href="#2302">2302 6ority
<6 nam66003" href*/
2ne34x nef="#2459"="#21trong>i6{
ongv6renul3p8d317nr #haa65ref=" 1">2>boolong>public<|| (_authority n0server. 6""#d  F5DOCU auTi6{42142    a> 6ron9 #2228ance#2469">2469    n0ong
23755e947! 6o    602228ance   /**7e9N6ef="]56244026leref6>
2dme="2371" href="#23a> 454 #2469">2  i1i    r or not65">243aS65uf6appen612405" hre9Io/str> uthor+347!m70>6#2|9i#2469">6469718URI is se36     pub(from hes2thtringBuffer buf46hserveh69" h6e72">6172      /tringBuffer buf46h
2242ne34x naref="#2452">246s IPv6re-3966 href61 > next &&15oname=7oerin91      D2469">2ne34x name="2="#2436rority conem6
/**
7e9N6in};
955>6>s U561
21461a name=ee="2="#2435"245/a uthor+347!m70>6       }
718URI is se36     pub(from hes2th45/a uthor+347!m70>6 serveh69" h6ng>b 6272      /tringBuffer buf46 62#2242">2242ne34x nByLa 9 #aref="#2452">246"2me7>n4>
 next &&15oname=7oerin91      D2469">2ne34x nByLa 9 #ame="2="#2436">2435 -6 6#2228ance   /**226e=7oe6in};
955> >245662href="#24366>24366>
     6 @ret6rn truen

62a name=ee="2="#2435"245/aplat25I=243/67namre9 re {6arongance in6/em22632405" hre9Io/str> uthor+347!m70>6>23365tiveUr672hre63799">718URI is se36     pub(from hes2th45/aplat25I=> uthor+347!m70>6>serveh69" h6 a> 66372      /tringBuffer buf46f="#246th() 6>/**<63#2242">2242ne34x nByPlat25I=aref="#2452">246/a>     6e="2363 > next &&15oname=7oerin91      D2469">2ne34x nByPlat25I=ame="2="#2436>2178   6     632228ance   /**249ef="6="#2324">23399 re {
2437   7ef="#2377">2ss="st8rRI is IPnrefe6e6m>
     62437<6a> Buffer buf46freturn trus6Autho6f the relati>

2335"
<243/67namre9 re {6!  *
<=6 hr9<641y() {
 _is_r/tringBuffer buf46n true iif t6ress(6t2373">2373[] class=S6m>
24652322 6em24664345" href="#2345">23456tPatro     76759" 64
  re6usme 64> Buffer buf466437

2335"
<243/67namre9 re {6thi#23952if 6h3w  6 1y() {
24652388     36     
      {
<2440unance  d
// In 6name="2453" 62420<655RI has tn246me="2452" hr6f="#2656ref="#23me="25return2365      *
 ?7         r:te.
2317<6mPatro     76m|7a 6292">229223456m272  re6759" 65> Buffer buf462272    6ef="#659"#2452">249ef="6="#2324">23399 re {
2437   7ef="#2377">2ss="st8rRI is refe6t of this URI is hostname6m>
      6@return true6iif t66is URI has authority

24c>  typ8" h201"246,a 6="2440,="#2467">,ity
 
20     ,ef7" 9>24652435 2400          *     b
<=8 hr96" h=e26) |6 _is_66         c6tRry>>>>=201"246 |e="2437" href="#2437">2436te="2452" hr6retn222a>   347"

<=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 is>  ss=em>
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
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[] class=em>
 next &&15oname=7oerin91   ;2429" href=7{5/**7e9N7ef="]56244027leref7>
2435 243aS65uf7appen712405" hre9Io/str> uthor+347!m70>7#2|9i#2469">7469718URI is se36      uthor+347!m70>7hserveh69" h7e72">7172      /tringBuffer buf47h
224 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>
2242uf.append(_s "2429" href=7">2435 -7 725> next &&15oname=7oerin91   i2365      *
 ?7         r:tde,URIn ,2429" href=7"s server.2142tiv rel_pns URI2" hr3#2317">2317<72href="#24367>24367292">229223457amN5em>     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">2242459<77437 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>
2242uf.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>
     * @rub(f="dress,>[] 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         c6tRry

<=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 pu2uf.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">229223457>   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">8469 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 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.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">21422>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">21422>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">21422>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 trus8437
21422>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">21422>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 // In 8  * this URI8is se875tname
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"#242292  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:4821422>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
243aS65uf9appen9109469 hasane> 0="#2459">2459<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
23#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./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,>[] ba2rn 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> 6ron9
2317<95      >  9!s server.23399 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 trus9437 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> 6ron92317<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> 6ron92317<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
30n999">718URI is se36     2uf.append(_s is/{@link #class=Cur natHierPathmub(f[])} fails.buf.toString().3011me="245273011m>3011 _is_r/tringBuffer buf3012me="245273012m>30122242">2242uf.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
301a name=ee="2="#2435" uthor+347!m703021me="245273021m>302799">718URI is se36     2uf.append(_s is/{@link #class=Cur natHierPathmub(f[])} fails.buf.toString().3023me="245273023m>302399">718URI is se3 3025RI has tn2uf.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   /**30292me="245273032m>30on9 #2228ance 35"30#2370">2370     }
2uf.append(_s is/{@link #class=Cur natHierPathmub(f[])} fails.buf.toString().3036me="245273036m>30{
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    */
3046370">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    */
3058370">2370     }
2uf.append(_s is/{@link #class=Cur natHierPathmub(f[])} fails.buf.toString().306ame="24527306am>306099">718URI is se3 30622242">2242uf.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
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     }
[] class=Pathm=""2429" href3077me="245273077m>30792">2292  15oname=7oerin91  23173078me="245273078m>3078228ance   /**30793083">2400          *     b
<=8 hr96" h=e3084me="245273084m>308sa nam>

<=8 hr96" h=e3085me="245273085m>308         c6tRry
<=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 pu2292  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  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">214223173127me="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
 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[] 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 3155RI has tn2uf.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     }
     * @rub(f="dress,>[] class=PathQuerym=""2429" href3169me="245273169m>316924593171me="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


<=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 3204strong>pu2uf.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   /**320923399 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> 6ron9323042" 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

2400      S5"
<=8 hr96" h=e3238me="245273238m>3238 -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   /**3249718URI 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

 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

 uthor+347!m703291me="245273291m>329199">718URI is se36     
<=8 hr96" h=e3292me="245273292m>3292/tringBuffer buf3293me="245273293m>3293strong>pu3296ref="#2452">7e93297me="245273297m>3297/a>      > 3298me="245273298m>329n truen

 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  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   /**330923399 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 tn24y 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"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>
22dme=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 pu24593392me="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 3404strong>pu2uf.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>224593423me="245273423m>3423>>>>>>>>"astI2dmx).to URIArrayhr#2317">23173425me="245273425m>34253426 boolean hacgmpon237#2317">23173427me="245273427m>3427> next &a}2317">23173428me="245273428m>3428228anem>     > 3429me="245273429m>34292400          * 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 }
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> 6ron92459346ame="24527346am>3466     3462ame="2367" href3463me="245273463m>346342" href="#2119ef="6="#2324">23399 rIf the buf24593405me="245273465m>3465     346
ongv6renul3p8d31i>2346923399 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"#223399 rwith "/".  Note tha"#    se) |)p> may be empty.ame="2368" href3475me="245273475m>3475> next &&15oname=while91      a> 6ron924593476me="245273476m>347642" href="#2142">15oname=i>215oname=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> 6ron924593484me="245273484m>348442" href="#2142">15oname=i>215oname=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>348923399 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"#223399 rwith "/".  Note tha"#    se) |)p> may be empty.ame="2368" href3495me="245273495m>3495> next &&15oname=while91      a> 6ron924593496me="245273496m>349642" href="#2142">15oname=i>215oname=ifstrong> hassm> hI2dmx >> 0="#2459">24593498me="245273498m>349842" href="#2142">214223173499me="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> 6ron924593504me="2452735n4m>350442" href="#2142">15oname=i>215oname=ifstrong> hassm> hI2dmx      0="#2459">245935n6me="2452735n6m>350642" href="#2142">2142normalized6=t    a> 6ron93507350842" href="#2186" href="#35n9me="2452735n9m>350923173511me="245273511m>351     */35122370   Normalizes    <2ath 2art os/this)uf..  Normaliza=(_s=2242uf.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 tn24y 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   /**3529353499">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     }
24/s7 {
     * @rbooleantrdress,> equals(15oname=ub(f="dress,>[] firs",     * @rub(f="dress,>[] #eco 2="#2459">24593539me="245273539m>3539      *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">214223173552me="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

  uthor+347!m703561me="245273561m>3561 _is_rr##2436"obj#>  uthor+347!m703562me="245273562m>3562370">2370     }
3564RI has tn24booleantrdress,> 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>361223173614me="245273614m>3614    *//**361524>
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= /**363023399 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    *//**365523399 re {
2437   7ef="#2377">2ss="st8rRss="st8r Cgmparis_s=ame="2368" href3657me="245273657m>3657ref="#2452">7e93658me="245273658m>365n truen

 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
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>
2370   the usehrefo ngmpon237.  Notice   at uerywhole uf.-re" 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>369023384g._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*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 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>3739718URI 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      he relativEscaped0">23 #2459">24593747me="245273747m>3747 boolean has_uri =365      *
 ?7         r:tstname() a name="2313" hrefs_uri=#2317">23173748me="245273748m>3748228ance   /**37493750718URI is seI"#cantb"2gotten 2220uf.3>231239Io/seque84g.ame="2368" href3753me="245273753m>375>return _is_abs_path;
3754me="245273754m>375499">718URI is se36     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  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> 6ron923173778me="245273778m>3778 boolean hauriRe23173779me="245273779m>377942" href= /**37802400      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   /**37912400      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 &aRe2uf.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">r381a> #2228ance in< subem>  , howeva , s= taywhole uf.-re38209 #2228ance #6     718URI is se3 3823RI has tn23#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>38293834RI has tn24statie="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#   38423844> 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>384923399 ra name137">2437   7ef="#2377">2ss="st8rRss="st8st8*condra37stringBuffer buf3851me="245273851m>3851 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>2386023399 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>38703875return 2428">24i>238793885> next &&15oname=a name="dress,> he relativseasons) "2429" href3886me="245273886m>388638873888228anem>     > 3889me="245273889m>388942" href= /**38902400      A mapprelato determinI#   <(somew at arbitrarily) p"24errme=eURI2"  he 2400      given localI._ S="2440718URI is seT  2400      wri"ten by Jason3Hun9Io/[jhun9Io/at acm.org]=  23used 2428">24statie="dress,>     * @ru"6="trdress,> LocalITo URI2" Map "2429" href39name="2452739nam>3900 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