19f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson/*
29f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * Licensed to the Apache Software Foundation (ASF) under one
39f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * or more contributor license agreements. See the NOTICE file
49f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * distributed with this work for additional information
59f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * regarding copyright ownership. The ASF licenses this file
69f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * to you under the Apache License, Version 2.0 (the  "License");
79f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * you may not use this file except in compliance with the License.
89f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * You may obtain a copy of the License at
99f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson *
109f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson *     http://www.apache.org/licenses/LICENSE-2.0
119f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson *
129f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * Unless required by applicable law or agreed to in writing, software
139f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * distributed under the License is distributed on an "AS IS" BASIS,
149f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
159f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * See the License for the specific language governing permissions and
169f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * limitations under the License.
179f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson */
189f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson/*
199f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * $Id: URI.java 468655 2006-10-28 07:12:06Z minchau $
209f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson */
219f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilsonpackage org.apache.xml.utils;
229f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
239f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilsonimport java.io.IOException;
249f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilsonimport java.io.Serializable;
259f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
269f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilsonimport org.apache.xml.res.XMLErrorResources;
279f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilsonimport org.apache.xml.res.XMLMessages;
289f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
299f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson/**
309f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * A class to represent a Uniform Resource Identifier (URI). This class
319f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * is designed to handle the parsing of URIs and provide access to
329f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * the various components (scheme, host, port, userinfo, path, query
339f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * string and fragment) that may constitute a URI.
349f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * <p>
359f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * Parsing of a URI specification is done according to the URI
369f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * syntax described in RFC 2396
379f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * <http://www.ietf.org/rfc/rfc2396.txt?number=2396>. Every URI consists
389f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * of a scheme, followed by a colon (':'), followed by a scheme-specific
399f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * part. For URIs that follow the "generic URI" syntax, the scheme-
409f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * specific part begins with two slashes ("//") and may be followed
419f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * by an authority segment (comprised of user information, host, and
429f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * port), path segment, query segment and fragment. Note that RFC 2396
439f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * no longer specifies the use of the parameters segment and excludes
449f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * the "user:password" syntax as part of the authority segment. If
459f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * "user:password" appears in a URI, the entire user/password string
469f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * is stored as userinfo.
479f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * <p>
489f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * For URIs that do not follow the "generic URI" syntax (e.g. mailto),
499f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * the entire scheme-specific part is treated as the "path" portion
509f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * of the URI.
519f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * <p>
529f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * Note that, unlike the java.net.URL class, this class does not provide
539f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * any built-in network access functionality nor does it provide any
549f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * scheme-specific functionality (for example, it does not know a
559f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * default port for a specific scheme). Rather, it only knows the
569f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * grammar and basic set of operations that can be applied to a URI.
579f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson *
589f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson *
599f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson */
609f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilsonpublic class URI implements Serializable
619f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson{
629f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    static final long serialVersionUID = 7096266377907081897L;
639f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
649f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  /**
659f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * MalformedURIExceptions are thrown in the process of building a URI
669f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * or setting fields on a URI when an operation would result in an
679f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * invalid URI specification.
689f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   *
699f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   */
709f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  public static class MalformedURIException extends IOException
719f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  {
729f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
739f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    /**
749f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * Constructs a <code>MalformedURIException</code> with no specified
759f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * detail message.
769f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     */
779f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    public MalformedURIException()
789f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    {
799f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      super();
809f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    }
819f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
829f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    /**
839f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * Constructs a <code>MalformedURIException</code> with the
849f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * specified detail message.
859f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     *
869f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * @param p_msg the detail message.
879f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     */
889f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    public MalformedURIException(String p_msg)
899f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    {
909f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      super(p_msg);
919f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    }
929f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  }
939f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
949f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  /** reserved characters */
959f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  private static final String RESERVED_CHARACTERS = ";/?:@&=+$,";
969f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
979f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  /**
989f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * URI punctuation mark characters - these, combined with
999f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   *   alphanumerics, constitute the "unreserved" characters
1009f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   */
1019f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  private static final String MARK_CHARACTERS = "-_.!~*'() ";
1029f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
1039f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  /** scheme can be composed of alphanumerics and these characters */
1049f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  private static final String SCHEME_CHARACTERS = "+-.";
1059f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
1069f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  /**
1079f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * userinfo can be composed of unreserved, escaped and these
1089f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   *   characters
1099f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   */
1109f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  private static final String USERINFO_CHARACTERS = ";:&=+$,";
1119f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
1129f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  /** Stores the scheme (usually the protocol) for this URI.
1139f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   *  @serial */
1149f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  private String m_scheme = null;
1159f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
1169f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  /** If specified, stores the userinfo for this URI; otherwise null.
1179f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   *  @serial */
1189f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  private String m_userinfo = null;
1199f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
1209f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  /** If specified, stores the host for this URI; otherwise null.
1219f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   *  @serial */
1229f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  private String m_host = null;
1239f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
1249f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  /** If specified, stores the port for this URI; otherwise -1.
1259f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   *  @serial */
1269f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  private int m_port = -1;
1279f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
1289f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  /** If specified, stores the path for this URI; otherwise null.
1299f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   *  @serial */
1309f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  private String m_path = null;
1319f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
1329f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  /**
1339f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * If specified, stores the query string for this URI; otherwise
1349f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   *   null.
1359f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * @serial
1369f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   */
1379f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  private String m_queryString = null;
1389f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
1399f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  /** If specified, stores the fragment for this URI; otherwise null.
1409f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   *  @serial */
1419f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  private String m_fragment = null;
1429f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
1439f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  /** Indicate whether in DEBUG mode          */
1449f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  private static boolean DEBUG = false;
1459f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
1469f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  /**
1479f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * Construct a new and uninitialized URI.
1489f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   */
1499f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  public URI(){}
1509f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
1519f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  /**
1529f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * Construct a new URI from another URI. All fields for this URI are
1539f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * set equal to the fields of the URI passed in.
1549f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   *
1559f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * @param p_other the URI to copy (cannot be null)
1569f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   */
1579f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  public URI(URI p_other)
1589f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  {
1599f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    initialize(p_other);
1609f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  }
1619f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
1629f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  /**
1639f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * Construct a new URI from a URI specification string. If the
1649f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * specification follows the "generic URI" syntax, (two slashes
1659f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * following the first colon), the specification will be parsed
1669f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * accordingly - setting the scheme, userinfo, host,port, path, query
1679f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * string and fragment fields as necessary. If the specification does
1689f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * not follow the "generic URI" syntax, the specification is parsed
1699f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * into a scheme and scheme-specific part (stored as the path) only.
1709f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   *
1719f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * @param p_uriSpec the URI specification string (cannot be null or
1729f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   *                  empty)
1739f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   *
1749f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * @throws MalformedURIException if p_uriSpec violates any syntax
1759f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   *                                   rules
1769f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   */
1779f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  public URI(String p_uriSpec) throws MalformedURIException
1789f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  {
1799f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    this((URI) null, p_uriSpec);
1809f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  }
1819f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
1829f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  /**
1839f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * Construct a new URI from a base URI and a URI specification string.
1849f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * The URI specification string may be a relative URI.
1859f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   *
1869f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * @param p_base the base URI (cannot be null if p_uriSpec is null or
1879f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   *               empty)
1889f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * @param p_uriSpec the URI specification string (cannot be null or
1899f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   *                  empty if p_base is null)
1909f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   *
1919f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * @throws MalformedURIException if p_uriSpec violates any syntax
1929f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   *                                  rules
1939f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   */
1949f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  public URI(URI p_base, String p_uriSpec) throws MalformedURIException
1959f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  {
1969f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    initialize(p_base, p_uriSpec);
1979f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  }
1989f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
1999f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  /**
2009f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * Construct a new URI that does not follow the generic URI syntax.
2019f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * Only the scheme and scheme-specific part (stored as the path) are
2029f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * initialized.
2039f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   *
2049f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * @param p_scheme the URI scheme (cannot be null or empty)
2059f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * @param p_schemeSpecificPart the scheme-specific part (cannot be
2069f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   *                             null or empty)
2079f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   *
2089f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * @throws MalformedURIException if p_scheme violates any
2099f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   *                                  syntax rules
2109f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   */
2119f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  public URI(String p_scheme, String p_schemeSpecificPart)
2129f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson          throws MalformedURIException
2139f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  {
2149f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
2159f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    if (p_scheme == null || p_scheme.trim().length() == 0)
2169f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    {
2179f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      throw new MalformedURIException(
2189f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        "Cannot construct URI with null/empty scheme!");
2199f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    }
2209f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
2219f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    if (p_schemeSpecificPart == null
2229f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            || p_schemeSpecificPart.trim().length() == 0)
2239f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    {
2249f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      throw new MalformedURIException(
2259f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        "Cannot construct URI with null/empty scheme-specific part!");
2269f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    }
2279f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
2289f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    setScheme(p_scheme);
2299f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    setPath(p_schemeSpecificPart);
2309f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  }
2319f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
2329f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  /**
2339f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * Construct a new URI that follows the generic URI syntax from its
2349f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * component parts. Each component is validated for syntax and some
2359f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * basic semantic checks are performed as well.  See the individual
2369f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * setter methods for specifics.
2379f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   *
2389f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * @param p_scheme the URI scheme (cannot be null or empty)
2399f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * @param p_host the hostname or IPv4 address for the URI
2409f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * @param p_path the URI path - if the path contains '?' or '#',
2419f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   *               then the query string and/or fragment will be
2429f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   *               set from the path; however, if the query and
2439f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   *               fragment are specified both in the path and as
2449f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   *               separate parameters, an exception is thrown
2459f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * @param p_queryString the URI query string (cannot be specified
2469f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   *                      if path is null)
2479f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * @param p_fragment the URI fragment (cannot be specified if path
2489f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   *                   is null)
2499f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   *
2509f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * @throws MalformedURIException if any of the parameters violates
2519f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   *                                  syntax rules or semantic rules
2529f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   */
2539f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  public URI(String p_scheme, String p_host, String p_path, String p_queryString, String p_fragment)
2549f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson          throws MalformedURIException
2559f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  {
2569f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    this(p_scheme, null, p_host, -1, p_path, p_queryString, p_fragment);
2579f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  }
2589f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
2599f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  /**
2609f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * Construct a new URI that follows the generic URI syntax from its
2619f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * component parts. Each component is validated for syntax and some
2629f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * basic semantic checks are performed as well.  See the individual
2639f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * setter methods for specifics.
2649f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   *
2659f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * @param p_scheme the URI scheme (cannot be null or empty)
2669f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * @param p_userinfo the URI userinfo (cannot be specified if host
2679f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   *                   is null)
2689f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * @param p_host the hostname or IPv4 address for the URI
2699f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * @param p_port the URI port (may be -1 for "unspecified"; cannot
2709f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   *               be specified if host is null)
2719f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * @param p_path the URI path - if the path contains '?' or '#',
2729f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   *               then the query string and/or fragment will be
2739f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   *               set from the path; however, if the query and
2749f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   *               fragment are specified both in the path and as
2759f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   *               separate parameters, an exception is thrown
2769f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * @param p_queryString the URI query string (cannot be specified
2779f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   *                      if path is null)
2789f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * @param p_fragment the URI fragment (cannot be specified if path
2799f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   *                   is null)
2809f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   *
2819f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * @throws MalformedURIException if any of the parameters violates
2829f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   *                                  syntax rules or semantic rules
2839f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   */
2849f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  public URI(String p_scheme, String p_userinfo, String p_host, int p_port, String p_path, String p_queryString, String p_fragment)
2859f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson          throws MalformedURIException
2869f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  {
2879f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
2889f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    if (p_scheme == null || p_scheme.trim().length() == 0)
2899f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    {
2909f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      throw new MalformedURIException(XMLMessages.createXMLMessage(XMLErrorResources.ER_SCHEME_REQUIRED, null)); //"Scheme is required!");
2919f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    }
2929f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
2939f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    if (p_host == null)
2949f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    {
2959f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      if (p_userinfo != null)
2969f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      {
2979f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        throw new MalformedURIException(
2989f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson          XMLMessages.createXMLMessage(XMLErrorResources.ER_NO_USERINFO_IF_NO_HOST, null)); //"Userinfo may not be specified if host is not specified!");
2999f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      }
3009f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
3019f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      if (p_port != -1)
3029f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      {
3039f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        throw new MalformedURIException(
3049f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson          XMLMessages.createXMLMessage(XMLErrorResources.ER_NO_PORT_IF_NO_HOST, null)); //"Port may not be specified if host is not specified!");
3059f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      }
3069f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    }
3079f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
3089f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    if (p_path != null)
3099f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    {
3109f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      if (p_path.indexOf('?') != -1 && p_queryString != null)
3119f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      {
3129f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        throw new MalformedURIException(
3139f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson          XMLMessages.createXMLMessage(XMLErrorResources.ER_NO_QUERY_STRING_IN_PATH, null)); //"Query string cannot be specified in path and query string!");
3149f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      }
3159f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
3169f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      if (p_path.indexOf('#') != -1 && p_fragment != null)
3179f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      {
3189f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        throw new MalformedURIException(
3199f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson          XMLMessages.createXMLMessage(XMLErrorResources.ER_NO_FRAGMENT_STRING_IN_PATH, null)); //"Fragment cannot be specified in both the path and fragment!");
3209f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      }
3219f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    }
3229f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
3239f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    setScheme(p_scheme);
3249f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    setHost(p_host);
3259f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    setPort(p_port);
3269f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    setUserinfo(p_userinfo);
3279f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    setPath(p_path);
3289f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    setQueryString(p_queryString);
3299f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    setFragment(p_fragment);
3309f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  }
3319f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
3329f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  /**
3339f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * Initialize all fields of this URI from another URI.
3349f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   *
3359f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * @param p_other the URI to copy (cannot be null)
3369f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   */
3379f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  private void initialize(URI p_other)
3389f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  {
3399f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
3409f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    m_scheme = p_other.getScheme();
3419f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    m_userinfo = p_other.getUserinfo();
3429f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    m_host = p_other.getHost();
3439f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    m_port = p_other.getPort();
3449f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    m_path = p_other.getPath();
3459f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    m_queryString = p_other.getQueryString();
3469f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    m_fragment = p_other.getFragment();
3479f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  }
3489f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
3499f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  /**
3509f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * Initializes this URI from a base URI and a URI specification string.
3519f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * See RFC 2396 Section 4 and Appendix B for specifications on parsing
3529f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * the URI and Section 5 for specifications on resolving relative URIs
3539f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * and relative paths.
3549f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   *
3559f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * @param p_base the base URI (may be null if p_uriSpec is an absolute
3569f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   *               URI)
3579f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * @param p_uriSpec the URI spec string which may be an absolute or
3589f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   *                  relative URI (can only be null/empty if p_base
3599f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   *                  is not null)
3609f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   *
3619f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * @throws MalformedURIException if p_base is null and p_uriSpec
3629f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   *                                  is not an absolute URI or if
3639f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   *                                  p_uriSpec violates syntax rules
3649f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   */
3659f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  private void initialize(URI p_base, String p_uriSpec)
3669f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson          throws MalformedURIException
3679f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  {
3689f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
3699f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    if (p_base == null
3709f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            && (p_uriSpec == null || p_uriSpec.trim().length() == 0))
3719f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    {
3729f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      throw new MalformedURIException(
3739f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        XMLMessages.createXMLMessage(XMLErrorResources.ER_CANNOT_INIT_URI_EMPTY_PARMS, null)); //"Cannot initialize URI with empty parameters.");
3749f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    }
3759f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
3769f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    // just make a copy of the base if spec is empty
3779f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    if (p_uriSpec == null || p_uriSpec.trim().length() == 0)
3789f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    {
3799f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      initialize(p_base);
3809f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
3819f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      return;
3829f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    }
3839f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
3849f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    String uriSpec = p_uriSpec.trim();
3859f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    int uriSpecLen = uriSpec.length();
3869f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    int index = 0;
3879f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
3889f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    // check for scheme
3899f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    int colonIndex = uriSpec.indexOf(':');
3909f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    if (colonIndex < 0)
3919f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    {
3929f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      if (p_base == null)
3939f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      {
3949f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        throw new MalformedURIException(XMLMessages.createXMLMessage(XMLErrorResources.ER_NO_SCHEME_IN_URI, new Object[]{uriSpec})); //"No scheme found in URI: "+uriSpec);
3959f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      }
3969f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    }
3979f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    else
3989f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    {
3999f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      initializeScheme(uriSpec);
4009f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      uriSpec = uriSpec.substring(colonIndex+1);
4019f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      // This is a fix for XALANJ-2059.
4029f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      if(m_scheme != null && p_base != null)
4039f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      {
4049f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        // a) If <uriSpec> starts with a slash (/), it means <uriSpec> is absolute
4059f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        //    and p_base can be ignored.
4069f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        //    For example,
4079f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        //    uriSpec = file:/myDIR/myXSLFile.xsl
4089f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        //    p_base = file:/myWork/
4099f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        //
4109f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        //    Here, uriSpec has absolute path after scheme file and :
4119f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        //    Hence p_base can be ignored.
4129f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        //
4139f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        // b) Similarily, according to RFC 2396, uri is resolved for <uriSpec> relative to <p_base>
4149f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        //    if scheme in <uriSpec> is same as scheme in <p_base>, else p_base can be ignored.
4159f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        //
4169f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        // c) if <p_base> is not hierarchical, it can be ignored.
4179f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        //
4189f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        if(uriSpec.startsWith("/") || !m_scheme.equals(p_base.m_scheme) || !p_base.getSchemeSpecificPart().startsWith("/"))
4199f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        {
4209f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson          p_base = null;
4219f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        }
4229f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      }
4239f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      // Fix for XALANJ-2059
4249f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      uriSpecLen = uriSpec.length();
4259f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    }
4269f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
4279f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    // two slashes means generic URI syntax, so we get the authority
4289f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    if (uriSpec.startsWith("//"))
4299f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    {
4309f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      index += 2;
4319f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
4329f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      int startPos = index;
4339f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
4349f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      // get authority - everything up to path, query or fragment
4359f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      char testChar = '\0';
4369f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
4379f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      while (index < uriSpecLen)
4389f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      {
4399f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        testChar = uriSpec.charAt(index);
4409f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
4419f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        if (testChar == '/' || testChar == '?' || testChar == '#')
4429f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        {
4439f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson          break;
4449f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        }
4459f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
4469f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        index++;
4479f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      }
4489f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
4499f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      // if we found authority, parse it out, otherwise we set the
4509f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      // host to empty string
4519f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      if (index > startPos)
4529f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      {
4539f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        initializeAuthority(uriSpec.substring(startPos, index));
4549f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      }
4559f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      else
4569f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      {
4579f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        m_host = "";
4589f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      }
4599f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    }
4609f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
4619f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    initializePath(uriSpec.substring(index));
4629f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
4639f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    // Resolve relative URI to base URI - see RFC 2396 Section 5.2
4649f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    // In some cases, it might make more sense to throw an exception
4659f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    // (when scheme is specified is the string spec and the base URI
4669f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    // is also specified, for example), but we're just following the
4679f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    // RFC specifications
4689f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    if (p_base != null)
4699f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    {
4709f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
4719f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      // check to see if this is the current doc - RFC 2396 5.2 #2
4729f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      // note that this is slightly different from the RFC spec in that
4739f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      // we don't include the check for query string being null
4749f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      // - this handles cases where the urispec is just a query
4759f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      // string or a fragment (e.g. "?y" or "#s") -
4769f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      // see <http://www.ics.uci.edu/~fielding/url/test1.html> which
4779f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      // identified this as a bug in the RFC
4789f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      if (m_path.length() == 0 && m_scheme == null && m_host == null)
4799f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      {
4809f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        m_scheme = p_base.getScheme();
4819f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        m_userinfo = p_base.getUserinfo();
4829f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        m_host = p_base.getHost();
4839f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        m_port = p_base.getPort();
4849f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        m_path = p_base.getPath();
4859f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
4869f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        if (m_queryString == null)
4879f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        {
4889f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson          m_queryString = p_base.getQueryString();
4899f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        }
4909f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
4919f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        return;
4929f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      }
4939f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
4949f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      // check for scheme - RFC 2396 5.2 #3
4959f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      // if we found a scheme, it means absolute URI, so we're done
4969f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      if (m_scheme == null)
4979f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      {
4989f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        m_scheme = p_base.getScheme();
4999f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      }
5009f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
5019f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      // check for authority - RFC 2396 5.2 #4
5029f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      // if we found a host, then we've got a network path, so we're done
5039f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      if (m_host == null)
5049f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      {
5059f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        m_userinfo = p_base.getUserinfo();
5069f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        m_host = p_base.getHost();
5079f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        m_port = p_base.getPort();
5089f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      }
5099f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      else
5109f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      {
5119f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        return;
5129f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      }
5139f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
5149f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      // check for absolute path - RFC 2396 5.2 #5
5159f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      if (m_path.length() > 0 && m_path.startsWith("/"))
5169f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      {
5179f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        return;
5189f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      }
5199f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
5209f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      // if we get to this point, we need to resolve relative path
5219f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      // RFC 2396 5.2 #6
5229f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      String path = new String();
5239f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      String basePath = p_base.getPath();
5249f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
5259f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      // 6a - get all but the last segment of the base URI path
5269f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      if (basePath != null)
5279f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      {
5289f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        int lastSlash = basePath.lastIndexOf('/');
5299f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
5309f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        if (lastSlash != -1)
5319f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        {
5329f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson          path = basePath.substring(0, lastSlash + 1);
5339f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        }
5349f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      }
5359f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
5369f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      // 6b - append the relative URI path
5379f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      path = path.concat(m_path);
5389f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
5399f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      // 6c - remove all "./" where "." is a complete path segment
5409f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      index = -1;
5419f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
5429f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      while ((index = path.indexOf("/./")) != -1)
5439f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      {
5449f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        path = path.substring(0, index + 1).concat(path.substring(index + 3));
5459f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      }
5469f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
5479f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      // 6d - remove "." if path ends with "." as a complete path segment
5489f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      if (path.endsWith("/."))
5499f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      {
5509f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        path = path.substring(0, path.length() - 1);
5519f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      }
5529f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
5539f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      // 6e - remove all "<segment>/../" where "<segment>" is a complete
5549f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      // path segment not equal to ".."
5559f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      index = -1;
5569f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
5579f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      int segIndex = -1;
5589f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      String tempString = null;
5599f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
5609f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      while ((index = path.indexOf("/../")) > 0)
5619f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      {
5629f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        tempString = path.substring(0, path.indexOf("/../"));
5639f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        segIndex = tempString.lastIndexOf('/');
5649f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
5659f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        if (segIndex != -1)
5669f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        {
5679f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson          if (!tempString.substring(segIndex++).equals(".."))
5689f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson          {
5699f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            path = path.substring(0, segIndex).concat(path.substring(index
5709f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                    + 4));
5719f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson          }
5729f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        }
5739f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      }
5749f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
5759f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      // 6f - remove ending "<segment>/.." where "<segment>" is a
5769f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      // complete path segment
5779f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      if (path.endsWith("/.."))
5789f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      {
5799f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        tempString = path.substring(0, path.length() - 3);
5809f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        segIndex = tempString.lastIndexOf('/');
5819f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
5829f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        if (segIndex != -1)
5839f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        {
5849f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson          path = path.substring(0, segIndex + 1);
5859f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        }
5869f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      }
5879f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
5889f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      m_path = path;
5899f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    }
5909f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  }
5919f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
5929f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  /**
5939f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * Initialize the scheme for this URI from a URI string spec.
5949f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   *
5959f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * @param p_uriSpec the URI specification (cannot be null)
5969f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   *
5979f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * @throws MalformedURIException if URI does not have a conformant
5989f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   *                                  scheme
5999f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   */
6009f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  private void initializeScheme(String p_uriSpec) throws MalformedURIException
6019f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  {
6029f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
6039f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    int uriSpecLen = p_uriSpec.length();
6049f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    int index = 0;
6059f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    String scheme = null;
6069f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    char testChar = '\0';
6079f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
6089f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    while (index < uriSpecLen)
6099f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    {
6109f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      testChar = p_uriSpec.charAt(index);
6119f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
6129f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      if (testChar == ':' || testChar == '/' || testChar == '?'
6139f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson              || testChar == '#')
6149f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      {
6159f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        break;
6169f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      }
6179f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
6189f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      index++;
6199f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    }
6209f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
6219f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    scheme = p_uriSpec.substring(0, index);
6229f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
6239f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    if (scheme.length() == 0)
6249f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    {
6259f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      throw new MalformedURIException(XMLMessages.createXMLMessage(XMLErrorResources.ER_NO_SCHEME_INURI, null)); //"No scheme found in URI.");
6269f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    }
6279f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    else
6289f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    {
6299f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      setScheme(scheme);
6309f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    }
6319f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  }
6329f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
6339f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  /**
6349f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * Initialize the authority (userinfo, host and port) for this
6359f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * URI from a URI string spec.
6369f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   *
6379f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * @param p_uriSpec the URI specification (cannot be null)
6389f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   *
6399f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * @throws MalformedURIException if p_uriSpec violates syntax rules
6409f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   */
6419f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  private void initializeAuthority(String p_uriSpec)
6429f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson          throws MalformedURIException
6439f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  {
6449f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
6459f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    int index = 0;
6469f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    int start = 0;
6479f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    int end = p_uriSpec.length();
6489f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    char testChar = '\0';
6499f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    String userinfo = null;
6509f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
6519f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    // userinfo is everything up @
6529f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    if (p_uriSpec.indexOf('@', start) != -1)
6539f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    {
6549f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      while (index < end)
6559f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      {
6569f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        testChar = p_uriSpec.charAt(index);
6579f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
6589f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        if (testChar == '@')
6599f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        {
6609f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson          break;
6619f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        }
6629f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
6639f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        index++;
6649f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      }
6659f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
6669f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      userinfo = p_uriSpec.substring(start, index);
6679f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
6689f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      index++;
6699f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    }
6709f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
6719f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    // host is everything up to ':'
6729f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    String host = null;
6739f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
6749f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    start = index;
6759f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
6769f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    while (index < end)
6779f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    {
6789f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      testChar = p_uriSpec.charAt(index);
6799f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
6809f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      if (testChar == ':')
6819f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      {
6829f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        break;
6839f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      }
6849f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
6859f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      index++;
6869f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    }
6879f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
6889f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    host = p_uriSpec.substring(start, index);
6899f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
6909f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    int port = -1;
6919f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
6929f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    if (host.length() > 0)
6939f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    {
6949f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
6959f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      // port
6969f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      if (testChar == ':')
6979f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      {
6989f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        index++;
6999f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
7009f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        start = index;
7019f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
7029f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        while (index < end)
7039f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        {
7049f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson          index++;
7059f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        }
7069f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
7079f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        String portStr = p_uriSpec.substring(start, index);
7089f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
7099f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        if (portStr.length() > 0)
7109f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        {
7119f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson          for (int i = 0; i < portStr.length(); i++)
7129f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson          {
7139f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            if (!isDigit(portStr.charAt(i)))
7149f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            {
7159f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson              throw new MalformedURIException(
7169f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                portStr + " is invalid. Port should only contain digits!");
7179f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            }
7189f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson          }
7199f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
7209f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson          try
7219f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson          {
7229f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            port = Integer.parseInt(portStr);
7239f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson          }
7249f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson          catch (NumberFormatException nfe)
7259f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson          {
7269f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
7279f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            // can't happen
7289f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson          }
7299f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        }
7309f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      }
7319f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    }
7329f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
7339f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    setHost(host);
7349f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    setPort(port);
7359f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    setUserinfo(userinfo);
7369f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  }
7379f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
7389f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  /**
7399f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * Initialize the path for this URI from a URI string spec.
7409f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   *
7419f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * @param p_uriSpec the URI specification (cannot be null)
7429f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   *
7439f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * @throws MalformedURIException if p_uriSpec violates syntax rules
7449f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   */
7459f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  private void initializePath(String p_uriSpec) throws MalformedURIException
7469f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  {
7479f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
7489f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    if (p_uriSpec == null)
7499f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    {
7509f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      throw new MalformedURIException(
7519f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        "Cannot initialize path from null string!");
7529f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    }
7539f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
7549f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    int index = 0;
7559f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    int start = 0;
7569f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    int end = p_uriSpec.length();
7579f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    char testChar = '\0';
7589f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
7599f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    // path - everything up to query string or fragment
7609f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    while (index < end)
7619f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    {
7629f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      testChar = p_uriSpec.charAt(index);
7639f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
7649f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      if (testChar == '?' || testChar == '#')
7659f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      {
7669f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        break;
7679f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      }
7689f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
7699f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      // check for valid escape sequence
7709f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      if (testChar == '%')
7719f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      {
7729f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        if (index + 2 >= end ||!isHex(p_uriSpec.charAt(index + 1))
7739f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                ||!isHex(p_uriSpec.charAt(index + 2)))
7749f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        {
7759f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson          throw new MalformedURIException(
7769f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            XMLMessages.createXMLMessage(XMLErrorResources.ER_PATH_CONTAINS_INVALID_ESCAPE_SEQUENCE, null)); //"Path contains invalid escape sequence!");
7779f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        }
7789f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      }
7799f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      else if (!isReservedCharacter(testChar)
7809f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson               &&!isUnreservedCharacter(testChar))
7819f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      {
7829f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        if ('\\' != testChar)
7839f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson          throw new MalformedURIException(XMLMessages.createXMLMessage(XMLErrorResources.ER_PATH_INVALID_CHAR, new Object[]{String.valueOf(testChar)})); //"Path contains invalid character: "
7849f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                                          //+ testChar);
7859f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      }
7869f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
7879f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      index++;
7889f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    }
7899f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
7909f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    m_path = p_uriSpec.substring(start, index);
7919f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
7929f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    // query - starts with ? and up to fragment or end
7939f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    if (testChar == '?')
7949f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    {
7959f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      index++;
7969f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
7979f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      start = index;
7989f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
7999f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      while (index < end)
8009f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      {
8019f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        testChar = p_uriSpec.charAt(index);
8029f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
8039f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        if (testChar == '#')
8049f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        {
8059f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson          break;
8069f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        }
8079f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
8089f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        if (testChar == '%')
8099f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        {
8109f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson          if (index + 2 >= end ||!isHex(p_uriSpec.charAt(index + 1))
8119f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                  ||!isHex(p_uriSpec.charAt(index + 2)))
8129f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson          {
8139f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            throw new MalformedURIException(
8149f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson              "Query string contains invalid escape sequence!");
8159f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson          }
8169f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        }
8179f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        else if (!isReservedCharacter(testChar)
8189f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                 &&!isUnreservedCharacter(testChar))
8199f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        {
8209f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson          throw new MalformedURIException(
8219f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            "Query string contains invalid character:" + testChar);
8229f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        }
8239f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
8249f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        index++;
8259f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      }
8269f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
8279f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      m_queryString = p_uriSpec.substring(start, index);
8289f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    }
8299f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
8309f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    // fragment - starts with #
8319f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    if (testChar == '#')
8329f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    {
8339f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      index++;
8349f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
8359f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      start = index;
8369f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
8379f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      while (index < end)
8389f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      {
8399f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        testChar = p_uriSpec.charAt(index);
8409f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
8419f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        if (testChar == '%')
8429f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        {
8439f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson          if (index + 2 >= end ||!isHex(p_uriSpec.charAt(index + 1))
8449f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                  ||!isHex(p_uriSpec.charAt(index + 2)))
8459f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson          {
8469f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            throw new MalformedURIException(
8479f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson              "Fragment contains invalid escape sequence!");
8489f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson          }
8499f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        }
8509f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        else if (!isReservedCharacter(testChar)
8519f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                 &&!isUnreservedCharacter(testChar))
8529f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        {
8539f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson          throw new MalformedURIException(
8549f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            "Fragment contains invalid character:" + testChar);
8559f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        }
8569f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
8579f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        index++;
8589f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      }
8599f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
8609f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      m_fragment = p_uriSpec.substring(start, index);
8619f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    }
8629f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  }
8639f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
8649f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  /**
8659f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * Get the scheme for this URI.
8669f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   *
8679f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * @return the scheme for this URI
8689f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   */
8699f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  public String getScheme()
8709f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  {
8719f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    return m_scheme;
8729f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  }
8739f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
8749f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  /**
8759f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * Get the scheme-specific part for this URI (everything following the
8769f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * scheme and the first colon). See RFC 2396 Section 5.2 for spec.
8779f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   *
8789f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * @return the scheme-specific part for this URI
8799f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   */
8809f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  public String getSchemeSpecificPart()
8819f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  {
8829f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
8839f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    StringBuffer schemespec = new StringBuffer();
8849f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
8859f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    if (m_userinfo != null || m_host != null || m_port != -1)
8869f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    {
8879f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      schemespec.append("//");
8889f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    }
8899f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
8909f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    if (m_userinfo != null)
8919f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    {
8929f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      schemespec.append(m_userinfo);
8939f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      schemespec.append('@');
8949f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    }
8959f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
8969f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    if (m_host != null)
8979f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    {
8989f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      schemespec.append(m_host);
8999f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    }
9009f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
9019f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    if (m_port != -1)
9029f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    {
9039f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      schemespec.append(':');
9049f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      schemespec.append(m_port);
9059f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    }
9069f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
9079f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    if (m_path != null)
9089f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    {
9099f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      schemespec.append((m_path));
9109f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    }
9119f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
9129f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    if (m_queryString != null)
9139f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    {
9149f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      schemespec.append('?');
9159f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      schemespec.append(m_queryString);
9169f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    }
9179f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
9189f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    if (m_fragment != null)
9199f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    {
9209f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      schemespec.append('#');
9219f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      schemespec.append(m_fragment);
9229f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    }
9239f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
9249f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    return schemespec.toString();
9259f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  }
9269f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
9279f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  /**
9289f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * Get the userinfo for this URI.
9299f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   *
9309f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * @return the userinfo for this URI (null if not specified).
9319f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   */
9329f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  public String getUserinfo()
9339f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  {
9349f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    return m_userinfo;
9359f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  }
9369f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
9379f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  /**
9389f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * Get the host for this URI.
9399f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   *
9409f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * @return the host for this URI (null if not specified).
9419f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   */
9429f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  public String getHost()
9439f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  {
9449f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    return m_host;
9459f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  }
9469f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
9479f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  /**
9489f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * Get the port for this URI.
9499f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   *
9509f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * @return the port for this URI (-1 if not specified).
9519f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   */
9529f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  public int getPort()
9539f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  {
9549f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    return m_port;
9559f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  }
9569f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
9579f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  /**
9589f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * Get the path for this URI (optionally with the query string and
9599f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * fragment).
9609f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   *
9619f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * @param p_includeQueryString if true (and query string is not null),
9629f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   *                             then a "?" followed by the query string
9639f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   *                             will be appended
9649f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * @param p_includeFragment if true (and fragment is not null),
9659f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   *                             then a "#" followed by the fragment
9669f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   *                             will be appended
9679f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   *
9689f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * @return the path for this URI possibly including the query string
9699f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   *         and fragment
9709f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   */
9719f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  public String getPath(boolean p_includeQueryString,
9729f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                        boolean p_includeFragment)
9739f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  {
9749f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
9759f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    StringBuffer pathString = new StringBuffer(m_path);
9769f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
9779f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    if (p_includeQueryString && m_queryString != null)
9789f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    {
9799f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      pathString.append('?');
9809f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      pathString.append(m_queryString);
9819f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    }
9829f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
9839f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    if (p_includeFragment && m_fragment != null)
9849f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    {
9859f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      pathString.append('#');
9869f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      pathString.append(m_fragment);
9879f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    }
9889f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
9899f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    return pathString.toString();
9909f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  }
9919f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
9929f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  /**
9939f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * Get the path for this URI. Note that the value returned is the path
9949f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * only and does not include the query string or fragment.
9959f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   *
9969f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * @return the path for this URI.
9979f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   */
9989f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  public String getPath()
9999f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  {
10009f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    return m_path;
10019f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  }
10029f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
10039f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  /**
10049f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * Get the query string for this URI.
10059f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   *
10069f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * @return the query string for this URI. Null is returned if there
10079f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   *         was no "?" in the URI spec, empty string if there was a
10089f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   *         "?" but no query string following it.
10099f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   */
10109f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  public String getQueryString()
10119f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  {
10129f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    return m_queryString;
10139f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  }
10149f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
10159f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  /**
10169f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * Get the fragment for this URI.
10179f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   *
10189f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * @return the fragment for this URI. Null is returned if there
10199f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   *         was no "#" in the URI spec, empty string if there was a
10209f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   *         "#" but no fragment following it.
10219f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   */
10229f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  public String getFragment()
10239f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  {
10249f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    return m_fragment;
10259f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  }
10269f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
10279f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  /**
10289f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * Set the scheme for this URI. The scheme is converted to lowercase
10299f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * before it is set.
10309f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   *
10319f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * @param p_scheme the scheme for this URI (cannot be null)
10329f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   *
10339f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * @throws MalformedURIException if p_scheme is not a conformant
10349f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   *                                  scheme name
10359f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   */
10369f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  public void setScheme(String p_scheme) throws MalformedURIException
10379f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  {
10389f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
10399f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    if (p_scheme == null)
10409f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    {
10419f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      throw new MalformedURIException(XMLMessages.createXMLMessage(XMLErrorResources.ER_SCHEME_FROM_NULL_STRING, null)); //"Cannot set scheme from null string!");
10429f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    }
10439f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
10449f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    if (!isConformantSchemeName(p_scheme))
10459f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    {
10469f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      throw new MalformedURIException(XMLMessages.createXMLMessage(XMLErrorResources.ER_SCHEME_NOT_CONFORMANT, null)); //"The scheme is not conformant.");
10479f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    }
10489f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
10499f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    m_scheme = p_scheme.toLowerCase();
10509f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  }
10519f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
10529f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  /**
10539f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * Set the userinfo for this URI. If a non-null value is passed in and
10549f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * the host value is null, then an exception is thrown.
10559f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   *
10569f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * @param p_userinfo the userinfo for this URI
10579f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   *
10589f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * @throws MalformedURIException if p_userinfo contains invalid
10599f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   *                                  characters
10609f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   */
10619f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  public void setUserinfo(String p_userinfo) throws MalformedURIException
10629f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  {
10639f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
10649f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    if (p_userinfo == null)
10659f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    {
10669f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      m_userinfo = null;
10679f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    }
10689f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    else
10699f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    {
10709f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      if (m_host == null)
10719f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      {
10729f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        throw new MalformedURIException(
10739f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson          "Userinfo cannot be set when host is null!");
10749f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      }
10759f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
10769f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      // userinfo can contain alphanumerics, mark characters, escaped
10779f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      // and ';',':','&','=','+','$',','
10789f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      int index = 0;
10799f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      int end = p_userinfo.length();
10809f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      char testChar = '\0';
10819f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
10829f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      while (index < end)
10839f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      {
10849f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        testChar = p_userinfo.charAt(index);
10859f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
10869f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        if (testChar == '%')
10879f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        {
10889f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson          if (index + 2 >= end ||!isHex(p_userinfo.charAt(index + 1))
10899f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                  ||!isHex(p_userinfo.charAt(index + 2)))
10909f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson          {
10919f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            throw new MalformedURIException(
10929f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson              "Userinfo contains invalid escape sequence!");
10939f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson          }
10949f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        }
10959f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        else if (!isUnreservedCharacter(testChar)
10969f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                 && USERINFO_CHARACTERS.indexOf(testChar) == -1)
10979f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        {
10989f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson          throw new MalformedURIException(
10999f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            "Userinfo contains invalid character:" + testChar);
11009f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        }
11019f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
11029f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        index++;
11039f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      }
11049f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    }
11059f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
11069f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    m_userinfo = p_userinfo;
11079f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  }
11089f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
11099f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  /**
11109f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * Set the host for this URI. If null is passed in, the userinfo
11119f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * field is also set to null and the port is set to -1.
11129f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   *
11139f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * @param p_host the host for this URI
11149f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   *
11159f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * @throws MalformedURIException if p_host is not a valid IP
11169f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   *                                  address or DNS hostname.
11179f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   */
11189f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  public void setHost(String p_host) throws MalformedURIException
11199f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  {
11209f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
11219f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    if (p_host == null || p_host.trim().length() == 0)
11229f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    {
11239f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      m_host = p_host;
11249f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      m_userinfo = null;
11259f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      m_port = -1;
11269f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    }
11279f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    else if (!isWellFormedAddress(p_host))
11289f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    {
11299f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      throw new MalformedURIException(XMLMessages.createXMLMessage(XMLErrorResources.ER_HOST_ADDRESS_NOT_WELLFORMED, null)); //"Host is not a well formed address!");
11309f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    }
11319f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
11329f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    m_host = p_host;
11339f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  }
11349f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
11359f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  /**
11369f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * Set the port for this URI. -1 is used to indicate that the port is
11379f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * not specified, otherwise valid port numbers are  between 0 and 65535.
11389f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * If a valid port number is passed in and the host field is null,
11399f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * an exception is thrown.
11409f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   *
11419f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * @param p_port the port number for this URI
11429f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   *
11439f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * @throws MalformedURIException if p_port is not -1 and not a
11449f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   *                                  valid port number
11459f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   */
11469f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  public void setPort(int p_port) throws MalformedURIException
11479f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  {
11489f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
11499f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    if (p_port >= 0 && p_port <= 65535)
11509f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    {
11519f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      if (m_host == null)
11529f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      {
11539f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        throw new MalformedURIException(
11549f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson          XMLMessages.createXMLMessage(XMLErrorResources.ER_PORT_WHEN_HOST_NULL, null)); //"Port cannot be set when host is null!");
11559f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      }
11569f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    }
11579f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    else if (p_port != -1)
11589f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    {
11599f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      throw new MalformedURIException(XMLMessages.createXMLMessage(XMLErrorResources.ER_INVALID_PORT, null)); //"Invalid port number!");
11609f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    }
11619f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
11629f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    m_port = p_port;
11639f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  }
11649f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
11659f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  /**
11669f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * Set the path for this URI. If the supplied path is null, then the
11679f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * query string and fragment are set to null as well. If the supplied
11689f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * path includes a query string and/or fragment, these fields will be
11699f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * parsed and set as well. Note that, for URIs following the "generic
11709f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * URI" syntax, the path specified should start with a slash.
11719f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * For URIs that do not follow the generic URI syntax, this method
11729f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * sets the scheme-specific part.
11739f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   *
11749f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * @param p_path the path for this URI (may be null)
11759f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   *
11769f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * @throws MalformedURIException if p_path contains invalid
11779f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   *                                  characters
11789f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   */
11799f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  public void setPath(String p_path) throws MalformedURIException
11809f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  {
11819f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
11829f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    if (p_path == null)
11839f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    {
11849f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      m_path = null;
11859f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      m_queryString = null;
11869f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      m_fragment = null;
11879f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    }
11889f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    else
11899f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    {
11909f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      initializePath(p_path);
11919f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    }
11929f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  }
11939f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
11949f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  /**
11959f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * Append to the end of the path of this URI. If the current path does
11969f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * not end in a slash and the path to be appended does not begin with
11979f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * a slash, a slash will be appended to the current path before the
11989f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * new segment is added. Also, if the current path ends in a slash
11999f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * and the new segment begins with a slash, the extra slash will be
12009f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * removed before the new segment is appended.
12019f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   *
12029f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * @param p_addToPath the new segment to be added to the current path
12039f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   *
12049f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * @throws MalformedURIException if p_addToPath contains syntax
12059f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   *                                  errors
12069f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   */
12079f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  public void appendPath(String p_addToPath) throws MalformedURIException
12089f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  {
12099f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
12109f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    if (p_addToPath == null || p_addToPath.trim().length() == 0)
12119f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    {
12129f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      return;
12139f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    }
12149f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
12159f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    if (!isURIString(p_addToPath))
12169f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    {
12179f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      throw new MalformedURIException(XMLMessages.createXMLMessage(XMLErrorResources.ER_PATH_INVALID_CHAR, new Object[]{p_addToPath})); //"Path contains invalid character!");
12189f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    }
12199f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
12209f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    if (m_path == null || m_path.trim().length() == 0)
12219f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    {
12229f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      if (p_addToPath.startsWith("/"))
12239f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      {
12249f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        m_path = p_addToPath;
12259f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      }
12269f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      else
12279f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      {
12289f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        m_path = "/" + p_addToPath;
12299f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      }
12309f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    }
12319f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    else if (m_path.endsWith("/"))
12329f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    {
12339f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      if (p_addToPath.startsWith("/"))
12349f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      {
12359f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        m_path = m_path.concat(p_addToPath.substring(1));
12369f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      }
12379f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      else
12389f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      {
12399f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        m_path = m_path.concat(p_addToPath);
12409f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      }
12419f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    }
12429f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    else
12439f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    {
12449f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      if (p_addToPath.startsWith("/"))
12459f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      {
12469f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        m_path = m_path.concat(p_addToPath);
12479f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      }
12489f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      else
12499f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      {
12509f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        m_path = m_path.concat("/" + p_addToPath);
12519f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      }
12529f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    }
12539f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  }
12549f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
12559f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  /**
12569f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * Set the query string for this URI. A non-null value is valid only
12579f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * if this is an URI conforming to the generic URI syntax and
12589f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * the path value is not null.
12599f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   *
12609f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * @param p_queryString the query string for this URI
12619f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   *
12629f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * @throws MalformedURIException if p_queryString is not null and this
12639f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   *                                  URI does not conform to the generic
12649f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   *                                  URI syntax or if the path is null
12659f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   */
12669f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  public void setQueryString(String p_queryString)
12679f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson          throws MalformedURIException
12689f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  {
12699f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
12709f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    if (p_queryString == null)
12719f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    {
12729f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      m_queryString = null;
12739f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    }
12749f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    else if (!isGenericURI())
12759f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    {
12769f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      throw new MalformedURIException(
12779f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        "Query string can only be set for a generic URI!");
12789f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    }
12799f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    else if (getPath() == null)
12809f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    {
12819f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      throw new MalformedURIException(
12829f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        "Query string cannot be set when path is null!");
12839f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    }
12849f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    else if (!isURIString(p_queryString))
12859f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    {
12869f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      throw new MalformedURIException(
12879f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        "Query string contains invalid character!");
12889f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    }
12899f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    else
12909f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    {
12919f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      m_queryString = p_queryString;
12929f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    }
12939f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  }
12949f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
12959f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  /**
12969f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * Set the fragment for this URI. A non-null value is valid only
12979f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * if this is a URI conforming to the generic URI syntax and
12989f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * the path value is not null.
12999f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   *
13009f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * @param p_fragment the fragment for this URI
13019f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   *
13029f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * @throws MalformedURIException if p_fragment is not null and this
13039f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   *                                  URI does not conform to the generic
13049f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   *                                  URI syntax or if the path is null
13059f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   */
13069f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  public void setFragment(String p_fragment) throws MalformedURIException
13079f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  {
13089f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
13099f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    if (p_fragment == null)
13109f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    {
13119f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      m_fragment = null;
13129f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    }
13139f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    else if (!isGenericURI())
13149f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    {
13159f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      throw new MalformedURIException(
13169f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        XMLMessages.createXMLMessage(XMLErrorResources.ER_FRAG_FOR_GENERIC_URI, null)); //"Fragment can only be set for a generic URI!");
13179f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    }
13189f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    else if (getPath() == null)
13199f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    {
13209f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      throw new MalformedURIException(
13219f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        XMLMessages.createXMLMessage(XMLErrorResources.ER_FRAG_WHEN_PATH_NULL, null)); //"Fragment cannot be set when path is null!");
13229f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    }
13239f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    else if (!isURIString(p_fragment))
13249f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    {
13259f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      throw new MalformedURIException(XMLMessages.createXMLMessage(XMLErrorResources.ER_FRAG_INVALID_CHAR, null)); //"Fragment contains invalid character!");
13269f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    }
13279f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    else
13289f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    {
13299f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      m_fragment = p_fragment;
13309f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    }
13319f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  }
13329f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
13339f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  /**
13349f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * Determines if the passed-in Object is equivalent to this URI.
13359f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   *
13369f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * @param p_test the Object to test for equality.
13379f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   *
13389f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * @return true if p_test is a URI with all values equal to this
13399f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   *         URI, false otherwise
13409f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   */
13419f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  public boolean equals(Object p_test)
13429f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  {
13439f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
13449f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    if (p_test instanceof URI)
13459f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    {
13469f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      URI testURI = (URI) p_test;
13479f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
13489f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      if (((m_scheme == null && testURI.m_scheme == null) || (m_scheme != null && testURI.m_scheme != null && m_scheme.equals(
13499f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson              testURI.m_scheme))) && ((m_userinfo == null && testURI.m_userinfo == null) || (m_userinfo != null && testURI.m_userinfo != null && m_userinfo.equals(
13509f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson              testURI.m_userinfo))) && ((m_host == null && testURI.m_host == null) || (m_host != null && testURI.m_host != null && m_host.equals(
13519f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson              testURI.m_host))) && m_port == testURI.m_port && ((m_path == null && testURI.m_path == null) || (m_path != null && testURI.m_path != null && m_path.equals(
13529f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson              testURI.m_path))) && ((m_queryString == null && testURI.m_queryString == null) || (m_queryString != null && testURI.m_queryString != null && m_queryString.equals(
13539f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson              testURI.m_queryString))) && ((m_fragment == null && testURI.m_fragment == null) || (m_fragment != null && testURI.m_fragment != null && m_fragment.equals(
13549f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson              testURI.m_fragment))))
13559f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      {
13569f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        return true;
13579f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      }
13589f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    }
13599f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
13609f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    return false;
13619f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  }
13629f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
13639f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  /**
13649f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * Get the URI as a string specification. See RFC 2396 Section 5.2.
13659f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   *
13669f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * @return the URI string specification
13679f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   */
13689f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  public String toString()
13699f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  {
13709f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
13719f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    StringBuffer uriSpecString = new StringBuffer();
13729f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
13739f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    if (m_scheme != null)
13749f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    {
13759f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      uriSpecString.append(m_scheme);
13769f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      uriSpecString.append(':');
13779f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    }
13789f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
13799f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    uriSpecString.append(getSchemeSpecificPart());
13809f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
13819f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    return uriSpecString.toString();
13829f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  }
13839f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
13849f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  /**
13859f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * Get the indicator as to whether this URI uses the "generic URI"
13869f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * syntax.
13879f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   *
13889f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * @return true if this URI uses the "generic URI" syntax, false
13899f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   *         otherwise
13909f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   */
13919f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  public boolean isGenericURI()
13929f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  {
13939f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
13949f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    // presence of the host (whether valid or empty) means
13959f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    // double-slashes which means generic uri
13969f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    return (m_host != null);
13979f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  }
13989f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
13999f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  /**
14009f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * Determine whether a scheme conforms to the rules for a scheme name.
14019f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * A scheme is conformant if it starts with an alphanumeric, and
14029f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * contains only alphanumerics, '+','-' and '.'.
14039f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   *
14049f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   *
14059f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * @param p_scheme The sheme name to check
14069f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * @return true if the scheme is conformant, false otherwise
14079f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   */
14089f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  public static boolean isConformantSchemeName(String p_scheme)
14099f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  {
14109f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
14119f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    if (p_scheme == null || p_scheme.trim().length() == 0)
14129f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    {
14139f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      return false;
14149f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    }
14159f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
14169f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    if (!isAlpha(p_scheme.charAt(0)))
14179f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    {
14189f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      return false;
14199f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    }
14209f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
14219f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    char testChar;
14229f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
14239f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    for (int i = 1; i < p_scheme.length(); i++)
14249f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    {
14259f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      testChar = p_scheme.charAt(i);
14269f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
14279f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      if (!isAlphanum(testChar) && SCHEME_CHARACTERS.indexOf(testChar) == -1)
14289f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      {
14299f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        return false;
14309f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      }
14319f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    }
14329f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
14339f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    return true;
14349f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  }
14359f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
14369f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  /**
14379f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * Determine whether a string is syntactically capable of representing
14389f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * a valid IPv4 address or the domain name of a network host. A valid
14399f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * IPv4 address consists of four decimal digit groups separated by a
14409f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * '.'. A hostname consists of domain labels (each of which must
14419f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * begin and end with an alphanumeric but may contain '-') separated
14429f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * & by a '.'. See RFC 2396 Section 3.2.2.
14439f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   *
14449f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   *
14459f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * @param p_address The address string to check
14469f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * @return true if the string is a syntactically valid IPv4 address
14479f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   *              or hostname
14489f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   */
14499f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  public static boolean isWellFormedAddress(String p_address)
14509f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  {
14519f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
14529f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    if (p_address == null)
14539f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    {
14549f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      return false;
14559f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    }
14569f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
14579f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    String address = p_address.trim();
14589f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    int addrLength = address.length();
14599f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
14609f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    if (addrLength == 0 || addrLength > 255)
14619f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    {
14629f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      return false;
14639f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    }
14649f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
14659f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    if (address.startsWith(".") || address.startsWith("-"))
14669f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    {
14679f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      return false;
14689f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    }
14699f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
14709f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    // rightmost domain label starting with digit indicates IP address
14719f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    // since top level domain label can only start with an alpha
14729f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    // see RFC 2396 Section 3.2.2
14739f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    int index = address.lastIndexOf('.');
14749f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
14759f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    if (address.endsWith("."))
14769f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    {
14779f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      index = address.substring(0, index).lastIndexOf('.');
14789f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    }
14799f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
14809f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    if (index + 1 < addrLength && isDigit(p_address.charAt(index + 1)))
14819f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    {
14829f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      char testChar;
14839f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      int numDots = 0;
14849f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
14859f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      // make sure that 1) we see only digits and dot separators, 2) that
14869f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      // any dot separator is preceded and followed by a digit and
14879f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      // 3) that we find 3 dots
14889f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      for (int i = 0; i < addrLength; i++)
14899f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      {
14909f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        testChar = address.charAt(i);
14919f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
14929f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        if (testChar == '.')
14939f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        {
14949f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson          if (!isDigit(address.charAt(i - 1))
14959f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                  || (i + 1 < addrLength &&!isDigit(address.charAt(i + 1))))
14969f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson          {
14979f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            return false;
14989f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson          }
14999f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
15009f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson          numDots++;
15019f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        }
15029f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        else if (!isDigit(testChar))
15039f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        {
15049f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson          return false;
15059f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        }
15069f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      }
15079f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
15089f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      if (numDots != 3)
15099f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      {
15109f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        return false;
15119f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      }
15129f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    }
15139f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    else
15149f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    {
15159f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
15169f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      // domain labels can contain alphanumerics and '-"
15179f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      // but must start and end with an alphanumeric
15189f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      char testChar;
15199f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
15209f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      for (int i = 0; i < addrLength; i++)
15219f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      {
15229f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        testChar = address.charAt(i);
15239f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
15249f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        if (testChar == '.')
15259f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        {
15269f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson          if (!isAlphanum(address.charAt(i - 1)))
15279f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson          {
15289f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            return false;
15299f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson          }
15309f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
15319f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson          if (i + 1 < addrLength &&!isAlphanum(address.charAt(i + 1)))
15329f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson          {
15339f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            return false;
15349f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson          }
15359f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        }
15369f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        else if (!isAlphanum(testChar) && testChar != '-')
15379f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        {
15389f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson          return false;
15399f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        }
15409f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      }
15419f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    }
15429f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
15439f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    return true;
15449f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  }
15459f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
15469f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  /**
15479f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * Determine whether a char is a digit.
15489f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   *
15499f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   *
15509f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * @param p_char the character to check
15519f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * @return true if the char is betweeen '0' and '9', false otherwise
15529f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   */
15539f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  private static boolean isDigit(char p_char)
15549f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  {
15559f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    return p_char >= '0' && p_char <= '9';
15569f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  }
15579f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
15589f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  /**
15599f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * Determine whether a character is a hexadecimal character.
15609f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   *
15619f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   *
15629f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * @param p_char the character to check
15639f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * @return true if the char is betweeen '0' and '9', 'a' and 'f'
15649f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   *         or 'A' and 'F', false otherwise
15659f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   */
15669f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  private static boolean isHex(char p_char)
15679f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  {
15689f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    return (isDigit(p_char) || (p_char >= 'a' && p_char <= 'f')
15699f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            || (p_char >= 'A' && p_char <= 'F'));
15709f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  }
15719f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
15729f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  /**
15739f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * Determine whether a char is an alphabetic character: a-z or A-Z
15749f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   *
15759f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   *
15769f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * @param p_char the character to check
15779f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * @return true if the char is alphabetic, false otherwise
15789f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   */
15799f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  private static boolean isAlpha(char p_char)
15809f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  {
15819f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    return ((p_char >= 'a' && p_char <= 'z')
15829f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            || (p_char >= 'A' && p_char <= 'Z'));
15839f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  }
15849f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
15859f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  /**
15869f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * Determine whether a char is an alphanumeric: 0-9, a-z or A-Z
15879f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   *
15889f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   *
15899f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * @param p_char the character to check
15909f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * @return true if the char is alphanumeric, false otherwise
15919f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   */
15929f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  private static boolean isAlphanum(char p_char)
15939f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  {
15949f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    return (isAlpha(p_char) || isDigit(p_char));
15959f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  }
15969f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
15979f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  /**
15989f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * Determine whether a character is a reserved character:
15999f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * ';', '/', '?', ':', '@', '&', '=', '+', '$' or ','
16009f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   *
16019f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   *
16029f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * @param p_char the character to check
16039f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * @return true if the string contains any reserved characters
16049f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   */
16059f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  private static boolean isReservedCharacter(char p_char)
16069f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  {
16079f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    return RESERVED_CHARACTERS.indexOf(p_char) != -1;
16089f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  }
16099f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
16109f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  /**
16119f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * Determine whether a char is an unreserved character.
16129f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   *
16139f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   *
16149f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * @param p_char the character to check
16159f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * @return true if the char is unreserved, false otherwise
16169f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   */
16179f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  private static boolean isUnreservedCharacter(char p_char)
16189f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  {
16199f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    return (isAlphanum(p_char) || MARK_CHARACTERS.indexOf(p_char) != -1);
16209f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  }
16219f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
16229f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  /**
16239f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * Determine whether a given string contains only URI characters (also
16249f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * called "uric" in RFC 2396). uric consist of all reserved
16259f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * characters, unreserved characters and escaped characters.
16269f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   *
16279f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   *
16289f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * @param p_uric URI string
16299f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * @return true if the string is comprised of uric, false otherwise
16309f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   */
16319f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  private static boolean isURIString(String p_uric)
16329f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  {
16339f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
16349f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    if (p_uric == null)
16359f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    {
16369f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      return false;
16379f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    }
16389f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
16399f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    int end = p_uric.length();
16409f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    char testChar = '\0';
16419f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
16429f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    for (int i = 0; i < end; i++)
16439f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    {
16449f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      testChar = p_uric.charAt(i);
16459f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
16469f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      if (testChar == '%')
16479f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      {
16489f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        if (i + 2 >= end ||!isHex(p_uric.charAt(i + 1))
16499f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                ||!isHex(p_uric.charAt(i + 2)))
16509f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        {
16519f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson          return false;
16529f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        }
16539f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        else
16549f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        {
16559f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson          i += 2;
16569f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
16579f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson          continue;
16589f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        }
16599f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      }
16609f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
16619f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      if (isReservedCharacter(testChar) || isUnreservedCharacter(testChar))
16629f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      {
16639f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        continue;
16649f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      }
16659f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      else
16669f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      {
16679f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        return false;
16689f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      }
16699f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    }
16709f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
16719f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    return true;
16729f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  }
16739f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson}
1674