46 |
import java.util.regex.Pattern; |
import java.util.regex.Pattern; |
47 |
|
|
48 |
/** |
/** |
49 |
|
* <p> |
50 |
|
* A URI instance represents that defined by |
51 |
|
* <a href="http://www.ietf.org/rfc/rfc3986.txt">RFC2396</a>, |
52 |
|
* with some deviations. |
53 |
|
* </p> |
54 |
|
* <p> |
55 |
|
* At its highest level, a URI consists of: |
56 |
|
* </p> |
57 |
|
* <code>[<em>scheme</em><strong>:</strong>]<em>scheme-specific-part</em> |
58 |
|
* [<strong>#</strong><em>fragment</em>]</code> |
59 |
|
* </p> |
60 |
|
* <p> |
61 |
|
* where <strong>#</strong> and <strong>:</strong> are literal characters, |
62 |
|
* and those parts enclosed in square brackets are optional. |
63 |
|
* </p> |
64 |
|
* <p> |
65 |
|
* There are two main types of URI. An <em>opaque</em> URI is one |
66 |
|
* which just consists of the above three parts, and is not further |
67 |
|
* defined. An example of such a URI would be <em>mailto:</em> URI. |
68 |
|
* In contrast, <em>hierarchical</em> URIs give further definition |
69 |
|
* to the scheme-specific part, so as represent some part of a hierarchical |
70 |
|
* structure. |
71 |
|
* </p> |
72 |
|
* <p> |
73 |
|
* <code>[<strong>//</strong><em>authority</em>][<em>path</em>] |
74 |
|
* [<strong>?</strong><em>query</em>]</code> |
75 |
|
* </p> |
76 |
|
* <p> |
77 |
|
* with <strong>/</strong> and <strong>?</strong> being literal characters. |
78 |
|
* When server-based, the authority section is further subdivided into: |
79 |
|
* </p> |
80 |
|
* <p> |
81 |
|
* <code>[<em>user-info</em><strong>@</strong>]<em>host</em> |
82 |
|
* [<strong>:</strong><em>port</em>]</code> |
83 |
|
* </p> |
84 |
|
* <p> |
85 |
|
* with <strong>@</strong> and <strong>:</strong> as literal characters. |
86 |
|
* Authority sections that are not server-based are said to be registry-based. |
87 |
|
* </p> |
88 |
|
* <p> |
89 |
|
* Hierarchical URIs can be either relative or absolute. Absolute URIs |
90 |
|
* always start with a `<strong>/</strong>', while relative URIs don't |
91 |
|
* specify a scheme. Opaque URIs are always absolute. |
92 |
|
* </p> |
93 |
|
* <p> |
94 |
|
* Each part of the URI may have one of three states: undefined, empty |
95 |
|
* or containing some content. The former two of these are represented |
96 |
|
* by <code>null</code> and the empty string in Java, respectively. |
97 |
|
* The scheme-specific part may never be undefined. It also follows from |
98 |
|
* this that the path sub-part may also not be undefined, so as to ensure |
99 |
|
* the former. |
100 |
|
* </p> |
101 |
|
* |
102 |
* @author Ito Kazumitsu (ito.kazumitsu@hitachi-cable.co.jp) |
* @author Ito Kazumitsu (ito.kazumitsu@hitachi-cable.co.jp) |
103 |
* @author Dalibor Topic (robilad@kaffe.org) |
* @author Dalibor Topic (robilad@kaffe.org) |
104 |
* @author Michael Koch (konqueror@gmx.de) |
* @author Michael Koch (konqueror@gmx.de) |
105 |
|
* @author Andrew John Hughes (gnu_andrew@member.fsf.org) |
106 |
* @since 1.4 |
* @since 1.4 |
107 |
*/ |
*/ |
108 |
public final class URI implements Comparable, Serializable |
public final class URI |
109 |
|
implements Comparable, Serializable |
110 |
{ |
{ |
111 |
static final long serialVersionUID = -6052424284110960213L; |
static final long serialVersionUID = -6052424284110960213L; |
112 |
|
|
235 |
if (matcher.matches()) |
if (matcher.matches()) |
236 |
{ |
{ |
237 |
scheme = getURIGroup(matcher, SCHEME_GROUP); |
scheme = getURIGroup(matcher, SCHEME_GROUP); |
238 |
rawSchemeSpecificPart = getURIGroup(matcher, SCHEME_SPEC_PART_GROUP); |
rawSchemeSpecificPart = matcher.group(SCHEME_SPEC_PART_GROUP); |
239 |
rawAuthority = getURIGroup(matcher, AUTHORITY_GROUP); |
schemeSpecificPart = unquote(rawSchemeSpecificPart); |
240 |
rawPath = getURIGroup(matcher, PATH_GROUP); |
if (!isOpaque()) |
241 |
rawQuery = getURIGroup(matcher, QUERY_GROUP); |
{ |
242 |
|
rawAuthority = getURIGroup(matcher, AUTHORITY_GROUP); |
243 |
|
rawPath = matcher.group(PATH_GROUP); |
244 |
|
rawQuery = getURIGroup(matcher, QUERY_GROUP); |
245 |
|
} |
246 |
rawFragment = getURIGroup(matcher, FRAGMENT_GROUP); |
rawFragment = getURIGroup(matcher, FRAGMENT_GROUP); |
247 |
} |
} |
248 |
else |
else |
280 |
|
|
281 |
// We must eagerly unquote the parts, because this is the only time |
// We must eagerly unquote the parts, because this is the only time |
282 |
// we may throw an exception. |
// we may throw an exception. |
|
schemeSpecificPart = unquote(rawSchemeSpecificPart); |
|
283 |
authority = unquote(rawAuthority); |
authority = unquote(rawAuthority); |
284 |
userInfo = unquote(rawUserInfo); |
userInfo = unquote(rawUserInfo); |
285 |
host = unquote(rawHost); |
host = unquote(rawHost); |
872 |
} |
} |
873 |
|
|
874 |
/** |
/** |
875 |
* Returns the URI as string |
* Returns the URI as a String. If the URI was created using a constructor, |
876 |
|
* then this will be the same as the original input string. |
877 |
|
* |
878 |
|
* @return a string representation of the URI. |
879 |
*/ |
*/ |
880 |
public String toString() |
public String toString() |
881 |
{ |
{ |
882 |
return (getScheme() == null ? "" : getScheme() + ":") |
return (getScheme() == null ? "" : getScheme() + ":") |
883 |
+ (getRawAuthority() == null ? "" : "//" + getRawAuthority()) |
+ getRawSchemeSpecificPart() |
|
+ (getRawPath() == null ? "" : getRawPath()) |
|
|
+ (getRawQuery() == null ? "" : "?" + getRawQuery()) |
|
884 |
+ (getRawFragment() == null ? "" : "#" + getRawFragment()); |
+ (getRawFragment() == null ? "" : "#" + getRawFragment()); |
885 |
} |
} |
886 |
|
|