/* * 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 2396: Uniform * Resource Identifiers (URI): Generic Syntax</i></a>, amended by <a * href="http://www.ietf.org/rfc/rfc2732.txt"><i>RFC 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 </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 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 </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 </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 <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> 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> .<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 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> through <tt>'Z'</tt> * and <tt>'a'</tt> through <tt>'z'</tt></td></tr> * <tr><th valign=top><i>digit</i></th> * <td>The US-ASCII decimal digit characters, * <tt>'0'</tt> through <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> </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) <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 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>'\u20AC'</tt>), * for example, is encoded as <tt>"%E2%82%AC"</tt>. <i>(<b>Deviation from * RFC 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 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>'\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> . * </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> ) or a * colon following a host name but no port (as in * <tt>http://java.sun.com:</tt> ), 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> * </tt><i>u</i><tt>.getSchemeSpecificPart(),<br> * </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> * </tt><i>u</i><tt>.getUserInfo(), </tt><i>u</i><tt>.getAuthority(),<br> * </tt><i>u</i><tt>.getPath(), </tt><i>u</i><tt>.getQuery(),<br> * </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> * </tt><i>u</i><tt>.getUserInfo(), </tt><i>u</i><tt>.getHost(), </tt><i>u</i><tt>.getPort(),<br> * </tt><i>u</i><tt>.getPath(), </tt><i>u</i><tt>.getQuery(),<br> * </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 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 2279: UTF-8, a * transformation format of ISO 10646</i></a>, <br><a * href="http://www.ietf.org/rfc/rfc2373.txt"><i>RFC 2373: IPv6 Addressing * Architecture</i></a>, <br><a * href="http://www.ietf.org/rfc/rfc2396.txt"><i>RFC 2396: Uniform * Resource Identifiers (URI): Generic Syntax</i></a>, <br><a * href="http://www.ietf.org/rfc/rfc2732.txt"><i>RFC 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 demandLines 1–500 of 3524. Load more
/* * 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 javadoc import 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 2396: Uniform * Resource Identifiers (URI): Generic Syntax</i></a>, amended by <a * href="http://www.ietf.org/rfc/rfc2732.txt"><i>RFC 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 </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 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 </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 </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 <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> 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> .<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 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> through <tt>'Z'</tt> * and <tt>'a'</tt> through <tt>'z'</tt></td></tr> * <tr><th valign=top><i>digit</i></th> * <td>The US-ASCII decimal digit characters, * <tt>'0'</tt> through <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> </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) <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 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>'\u20AC'</tt>), * for example, is encoded as <tt>"%E2%82%AC"</tt>. <i>(<b>Deviation from * RFC 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 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>'\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> . * </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> ) or a * colon following a host name but no port (as in * <tt>http://java.sun.com:</tt> ), 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> * </tt><i>u</i><tt>.getSchemeSpecificPart(),<br> * </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> * </tt><i>u</i><tt>.getUserInfo(), </tt><i>u</i><tt>.getAuthority(),<br> * </tt><i>u</i><tt>.getPath(), </tt><i>u</i><tt>.getQuery(),<br> * </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> * </tt><i>u</i><tt>.getUserInfo(), </tt><i>u</i><tt>.getHost(), </tt><i>u</i><tt>.getPort(),<br> * </tt><i>u</i><tt>.getPath(), </tt><i>u</i><tt>.getQuery(),<br> * </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 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 2279: UTF-8, a * transformation format of ISO 10646</i></a>, <br><a * href="http://www.ietf.org/rfc/rfc2373.txt"><i>RFC 2373: IPv6 Addressing * Architecture</i></a>, <br><a * href="http://www.ietf.org/rfc/rfc2396.txt"><i>RFC 2396: Uniform * Resource Identifiers (URI): Generic Syntax</i></a>, <br><a * href="http://www.ietf.org/rfc/rfc2732.txt"><i>RFC 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