/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements. See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership. The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the  "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
/*
 * $Id: URI.java 468655 2006-10-28 07:12:06Z minchau $
 */
package org.apache.xml.utils;

import java.io.IOException;
import java.io.Serializable;

import org.apache.xml.res.XMLErrorResources;
import org.apache.xml.res.XMLMessages;

/**
 * A class to represent a Uniform Resource Identifier (URI). This class
 * is designed to handle the parsing of URIs and provide access to
 * the various components (scheme, host, port, userinfo, path, query
 * string and fragment) that may constitute a URI.
 * <p>
 * Parsing of a URI specification is done according to the URI
 * syntax described in RFC 2396
 * <http://www.ietf.org/rfc/rfc2396.txt?number=2396>. Every URI consists
 * of a scheme, followed by a colon (':'), followed by a scheme-specific
 * part. For URIs that follow the "generic URI" syntax, the scheme-
 * specific part begins with two slashes ("//") and may be followed
 * by an authority segment (comprised of user information, host, and
 * port), path segment, query segment and fragment. Note that RFC 2396
 * no longer specifies the use of the parameters segment and excludes
 * the "user:password" syntax as part of the authority segment. If
 * "user:password" appears in a URI, the entire user/password string
 * is stored as userinfo.
 * <p>
 * For URIs that do not follow the "generic URI" syntax (e.g. mailto),
 * the entire scheme-specific part is treated as the "path" portion
 * of the URI.
 * <p>
 * Note that, unlike the java.net.URL class, this class does not provide
 * any built-in network access functionality nor does it provide any
 * scheme-specific functionality (for example, it does not know a
 * default port for a specific scheme). Rather, it only knows the
 * grammar and basic set of operations that can be applied to a URI.
 *
 *
 */
public class URI implements Serializable
{
    static final long serialVersionUID = 7096266377907081897L;

  /**
   * MalformedURIExceptions are thrown in the process of building a URI
   * or setting fields on a URI when an operation would result in an
   * invalid URI specification.
   *
   */
  public static class MalformedURIException extends IOException
  {

    /**
     * Constructs a <code>MalformedURIException</code> with no specified
     * detail message.
     */
    public MalformedURIException()
    {
      super();
    }

    /**
     * Constructs a <code>MalformedURIException</code> with the
     * specified detail message.
     *
     * @param p_msg the detail message.
     */
    public MalformedURIException(String p_msg)
    {
      super(p_msg);
    }
  }

  /** reserved characters */
  private static final String RESERVED_CHARACTERS = ";/?:@&=+$,";

  /**
   * URI punctuation mark characters - these, combined with
   *   alphanumerics, constitute the "unreserved" characters 
   */
  private static final String MARK_CHARACTERS = "-_.!~*'() ";

  /** scheme can be composed of alphanumerics and these characters */
  private static final String SCHEME_CHARACTERS = "+-.";

  /**
   * userinfo can be composed of unreserved, escaped and these
   *   characters 
   */
  private static final String USERINFO_CHARACTERS = ";:&=+$,";

  /** Stores the scheme (usually the protocol) for this URI.
   *  @serial */
  private String m_scheme = null;

  /** If specified, stores the userinfo for this URI; otherwise null.
   *  @serial */
  private String m_userinfo = null;

  /** If specified, stores the host for this URI; otherwise null.
   *  @serial */
  private String m_host = null;

  /** If specified, stores the port for this URI; otherwise -1.
   *  @serial */
  private int m_port = -1;

  /** If specified, stores the path for this URI; otherwise null.
   *  @serial */
  private String m_path = null;

  /**
   * If specified, stores the query string for this URI; otherwise
   *   null. 
   * @serial 
   */
  private String m_queryString = null;

  /** If specified, stores the fragment for this URI; otherwise null.
   *  @serial */
  private String m_fragment = null;

  /** Indicate whether in DEBUG mode          */
  private static boolean DEBUG = false;

  /**
   * Construct a new and uninitialized URI.
   */
  public URI(){}

  /**
   * Construct a new URI from another URI. All fields for this URI are
   * set equal to the fields of the URI passed in.
   *
   * @param p_other the URI to copy (cannot be null)
   */
  public URI(URI p_other)
  {
    initialize(p_other);
  }

  /**
   * Construct a new URI from a URI specification string. If the
   * specification follows the "generic URI" syntax, (two slashes
   * following the first colon), the specification will be parsed
   * accordingly - setting the scheme, userinfo, host,port, path, query
   * string and fragment fields as necessary. If the specification does
   * not follow the "generic URI" syntax, the specification is parsed
   * into a scheme and scheme-specific part (stored as the path) only.
   *
   * @param p_uriSpec the URI specification string (cannot be null or
   *                  empty)
   *
   * @throws MalformedURIException if p_uriSpec violates any syntax
   *                                   rules
   */
  public URI(String p_uriSpec) throws MalformedURIException
  {
    this((URI) null, p_uriSpec);
  }

  /**
   * Construct a new URI from a base URI and a URI specification string.
   * The URI specification string may be a relative URI.
   *
   * @param p_base the base URI (cannot be null if p_uriSpec is null or
   *               empty)
   * @param p_uriSpec the URI specification string (cannot be null or
   *                  empty if p_base is null)
   *
   * @throws MalformedURIException if p_uriSpec violates any syntax
   *                                  rules
   */
  public URI(URI p_base, String p_uriSpec) throws MalformedURIException
  {
    initialize(p_base, p_uriSpec);
  }

