View Javadoc

    1   /*
    2    * $Header: /home/jerenkrantz/tmp/commons/commons-convert/cvs/home/cvs/jakarta-commons//httpclient/src/java/org/apache/commons/httpclient/HttpURL.java,v 1.18 2004/09/30 17:26:41 oglueck Exp $
    3    * $Revision: 507324 $
    4    * $Date: 2007-02-14 01:12:11 +0100 (Wed, 14 Feb 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 org.apache.commons.httpclient.util.URIUtil;
    34
    35  /**
    36   * The HTTP URL.
    37   *
    38   * @author <a href="mailto:jericho at apache.org">Sung-Gu</a>
    39   * @author <a href="mailto:mbowler@GargoyleSoftware.com">Mike Bowler</a>
    40   */
    41  public class HttpURL extends URI {
    42
    43      // ----------------------------------------------------------- Constructors
    44
    45      /** Create an instance as an internal use. */
    46      protected HttpURL() {
    47      }
    48
    49
    50      /**
    51       * Construct a HTTP URL as an escaped form of a character array with the
    52       * given charset to do escape encoding.
    53       *
    54       * @param escaped the HTTP URL character sequence
    55       * @param charset the charset string to do escape encoding
    56       * @throws URIException If {@link #checkValid()} fails
    57       * @throws NullPointerException if <code>escaped</code> is <code>null</code>
    58       * @see #getProtocolCharset
    59       */
    60      public HttpURL(char[] escaped, String charset)
    61          throws URIException, NullPointerException {
    62          protocolCharset = charset;
    63          parseUriReference(new String(escaped), true);
    64          checkValid();
    65      }
    66
    67
    68      /**
    69       * Construct a HTTP URL as an escaped form of a character array.
    70       *
    71       * @param escaped the HTTP URL character sequence
    72       * @throws URIException If {@link #checkValid()} fails
    73       * @throws NullPointerException if <code>escaped</code> is <code>null</code>
    74       * @see #getDefaultProtocolCharset
    75       */
    76      public HttpURL(char[] escaped) throws URIException, NullPointerException {
    77          parseUriReference(new String(escaped), true);
    78          checkValid();
    79      }
    80
    81
    82      /**
    83       * Construct a HTTP URL from a given string with the given charset to do
    84       * escape encoding.
    85       *
    86       * @param original the HTTP URL string
    87       * @param charset the charset string to do escape encoding
    88       * @throws URIException If {@link #checkValid()} fails
    89       * @see #getProtocolCharset
    90       */
    91      public HttpURL(String original, String charset) throws URIException {
    92          protocolCharset = charset;
    93          parseUriReference(original, false);
    94          checkValid();
    95      }
    96
    97
    98      /**
    99       * Construct a HTTP URL from a given string.
    100      *
    101      * @param original the HTTP URL string
    102      * @throws URIException If {@link #checkValid()} fails
    103      * @see #getDefaultProtocolCharset
    104      */
    105     public HttpURL(String original) throws URIException {
    106         parseUriReference(original, false);
    107         checkValid();
    108     }
    109
    110
    111     /**
    112      * Construct a HTTP URL from given components.
    113      *
    114      * @param host the host string
    115      * @param port the port number
    116      * @param path the path string
    117      * @throws URIException If {@link #checkValid()} fails
    118      * @see #getDefaultProtocolCharset
    119      */
    120     public HttpURL(String host, int port, String path) throws URIException {
    121         this(null, null, host, port, path, null, null);
    122     }
    123
    124
    125     /**
    126      * Construct a HTTP URL from given components.
    127      *
    128      * @param host the host string
    129      * @param port the port number
    130      * @param path the path string
    131      * @param query the query string
    132      * @throws URIException If {@link #checkValid()} fails
    133      * @see #getDefaultProtocolCharset
    134      */
    135     public HttpURL(String host, int port, String path, String query)
    136         throws URIException {
    137
    138         this(null, null, host, port, path, query, null);
    139     }
    140
    141
    142     /**
    143      * Construct a HTTP URL from given components.
    144      *
    145      * @param user the user name
    146      * @param password his or her password
    147      * @param host the host string
    148      * @throws URIException If {@link #checkValid()} fails
    149      * @see #getDefaultProtocolCharset
    150      */
    151     public HttpURL(String user, String password, String host)
    152         throws URIException {
    153
    154         this(user, password, host, -1, null, null, null);
    155     }
    156
    157
    158     /**
    159      * Construct a HTTP URL from given components.
    160      *
    161      * @param user the user name
    162      * @param password his or her password
    163      * @param host the host string
    164      * @param port the port number
    165      * @throws URIException If {@link #checkValid()} fails
    166      * @see #getDefaultProtocolCharset
    167      */
    168     public HttpURL(String user, String password, String host, int port)
    169         throws URIException {
    170
    171         this(user, password, host, port, null, null, null);
    172     }
    173
    174
    175     /**
    176      * Construct a HTTP URL from given components.
    177      *
    178      * @param user the user name
    179      * @param password his or her password
    180      * @param host the host string
    181      * @param port the port number
    182      * @param path the path string
    183      * @throws URIException If {@link #checkValid()} fails
    184      * @see #getDefaultProtocolCharset
    185      */
    186     public HttpURL(String user, String password, String host, int port,
    187             String path) throws URIException {
    188
    189         this(user, password, host, port, path, null, null);
    190     }
    191
    192
    193     /**
    194      * Construct a HTTP URL from given components.
    195      *
    196      * @param user the user name
    197      * @param password his or her password
    198      * @param host the host string
    199      * @param port the port number
    200      * @param path the path string
    201      * @param query The query string.
    202      * @throws URIException If {@link #checkValid()} fails
    203      * @see #getDefaultProtocolCharset
    204      */
    205     public HttpURL(String user, String password, String host, int port,
    206             String path, String query) throws URIException {
    207
    208         this(user, password, host, port, path, query, null);
    209     }
    210
    211
    212     /**
    213      * Construct a HTTP URL from given components.
    214      *
    215      * @param host the host string
    216      * @param path the path string
    217      * @param query the query string
    218      * @param fragment the fragment string
    219      * @throws URIException If {@link #checkValid()} fails
    220      * @see #getDefaultProtocolCharset
    221      */
    222     public HttpURL(String host, String path, String query, String fragment)
    223         throws URIException {
    224
    225         this(null, null, host, -1, path, query, fragment);
    226     }
    227
    228
    229     /**
    230      * Construct a HTTP URL from given components.
    231      *
    232      * Note: The <code>userinfo</code> format is normally
    233      * <code>&lt;username&gt;:&lt;password&gt;</code> where
    234      * username and password must both be URL escaped.
    235      *
    236      * @param userinfo the userinfo string whose parts are URL escaped
    237      * @param host the host string
    238      * @param path the path string
    239      * @param query the query string
    240      * @param fragment the fragment string
    241      * @throws URIException If {@link #checkValid()} fails
    242      * @see #getDefaultProtocolCharset
    243      */
    244     public HttpURL(String userinfo, String host, String path, String query,
    245             String fragment) throws URIException {
    246
    247         this(userinfo, host, -1, path, query, fragment);
    248     }
    249
    250
    251     /**
    252      * Construct a HTTP URL from given components.
    253      *
    254      * Note: The <code>userinfo</code> format is normally
    255      * <code>&lt;username&gt;:&lt;password&gt;</code> where
    256      * username and password must both be URL escaped.
    257      *
    258      * @param userinfo the userinfo string whose parts are URL escaped
    259      * @param host the host string
    260      * @param port the port number
    261      * @param path the path string
    262      * @throws URIException If {@link #checkValid()} fails
    263      * @see #getDefaultProtocolCharset
    264      */
    265     public HttpURL(String userinfo, String host, int port, String path)
    266         throws URIException {
    267
    268         this(userinfo, host, port, path, null, null);
    269     }
    270
    271
    272     /**
    273      * Construct a HTTP URL from given components.
    274      *
    275      * Note: The <code>userinfo</code> format is normally
    276      * <code>&lt;username&gt;:&lt;password&gt;</code> where
    277      * username and password must both be URL escaped.
    278      *
    279      * @param userinfo the userinfo string whose parts are URL escaped
    280      * @param host the host string
    281      * @param port the port number
    282      * @param path the path string
    283      * @param query the query string
    284      * @throws URIException If {@link #checkValid()} fails
    285      * @see #getDefaultProtocolCharset
    286      */
    287     public HttpURL(String userinfo, String host, int port, String path,
    288             String query) throws URIException {
    289
    290         this(userinfo, host, port, path, query, null);
    291     }
    292
    293
    294     /**
    295      * Construct a HTTP URL from given components.
    296      *
    297      * Note: The <code>userinfo</code> format is normally
    298      * <code>&lt;username&gt;:&lt;password&gt;</code> where
    299      * username and password must both be URL escaped.
    300      *
    301      * @param userinfo the userinfo string whose parts are URL escaped
    302      * @param host the host string
    303      * @param port the port number
    304      * @param path the path string
    305      * @param query the query string
    306      * @param fragment the fragment string
    307      * @throws URIException If {@link #checkValid()} fails
    308      * @see #getDefaultProtocolCharset
    309      */
    310     public HttpURL(String userinfo, String host, int port, String path,
    311             String query, String fragment) throws URIException {
    312
    313         // validate and contruct the URI character sequence
    314         StringBuffer buff = new StringBuffer();
    315         if (userinfo != null || host != null || port != -1) {
    316             _scheme = DEFAULT_SCHEME; // in order to verify the own protocol
    317             buff.append(_default_scheme);
    318             buff.append("://");
    319             if (userinfo != null) {
    320                 buff.append(userinfo);
    321                 buff.append('@');
    322             }
    323             if (host != null) {
    324                 buff.append(URIUtil.encode(host, URI.allowed_host));
    325                 if (port != -1 || port != DEFAULT_PORT) {
    326                     buff.append(':');
    327                     buff.append(port);
    328                 }
    329             }
    330         }
    331         if (path != null) {  // accept empty path
    332             if (scheme != null && !path.startsWith("/")) {
    333                 throw new URIException(URIException.PARSING,
    334                         "abs_path requested");
    335             }
    336             buff.append(URIUtil.encode(path, URI.allowed_abs_path));
    337         }
    338         if (query != null) {
    339             buff.append('?');
    340             buff.append(URIUtil.encode(query, URI.allowed_query));
    341         }
    342         if (fragment != null) {
    343             buff.append('#');
    344             buff.append(URIUtil.encode(fragment, URI.allowed_fragment));
    345         }
    346         parseUriReference(buff.toString(), true);
    347         checkValid();
    348     }
    349
    350
    351     /**
    352      * Construct a HTTP URL from given components.
    353      *
    354      * @param user the user name
    355      * @param password his or her password
    356      * @param host the host string
    357      * @param port the port number
    358      * @param path the path string
    359      * @param query the query string
    360      * @param fragment the fragment string
    361      * @throws URIException If {@link #checkValid()} fails
    362      * @see #getDefaultProtocolCharset
    363      */
    364     public HttpURL(String user, String password, String host, int port,
    365             String path, String query, String fragment) throws URIException {
    366         this(toUserinfo(user, password), host, port, path, query, fragment);
    367     }
    368
    369     protected static String toUserinfo(String user, String password) throws URIException {
    370         if (user == null) return null;
    371         StringBuffer usrinfo = new StringBuffer(20); //sufficient for real world
    372         usrinfo.append(URIUtil.encode(user, URI.allowed_within_userinfo));
    373         if (password == null) return usrinfo.toString();
    374         usrinfo.append(':');
    375         usrinfo.append(URIUtil.encode(password, URI.allowed_within_userinfo));
    376         return usrinfo.toString();
    377     }
    378
    379
    380     /**
    381      * Construct a HTTP URL with a given relative URL string.
    382      *
    383      * @param base the base HttpURL
    384      * @param relative the relative HTTP URL string
    385      * @throws URIException If {@link #checkValid()} fails
    386      */
    387     public HttpURL(HttpURL base, String relative) throws URIException {
    388         this(base, new HttpURL(relative));
    389     }
    390
    391
    392     /**
    393      * Construct a HTTP URL with a given relative URL.
    394      *
    395      * @param base the base HttpURL
    396      * @param relative the relative HttpURL
    397      * @throws URIException If {@link #checkValid()} fails
    398      */
    399     public HttpURL(HttpURL base, HttpURL relative) throws URIException {
    400         super(base, relative);
    401         checkValid();
    402     }
    403
    404     // -------------------------------------------------------------- Constants
    405
    406     /**
    407      * Default scheme for HTTP URL.
    408      */
    409     public static final char[] DEFAULT_SCHEME = { 'h', 't', 't', 'p' };
    410
    411     /**
    412      * Default scheme for HTTP URL.
    413      * @deprecated Use {@link #DEFAULT_SCHEME} instead.  This one doesn't
    414      * conform to the project naming conventions.
    415      */
    416     public static final char[] _default_scheme = DEFAULT_SCHEME;
    417
    418     /**
    419      * Default port for HTTP URL.
    420      */
    421     public static final int DEFAULT_PORT = 80;
    422
    423     /**
    424      * Default port for HTTP URL.
    425      * @deprecated Use {@link #DEFAULT_PORT} instead.  This one doesn't conform
    426      * to the project naming conventions.
    427      */
    428     public static final int _default_port = DEFAULT_PORT;
    429
    430     /**
    431      * The serialVersionUID.
    432      */
    433     static final long serialVersionUID = -7158031098595039459L;
    434
    435     // ------------------------------------------------------------- The scheme
    436
    437     /**
    438      * Get the scheme.  You can get the scheme explicitly.
    439      *
    440      * @return the scheme
    441      */
    442     public char[] getRawScheme() {
    443         return (_scheme == null) ? null : HttpURL.DEFAULT_SCHEME;
    444     }
    445
    446
    447     /**
    448      * Get the scheme.  You can get the scheme explicitly.
    449      *
    450      * @return the scheme null if empty or undefined
    451      */
    452     public String getScheme() {
    453         return (_scheme == null) ? null : new String(HttpURL.DEFAULT_SCHEME);
    454     }
    455
    456     // --------------------------------------------------------------- The port
    457
    458     /**
    459      * Get the port number.
    460      * @return the port number
    461      */
    462     public int getPort() {
    463         return (_port == -1) ? HttpURL.DEFAULT_PORT : _port;
    464     }
    465
    466     // ----------------------------------------------------------- The userinfo
    467
    468     /**
    469      * Set the raw-escaped user and password.
    470      *
    471      * @param escapedUser the raw-escaped user
    472      * @param escapedPassword the raw-escaped password; could be null
    473      * @throws URIException escaped user not valid or user required; escaped
    474      * password not valid or username missed
    475      */
    476     public void setRawUserinfo(char[] escapedUser, char[] escapedPassword)
    477         throws URIException {
    478
    479         if (escapedUser == null || escapedUser.length == 0) {
    480             throw new URIException(URIException.PARSING, "user required");
    481         }
    482         if (!validate(escapedUser, within_userinfo)
    483             || ((escapedPassword != null)
    484             && !validate(escapedPassword, within_userinfo))) {
    485             throw new URIException(URIException.ESCAPING,
    486                     "escaped userinfo not valid");
    487         }
    488         String username = new String(escapedUser);
    489         String password = (escapedPassword == null)
    490             ? null : new String(escapedPassword);
    491         String userinfo = username + ((password == null) ? "" : ":" + password);
    492         String hostname = new String(getRawHost());
    493         String hostport = (_port == -1) ? hostname : hostname + ":" + _port;
    494         String authority = userinfo + "@" + hostport;
    495         _userinfo = userinfo.toCharArray();
    496         _authority = authority.toCharArray();
    497         setURI();
    498     }
    499
    500
    501     /**
    502      * Set the raw-escaped user and password.
    503      *
    504      * @param escapedUser the escaped user
    505      * @param escapedPassword the escaped password; could be null
    506      * @throws URIException escaped user not valid or user required; escaped
    507      * password not valid or username missed
    508      * @throws NullPointerException null user
    509      */
    510     public void setEscapedUserinfo(String escapedUser, String escapedPassword)
    511         throws URIException, NullPointerException {
    512
    513         setRawUserinfo(escapedUser.toCharArray(), (escapedPassword == null)
    514             ? null : escapedPassword.toCharArray());
    515     }
    516
    517
    518     /**
    519      * Set the user and password.
    520      *
    521      * @param user the user
    522      * @param password the password; could be null
    523      * @throws URIException encoding error or username missed
    524      * @throws NullPointerException null user
    525      */
    526     public void setUserinfo(String user, String password)
    527         throws URIException, NullPointerException {
    528         // set the charset to do escape encoding
    529         String charset = getProtocolCharset();
    530         setRawUserinfo(encode(user, within_userinfo, charset),
    531                 (password == null)
    532                 ? null
    533                 : encode(password, within_userinfo, charset));
    534     }
    535
    536
    537     /**
    538      * Set the raw-escaped user.
    539      *
    540      * @param escapedUser the raw-escaped user
    541      * @throws URIException escaped user not valid or user required
    542      */
    543     public void setRawUser(char[] escapedUser) throws URIException {
    544         if (escapedUser == null || escapedUser.length == 0) {
    545             throw new URIException(URIException.PARSING, "user required");
    546         }
    547         if (!validate(escapedUser, within_userinfo)) {
    548             throw new URIException(URIException.ESCAPING,
    549                     "escaped user not valid");
    550         }
    551         String username = new String(escapedUser);
    552         char[] rawPassword = getRawPassword();
    553 		String password = rawPassword == null ? null : new String(rawPassword);
    554         String userinfo = username + ((password == null) ? "" : ":" + password);
    555         String hostname = new String(getRawHost());
    556         String hostport = (_port == -1) ? hostname : hostname + ":" + _port;
    557         String authority = userinfo + "@" + hostport;
    558         _userinfo = userinfo.toCharArray();
    559         _authority = authority.toCharArray();
    560         setURI();
    561     }
    562
    563
    564     /**
    565      * Set the escaped user string.
    566      *
    567      * @param escapedUser the escaped user string
    568      * @throws URIException escaped user not valid
    569      * @throws NullPointerException null user
    570      */
    571     public void setEscapedUser(String escapedUser)
    572         throws URIException, NullPointerException {
    573         setRawUser(escapedUser.toCharArray());
    574     }
    575
    576
    577     /**
    578      * Set the user string.
    579      *
    580      * @param user the user string
    581      * @throws URIException user encoding error
    582      * @throws NullPointerException null user
    583      */
    584     public void setUser(String user) throws URIException, NullPointerException {
    585         setRawUser(encode(user, allowed_within_userinfo, getProtocolCharset()));
    586     }
    587
    588
    589     /**
    590      * Get the raw-escaped user.
    591      *
    592      * @return the raw-escaped user
    593      */
    594     public char[] getRawUser() {
    595         if (_userinfo == null || _userinfo.length == 0) {
    596             return null;
    597         }
    598         int to = indexFirstOf(_userinfo, ':');
    599         // String.indexOf(':', 0, _userinfo.length, _userinfo, 0, 1, 0);
    600         if (to == -1) {
    601             return _userinfo; // only user.
    602         }
    603         char[] result = new char[to];
    604         System.arraycopy(_userinfo, 0, result, 0, to);
    605         return result;
    606     }
    607
    608
    609     /**
    610      * Get the escaped user
    611      *
    612      * @return the escaped user
    613      */
    614     public String getEscapedUser() {
    615         char[] user = getRawUser();
    616         return (user == null) ? null : new String(user);
    617     }
    618
    619
    620     /**
    621      * Get the user.
    622      *
    623      * @return the user name
    624      * @throws URIException If {@link #decode} fails
    625      */
    626     public String getUser() throws URIException {
    627         char[] user = getRawUser();
    628         return (user == null) ? null : decode(user, getProtocolCharset());
    629     }
    630
    631
    632     /**
    633      * Set the raw-escaped password.
    634      *
    635      * @param escapedPassword the raw-escaped password; could be null
    636      * @throws URIException escaped password not valid or username missed
    637      */
    638     public void setRawPassword(char[] escapedPassword) throws URIException {
    639         if (escapedPassword != null
    640             && !validate(escapedPassword, within_userinfo)) {
    641             throw new URIException(URIException.ESCAPING,
    642                "escaped password not valid");
    643         }
    644         if (getRawUser() == null || getRawUser().length == 0) {
    645             throw new URIException(URIException.PARSING, "username required");
    646         }
    647         String username = new String(getRawUser());
    648         String password = escapedPassword == null ? null : new String(escapedPassword);
    649         // an emtpy string is allowed as a password
    650         String userinfo = username + ((password == null) ? "" : ":" + password);
    651         String hostname = new String(getRawHost());
    652         String hostport = (_port == -1) ? hostname : hostname + ":" + _port;
    653         String authority = userinfo + "@" + hostport;
    654         _userinfo = userinfo.toCharArray();
    655         _authority = authority.toCharArray();
    656         setURI();
    657     }
    658
    659
    660     /**
    661      * Set the escaped password string.
    662      *
    663      * @param escapedPassword the escaped password string; could be null
    664      * @throws URIException escaped password not valid or username missed
    665      */
    666     public void setEscapedPassword(String escapedPassword) throws URIException {
    667         setRawPassword((escapedPassword == null) ? null
    668             : escapedPassword.toCharArray());
    669     }
    670
    671
    672     /**
    673      * Set the password string.
    674      *
    675      * @param password the password string; could be null
    676      * @throws URIException encoding error or username missed
    677      */
    678     public void setPassword(String password) throws URIException {
    679         setRawPassword((password == null) ? null : encode(password,
    680                     allowed_within_userinfo, getProtocolCharset()));
    681     }
    682
    683
    684     /**
    685      * Get the raw-escaped password.
    686      *
    687      * @return the raw-escaped password
    688      */
    689     public char[] getRawPassword() {
    690         int from = indexFirstOf(_userinfo, ':');
    691         if (from == -1) {
    692             return null; // null or only user.
    693         }
    694         int len = _userinfo.length - from - 1;
    695         char[] result = new char[len];
    696         System.arraycopy(_userinfo, from + 1, result, 0, len);
    697         return result;
    698     }
    699
    700
    701     /**
    702      * Get the escaped password.
    703      *
    704      * @return the escaped password
    705      */
    706     public String getEscapedPassword() {
    707         char[] password = getRawPassword();
    708         return (password == null) ? null : new String(password);
    709     }
    710
    711
    712     /**
    713      * Get the password.
    714      *
    715      * @return the password
    716      * @throws URIException If {@link #decode(char[],String)} fails.
    717      */
    718     public String getPassword() throws URIException {
    719         char[] password = getRawPassword();
    720         return (password == null) ? null : decode(password,
    721                 getProtocolCharset());
    722     }
    723
    724     // --------------------------------------------------------------- The path
    725
    726     /**
    727      * Get the raw-escaped current hierarchy level.
    728      *
    729      * @return the raw-escaped current hierarchy level
    730      * @throws URIException If {@link #getRawCurrentHierPath(char[])} fails.
    731      */
    732     public char[] getRawCurrentHierPath() throws URIException {
    733         return (_path == null || _path.length == 0) ? rootPath
    734             : super.getRawCurrentHierPath(_path);
    735     }
    736
    737
    738     /**
    739      * Get the level above the this hierarchy level.
    740      *
    741      * @return the raw above hierarchy level
    742      * @throws URIException If {@link #getRawCurrentHierPath(char[])} fails.
    743      */
    744     public char[] getRawAboveHierPath() throws URIException {
    745         char[] path = getRawCurrentHierPath();
    746         return (path == null || path.length == 0) ? rootPath : getRawCurrentHierPath(path);
    747     }
    748
    749
    750     /**
    751      * Get the raw escaped path.
    752      *
    753      * @return the path '/' if empty or undefined
    754      */
    755     public char[] getRawPath() {
    756         char[] path =  super.getRawPath();
    757         return (path == null || path.length == 0) ? rootPath : path;
    758     }
    759
    760     // -------------------------------------------------------------- The query
    761
    762     /**
    763      * Set the query as the name and value pair.
    764      *
    765      * @param queryName the query string.
    766      * @param queryValue the query string.
    767      * @throws URIException incomplete trailing escape pattern
    768      * Or unsupported character encoding
    769      * @throws NullPointerException null query
    770      * @see #encode
    771      */
    772     public void setQuery(String queryName, String queryValue)
    773         throws URIException, NullPointerException {
    774
    775         StringBuffer buff = new StringBuffer();
    776         // set the charset to do escape encoding
    777         String charset = getProtocolCharset();
    778         buff.append(encode(queryName, allowed_within_query, charset));
    779         buff.append('=');
    780         buff.append(encode(queryValue, allowed_within_query, charset));
    781         _query = buff.toString().toCharArray();
    782         setURI();
    783     }
    784
    785
    786     /**
    787      * Set the query as the name and value pairs.
    788      *
    789      * @param queryName the array of the query string.
    790      * @param queryValue the array of the query string.
    791      * @throws URIException incomplete trailing escape pattern,
    792      * unsupported character encoding or wrong array size
    793      * @throws NullPointerException null query
    794      * @see #encode
    795      */
    796     public void setQuery(String[] queryName, String[] queryValue)
    797         throws URIException, NullPointerException {
    798
    799         int length = queryName.length;
    800         if (length != queryValue.length) {
    801             throw new URIException("wrong array size of query");
    802         }
    803
    804         StringBuffer buff = new StringBuffer();
    805         // set the charset to do escape encoding
    806         String charset = getProtocolCharset();
    807         for (int i = 0; i < length; i++) {
    808             buff.append(encode(queryName[i], allowed_within_query, charset));
    809             buff.append('=');
    810             buff.append(encode(queryValue[i], allowed_within_query, charset));
    811             if (i + 1 < length) {
    812                 buff.append('&');
    813             }
    814         }
    815         _query = buff.toString().toCharArray();
    816         setURI();
    817     }
    818
    819     // ---------------------------------------------------------------- Utility
    820
    821     /**
    822      * Verify the valid class use for construction.
    823      *
    824      * @throws URIException the wrong scheme use
    825      */
    826     protected void checkValid() throws URIException {
    827         // could be explicit protocol or undefined.
    828         if (!(equals(_scheme, DEFAULT_SCHEME) || _scheme == null)) {
    829             throw new URIException(URIException.PARSING, "wrong class use");
    830         }
    831     }
    832
    833     /**
    834      * Once it's parsed successfully, set this URI.
    835      *
    836      * @see #getRawURI
    837      */
    838     protected void setURI() {
    839         // set _uri
    840         StringBuffer buf = new StringBuffer();
    841         // ^(([^:/?#]+):)?(//([^/?#]*))?([^?#]*)(\?([^#]*))?(#(.*))?
    842         if (_scheme != null) {
    843             buf.append(_scheme);
    844             buf.append(':');
    845         }
    846         if (_is_net_path) {
    847             buf.append("//");
    848             if (_authority != null) { // has_authority
    849                 if (_userinfo != null) { // by default, remove userinfo part
    850                     if (_host != null) {
    851                         buf.append(_host);
    852                         if (_port != -1) {
    853                             buf.append(':');
    854                             buf.append(_port);
    855                         }
    856                     }
    857                 } else {
    858                     buf.append(_authority);
    859                 }
    860             }
    861         }
    862         if (_opaque != null && _is_opaque_part) {
    863             buf.append(_opaque);
    864         } else if (_path != null) {
    865             // _is_hier_part or _is_relativeURI
    866             if (_path.length != 0) {
    867                 buf.append(_path);
    868             }
    869         }
    870         if (_query != null) { // has_query
    871             buf.append('?');
    872             buf.append(_query);
    873         }
    874         // ignore the fragment identifier
    875         _uri = buf.toString().toCharArray();
    876         hash = 0;
    877     }
    878
    879 }
    880