uri.java

来自「开源的axis2框架的源码。用于开发WEBSERVER」· Java 代码 · 共 1,619 行 · 第 1/5 页

JAVA
1,619
字号
/*
 * 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.
 */

package org.apache.axis2.databinding.types;

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

/**
 * ******************************************************************* <i>Axis Note: This class was
 * 'borrowed' from Xerces 2.0.2</i>
 * <p/>
 * 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 <a
 * href="http://www.ietf.org/rfc/rfc2396.txt?number=2396">RFC 2396</a>, and amended by <a
 * href="http://www.ietf.org/rfc/rfc2732.txt?number=2732">RFC 2732</a>.
 * <p/>
 * Every absolute 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.
 * <p/>
 * ********************************************************************
 */
public class URI implements Serializable {

    private static final long serialVersionUID = 2172306044361227627L;


    /**
     * **************************************************************** 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.
     * <p/>
     * ******************************************************************
     */
    public static class MalformedURIException extends IOException {

        private static final long serialVersionUID = -8488692760975768757L;

        /**
         * *************************************************************** 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);
        }
    }

    private static final byte [] fgLookupTable = new byte[128];

    /**
     * Character Classes
     */

    /** reserved characters ;/?:@&=+$,[] */
    //RFC 2732 added '[' and ']' as reserved characters
    private static final int RESERVED_CHARACTERS = 0x01;

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

    /** scheme can be composed of alphanumerics and these characters: +-. */
    private static final int SCHEME_CHARACTERS = 0x04;

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

    /** ASCII letter characters */
    private static final int ASCII_ALPHA_CHARACTERS = 0x10;

    /** ASCII digit characters */
    private static final int ASCII_DIGIT_CHARACTERS = 0x20;

    /** ASCII hex characters */
    private static final int ASCII_HEX_CHARACTERS = 0x40;

    /** Path characters */
    private static final int PATH_CHARACTERS = 0x80;

    /** Mask for alpha-numeric characters */
    private static final int MASK_ALPHA_NUMERIC = ASCII_ALPHA_CHARACTERS | ASCII_DIGIT_CHARACTERS;

    /** Mask for unreserved characters */
    private static final int MASK_UNRESERVED_MASK = MASK_ALPHA_NUMERIC | MARK_CHARACTERS;

    /** Mask for URI allowable characters except for % */
    private static final int MASK_URI_CHARACTER = MASK_UNRESERVED_MASK | RESERVED_CHARACTERS;

    /** Mask for scheme characters */
    private static final int MASK_SCHEME_CHARACTER = MASK_ALPHA_NUMERIC | SCHEME_CHARACTERS;

    /** Mask for userinfo characters */
    private static final int MASK_USERINFO_CHARACTER = MASK_UNRESERVED_MASK | USERINFO_CHARACTERS;

    /** Mask for path characters */
    private static final int MASK_PATH_CHARACTER = MASK_UNRESERVED_MASK | PATH_CHARACTERS;

    static {
        // Add ASCII Digits and ASCII Hex Numbers
        for (int i = '0'; i <= '9'; ++i) {
            fgLookupTable[i] |= ASCII_DIGIT_CHARACTERS | ASCII_HEX_CHARACTERS;
        }

        // Add ASCII Letters and ASCII Hex Numbers
        for (int i = 'A'; i <= 'F'; ++i) {
            fgLookupTable[i] |= ASCII_ALPHA_CHARACTERS | ASCII_HEX_CHARACTERS;
            fgLookupTable[i + 0x00000020] |= ASCII_ALPHA_CHARACTERS | ASCII_HEX_CHARACTERS;
        }

        // Add ASCII Letters
        for (int i = 'G'; i <= 'Z'; ++i) {
            fgLookupTable[i] |= ASCII_ALPHA_CHARACTERS;
            fgLookupTable[i + 0x00000020] |= ASCII_ALPHA_CHARACTERS;
        }

        // Add Reserved Characters
        fgLookupTable[';'] |= RESERVED_CHARACTERS;
        fgLookupTable['/'] |= RESERVED_CHARACTERS;
        fgLookupTable['?'] |= RESERVED_CHARACTERS;
        fgLookupTable[':'] |= RESERVED_CHARACTERS;
        fgLookupTable['@'] |= RESERVED_CHARACTERS;
        fgLookupTable['&'] |= RESERVED_CHARACTERS;
        fgLookupTable['='] |= RESERVED_CHARACTERS;
        fgLookupTable['+'] |= RESERVED_CHARACTERS;
        fgLookupTable['$'] |= RESERVED_CHARACTERS;
        fgLookupTable[','] |= RESERVED_CHARACTERS;
        fgLookupTable['['] |= RESERVED_CHARACTERS;
        fgLookupTable[']'] |= RESERVED_CHARACTERS;

        // Add Mark Characters
        fgLookupTable['-'] |= MARK_CHARACTERS;
        fgLookupTable['_'] |= MARK_CHARACTERS;
        fgLookupTable['.'] |= MARK_CHARACTERS;
        fgLookupTable['!'] |= MARK_CHARACTERS;
        fgLookupTable['~'] |= MARK_CHARACTERS;
        fgLookupTable['*'] |= MARK_CHARACTERS;
        fgLookupTable['\''] |= MARK_CHARACTERS;
        fgLookupTable['('] |= MARK_CHARACTERS;
        fgLookupTable[')'] |= MARK_CHARACTERS;

        // Add Scheme Characters
        fgLookupTable['+'] |= SCHEME_CHARACTERS;
        fgLookupTable['-'] |= SCHEME_CHARACTERS;
        fgLookupTable['.'] |= SCHEME_CHARACTERS;

        // Add Userinfo Characters
        fgLookupTable[';'] |= USERINFO_CHARACTERS;
        fgLookupTable[':'] |= USERINFO_CHARACTERS;
        fgLookupTable['&'] |= USERINFO_CHARACTERS;
        fgLookupTable['='] |= USERINFO_CHARACTERS;
        fgLookupTable['+'] |= USERINFO_CHARACTERS;
        fgLookupTable['$'] |= USERINFO_CHARACTERS;
        fgLookupTable[','] |= USERINFO_CHARACTERS;

        // Add Path Characters
        fgLookupTable[';'] |= PATH_CHARACTERS;
        fgLookupTable['/'] |= PATH_CHARACTERS;
        fgLookupTable[':'] |= PATH_CHARACTERS;
        fgLookupTable['@'] |= PATH_CHARACTERS;
        fgLookupTable['&'] |= PATH_CHARACTERS;
        fgLookupTable['='] |= PATH_CHARACTERS;
        fgLookupTable['+'] |= PATH_CHARACTERS;
        fgLookupTable['$'] |= PATH_CHARACTERS;
        fgLookupTable[','] |= PATH_CHARACTERS;
    }

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

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

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

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

    /** If specified, stores the registry based authority for this URI; otherwise -1 */
    private String m_regAuthority = null;

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

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

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

    /** 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, IPv4 address or IPv6 reference 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.
     *

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?