  /**
   * Construct a new URI that does not follow the generic URI syntax.
   * Only the scheme and scheme-specific part (stored as the path) are
   * initialized.
   *
   * @param p_scheme the URI scheme (cannot be null or empty)
   * @param p_schemeSpecificPart the scheme-specific part (cannot be
   *                             null or empty)
   *
   * @throws MalformedURIException if p_scheme violates any
   *                                  syntax rules
   */
  public URI(String p_scheme, String p_schemeSpecificPart)
          throws MalformedURIException
  {

    if (p_scheme == null || p_scheme.trim().length() == 0)
    {
      throw new MalformedURIException(
        "Cannot construct URI with null/empty scheme!");
    }

    if (p_schemeSpecificPart == null
            || p_schemeSpecificPart.trim().length() == 0)
    {
      throw new MalformedURIException(
        "Cannot construct URI with null/empty scheme-specific part!");
    }

    setScheme(p_scheme);
    setPath(p_schemeSpecificPart);
  }

  /**
   * Construct a new URI that follows the generic URI syntax from its
   * component parts. Each component is validated for syntax and some
   * basic semantic checks are performed as well.  See the individual
   * setter methods for specifics.
   *
   * @param p_scheme the URI scheme (cannot be null or empty)
   * @param p_host the hostname or IPv4 address for the URI
   * @param p_path the URI path - if the path contains '?' or '#',
   *               then the query string and/or fragment will be
   *               set from the path; however, if the query and
   *               fragment are specified both in the path and as
   *               separate parameters, an exception is thrown
   * @param p_queryString the URI query string (cannot be specified
   *                      if path is null)
   * @param p_fragment the URI fragment (cannot be specified if path
   *                   is null)
   *
   * @throws MalformedURIException if any of the parameters violates
   *                                  syntax rules or semantic rules
   */
  public URI(String p_scheme, String p_host, String p_path, String p_queryString, String p_fragment)
          throws MalformedURIException
  {
    this(p_scheme, null, p_host, -1, p_path, p_queryString, p_fragment);
  }

  /**
   * Construct a new URI that follows the generic URI syntax from its
   * component parts. Each component is validated for syntax and some
   * basic semantic checks are performed as well.  See the individual
   * setter methods for specifics.
   *
   * @param p_scheme the URI scheme (cannot be null or empty)
   * @param p_userinfo the URI userinfo (cannot be specified if host
   *                   is null)
   * @param p_host the hostname or IPv4 address for the URI
   * @param p_port the URI port (may be -1 for "unspecified"; cannot
   *               be specified if host is null)
   * @param p_path the URI path - if the path contains '?' or '#',
   *               then the query string and/or fragment will be
   *               set from the path; however, if the query and
   *               fragment are specified both in the path and as
   *               separate parameters, an exception is thrown
   * @param p_queryString the URI query string (cannot be specified
   *                      if path is null)
   * @param p_fragment the URI fragment (cannot be specified if path
   *                   is null)
   *
   * @throws MalformedURIException if any of the parameters violates
   *                                  syntax rules or semantic rules
   */
  public URI(String p_scheme, String p_userinfo, String p_host, int p_port, String p_path, String p_queryString, String p_fragment)
          throws MalformedURIException
  {

    if (p_scheme == null || p_scheme.trim().length() == 0)
    {
      throw new MalformedURIException(XMLMessages.createXMLMessage(XMLErrorResources.ER_SCHEME_REQUIRED, null)); //"Scheme is required!");
    }

    if (p_host == null)
    {
      if (p_userinfo != null)
      {
        throw new MalformedURIException(
          XMLMessages.createXMLMessage(XMLErrorResources.ER_NO_USERINFO_IF_NO_HOST, null)); //"Userinfo may not be specified if host is not specified!");
      }

      if (p_port != -1)
      {
        throw new MalformedURIException(
          XMLMessages.createXMLMessage(XMLErrorResources.ER_NO_PORT_IF_NO_HOST, null)); //"Port may not be specified if host is not specified!");
      }
    }

    if (p_path != null)
    {
      if (p_path.indexOf('?') != -1 && p_queryString != null)
      {
        throw new MalformedURIException(
          XMLMessages.createXMLMessage(XMLErrorResources.ER_NO_QUERY_STRING_IN_PATH, null)); //"Query string cannot be specified in path and query string!");
      }

      if (p_path.indexOf('#') != -1 && p_fragment != null)
      {
        throw new MalformedURIException(
          XMLMessages.createXMLMessage(XMLErrorResources.ER_NO_FRAGMENT_STRING_IN_PATH, null)); //"Fragment cannot be specified in both the path and fragment!");
      }
    }

    setScheme(p_scheme);
    setHost(p_host);
    setPort(p_port);
    setUserinfo(p_userinfo);
    setPath(p_path);
    setQueryString(p_queryString);
    setFragment(p_fragment);
  }

  /**
   * Initialize all fields of this URI from another URI.
   *
   * @param p_other the URI to copy (cannot be null)
   */
  private void initialize(URI p_other)
  {

    m_scheme = p_other.getScheme();
    m_userinfo = p_other.getUserinfo();
    m_host = p_other.getHost();
    m_port = p_other.getPort();
    m_path = p_other.getPath();
    m_queryString = p_other.getQueryString();
    m_fragment = p_other.getFragment();
  }

