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