3524 lines · 132.3 KB · Java
RawDownload
/* * Copyright (c) 2000, 2011, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation.  Oracle designates this * particular file as subject to the "Classpath" exception as provided * by Oracle in the LICENSE file that accompanied this code. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License * version 2 for more details (a copy is included in the LICENSE file that * accompanied this code). * * You should have received a copy of the GNU General Public License version * 2 along with this work; if not, write to the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA * or visit www.oracle.com if you need additional information or have any * questions. */ package java.net; import java.io.IOException;import java.io.InvalidObjectException;import java.io.ObjectInputStream;import java.io.ObjectOutputStream;import java.io.Serializable;import java.nio.ByteBuffer;import java.nio.CharBuffer;import java.nio.charset.CharsetDecoder;import java.nio.charset.CharsetEncoder;import java.nio.charset.CoderResult;import java.nio.charset.CodingErrorAction;import java.nio.charset.CharacterCodingException;import java.text.Normalizer;import sun.nio.cs.ThreadLocalCoders; import java.lang.Character;             // for javadocimport java.lang.NullPointerException;  // for javadoc  /** * Represents a Uniform Resource Identifier (URI) reference. * * <p> Aside from some minor deviations noted below, an instance of this * class represents a URI reference as defined by * <a href="http://www.ietf.org/rfc/rfc2396.txt"><i>RFC&nbsp;2396: Uniform * Resource Identifiers (URI): Generic Syntax</i></a>, amended by <a * href="http://www.ietf.org/rfc/rfc2732.txt"><i>RFC&nbsp;2732: Format for * Literal IPv6 Addresses in URLs</i></a>. The Literal IPv6 address format * also supports scope_ids. The syntax and usage of scope_ids is described * <a href="Inet6Address.html#scoped">here</a>. * This class provides constructors for creating URI instances from * their components or by parsing their string forms, methods for accessing the * various components of an instance, and methods for normalizing, resolving, * and relativizing URI instances.  Instances of this class are immutable. * * * <h4> URI syntax and components </h4> * * At the highest level a URI reference (hereinafter simply "URI") in string * form has the syntax * * <blockquote> * [<i>scheme</i><tt><b>:</b></tt><i></i>]<i>scheme-specific-part</i>[<tt><b>#</b></tt><i>fragment</i>] * </blockquote> * * where square brackets [...] delineate optional components and the characters * <tt><b>:</b></tt> and <tt><b>#</b></tt> stand for themselves. * * <p> An <i>absolute</i> URI specifies a scheme; a URI that is not absolute is * said to be <i>relative</i>.  URIs are also classified according to whether * they are <i>opaque</i> or <i>hierarchical</i>. * * <p> An <i>opaque</i> URI is an absolute URI whose scheme-specific part does * not begin with a slash character (<tt>'/'</tt>).  Opaque URIs are not * subject to further parsing.  Some examples of opaque URIs are: * * <blockquote><table cellpadding=0 cellspacing=0 summary="layout"> * <tr><td><tt>mailto:java-net@java.sun.com</tt><td></tr> * <tr><td><tt>news:comp.lang.java</tt><td></tr> * <tr><td><tt>urn:isbn:096139210x</tt></td></tr> * </table></blockquote> * * <p> A <i>hierarchical</i> URI is either an absolute URI whose * scheme-specific part begins with a slash character, or a relative URI, that * is, a URI that does not specify a scheme.  Some examples of hierarchical * URIs are: * * <blockquote> * <tt>http://java.sun.com/j2se/1.3/</tt><br> * <tt>docs/guide/collections/designfaq.html#28</tt><br> * <tt>../../../demo/jfc/SwingSet2/src/SwingSet2.java</tt><br> * <tt>file:///~/calendar</tt> * </blockquote> * * <p> A hierarchical URI is subject to further parsing according to the syntax * * <blockquote> * [<i>scheme</i><tt><b>:</b></tt>][<tt><b>//</b></tt><i>authority</i>][<i>path</i>][<tt><b>?</b></tt><i>query</i>][<tt><b>#</b></tt><i>fragment</i>] * </blockquote> * * where the characters <tt><b>:</b></tt>, <tt><b>/</b></tt>, * <tt><b>?</b></tt>, and <tt><b>#</b></tt> stand for themselves.  The * scheme-specific part of a hierarchical URI consists of the characters * between the scheme and fragment components. * * <p> The authority component of a hierarchical URI is, if specified, either * <i>server-based</i> or <i>registry-based</i>.  A server-based authority * parses according to the familiar syntax * * <blockquote> * [<i>user-info</i><tt><b>@</b></tt>]<i>host</i>[<tt><b>:</b></tt><i>port</i>] * </blockquote> * * where the characters <tt><b>@</b></tt> and <tt><b>:</b></tt> stand for * themselves.  Nearly all URI schemes currently in use are server-based.  An * authority component that does not parse in this way is considered to be * registry-based. * * <p> The path component of a hierarchical URI is itself said to be absolute * if it begins with a slash character (<tt>'/'</tt>); otherwise it is * relative.  The path of a hierarchical URI that is either absolute or * specifies an authority is always absolute. * * <p> All told, then, a URI instance has the following nine components: * * <blockquote><table summary="Describes the components of a URI:scheme,scheme-specific-part,authority,user-info,host,port,path,query,fragment"> * <tr><th><i>Component</i></th><th><i>Type</i></th></tr> * <tr><td>scheme</td><td><tt>String</tt></td></tr> * <tr><td>scheme-specific-part&nbsp;&nbsp;&nbsp;&nbsp;</td><td><tt>String</tt></td></tr> * <tr><td>authority</td><td><tt>String</tt></td></tr> * <tr><td>user-info</td><td><tt>String</tt></td></tr> * <tr><td>host</td><td><tt>String</tt></td></tr> * <tr><td>port</td><td><tt>int</tt></td></tr> * <tr><td>path</td><td><tt>String</tt></td></tr> * <tr><td>query</td><td><tt>String</tt></td></tr> * <tr><td>fragment</td><td><tt>String</tt></td></tr> * </table></blockquote> * * In a given instance any particular component is either <i>undefined</i> or * <i>defined</i> with a distinct value.  Undefined string components are * represented by <tt>null</tt>, while undefined integer components are * represented by <tt>-1</tt>.  A string component may be defined to have the * empty string as its value; this is not equivalent to that component being * undefined. * * <p> Whether a particular component is or is not defined in an instance * depends upon the type of the URI being represented.  An absolute URI has a * scheme component.  An opaque URI has a scheme, a scheme-specific part, and * possibly a fragment, but has no other components.  A hierarchical URI always * has a path (though it may be empty) and a scheme-specific-part (which at * least contains the path), and may have any of the other components.  If the * authority component is present and is server-based then the host component * will be defined and the user-information and port components may be defined. * * * <h4> Operations on URI instances </h4> * * The key operations supported by this class are those of * <i>normalization</i>, <i>resolution</i>, and <i>relativization</i>. * * <p> <i>Normalization</i> is the process of removing unnecessary <tt>"."</tt> * and <tt>".."</tt> segments from the path component of a hierarchical URI. * Each <tt>"."</tt> segment is simply removed.  A <tt>".."</tt> segment is * removed only if it is preceded by a non-<tt>".."</tt> segment. * Normalization has no effect upon opaque URIs. * * <p> <i>Resolution</i> is the process of resolving one URI against another, * <i>base</i> URI.  The resulting URI is constructed from components of both * URIs in the manner specified by RFC&nbsp;2396, taking components from the * base URI for those not specified in the original.  For hierarchical URIs, * the path of the original is resolved against the path of the base and then * normalized.  The result, for example, of resolving * * <blockquote> * <tt>docs/guide/collections/designfaq.html#28&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt>(1) * </blockquote> * * against the base URI <tt>http://java.sun.com/j2se/1.3/</tt> is the result * URI * * <blockquote> * <tt>http://java.sun.com/j2se/1.3/docs/guide/collections/designfaq.html#28</tt> * </blockquote> * * Resolving the relative URI * * <blockquote> * <tt>../../../demo/jfc/SwingSet2/src/SwingSet2.java&nbsp;&nbsp;&nbsp;&nbsp;</tt>(2) * </blockquote> * * against this result yields, in turn, * * <blockquote> * <tt>http://java.sun.com/j2se/1.3/demo/jfc/SwingSet2/src/SwingSet2.java</tt> * </blockquote> * * Resolution of both absolute and relative URIs, and of both absolute and * relative paths in the case of hierarchical URIs, is supported.  Resolving * the URI <tt>file:///~calendar</tt> against any other URI simply yields the * original URI, since it is absolute.  Resolving the relative URI (2) above * against the relative base URI (1) yields the normalized, but still relative, * URI * * <blockquote> * <tt>demo/jfc/SwingSet2/src/SwingSet2.java</tt> * </blockquote> * * <p> <i>Relativization</i>, finally, is the inverse of resolution: For any * two normalized URIs <i>u</i> and&nbsp;<i>v</i>, * * <blockquote> *   <i>u</i><tt>.relativize(</tt><i>u</i><tt>.resolve(</tt><i>v</i><tt>)).equals(</tt><i>v</i><tt>)</tt>&nbsp;&nbsp;and<br> *   <i>u</i><tt>.resolve(</tt><i>u</i><tt>.relativize(</tt><i>v</i><tt>)).equals(</tt><i>v</i><tt>)</tt>&nbsp;&nbsp;.<br> * </blockquote> * * This operation is often useful when constructing a document containing URIs * that must be made relative to the base URI of the document wherever * possible.  For example, relativizing the URI * * <blockquote> * <tt>http://java.sun.com/j2se/1.3/docs/guide/index.html</tt> * </blockquote> * * against the base URI * * <blockquote> * <tt>http://java.sun.com/j2se/1.3</tt> * </blockquote> * * yields the relative URI <tt>docs/guide/index.html</tt>. * * * <h4> Character categories </h4> * * RFC&nbsp;2396 specifies precisely which characters are permitted in the * various components of a URI reference.  The following categories, most of * which are taken from that specification, are used below to describe these * constraints: * * <blockquote><table cellspacing=2 summary="Describes categories alpha,digit,alphanum,unreserved,punct,reserved,escaped,and other"> *   <tr><th valign=top><i>alpha</i></th> *       <td>The US-ASCII alphabetic characters, *        <tt>'A'</tt>&nbsp;through&nbsp;<tt>'Z'</tt> *        and <tt>'a'</tt>&nbsp;through&nbsp;<tt>'z'</tt></td></tr> *   <tr><th valign=top><i>digit</i></th> *       <td>The US-ASCII decimal digit characters, *       <tt>'0'</tt>&nbsp;through&nbsp;<tt>'9'</tt></td></tr> *   <tr><th valign=top><i>alphanum</i></th> *       <td>All <i>alpha</i> and <i>digit</i> characters</td></tr> *   <tr><th valign=top><i>unreserved</i>&nbsp;&nbsp;&nbsp;&nbsp;</th> *       <td>All <i>alphanum</i> characters together with those in the string *        <tt>"_-!.~'()*"</tt></td></tr> *   <tr><th valign=top><i>punct</i></th> *       <td>The characters in the string <tt>",;:$&+="</tt></td></tr> *   <tr><th valign=top><i>reserved</i></th> *       <td>All <i>punct</i> characters together with those in the string *        <tt>"?/[]@"</tt></td></tr> *   <tr><th valign=top><i>escaped</i></th> *       <td>Escaped octets, that is, triplets consisting of the percent *           character (<tt>'%'</tt>) followed by two hexadecimal digits *           (<tt>'0'</tt>-<tt>'9'</tt>, <tt>'A'</tt>-<tt>'F'</tt>, and *           <tt>'a'</tt>-<tt>'f'</tt>)</td></tr> *   <tr><th valign=top><i>other</i></th> *       <td>The Unicode characters that are not in the US-ASCII character set, *           are not control characters (according to the {@link *           java.lang.Character#isISOControl(char) Character.isISOControl} *           method), and are not space characters (according to the {@link *           java.lang.Character#isSpaceChar(char) Character.isSpaceChar} *           method)&nbsp;&nbsp;<i>(<b>Deviation from RFC 2396</b>, which is *           limited to US-ASCII)</i></td></tr> * </table></blockquote> * * <p><a name="legal-chars"></a> The set of all legal URI characters consists of * the <i>unreserved</i>, <i>reserved</i>, <i>escaped</i>, and <i>other</i> * characters. * * * <h4> Escaped octets, quotation, encoding, and decoding </h4> * * RFC 2396 allows escaped octets to appear in the user-info, path, query, and * fragment components.  Escaping serves two purposes in URIs: * * <ul> * *   <li><p> To <i>encode</i> non-US-ASCII characters when a URI is required to *   conform strictly to RFC&nbsp;2396 by not containing any <i>other</i> *   characters.  </p></li> * *   <li><p> To <i>quote</i> characters that are otherwise illegal in a *   component.  The user-info, path, query, and fragment components differ *   slightly in terms of which characters are considered legal and illegal. *   </p></li> * * </ul> * * These purposes are served in this class by three related operations: * * <ul> * *   <li><p><a name="encode"></a> A character is <i>encoded</i> by replacing it *   with the sequence of escaped octets that represent that character in the *   UTF-8 character set.  The Euro currency symbol (<tt>'&#92;u20AC'</tt>), *   for example, is encoded as <tt>"%E2%82%AC"</tt>.  <i>(<b>Deviation from *   RFC&nbsp;2396</b>, which does not specify any particular character *   set.)</i> </p></li> * *   <li><p><a name="quote"></a> An illegal character is <i>quoted</i> simply by *   encoding it.  The space character, for example, is quoted by replacing it *   with <tt>"%20"</tt>.  UTF-8 contains US-ASCII, hence for US-ASCII *   characters this transformation has exactly the effect required by *   RFC&nbsp;2396. </p></li> * *   <li><p><a name="decode"></a> *   A sequence of escaped octets is <i>decoded</i> by *   replacing it with the sequence of characters that it represents in the *   UTF-8 character set.  UTF-8 contains US-ASCII, hence decoding has the *   effect of de-quoting any quoted US-ASCII characters as well as that of *   decoding any encoded non-US-ASCII characters.  If a <a *   href="../nio/charset/CharsetDecoder.html#ce">decoding error</a> occurs *   when decoding the escaped octets then the erroneous octets are replaced by *   <tt>'&#92;uFFFD'</tt>, the Unicode replacement character.  </p></li> * * </ul> * * These operations are exposed in the constructors and methods of this class * as follows: * * <ul> * *   <li><p> The {@link #URI(java.lang.String) <code>single-argument *   constructor</code>} requires any illegal characters in its argument to be *   quoted and preserves any escaped octets and <i>other</i> characters that *   are present.  </p></li> * *   <li><p> The {@link *   #URI(java.lang.String,java.lang.String,java.lang.String,int,java.lang.String,java.lang.String,java.lang.String) *   <code>multi-argument constructors</code>} quote illegal characters as *   required by the components in which they appear.  The percent character *   (<tt>'%'</tt>) is always quoted by these constructors.  Any <i>other</i> *   characters are preserved.  </p></li> * *   <li><p> The {@link #getRawUserInfo() getRawUserInfo}, {@link #getRawPath() *   getRawPath}, {@link #getRawQuery() getRawQuery}, {@link #getRawFragment() *   getRawFragment}, {@link #getRawAuthority() getRawAuthority}, and {@link *   #getRawSchemeSpecificPart() getRawSchemeSpecificPart} methods return the *   values of their corresponding components in raw form, without interpreting *   any escaped octets.  The strings returned by these methods may contain *   both escaped octets and <i>other</i> characters, and will not contain any *   illegal characters.  </p></li> * *   <li><p> The {@link #getUserInfo() getUserInfo}, {@link #getPath() *   getPath}, {@link #getQuery() getQuery}, {@link #getFragment() *   getFragment}, {@link #getAuthority() getAuthority}, and {@link *   #getSchemeSpecificPart() getSchemeSpecificPart} methods decode any escaped *   octets in their corresponding components.  The strings returned by these *   methods may contain both <i>other</i> characters and illegal characters, *   and will not contain any escaped octets.  </p></li> * *   <li><p> The {@link #toString() toString} method returns a URI string with *   all necessary quotation but which may contain <i>other</i> characters. *   </p></li> * *   <li><p> The {@link #toASCIIString() toASCIIString} method returns a fully *   quoted and encoded URI string that does not contain any <i>other</i> *   characters.  </p></li> * * </ul> * * * <h4> Identities </h4> * * For any URI <i>u</i>, it is always the case that * * <blockquote> * <tt>new URI(</tt><i>u</i><tt>.toString()).equals(</tt><i>u</i><tt>)</tt>&nbsp;. * </blockquote> * * For any URI <i>u</i> that does not contain redundant syntax such as two * slashes before an empty authority (as in <tt>file:///tmp/</tt>&nbsp;) or a * colon following a host name but no port (as in * <tt>http://java.sun.com:</tt>&nbsp;), and that does not encode characters * except those that must be quoted, the following identities also hold: * * <blockquote> * <tt>new URI(</tt><i>u</i><tt>.getScheme(),<br> * &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt><i>u</i><tt>.getSchemeSpecificPart(),<br> * &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt><i>u</i><tt>.getFragment())<br> * .equals(</tt><i>u</i><tt>)</tt> * </blockquote> * * in all cases, * * <blockquote> * <tt>new URI(</tt><i>u</i><tt>.getScheme(),<br> * &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt><i>u</i><tt>.getUserInfo(),&nbsp;</tt><i>u</i><tt>.getAuthority(),<br> * &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt><i>u</i><tt>.getPath(),&nbsp;</tt><i>u</i><tt>.getQuery(),<br> * &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt><i>u</i><tt>.getFragment())<br> * .equals(</tt><i>u</i><tt>)</tt> * </blockquote> * * if <i>u</i> is hierarchical, and * * <blockquote> * <tt>new URI(</tt><i>u</i><tt>.getScheme(),<br> * &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt><i>u</i><tt>.getUserInfo(),&nbsp;</tt><i>u</i><tt>.getHost(),&nbsp;</tt><i>u</i><tt>.getPort(),<br> * &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt><i>u</i><tt>.getPath(),&nbsp;</tt><i>u</i><tt>.getQuery(),<br> * &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt><i>u</i><tt>.getFragment())<br> * .equals(</tt><i>u</i><tt>)</tt> * </blockquote> * * if <i>u</i> is hierarchical and has either no authority or a server-based * authority. * * * <h4> URIs, URLs, and URNs </h4> * * A URI is a uniform resource <i>identifier</i> while a URL is a uniform * resource <i>locator</i>.  Hence every URL is a URI, abstractly speaking, but * not every URI is a URL.  This is because there is another subcategory of * URIs, uniform resource <i>names</i> (URNs), which name resources but do not * specify how to locate them.  The <tt>mailto</tt>, <tt>news</tt>, and * <tt>isbn</tt> URIs shown above are examples of URNs. * * <p> The conceptual distinction between URIs and URLs is reflected in the * differences between this class and the {@link URL} class. * * <p> An instance of this class represents a URI reference in the syntactic * sense defined by RFC&nbsp;2396.  A URI may be either absolute or relative. * A URI string is parsed according to the generic syntax without regard to the * scheme, if any, that it specifies.  No lookup of the host, if any, is * performed, and no scheme-dependent stream handler is constructed.  Equality, * hashing, and comparison are defined strictly in terms of the character * content of the instance.  In other words, a URI instance is little more than * a structured string that supports the syntactic, scheme-independent * operations of comparison, normalization, resolution, and relativization. * * <p> An instance of the {@link URL} class, by contrast, represents the * syntactic components of a URL together with some of the information required * to access the resource that it describes.  A URL must be absolute, that is, * it must always specify a scheme.  A URL string is parsed according to its * scheme.  A stream handler is always established for a URL, and in fact it is * impossible to create a URL instance for a scheme for which no handler is * available.  Equality and hashing depend upon both the scheme and the * Internet address of the host, if any; comparison is not defined.  In other * words, a URL is a structured string that supports the syntactic operation of * resolution as well as the network I/O operations of looking up the host and * opening a connection to the specified resource. * * * @author Mark Reinhold * @since 1.4 * * @see <a href="http://www.ietf.org/rfc/rfc2279.txt"><i>RFC&nbsp;2279: UTF-8, a * transformation format of ISO 10646</i></a>, <br><a * href="http://www.ietf.org/rfc/rfc2373.txt"><i>RFC&nbsp;2373: IPv6 Addressing * Architecture</i></a>, <br><a * href="http://www.ietf.org/rfc/rfc2396.txt"><i>RFC&nbsp;2396: Uniform * Resource Identifiers (URI): Generic Syntax</i></a>, <br><a * href="http://www.ietf.org/rfc/rfc2732.txt"><i>RFC&nbsp;2732: Format for * Literal IPv6 Addresses in URLs</i></a>, <br><a * href="URISyntaxException.html">URISyntaxException</a> */ public final class URI    implements Comparable<URI>, Serializable{     // Note: Comments containing the word "ASSERT" indicate places where a    // throw of an InternalError should be replaced by an appropriate assertion    // statement once asserts are enabled in the build.     static final long serialVersionUID = -6052424284110960213L;      // -- Properties and components of this instance --     // Components of all URIs: [<scheme>:]<scheme-specific-part>[#<fragment>]    private transient String scheme;            // null ==> relative URI    private transient String fragment;     // Hierarchical URI components: [//<authority>]<path>[?<query>]    private transient String authority;         // Registry or server     // Server-based authority: [<userInfo>@]<host>[:<port>]    private transient String userInfo;    private transient String host;              // null ==> registry-based    private transient int port = -1;            // -1 ==> undefined     // Remaining components of hierarchical URIs    private transient String path;              // null ==> opaque    private transient String query;     // The remaining fields may be computed on demand

Lines 1–500 of 3524.