  /**
   * Initializes this URI from a base URI and a URI specification string.
   * See RFC 2396 Section 4 and Appendix B for specifications on parsing
   * the URI and Section 5 for specifications on resolving relative URIs
   * and relative paths.
   *
   * @param p_base the base URI (may be null if p_uriSpec is an absolute
   *               URI)
   * @param p_uriSpec the URI spec string which may be an absolute or
   *                  relative URI (can only be null/empty if p_base
   *                  is not null)
   *
   * @throws MalformedURIException if p_base is null and p_uriSpec
   *                                  is not an absolute URI or if
   *                                  p_uriSpec violates syntax rules
   */
  private void initialize(URI p_base, String p_uriSpec)
          throws MalformedURIException
  {

    if (p_base == null
            && (p_uriSpec == null || p_uriSpec.trim().length() == 0))
    {
      throw new MalformedURIException(
        XMLMessages.createXMLMessage(XMLErrorResources.ER_CANNOT_INIT_URI_EMPTY_PARMS, null)); //"Cannot initialize URI with empty parameters.");
    }

    // just make a copy of the base if spec is empty
    if (p_uriSpec == null || p_uriSpec.trim().length() == 0)
    {
      initialize(p_base);

      return;
    }

    String uriSpec = p_uriSpec.trim();
    int uriSpecLen = uriSpec.length();
    int index = 0;

    // check for scheme
    int colonIndex = uriSpec.indexOf(':');
    if (colonIndex < 0)
    {
      if (p_base == null)
      {
        throw new MalformedURIException(XMLMessages.createXMLMessage(XMLErrorResources.ER_NO_SCHEME_IN_URI, new Object[]{uriSpec})); //"No scheme found in URI: "+uriSpec);
      }
    }
    else
    {
      initializeScheme(uriSpec);
      uriSpec = uriSpec.substring(colonIndex+1);
      // This is a fix for XALANJ-2059.
      if(m_scheme != null && p_base != null)
      {	  	
        // a) If <uriSpec> starts with a slash (/), it means <uriSpec> is absolute 
        //    and p_base can be ignored.
        //    For example,
        //    uriSpec = file:/myDIR/myXSLFile.xsl
        //    p_base = file:/myWork/
        //
        //    Here, uriSpec has absolute path after scheme file and :
        //    Hence p_base can be ignored.
        // 
        // b) Similarily, according to RFC 2396, uri is resolved for <uriSpec> relative to <p_base>
        //    if scheme in <uriSpec> is same as scheme in <p_base>, else p_base can be ignored.
        // 
        // c) if <p_base> is not hierarchical, it can be ignored.
        //
        if(uriSpec.startsWith("/") || !m_scheme.equals(p_base.m_scheme) || !p_base.getSchemeSpecificPart().startsWith("/"))
        {
          p_base = null;
        }
      }
      // Fix for XALANJ-2059  
      uriSpecLen = uriSpec.length();
    }

    // two slashes means generic URI syntax, so we get the authority
    if (uriSpec.startsWith("//"))
    {
      index += 2;

      int startPos = index;

      // get authority - everything up to path, query or fragment
      char testChar = '\0';

      while (index < uriSpecLen)
      {
        testChar = uriSpec.charAt(index);

        if (testChar == '/' || testChar == '?' || testChar == '#')
        {
          break;
        }

        index++;
      }

      // if we found authority, parse it out, otherwise we set the
      // host to empty string
      if (index > startPos)
      {
        initializeAuthority(uriSpec.substring(startPos, index));
      }
      else
      {
        m_host = "";
      }
    }

    initializePath(uriSpec.substring(index));

    // Resolve relative URI to base URI - see RFC 2396 Section 5.2
    // In some cases, it might make more sense to throw an exception
    // (when scheme is specified is the string spec and the base URI
    // is also specified, for example), but we're just following the
    // RFC specifications 
    if (p_base != null)
    {

      // check to see if this is the current doc - RFC 2396 5.2 #2
      // note that this is slightly different from the RFC spec in that
      // we don't include the check for query string being null
      // - this handles cases where the urispec is just a query
      // string or a fragment (e.g. "?y" or "#s") - 
      // see <http://www.ics.uci.edu/~fielding/url/test1.html> which
      // identified this as a bug in the RFC
      if (m_path.length() == 0 && m_scheme == null && m_host == null)
      {
        m_scheme = p_base.getScheme();
        m_userinfo = p_base.getUserinfo();
        m_host = p_base.getHost();
        m_port = p_base.getPort();
        m_path = p_base.getPath();

        if (m_queryString == null)
        {
          m_queryString = p_base.getQueryString();
        }

        return;
      }

      // check for scheme - RFC 2396 5.2 #3
      // if we found a scheme, it means absolute URI, so we're done
      if (m_scheme == null)
      {
        m_scheme = p_base.getScheme();
      }

      // check for authority - RFC 2396 5.2 #4
      // if we found a host, then we've got a network path, so we're done
      if (m_host == null)
      {
        m_userinfo = p_base.getUserinfo();
        m_host = p_base.getHost();
        m_port = p_base.getPort();
      }
      else
      {
        return;
      }

      // check for absolute path - RFC 2396 5.2 #5
      if (m_path.length() > 0 && m_path.startsWith("/"))
      {
        return;
      }

      // if we get to this point, we need to resolve relative path
      // RFC 2396 5.2 #6
      String path = new String();
      String basePath = p_base.getPath();

      // 6a - get all but the last segment of the base URI path
      if (basePath != null)
      {
        int lastSlash = basePath.lastIndexOf('/');

        if (lastSlash != -1)
        {
          path = basePath.substring(0, lastSlash + 1);
        }
      }

      // 6b - append the relative URI path
      path = path.concat(m_path);

      // 6c - remove all "./" where "." is a complete path segment
      index = -1;

      while ((index = path.indexOf("/./")) != -1)
      {
        path = path.substring(0, index + 1).concat(path.substring(index + 3));
      }

      // 6d - remove "." if path ends with "." as a complete path segment
      if (path.endsWith("/."))
      {
        path = path.substring(0, path.length() - 1);
      }

      // 6e - remove all "<segment>/../" where "<segment>" is a complete 
      // path segment not equal to ".."
      index = -1;

      int segIndex = -1;
      String tempString = null;

      while ((index = path.indexOf("/../")) > 0)
      {
        tempString = path.substring(0, path.indexOf("/../"));
        segIndex = tempString.lastIndexOf('/');

        if (segIndex != -1)
        {
          if (!tempString.substring(segIndex++).equals(".."))
          {
            path = path.substring(0, segIndex).concat(path.substring(index
                    + 4));
          }
        }
      }

      // 6f - remove ending "<segment>/.." where "<segment>" is a 
      // complete path segment
      if (path.endsWith("/.."))
      {
        tempString = path.substring(0, path.length() - 3);
        segIndex = tempString.lastIndexOf('/');

        if (segIndex != -1)
        {
          path = path.substring(0, segIndex + 1);
        }
      }

      m_path = path;
    }
  }

