KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > apache > commons > httpclient > URI


1 /*
2  * $Header: /home/cvs/jakarta-commons/httpclient/src/java/org/apache/commons/httpclient/URI.java,v 1.36.2.5 2004/02/22 18:21:13 olegk Exp $
3  * $Revision: 1.36.2.5 $
4  * $Date: 2004/02/22 18:21:13 $
5  *
6  * ====================================================================
7  *
8  * Copyright 2002-2004 The Apache Software Foundation
9  *
10  * Licensed under the Apache License, Version 2.0 (the "License");
11  * you may not use this file except in compliance with the License.
12  * You may obtain a copy of the License at
13  *
14  * http://www.apache.org/licenses/LICENSE-2.0
15  *
16  * Unless required by applicable law or agreed to in writing, software
17  * distributed under the License is distributed on an "AS IS" BASIS,
18  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
19  * See the License for the specific language governing permissions and
20  * limitations under the License.
21  * ====================================================================
22  *
23  * This software consists of voluntary contributions made by many
24  * individuals on behalf of the Apache Software Foundation. For more
25  * information on the Apache Software Foundation, please see
26  * <http://www.apache.org/>.
27  *
28  * [Additional notices, if required by prior licensing conditions]
29  *
30  */

31
32 package org.apache.commons.httpclient;
33
34 import java.io.IOException JavaDoc;
35 import java.io.ObjectInputStream JavaDoc;
36 import java.io.ObjectOutputStream JavaDoc;
37 import java.io.Serializable JavaDoc;
38 import java.io.UnsupportedEncodingException JavaDoc;
39 import java.util.Locale JavaDoc;
40 import java.util.BitSet JavaDoc;
41 import java.util.Hashtable JavaDoc;
42 import java.net.URL JavaDoc;
43
44 /**
45  * The interface for the URI(Uniform Resource Identifiers) version of RFC 2396.
46  * This class has the purpose of supportting of parsing a URI reference to
47  * extend any specific protocols, the character encoding of the protocol to
48  * be transported and the charset of the document.
49  * <p>
50  * A URI is always in an "escaped" form, since escaping or unescaping a
51  * completed URI might change its semantics.
52  * <p>
53  * Implementers should be careful not to escape or unescape the same string
54  * more than once, since unescaping an already unescaped string might lead to
55  * misinterpreting a percent data character as another escaped character,
56  * or vice versa in the case of escaping an already escaped string.
57  * <p>
58  * In order to avoid these problems, data types used as follows:
59  * <p><blockquote><pre>
60  * URI character sequence: char
61  * octet sequence: byte
62  * original character sequence: String
63  * </pre></blockquote><p>
64  *
65  * So, a URI is a sequence of characters as an array of a char type, which
66  * is not always represented as a sequence of octets as an array of byte.
67  * <p>
68  *
69  * URI Syntactic Components
70  * <p><blockquote><pre>
71  * - In general, written as follows:
72  * Absolute URI = &lt;scheme&gt:&lt;scheme-specific-part&gt;
73  * Generic URI = &lt;scheme&gt;://&lt;authority&gt;&lt;path&gt;?&lt;query&gt;
74  *
75  * - Syntax
76  * absoluteURI = scheme ":" ( hier_part | opaque_part )
77  * hier_part = ( net_path | abs_path ) [ "?" query ]
78  * net_path = "//" authority [ abs_path ]
79  * abs_path = "/" path_segments
80  * </pre></blockquote><p>
81  *
82  * The following examples illustrate URI that are in common use.
83  * <pre>
84  * ftp://ftp.is.co.za/rfc/rfc1808.txt
85  * -- ftp scheme for File Transfer Protocol services
86  * gopher://spinaltap.micro.umn.edu/00/Weather/California/Los%20Angeles
87  * -- gopher scheme for Gopher and Gopher+ Protocol services
88  * http://www.math.uio.no/faq/compression-faq/part1.html
89  * -- http scheme for Hypertext Transfer Protocol services
90  * mailto:mduerst@ifi.unizh.ch
91  * -- mailto scheme for electronic mail addresses
92  * news:comp.infosystems.www.servers.unix
93  * -- news scheme for USENET news groups and articles
94  * telnet://melvyl.ucop.edu/
95  * -- telnet scheme for interactive services via the TELNET Protocol
96  * </pre>
97  * Please, notice that there are many modifications from URL(RFC 1738) and
98  * relative URL(RFC 1808).
99  * <p>
100  * <b>The expressions for a URI</b>
101  * <p><pre>
102  * For escaped URI forms
103  * - URI(char[]) // constructor
104  * - char[] getRawXxx() // method
105  * - String getEscapedXxx() // method
106  * - String toString() // method
107  * <p>
108  * For unescaped URI forms
109  * - URI(String) // constructor
110  * - String getXXX() // method
111  * </pre><p>
112  *
113  * @author <a HREF="mailto:jericho@apache.org">Sung-Gu</a>
114  * @author <a HREF="mailto:mbowler@GargoyleSoftware.com">Mike Bowler</a>
115  * @version $Revision: 1.36.2.5 $ $Date: 2002/03/14 15:14:01
116  */