  /**
   * Initialize the scheme for this URI from a URI string spec.
   *
   * @param p_uriSpec the URI specification (cannot be null)
   *
   * @throws MalformedURIException if URI does not have a conformant
   *                                  scheme
   */
  private void initializeScheme(String p_uriSpec) throws MalformedURIException
  {

    int uriSpecLen = p_uriSpec.length();
    int index = 0;
    String scheme = null;
    char testChar = '\0';

    while (index < uriSpecLen)
    {
      testChar = p_uriSpec.charAt(index);

      if (testChar == ':' || testChar == '/' || testChar == '?'
              || testChar == '#')
      {
        break;
      }

      index++;
    }

    scheme = p_uriSpec.substring(0, index);

    if (scheme.length() == 0)
    {
      throw new MalformedURIException(XMLMessages.createXMLMessage(XMLErrorResources.ER_NO_SCHEME_INURI, null)); //"No scheme found in URI.");
    }
    else
    {
      setScheme(scheme);
    }
  }

  /**
   * Initialize the authority (userinfo, host and port) for this
   * URI from a URI string spec.
   *
   * @param p_uriSpec the URI specification (cannot be null)
   *
   * @throws MalformedURIException if p_uriSpec violates syntax rules
   */
  private void initializeAuthority(String p_uriSpec)
          throws MalformedURIException
  {

    int index = 0;
    int start = 0;
    int end = p_uriSpec.length();
    char testChar = '\0';
    String userinfo = null;

    // userinfo is everything up @
    if (p_uriSpec.indexOf('@', start) != -1)
    {
      while (index < end)
      {
        testChar = p_uriSpec.charAt(index);

        if (testChar == '@')
        {
          break;
        }

        index++;
      }

      userinfo = p_uriSpec.substring(start, index);

      index++;
    }

    // host is everything up to ':'
    String host = null;

    start = index;

    while (index < end)
    {
      testChar = p_uriSpec.charAt(index);

      if (testChar == ':')
      {
        break;
      }

      index++;
    }

    host = p_uriSpec.substring(start, index);

    int port = -1;

    if (host.length() > 0)
    {

      // port
      if (testChar == ':')
      {
        index++;

        start = index;

        while (index < end)
        {
          index++;
        }

        String portStr = p_uriSpec.substring(start, index);

        if (portStr.length() > 0)
        {
          for (int i = 0; i < portStr.length(); i++)
          {
            if (!isDigit(portStr.charAt(i)))
            {
              throw new MalformedURIException(
                portStr + " is invalid. Port should only contain digits!");
            }
          }

          try
          {
            port = Integer.parseInt(portStr);
          }
          catch (NumberFormatException nfe)
          {

            // can't happen
          }
        }
      }
    }

    setHost(host);
    setPort(port);
    setUserinfo(userinfo);
  }

  /**
   * Initialize the path for this URI from a URI string spec.
   *
   * @param p_uriSpec the URI specification (cannot be null)
   *
   * @throws MalformedURIException if p_uriSpec violates syntax rules
   */
  private void initializePath(String p_uriSpec) throws MalformedURIException
  {

    if (p_uriSpec == null)
    {
      throw new MalformedURIException(
        "Cannot initialize path from null string!");
    }

    int index = 0;
    int start = 0;
    int end = p_uriSpec.length();
    char testChar = '\0';

    // path - everything up to query string or fragment
    while (index < end)
    {
      testChar = p_uriSpec.charAt(index);

      if (testChar == '?' || testChar == '#')
      {
        break;
      }

      // check for valid escape sequence
      if (testChar == '%')
      {
        if (index + 2 >= end ||!isHex(p_uriSpec.charAt(index + 1))
                ||!isHex(p_uriSpec.charAt(index + 2)))
        {
          throw new MalformedURIException(
            XMLMessages.createXMLMessage(XMLErrorResources.ER_PATH_CONTAINS_INVALID_ESCAPE_SEQUENCE, null)); //"Path contains invalid escape sequence!");
        }
      }
      else if (!isReservedCharacter(testChar)
               &&!isUnreservedCharacter(testChar))
      {
        if ('\\' != testChar)
          throw new MalformedURIException(XMLMessages.createXMLMessage(XMLErrorResources.ER_PATH_INVALID_CHAR, new Object[]{String.valueOf(testChar)})); //"Path contains invalid character: "
                                          //+ testChar);
      }

      index++;
    }

    m_path = p_uriSpec.substring(start, index);

    // query - starts with ? and up to fragment or end
    if (testChar == '?')
    {
      index++;

      start = index;

      while (index < end)
      {
        testChar = p_uriSpec.charAt(index);

        if (testChar == '#')
        {
          break;
        }

        if (testChar == '%')
        {
          if (index + 2 >= end ||!isHex(p_uriSpec.charAt(index + 1))
                  ||!isHex(p_uriSpec.charAt(index + 2)))
          {
            throw new MalformedURIException(
              "Query string contains invalid escape sequence!");
          }
        }
        else if (!isReservedCharacter(testChar)
                 &&!isUnreservedCharacter(testChar))
        {
          throw new MalformedURIException(
            "Query string contains invalid character:" + testChar);
        }

        index++;
      }

      m_queryString = p_uriSpec.substring(start, index);
    }

    // fragment - starts with #
    if (testChar == '#')
    {
      index++;

      start = index;

      while (index < end)
      {
        testChar = p_uriSpec.charAt(index);

        if (testChar == '%')
        {
          if (index + 2 >= end ||!isHex(p_uriSpec.charAt(index + 1))
                  ||!isHex(p_uriSpec.charAt(index + 2)))
          {
            throw new MalformedURIException(
              "Fragment contains invalid escape sequence!");
          }
        }
        else if (!isReservedCharacter(testChar)
                 &&!isUnreservedCharacter(testChar))
        {
          throw new MalformedURIException(
            "Fragment contains invalid character:" + testChar);
        }

        index++;
      }

      m_fragment = p_uriSpec.substring(start, index);
    }
  }

  /**
   * Get the scheme for this URI.
   *
   * @return the scheme for this URI
   */
  public String getScheme()
  {
    return m_scheme;
  }

  /**
   * Get the scheme-specific part for this URI (everything following the
   * scheme and the first colon). See RFC 2396 Section 5.2 for spec.
   *
   * @return the scheme-specific part for this URI
   */
  public String getSchemeSpecificPart()
  {

    StringBuffer schemespec = new StringBuffer();

    if (m_userinfo != null || m_host != null || m_port != -1)
    {
      schemespec.append("//");
    }

    if (m_userinfo != null)
    {
      schemespec.append(m_userinfo);
      schemespec.append('@');
    }

    if (m_host != null)
    {
      schemespec.append(m_host);
    }

    if (m_port != -1)
    {
      schemespec.append(':');
      schemespec.append(m_port);
    }

    if (m_path != null)
    {
      schemespec.append((m_path));
    }

    if (m_queryString != null)
    {
      schemespec.append('?');
      schemespec.append(m_queryString);
    }

    if (m_fragment != null)
    {
      schemespec.append('#');
      schemespec.append(m_fragment);
    }

    return schemespec.toString();
  }

  /**
   * Get the userinfo for this URI.
   *
   * @return the userinfo for this URI (null if not specified).
   */
  public String getUserinfo()
  {
    return m_userinfo;
  }

  /**
   * Get the host for this URI.
   *
   * @return the host for this URI (null if not specified).
   */
  public String getHost()
  {
    return m_host;
  }

  /**
   * Get the port for this URI.
   *
   * @return the port for this URI (-1 if not specified).
   */
  public int getPort()
  {
    return m_port;
  }

  /**
   * Get the path for this URI (optionally with the query string and
   * fragment).
   *
   * @param p_includeQueryString if true (and query string is not null),
   *                             then a "?" followed by the query string
   *                             will be appended
   * @param p_includeFragment if true (and fragment is not null),
   *                             then a "#" followed by the fragment
   *                             will be appended
   *
   * @return the path for this URI possibly including the query string
   *         and fragment
   */
  public String getPath(boolean p_includeQueryString,
                        boolean p_includeFragment)
  {

    StringBuffer pathString = new StringBuffer(m_path);

    if (p_includeQueryString && m_queryString != null)
    {
      pathString.append('?');
      pathString.append(m_queryString);
    }

    if (p_includeFragment && m_fragment != null)
    {
      pathString.append('#');
      pathString.append(m_fragment);
    }

    return pathString.toString();
  }

  /**
   * Get the path for this URI. Note that the value returned is the path
   * only and does not include the query string or fragment.
   *
   * @return the path for this URI.
   */
  public String getPath()
  {
    return m_path;
  }

  /**
   * Get the query string for this URI.
   *
   * @return the query string for this URI. Null is returned if there
   *         was no "?" in the URI spec, empty string if there was a
   *         "?" but no query string following it.
   */
  public String getQueryString()
  {
    return m_queryString;
  }

  /**
   * Get the fragment for this URI.
   *
   * @return the fragment for this URI. Null is returned if there
   *         was no "#" in the URI spec, empty string if there was a
   *         "#" but no fragment following it.
   */
  public String getFragment()
  {
    return m_fragment;
  }

  /**
   * Set the scheme for this URI. The scheme is converted to lowercase
   * before it is set.
   *
   * @param p_scheme the scheme for this URI (cannot be null)
   *
   * @throws MalformedURIException if p_scheme is not a conformant
   *                                  scheme name
   */
  public void setScheme(String p_scheme) throws MalformedURIException
  {

    if (p_scheme == null)
    {
      throw new MalformedURIException(XMLMessages.createXMLMessage(XMLErrorResources.ER_SCHEME_FROM_NULL_STRING, null)); //"Cannot set scheme from null string!");
    }

    if (!isConformantSchemeName(p_scheme))
    {
      throw new MalformedURIException(XMLMessages.createXMLMessage(XMLErrorResources.ER_SCHEME_NOT_CONFORMANT, null)); //"The scheme is not conformant.");
    }

    m_scheme = p_scheme.toLowerCase();
  }