117 public class URI implements Cloneable JavaDoc, Comparable JavaDoc, Serializable JavaDoc {
118
119
120     // ----------------------------------------------------------- Constructors
121

122     /** Create an instance as an internal use */
123     protected URI() {
124     }
125
126
127     /**
128      * Construct a URI as an escaped form of a character array with the given
129      * charset.
130      *
131      * @param escaped the URI character sequence
132      * @param charset the charset string to do escape encoding
133      * @throws URIException If the URI cannot be created.
134      * @throws NullPointerException if <code>escaped</code> is <code>null</code>
135      * @see #getProtocolCharset
136      */

137     public URI(char[] escaped, String JavaDoc charset)
138         throws URIException, NullPointerException JavaDoc {
139         protocolCharset = charset;
140         parseUriReference(new String JavaDoc(escaped), true);
141     }
142
143
144     /**
145      * Construct a URI as an escaped form of a character array.
146      * An URI can be placed within double-quotes or angle brackets like
147      * "http://test.com/" and &lt;http://test.com/&gt;
148      *
149      * @param escaped the URI character sequence
150      * @throws URIException If the URI cannot be created.
151      * @throws NullPointerException if <code>escaped</code> is <code>null</code>
152      * @see #getDefaultProtocolCharset
153      */

154     public URI(char[] escaped)
155         throws URIException, NullPointerException JavaDoc {
156         parseUriReference(new String JavaDoc(escaped), true);
157     }
158
159
160     /**
161      * Construct a URI from the given string with the given charset.
162      *
163      * @param original the string to be represented to URI character sequence
164      * It is one of absoluteURI and relativeURI.
165      * @param charset the charset string to do escape encoding
166      * @throws URIException If the URI cannot be created.
167      * @see #getProtocolCharset
168      */

169     public URI(String JavaDoc original, String JavaDoc charset) throws URIException {
170         protocolCharset = charset;
171         parseUriReference(original, false);
172     }
173
174
175     /**
176      * Construct a URI from the given string.
177      * <p><blockquote><pre>
178      * URI-reference = [ absoluteURI | relativeURI ] [ "#" fragment ]
179      * </pre></blockquote><p>
180      * An URI can be placed within double-quotes or angle brackets like
181      * "http://test.com/" and &lt;http://test.com/&gt;
182      *
183      * @param original the string to be represented to URI character sequence
184      * It is one of absoluteURI and relativeURI.
185      * @throws URIException If the URI cannot be created.
186      * @see #getDefaultProtocolCharset
187      */

188     public URI(String JavaDoc original) throws URIException {
189         parseUriReference(original, false);
190     }
191
192
193     /**
194      * Construct a URI from a URL.
195      *
196      * @param url a valid URL.
197      * @throws URIException If the URI cannot be created.
198      * @since 2.0
199      * @deprecated currently somewhat wrong and diffrent with java.net.URL usage
200      */

201     public URI(URL JavaDoc url) throws URIException {
202         this(url.toString());
203     }
204
205
206     /**
207      * Construct a general URI from the given components.
208      * <p><blockquote><pre>
209      * URI-reference = [ absoluteURI | relativeURI ] [ "#" fragment ]
210      * absoluteURI = scheme ":" ( hier_part | opaque_part )
211      * opaque_part = uric_no_slash *uric
212      * </pre></blockquote><p>
213      * It's for absolute URI = &lt;scheme&gt;:&lt;scheme-specific-part&gt;#
214      * &lt;fragment&gt;.
215      *
216      * @param scheme the scheme string
217      * @param schemeSpecificPart scheme_specific_part
218      * @param fragment the fragment string
219      * @throws URIException If the URI cannot be created.
220      * @see #getDefaultProtocolCharset
221      */

222     public URI(String JavaDoc scheme, String JavaDoc schemeSpecificPart, String JavaDoc fragment)
223         throws URIException {
224
225         // validate and contruct the URI character sequence
226
if (scheme == null) {
227            throw new URIException(URIException.PARSING, "scheme required");
228         }
229         char[] s = scheme.toLowerCase().toCharArray();
230         if (validate(s, URI.scheme)) {
231             _scheme = s; // is_absoluteURI
232
} else {
233             throw new URIException(URIException.PARSING, "incorrect scheme");
234         }
235         _opaque = encode(schemeSpecificPart, allowed_opaque_part,
236                 getProtocolCharset());
237         // Set flag
238
_is_opaque_part = true;
239         _fragment = fragment.toCharArray();
240
241         setURI();
242     }
243
244
245     /**
246      * Construct a general URI from the given components.
247      * <p><blockquote><pre>
248      * URI-reference = [ absoluteURI | relativeURI ] [ "#" fragment ]
249      * absoluteURI = scheme ":" ( hier_part | opaque_part )
250      * relativeURI = ( net_path | abs_path | rel_path ) [ "?" query ]
251      * hier_part = ( net_path | abs_path ) [ "?" query ]
252      * </pre></blockquote><p>
253      * It's for absolute URI = &lt;scheme&gt;:&lt;path&gt;?&lt;query&gt;#&lt;
254      * fragment&gt; and relative URI = &lt;path&gt;?&lt;query&gt;#&lt;fragment
255      * &gt;.
256      *
257      * @param scheme the scheme string
258      * @param authority the authority string
259      * @param path the path string
260      * @param query the query string
261      * @param fragment the fragment string
262      * @throws URIException If the new URI cannot be created.
263      * @see #getDefaultProtocolCharset
264      */

265     public URI(String JavaDoc scheme, String JavaDoc authority, String JavaDoc path, String JavaDoc query,
266                String JavaDoc fragment) throws URIException {
267
268         // validate and contruct the URI character sequence
269
StringBuffer JavaDoc buff = new StringBuffer JavaDoc();
270         if (scheme != null) {
271             buff.append(scheme);
272             buff.append(':');
273         }
274         if (authority != null) {
275             buff.append("//");
276             buff.append(authority);
277         }
278         if (path != null) { // accept empty path
279
if ((scheme != null || authority != null)
280                     && !path.startsWith("/")) {
281                 throw new URIException(URIException.PARSING,
282                         "abs_path requested");
283             }
284             buff.append(path);
285         }
286         if (query != null) {
287             buff.append('?');
288             buff.append(query);
289         }
290         if (fragment != null) {
291             buff.append('#');
292             buff.append(fragment);
293         }
294         parseUriReference(buff.toString(), false);
295     }
296
297
298     /**
299      * Construct a general URI from the given components.
300      *
301      * @param scheme the scheme string
302      * @param userinfo the userinfo string
303      * @param host the host string
304      * @param port the port number
305      * @throws URIException If the new URI cannot be created.
306      * @see #getDefaultProtocolCharset
307      */

308     public URI(String JavaDoc scheme, String JavaDoc userinfo, String JavaDoc host, int port)
309         throws URIException {
310
311         this(scheme, userinfo, host, port, null, null, null);
312     }
313
314
315     /**
316      * Construct a general URI from the given components.
317      *
318      * @param scheme the scheme string
319      * @param userinfo the userinfo string
320      * @param host the host string
321      * @param port the port number
322      * @param path the path string
323      * @throws URIException If the new URI cannot be created.
324      * @see #getDefaultProtocolCharset
325      */

326     public URI(String JavaDoc scheme, String JavaDoc userinfo, String JavaDoc host, int port,
327             String JavaDoc path) throws URIException {
328
329         this(scheme, userinfo, host, port, path, null, null);
330     }
331
332
333     /**
334      * Construct a general URI from the given components.
335      *
336      * @param scheme the scheme string
337      * @param userinfo the userinfo string
338      * @param host the host string
339      * @param port the port number
340      * @param path the path string
341      * @param query the query string
342      * @throws URIException If the new URI cannot be created.
343      * @see #getDefaultProtocolCharset
344      */

345     public URI(String JavaDoc scheme, String JavaDoc userinfo, String JavaDoc host, int port,
346             String JavaDoc path, String JavaDoc query) throws URIException {
347
348         this(scheme, userinfo, host, port, path, query, 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      * @param query the query string
361      * @param fragment the fragment string
362      * @throws URIException If the new URI cannot be created.
363      * @see #getDefaultProtocolCharset
364      */

365     public URI(String JavaDoc scheme, String JavaDoc userinfo, String JavaDoc host, int port,
366             String JavaDoc path, String JavaDoc query, String JavaDoc fragment) throws URIException {
367
368         this(scheme, (host == null) ? null
369             : ((userinfo != null) ? userinfo + '@' : "") + host
370                 + ((port != -1) ? ":" + port : ""), path, query, fragment);
371     }
372
373
374     /**
375      * Construct a general URI from the given components.
376      *
377      * @param scheme the scheme string
378      * @param host the host string
379      * @param path the path string
380      * @param fragment the fragment string
381      * @throws URIException If the new URI cannot be created.
382      * @see #getDefaultProtocolCharset
383      */

384     public URI(String JavaDoc scheme, String JavaDoc host, String JavaDoc path, String JavaDoc fragment)
385         throws URIException {
386
387         this(scheme, host, path, null, fragment);
388     }
389
390
391     /**
392      * Construct a general URI with the given relative URI string.
393      *
394      * @param base the base URI
395      * @param relative the relative URI string
396      * @throws URIException If the new URI cannot be created.
397      */

398     public URI(URI base, String JavaDoc relative) throws URIException {
399         this(base, new URI(relative));
400     }
401
402
403     /**
404      * Construct a general URI with the given relative URI.
405      * <p><blockquote><pre>
406      * URI-reference = [ absoluteURI | relativeURI ] [ "#" fragment ]
407      * relativeURI = ( net_path | abs_path | rel_path ) [ "?" query ]
408      * </pre></blockquote><p>
409      * Resolving Relative References to Absolute Form.
410      *
411      * <strong>Examples of Resolving Relative URI References</strong>
412      *
413      * Within an object with a well-defined base URI of
414      * <p><blockquote><pre>
415      * http://a/b/c/d;p?q
416      * </pre></blockquote><p>
417      * the relative URI would be resolved as follows:
418      *
419      * Normal Examples
420      *
421      * <p><blockquote><pre>
422      * g:h = g:h
423      * g = http://a/b/c/g
424      * ./g = http://a/b/c/g
425      * g/ = http://a/b/c/g/
426      * /g = http://a/g
427      * //g = http://g
428      * ?y = http://a/b/c/?y
429      * g?y = http://a/b/c/g?y
430      * #s = (current document)#s
431      * g#s = http://a/b/c/g#s
432      * g?y#s = http://a/b/c/g?y#s
433      * ;x = http://a/b/c/;x
434      * g;x = http://a/b/c/g;x
435      * g;x?y#s = http://a/b/c/g;x?y#s
436      * . = http://a/b/c/
437      * ./ = http://a/b/c/
438      * .. = http://a/b/
439      * ../ = http://a/b/
440      * ../g = http://a/b/g
441      * ../.. = http://a/
442      * ../../ = http://a/
443      * ../../g = http://a/g
444      * </pre></blockquote><p>
445      *
446      * Some URI schemes do not allow a hierarchical syntax matching the
447      * <hier_part> syntax, and thus cannot use relative references.
448      *
449      * @param base the base URI
450      * @param relative the relative URI
451      * @throws URIException If the new URI cannot be created.
452      */

453     public URI(URI base, URI relative) throws URIException {
454
455         if (base._scheme == null) {
456             throw new URIException(URIException.PARSING, "base URI required");
457         }
458         if (base._scheme != null) {
459             this._scheme = base._scheme;
460             this._authority = base._authority;
461         }
462         if (base._is_opaque_part || relative._is_opaque_part) {
463             this._scheme = base._scheme;
464             this._is_opaque_part = base._is_opaque_part
465                 || relative._is_opaque_part;
466             this._opaque = relative._opaque;
467             this._fragment = relative._fragment;
468             this.setURI();
469             return;
470         }
471         if (relative._scheme != null) {
472             this._scheme = relative._scheme;
473             this._is_net_path = relative._is_net_path;
474             this._authority = relative._authority;
475             if (relative._is_server) {
476                 this._is_server = relative._is_server;
477                 this._userinfo = relative._userinfo;
478                 this._host = relative._host;
479                 this._port = relative._port;
480             } else if (relative._is_reg_name) {
481                 this._is_reg_name = relative._is_reg_name;
482             }
483             this._is_abs_path = relative._is_abs_path;
484             this._is_rel_path = relative._is_rel_path;
485             this._path = relative._path;
486         } else if (base._authority != null && relative._scheme == null) {
487             this._is_net_path = base._is_net_path;
488             this._authority = base._authority;
489             if (base._is_server) {
490                 this._is_server = base._is_server;
491                 this._userinfo = base._userinfo;
492                 this._host = base._host;
493                 this._port = base._port;
494             } else if (base._is_reg_name) {
495                 this._is_reg_name = base._is_reg_name;
496             }
497         }
498         if (relative._authority != null) {
499             this._is_net_path = relative._is_net_path;
500             this._authority = relative._authority;
501             if (relative._is_server) {
502                 this._is_server = relative._is_server;
503                 this._userinfo = relative._userinfo;
504                 this._host = relative._host;
505                 this._port = relative._port;
506             } else if (relative._is_reg_name) {
507                 this._is_reg_name = relative._is_reg_name;
508             }
509             this._is_abs_path = relative._is_abs_path;
510             this._is_rel_path = relative._is_rel_path;
511             this._path = relative._path;
512         }
513         // resolve the path and query if necessary
514
if (relative._scheme == null && relative._authority == null) {
515             if ((relative._path == null || relative._path.length == 0)
516                 && relative._query == null) {
517                 // handle a reference to the current document, see RFC 2396
518
// section 5.2 step 2
519
this._path = base._path;
520                 this._query = base._query;
521             } else {
522                 this._path = resolvePath(base._path, relative._path);
523             }
524         }
525         // base._query removed
526
if (relative._query != null) {
527             this._query = relative._query;
528         }
529         // base._fragment removed
530
if (relative._fragment != null) {
531             this._fragment = relative._fragment;
532         }
533         this.setURI();
534         // reparse the newly built URI, this will ensure that all flags are set correctly.
535
// TODO there must be a better way to do this
536
parseUriReference(new String JavaDoc(_uri), true);
537     }
538
539     // --------------------------------------------------- Instance Variables
540

541     /** Version ID for serialization */
542     static final long serialVersionUID = 604752400577948726L;
543
544
545     /**
546      * Cache the hash code for this URI.
547      */

548     protected int hash = 0;
549
550
551     /**
552      * This Uniform Resource Identifier (URI).
553      * The URI is always in an "escaped" form, since escaping or unescaping
554      * a completed URI might change its semantics.
555      */

556     protected char[] _uri = null;
557
558
559     /**
560      * The charset of the protocol used by this URI instance.
561      */

562     protected String JavaDoc protocolCharset = null;
563
564
565     /**
566      * The default charset of the protocol. RFC 2277, 2396
567      */

568     protected static String JavaDoc defaultProtocolCharset = "UTF-8";
569
570
571     /**
572      * The default charset of the document. RFC 2277, 2396
573      * The platform's charset is used for the document by default.
574      */

575     protected static String JavaDoc defaultDocumentCharset = null;
576     protected static String JavaDoc defaultDocumentCharsetByLocale = null;
577     protected static String JavaDoc defaultDocumentCharsetByPlatform = null;
578     // Static initializer for defaultDocumentCharset
579
static {
580         Locale JavaDoc locale = Locale.getDefault();
581         // in order to support backward compatiblity
582
if (locale != null) {
583             defaultDocumentCharsetByLocale =
584                 LocaleToCharsetMap.getCharset(locale);
585             // set the default document charset
586
defaultDocumentCharset = defaultDocumentCharsetByLocale;
587         }
588         // in order to support platform encoding
589
try {
590             defaultDocumentCharsetByPlatform = System.getProperty("file.encoding");
591         } catch(SecurityException JavaDoc ignore) {
592         }
593         if (defaultDocumentCharset == null) {
594             // set the default document charset
595
defaultDocumentCharset = defaultDocumentCharsetByPlatform;
596         }
597     }
598
599
600     /**
601      * The scheme.
602      */

603     protected char[] _scheme = null;
604
605
606     /**
607      * The opaque.
608      */

609     protected char[] _opaque = null;
610
611
612     /**
613      * The authority.
614      */

615     protected char[] _authority = null;
616
617
618     /**
619      * The userinfo.
620      */

621     protected char[] _userinfo = null;
622
623
624     /**
625      * The host.
626      */

627     protected char[] _host = null;
628
629
630     /**
631      * The port.
632      */

633     protected int _port = -1;
634
635
636     /**
637      * The path.
638      */

639     protected char[] _path = null;
640
641
642     /**
643      * The query.
644      */

645     protected char[] _query = null;
646
647
648     /**
649      * The fragment.
650      */

651     protected char[] _fragment = null;
652
653
654     /**
655      * The root path.
656      */

657     protected static char[] rootPath = { '/' };
658
659     // ---------------------- Generous characters for each component validation
660

661     /**
662      * The percent "%" character always has the reserved purpose of being the
663      * escape indicator, it must be escaped as "%25" in order to be used as
664      * data within a URI.
665      */

666     protected static final BitSet JavaDoc percent = new BitSet JavaDoc(256);
667     // Static initializer for percent
668
static {
669         percent.set('%');
670     }
671
672
673     /**
674      * BitSet for digit.
675      * <p><blockquote><pre>
676      * digit = "0" | "1" | "2" | "3" | "4" | "5" | "6" | "7" |
677      * "8" | "9"
678      * </pre></blockquote><p>
679      */

680     protected static final BitSet JavaDoc digit = new BitSet JavaDoc(256);
681     // Static initializer for digit
682
static {
683         for (int i = '0'; i <= '9'; i++) {
684             digit.set(i);
685         }
686     }
687
688
689     /**
690      * BitSet for alpha.
691      * <p><blockquote><pre>
692      * alpha = lowalpha | upalpha
693      * </pre></blockquote><p>
694      */

695     protected static final BitSet JavaDoc alpha = new BitSet JavaDoc(256);
696     // Static initializer for alpha
697
static {
698         for (int i = 'a'; i <= 'z'; i++) {
699             alpha.set(i);
700         }
701         for (int i = 'A'; i <= 'Z'; i++) {
702             alpha.set(i);
703         }
704     }
705
706
707     /**
708      * BitSet for alphanum (join of alpha &amp; digit).
709      * <p><blockquote><pre>
710      * alphanum = alpha | digit
711      * </pre></blockquote><p>
712      */

713     protected static final BitSet JavaDoc alphanum = new BitSet JavaDoc(256);
714     // Static initializer for alphanum
715
static {
716         alphanum.or(alpha);
717         alphanum.or(digit);
718     }
719
720
721     /**
722      * BitSet for hex.
723      * <p><blockquote><pre>
724      * hex = digit | "A" | "B" | "C" | "D" | "E" | "F" |
725      * "a" | "b" | "c" | "d" | "e" | "f"
726      * </pre></blockquote><p>
727      */

728     protected static final BitSet JavaDoc hex = new BitSet JavaDoc(256);
729     // Static initializer for hex
730
static {
731         hex.or(digit);
732         for (int i = 'a'; i <= 'f'; i++) {
733             hex.set(i);
734         }
735         for (int i = 'A'; i <= 'F'; i++) {
736             hex.set(i);
737         }
738     }
739
740
741     /**
742      * BitSet for escaped.
743      * <p><blockquote><pre>
744      * escaped = "%" hex hex
745      * </pre></blockquote><p>
746      */

747     protected static final BitSet JavaDoc escaped = new BitSet JavaDoc(256);
748     // Static initializer for escaped
749
static {
750         escaped.or(percent);
751         escaped.or(hex);
752     }
753
754
755     /**
756      * BitSet for mark.
757      * <p><blockquote><pre>
758      * mark = "-" | "_" | "." | "!" | "~" | "*" | "'" |
759      * "(" | ")"
760      * </pre></blockquote><p>
761      */

762     protected static final BitSet JavaDoc mark = new BitSet JavaDoc(256);
763     // Static initializer for mark
764
static {
765         mark.set('-');
766         mark.set('_');
767         mark.set('.');
768         mark.set('!');
769         mark.set('~');
770         mark.set('*');
771         mark.set('\'');
772         mark.set('(');
773         mark.set(')');
774     }
775
776
777     /**
778      * Data characters that are allowed in a URI but do not have a reserved
779      * purpose are called unreserved.
780      * <p><blockquote><pre>
781      * unreserved = alphanum | mark
782      * </pre></blockquote><p>
783      */

784     protected static final BitSet JavaDoc unreserved = new BitSet JavaDoc(256);
785     // Static initializer for unreserved
786
static {
787         unreserved.or(alphanum);
788         unreserved.or(mark);
789     }
790
791
792     /**
793      * BitSet for reserved.
794      * <p><blockquote><pre>
795      * reserved = ";" | "/" | "?" | ":" | "@" | "&amp;" | "=" | "+" |
796      * "$" | ","
797      * </pre></blockquote><p>
798      */

799     protected static final BitSet JavaDoc reserved = new BitSet JavaDoc(256);
800     // Static initializer for reserved
801
static {
802         reserved.set(';');
803         reserved.set('/');
804         reserved.set('?');
805         reserved.set(':');
806         reserved.set('@');
807         reserved.set('&');
808         reserved.set('=');
809         reserved.set('+');
810         reserved.set('$');
811         reserved.set(',');
812     }
813
814
815     /**
816      * BitSet for uric.
817      * <p><blockquote><pre>
818      * uric = reserved | unreserved | escaped
819      * </pre></blockquote><p>
820      */

821     protected static final BitSet JavaDoc uric = new BitSet JavaDoc(256);
822     // Static initializer for uric
823
static {
824         uric.or(reserved);
825         uric.or(unreserved);
826         uric.or(escaped);
827     }
828
829
830     /**
831      * BitSet for fragment (alias for uric).
832      * <p><blockquote><pre>
833      * fragment = *uric
834      * </pre></blockquote><p>
835      */

836     protected static final BitSet JavaDoc fragment = uric;
837
838
839     /**
840      * BitSet for query (alias for uric).
841      * <p><blockquote><pre>
842      * query = *uric
843      * </pre></blockquote><p>
844      */

845     protected static final BitSet JavaDoc query = uric;
846
847
848     /**
849      * BitSet for pchar.
850      * <p><blockquote><pre>
851      * pchar = unreserved | escaped |
852      * ":" | "@" | "&amp;" | "=" | "+" | "$" | ","
853      * </pre></blockquote><p>
854      */

855     protected static final BitSet JavaDoc pchar = new BitSet JavaDoc(256);
856     // Static initializer for pchar
857
static {
858         pchar.or(unreserved);
859         pchar.or(escaped);
860         pchar.set(':');
861         pchar.set('@');
862         pchar.set('&');
863         pchar.set('=');
864         pchar.set('+');
865         pchar.set('$');
866         pchar.set(',');
867     }
868
869
870     /**
871      * BitSet for param (alias for pchar).
872      * <p><blockquote><pre>
873      * param = *pchar
874      * </pre></blockquote><p>
875      */

876     protected static final BitSet JavaDoc param = pchar;
877
878
879     /**
880      * BitSet for segment.
881      * <p><blockquote><pre>
882      * segment = *pchar *( ";" param )
883      * </pre></blockquote><p>
884      */

885     protected static final BitSet JavaDoc segment = new BitSet JavaDoc(256);
886     // Static initializer for segment
887
static {
888         segment.or(pchar);
889         segment.set(';');
890         segment.or(param);
891     }
892
893
894     /**
895      * BitSet for path segments.
896      * <p><blockquote><pre>
897      * path_segments = segment *( "/" segment )
898      * </pre></blockquote><p>
899      */

900     protected static final BitSet JavaDoc path_segments = new BitSet JavaDoc(256);
901     // Static initializer for path_segments
902
static {
903         path_segments.set('/');
904         path_segments.or(segment);
905     }
906
907
908     /**
909      * URI absolute path.
910      * <p><blockquote><pre>
911      * abs_path = "/" path_segments
912      * </pre></blockquote><p>
913      */

914     protected static final BitSet JavaDoc abs_path = new BitSet JavaDoc(256);
915     // Static initializer for abs_path
916
static {
917         abs_path.set('/');
918         abs_path.or(path_segments);
919     }
920
921
922     /**
923      * URI bitset for encoding typical non-slash characters.
924      * <p><blockquote><pre>
925      * uric_no_slash = unreserved | escaped | ";" | "?" | ":" | "@" |
926      * "&amp;" | "=" | "+" | "$" | ","
927      * </pre></blockquote><p>
928      */

929     protected static final BitSet JavaDoc uric_no_slash = new BitSet JavaDoc(256);
930     // Static initializer for uric_no_slash
931
static {
932         uric_no_slash.or(unreserved);
933         uric_no_slash.or(escaped);
934         uric_no_slash.set(';');
935         uric_no_slash.set('?');
936         uric_no_slash.set(';');
937         uric_no_slash.set('@');
938         uric_no_slash.set('&');
939         uric_no_slash.set('=');
940         uric_no_slash.set('+');
941         uric_no_slash.set('$');
942         uric_no_slash.set(',');
943     }
944     
945
946     /**
947      * URI bitset that combines uric_no_slash and uric.
948      * <p><blockquote><pre>
949      * opaque_part = uric_no_slash *uric
950 </