  /**
   * Set the userinfo for this URI. If a non-null value is passed in and
   * the host value is null, then an exception is thrown.
   *
   * @param p_userinfo the userinfo for this URI
   *
   * @throws MalformedURIException if p_userinfo contains invalid
   *                                  characters
   */
  public void setUserinfo(String p_userinfo) throws MalformedURIException
  {

    if (p_userinfo == null)
    {
      m_userinfo = null;
    }
    else
    {
      if (m_host == null)
      {
        throw new MalformedURIException(
          "Userinfo cannot be set when host is null!");
      }

      // userinfo can contain alphanumerics, mark characters, escaped
      // and ';',':','&','=','+','$',','
      int index = 0;
      int end = p_userinfo.length();
      char testChar = '\0';

      while (index < end)
      {
        testChar = p_userinfo.charAt(index);

        if (testChar == '%')
        {
          if (index + 2 >= end ||!isHex(p_userinfo.charAt(index + 1))
                  ||!isHex(p_userinfo.charAt(index + 2)))
          {
            throw new MalformedURIException(
              "Userinfo contains invalid escape sequence!");
          }
        }
        else if (!isUnreservedCharacter(testChar)
                 && USERINFO_CHARACTERS.indexOf(testChar) == -1)
        {
          throw new MalformedURIException(
            "Userinfo contains invalid character:" + testChar);
        }

        index++;
      }
    }

    m_userinfo = p_userinfo;
  }

  /**
   * Set the host for this URI. If null is passed in, the userinfo
   * field is also set to null and the port is set to -1.
   *
   * @param p_host the host for this URI
   *
   * @throws MalformedURIException if p_host is not a valid IP
   *                                  address or DNS hostname.
   */
  public void setHost(String p_host) throws MalformedURIException
  {

    if (p_host == null || p_host.trim().length() == 0)
    {
      m_host = p_host;
      m_userinfo = null;
      m_port = -1;
    }
    else if (!isWellFormedAddress(p_host))
    {
      throw new MalformedURIException(XMLMessages.createXMLMessage(XMLErrorResources.ER_HOST_ADDRESS_NOT_WELLFORMED, null)); //"Host is not a well formed address!");
    }

    m_host = p_host;
  }

  /**
   * Set the port for this URI. -1 is used to indicate that the port is
   * not specified, otherwise valid port numbers are  between 0 and 65535.
   * If a valid port number is passed in and the host field is null,
   * an exception is thrown.
   *
   * @param p_port the port number for this URI
   *
   * @throws MalformedURIException if p_port is not -1 and not a
   *                                  valid port number
   */
  public void setPort(int p_port) throws MalformedURIException
  {

    if (p_port >= 0 && p_port <= 65535)
    {
      if (m_host == null)
      {
        throw new MalformedURIException(
          XMLMessages.createXMLMessage(XMLErrorResources.ER_PORT_WHEN_HOST_NULL, null)); //"Port cannot be set when host is null!");
      }
    }
    else if (p_port != -1)
    {
      throw new MalformedURIException(XMLMessages.createXMLMessage(XMLErrorResources.ER_INVALID_PORT, null)); //"Invalid port number!");
    }

    m_port = p_port;
  }

  /**
   * Set the path for this URI. If the supplied path is null, then the
   * query string and fragment are set to null as well. If the supplied
   * path includes a query string and/or fragment, these fields will be
   * parsed and set as well. Note that, for URIs following the "generic
   * URI" syntax, the path specified should start with a slash.
   * For URIs that do not follow the generic URI syntax, this method
   * sets the scheme-specific part.
   *
   * @param p_path the path for this URI (may be null)
   *
   * @throws MalformedURIException if p_path contains invalid
   *                                  characters
   */
  public void setPath(String p_path) throws MalformedURIException
  {

    if (p_path == null)
    {
      m_path = null;
      m_queryString = null;
      m_fragment = null;
    }
    else
    {
      initializePath(p_path);
    }
  }

  /**
   * Append to the end of the path of this URI. If the current path does
   * not end in a slash and the path to be appended does not begin with
   * a slash, a slash will be appended to the current path before the
   * new segment is added. Also, if the current path ends in a slash
   * and the new segment begins with a slash, the extra slash will be
   * removed before the new segment is appended.
   *
   * @param p_addToPath the new segment to be added to the current path
   *
   * @throws MalformedURIException if p_addToPath contains syntax
   *                                  errors
   */
  public void appendPath(String p_addToPath) throws MalformedURIException
  {

    if (p_addToPath == null || p_addToPath.trim().length() == 0)
    {
      return;
    }

    if (!isURIString(p_addToPath))
    {
      throw new MalformedURIException(XMLMessages.createXMLMessage(XMLErrorResources.ER_PATH_INVALID_CHAR, new Object[]{p_addToPath})); //"Path contains invalid character!");
    }

    if (m_path == null || m_path.trim().length() == 0)
    {
      if (p_addToPath.startsWith("/"))
      {
        m_path = p_addToPath;
      }
      else
      {
        m_path = "/" + p_addToPath;
      }
    }
    else if (m_path.endsWith("/"))
    {
      if (p_addToPath.startsWith("/"))
      {
        m_path = m_path.concat(p_addToPath.substring(1));
      }
      else
      {
        m_path = m_path.concat(p_addToPath);
      }
    }
    else
    {
      if (p_addToPath.startsWith("/"))
      {
        m_path = m_path.concat(p_addToPath);
      }
      else
      {
        m_path = m_path.concat("/" + p_addToPath);
      }
    }
  }

  /**
   * Set the query string for this URI. A non-null value is valid only
   * if this is an URI conforming to the generic URI syntax and
   * the path value is not null.
   *
   * @param p_queryString the query string for this URI
   *
   * @throws MalformedURIException if p_queryString is not null and this
   *                                  URI does not conform to the generic
   *                                  URI syntax or if the path is null
   */
  public void setQueryString(String p_queryString)
          throws MalformedURIException
  {

    if (p_queryString == null)
    {
      m_queryString = null;
    }
    else if (!isGenericURI())
    {
      throw new MalformedURIException(
        "Query string can only be set for a generic URI!");
    }
    else if (getPath() == null)
    {
      throw new MalformedURIException(
        "Query string cannot be set when path is null!");
    }
    else if (!isURIString(p_queryString))
    {
      throw new MalformedURIException(
        "Query string contains invalid character!");
    }
    else
    {
      m_queryString = p_queryString;
    }
  }

  /**
   * Set the fragment for this URI. A non-null value is valid only
   * if this is a URI conforming to the generic URI syntax and
   * the path value is not null.
   *
   * @param p_fragment the fragment for this URI
   *
   * @throws MalformedURIException if p_fragment is not null and this
   *                                  URI does not conform to the generic
   *                                  URI syntax or if the path is null
   */
  public void setFragment(String p_fragment) throws MalformedURIException
  {

    if (p_fragment == null)
    {
      m_fragment = null;
    }
    else if (!isGenericURI())
    {
      throw new MalformedURIException(
        XMLMessages.createXMLMessage(XMLErrorResources.ER_FRAG_FOR_GENERIC_URI, null)); //"Fragment can only be set for a generic URI!");
    }
    else if (getPath() == null)
    {
      throw new MalformedURIException(
        XMLMessages.createXMLMessage(XMLErrorResources.ER_FRAG_WHEN_PATH_NULL, null)); //"Fragment cannot be set when path is null!");
    }
    else if (!isURIString(p_fragment))
    {
      throw new MalformedURIException(XMLMessages.createXMLMessage(XMLErrorResources.ER_FRAG_INVALID_CHAR, null)); //"Fragment contains invalid character!");
    }
    else
    {
      m_fragment = p_fragment;
    }
  }

  /**
   * Determines if the passed-in Object is equivalent to this URI.
   *
   * @param p_test the Object to test for equality.
   *
   * @return true if p_test is a URI with all values equal to this
   *         URI, false otherwise
   */
  public boolean equals(Object p_test)
  {

    if (p_test instanceof URI)
    {
      URI testURI = (URI) p_test;

      if (((m_scheme == null && testURI.m_scheme == null) || (m_scheme != null && testURI.m_scheme != null && m_scheme.equals(
              testURI.m_scheme))) && ((m_userinfo == null && testURI.m_userinfo == null) || (m_userinfo != null && testURI.m_userinfo != null && m_userinfo.equals(
              testURI.m_userinfo))) && ((m_host == null && testURI.m_host == null) || (m_host != null && testURI.m_host != null && m_host.equals(
              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(
              testURI.m_path))) && ((m_queryString == null && testURI.m_queryString == null) || (m_queryString != null && testURI.m_queryString != null && m_queryString.equals(
              testURI.m_queryString))) && ((m_fragment == null && testURI.m_fragment == null) || (m_fragment != null && testURI.m_fragment != null && m_fragment.equals(
              testURI.m_fragment))))
      {
        return true;
      }
    }

    return false;
  }

  /**
   * Get the URI as a string specification. See RFC 2396 Section 5.2.
   *
   * @return the URI string specification
   */
  public String toString()
  {

    StringBuffer uriSpecString = new StringBuffer();

    if (m_scheme != null)
    {
      uriSpecString.append(m_scheme);
      uriSpecString.append(':');
    }

    uriSpecString.append(getSchemeSpecificPart());

    return uriSpecString.toString();
  }

  /**
   * Get the indicator as to whether this URI uses the "generic URI"
   * syntax.
   *
   * @return true if this URI uses the "generic URI" syntax, false
   *         otherwise
   */
  public boolean isGenericURI()
  {

    // presence of the host (whether valid or empty) means 
    // double-slashes which means generic uri
    return (m_host != null);
  }

  /**
   * Determine whether a scheme conforms to the rules for a scheme name.
   * A scheme is conformant if it starts with an alphanumeric, and
   * contains only alphanumerics, '+','-' and '.'.
   *
   *
   * @param p_scheme The sheme name to check
   * @return true if the scheme is conformant, false otherwise
   */
  public static boolean isConformantSchemeName(String p_scheme)
  {

    if (p_scheme == null || p_scheme.trim().length() == 0)
    {
      return false;
    }

    if (!isAlpha(p_scheme.charAt(0)))
    {
      return false;
    }

    char testChar;

    for (int i = 1; i < p_scheme.length(); i++)
    {
      testChar = p_scheme.charAt(i);

      if (!isAlphanum(testChar) && SCHEME_CHARACTERS.indexOf(testChar) == -1)
      {
        return false;
      }
    }

    return true;
  }

  /**
   * Determine whether a string is syntactically capable of representing
   * a valid IPv4 address or the domain name of a network host. A valid
   * IPv4 address consists of four decimal digit groups separated by a
   * '.'. A hostname consists of domain labels (each of which must
   * begin and end with an alphanumeric but may contain '-') separated
   * & by a '.'. See RFC 2396 Section 3.2.2.
   *
   *
   * @param p_address The address string to check
   * @return true if the string is a syntactically valid IPv4 address
   *              or hostname
   */
  public static boolean isWellFormedAddress(String p_address)
  {

    if (p_address == null)
    {
      return false;
    }

    String address = p_address.trim();
    int addrLength = address.length();

    if (addrLength == 0 || addrLength > 255)
    {
      return false;
    }

    if (address.startsWith(".") || address.startsWith("-"))
    {
      return false;
    }

    // rightmost domain label starting with digit indicates IP address
    // since top level domain label can only start with an alpha
    // see RFC 2396 Section 3.2.2
    int index = address.lastIndexOf('.');

    if (address.endsWith("."))
    {
      index = address.substring(0, index).lastIndexOf('.');
    }

    if (index + 1 < addrLength && isDigit(p_address.charAt(index + 1)))
    {
      char testChar;
      int numDots = 0;

      // make sure that 1) we see only digits and dot separators, 2) that
      // any dot separator is preceded and followed by a digit and 
      // 3) that we find 3 dots
      for (int i = 0; i < addrLength; i++)
      {
        testChar = address.charAt(i);

        if (testChar == '.')
        {
          if (!isDigit(address.charAt(i - 1))
                  || (i + 1 < addrLength &&!isDigit(address.charAt(i + 1))))
          {
            return false;
          }

          numDots++;
        }
        else if (!isDigit(testChar))
        {
          return false;
        }
      }

      if (numDots != 3)
      {
        return false;
      }
    }
    else
    {

      // domain labels can contain alphanumerics and '-"
      // but must start and end with an alphanumeric
      char testChar;

      for (int i = 0; i < addrLength; i++)
      {
        testChar = address.charAt(i);

        if (testChar == '.')
        {
          if (!isAlphanum(address.charAt(i - 1)))
          {
            return false;
          }

          if (i + 1 < addrLength &&!isAlphanum(address.charAt(i + 1)))
          {
            return false;
          }
        }
        else if (!isAlphanum(testChar) && testChar != '-')
        {
          return false;
        }
      }
    }

    return true;
  }

  /**
   * Determine whether a char is a digit.
   *
   *
   * @param p_char the character to check
   * @return true if the char is betweeen '0' and '9', false otherwise
   */
  private static boolean isDigit(char p_char)
  {
    return p_char >= '0' && p_char <= '9';
  }

  /**
   * Determine whether a character is a hexadecimal character.
   *
   *
   * @param p_char the character to check
   * @return true if the char is betweeen '0' and '9', 'a' and 'f'
   *         or 'A' and 'F', false otherwise
   */
  private static boolean isHex(char p_char)
  {
    return (isDigit(p_char) || (p_char >= 'a' && p_char <= 'f')
            || (p_char >= 'A' && p_char <= 'F'));
  }

  /**
   * Determine whether a char is an alphabetic character: a-z or A-Z
   *
   *
   * @param p_char the character to check
   * @return true if the char is alphabetic, false otherwise
   */
  private static boolean isAlpha(char p_char)
  {
    return ((p_char >= 'a' && p_char <= 'z')
            || (p_char >= 'A' && p_char <= 'Z'));
  }

  /**
   * Determine whether a char is an alphanumeric: 0-9, a-z or A-Z
   *
   *
   * @param p_char the character to check
   * @return true if the char is alphanumeric, false otherwise
   */
  private static boolean isAlphanum(char p_char)
  {
    return (isAlpha(p_char) || isDigit(p_char));
  }

  /**
   * Determine whether a character is a reserved character:
   * ';', '/', '?', ':', '@', '&', '=', '+', '$' or ','
   *
   *
   * @param p_char the character to check
   * @return true if the string contains any reserved characters
   */
  private static boolean isReservedCharacter(char p_char)
  {
    return RESERVED_CHARACTERS.indexOf(p_char) != -1;
  }

  /**
   * Determine whether a char is an unreserved character.
   *
   *
   * @param p_char the character to check
   * @return true if the char is unreserved, false otherwise
   */
  private static boolean isUnreservedCharacter(char p_char)
  {
    return (isAlphanum(p_char) || MARK_CHARACTERS.indexOf(p_char) != -1);
  }

  /**
   * Determine whether a given string contains only URI characters (also
   * called "uric" in RFC 2396). uric consist of all reserved
   * characters, unreserved characters and escaped characters.
   *
   *
   * @param p_uric URI string
   * @return true if the string is comprised of uric, false otherwise
   */
  private static boolean isURIString(String p_uric)
  {

    if (p_uric == null)
    {
      return false;
    }

    int end = p_uric.length();
    char testChar = '\0';

    for (int i = 0; i < end; i++)
    {
      testChar = p_uric.charAt(i);

      if (testChar == '%')
      {
        if (i + 2 >= end ||!isHex(p_uric.charAt(i + 1))
                ||!isHex(p_uric.charAt(i + 2)))
        {
          return false;
        }
        else
        {
          i += 2;

          continue;
        }
      }

      if (isReservedCharacter(testChar) || isUnreservedCharacter(testChar))
      {
        continue;
      }
      else
      {
        return false;
      }
    }

    return true;
  }
}
