package java.net;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.Serializable;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public final class URI implements Comparable, Serializable
{
static final long serialVersionUID = -6052424284110960213L;
private static final String URI_REGEXP =
"^(([^:/?#]+):)?((//([^/?#]*))?([^?#]*)(\\?([^#]*))?)?(#(.*))?";
private static final String AUTHORITY_REGEXP =
"^((([^?#]*)@)?([^?#:]*)(:([^?#]*)))?";
private static final String RFC2396_DIGIT = "0123456789";
private static final String RFC2396_LOWALPHA = "abcdefghijklmnopqrstuvwxyz";
private static final String RFC2396_UPALPHA = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
private static final String RFC2396_ALPHA =
RFC2396_LOWALPHA + RFC2396_UPALPHA;
private static final String RFC2396_ALPHANUM = RFC2396_DIGIT + RFC2396_ALPHA;
private static final String RFC2396_MARK = "-_.!~*'()";
private static final String RFC2396_UNRESERVED =
RFC2396_ALPHANUM + RFC2396_MARK;
private static final String RFC2396_REG_NAME =
RFC2396_UNRESERVED + "$,;:@&=+";
private static final String RFC2396_PCHAR = RFC2396_UNRESERVED + ":@&=+$,";
private static final String RFC2396_SEGMENT = RFC2396_PCHAR + ";";
private static final String RFC2396_PATH_SEGMENTS = RFC2396_SEGMENT + "/";
private static final int SCHEME_GROUP = 2;
private static final int SCHEME_SPEC_PART_GROUP = 3;
private static final int AUTHORITY_GROUP = 5;
private static final int PATH_GROUP = 6;
private static final int QUERY_GROUP = 8;
private static final int FRAGMENT_GROUP = 10;
private static final int AUTHORITY_USERINFO_GROUP = 3;
private static final int AUTHORITY_HOST_GROUP = 4;
private static final int AUTHORITY_PORT_GROUP = 6;
private transient String scheme;
private transient String rawSchemeSpecificPart;
private transient String schemeSpecificPart;
private transient String rawAuthority;
private transient String authority;
private transient String rawUserInfo;
private transient String userInfo;
private transient String rawHost;
private transient String host;
private transient int port = -1;
private transient String rawPath;
private transient String path;
private transient String rawQuery;
private transient String query;
private transient String rawFragment;
private transient String fragment;
private String string;
private void readObject(ObjectInputStream is)
throws ClassNotFoundException, IOException
{
this.string = (String) is.readObject();
try
{
parseURI(this.string);
}
catch (URISyntaxException x)
{
throw new RuntimeException(x);
}
}
private void writeObject(ObjectOutputStream os) throws IOException
{
if (string == null)
string = toString();
os.writeObject(string);
}
private static String getURIGroup(Matcher match, int group)
{
String matched = match.group(group);
return matched.length() == 0 ? null : matched;
}
private void parseURI(String str) throws URISyntaxException
{
Pattern pattern = Pattern.compile(URI_REGEXP);
Matcher matcher = pattern.matcher(str);
if (matcher.matches())
{
scheme = getURIGroup(matcher, SCHEME_GROUP);
rawSchemeSpecificPart = getURIGroup(matcher, SCHEME_SPEC_PART_GROUP);
rawAuthority = getURIGroup(matcher, AUTHORITY_GROUP);
rawPath = getURIGroup(matcher, PATH_GROUP);
rawQuery = getURIGroup(matcher, QUERY_GROUP);
rawFragment = getURIGroup(matcher, FRAGMENT_GROUP);
}
else
throw new URISyntaxException(str, "doesn't match URI regular expression");
if (rawAuthority != null)
{
pattern = Pattern.compile(AUTHORITY_REGEXP);
matcher = pattern.matcher(rawAuthority);
if (matcher.matches())
{
rawUserInfo = getURIGroup(matcher, AUTHORITY_USERINFO_GROUP);
rawHost = getURIGroup(matcher, AUTHORITY_HOST_GROUP);
String portStr = getURIGroup(matcher, AUTHORITY_PORT_GROUP);
if (portStr != null)
try
{
port = Integer.parseInt(portStr);
}
catch (NumberFormatException e)
{
URISyntaxException use =
new URISyntaxException
(str, "doesn't match URI regular expression");
use.initCause(e);
throw use;
}
}
else
throw new URISyntaxException(str, "doesn't match URI regular expression");
}
schemeSpecificPart = unquote(rawSchemeSpecificPart);
authority = unquote(rawAuthority);
userInfo = unquote(rawUserInfo);
host = unquote(rawHost);
path = unquote(rawPath);
query = unquote(rawQuery);
fragment = unquote(rawFragment);
}
private static String unquote(String str) throws URISyntaxException
{
if (str == null)
return null;
byte[] buf = new byte[str.length()];
int pos = 0;
for (int i = 0; i < str.length(); i++)
{
char c = str.charAt(i);
if (c > 127)
throw new URISyntaxException(str, "Invalid character");
if (c == '%')
{
if (i + 2 >= str.length())
throw new URISyntaxException(str, "Invalid quoted character");
int hi = Character.digit(str.charAt(++i), 16);
int lo = Character.digit(str.charAt(++i), 16);
if (lo < 0 || hi < 0)
throw new URISyntaxException(str, "Invalid quoted character");
buf[pos++] = (byte) (hi * 16 + lo);
}
else
buf[pos++] = (byte) c;
}
try
{
return new String(buf, 0, pos, "utf-8");
}
catch (java.io.UnsupportedEncodingException x2)
{
throw (Error) new InternalError().initCause(x2);
}
}
private static String quote(String str)
{
return str;
}
private static String quoteAuthority(String str)
{
return quote(str, RFC2396_REG_NAME);
}
private static String quote(String str, String legalCharacters)
{
StringBuffer sb = new StringBuffer(str.length());
for (int i = 0; i < str.length(); i++)
{
char c = str.charAt(i);
if (legalCharacters.indexOf(c) == -1)
{
String hex = "0123456789ABCDEF";
if (c <= 127)
sb.append('%').append(hex.charAt(c / 16)).append(hex.charAt(c % 16));
else
{
try
{
byte[] utf8 = str.substring(i, i + 1).getBytes("utf-8");
for (int j = 0; j < utf8.length; j++)
sb.append('%').append(hex.charAt((utf8[j] & 0xff) / 16))
.append(hex.charAt((utf8[j] & 0xff) % 16));
}
catch (java.io.UnsupportedEncodingException x)
{
throw (Error) new InternalError().initCause(x);
}
}
}
else
sb.append(c);
}
return sb.toString();
}
private static String quoteHost(String str)
{
return str;
}
private static String quotePath(String str)
{
return quote(str, RFC2396_PATH_SEGMENTS);
}
private static String quoteUserInfo(String str)
{
return str;
}
public URI(String str) throws URISyntaxException
{
this.string = str;
parseURI(str);
}
public URI(String scheme, String userInfo, String host, int port,
String path, String query, String fragment)
throws URISyntaxException
{
this((scheme == null ? "" : scheme + ":")
+ (userInfo == null && host == null && port == -1 ? "" : "//")
+ (userInfo == null ? "" : quoteUserInfo(userInfo) + "@")
+ (host == null ? "" : quoteHost(host))
+ (port == -1 ? "" : ":" + String.valueOf(port))
+ (path == null ? "" : quotePath(path))
+ (query == null ? "" : "?" + quote(query))
+ (fragment == null ? "" : "#" + quote(fragment)));
parseServerAuthority();
}
public URI(String scheme, String authority, String path, String query,
String fragment) throws URISyntaxException
{
this((scheme == null ? "" : scheme + ":")
+ (authority == null ? "" : "//" + quoteAuthority(authority))
+ (path == null ? "" : quotePath(path))
+ (query == null ? "" : "?" + quote(query))
+ (fragment == null ? "" : "#" + quote(fragment)));
}
public URI(String scheme, String host, String path, String fragment)
throws URISyntaxException
{
this(scheme, null, host, -1, path, null, fragment);
}
public URI(String scheme, String ssp, String fragment)
throws URISyntaxException
{
this((scheme == null ? "" : scheme + ":")
+ (ssp == null ? "" : quote(ssp))
+ (fragment == null ? "" : "#" + quote(fragment)));
}
public static URI create(String str)
{
try
{
return new URI(str);
}
catch (URISyntaxException e)
{
throw (IllegalArgumentException) new IllegalArgumentException()
.initCause(e);
}
}
public URI parseServerAuthority() throws URISyntaxException
{
return null;
}
public URI normalize()
{
return null;
}
public URI resolve(URI uri)
{
if (uri.isAbsolute())
return uri;
if (uri.isOpaque())
return uri;
String scheme = uri.getScheme();
String schemeSpecificPart = uri.getSchemeSpecificPart();
String authority = uri.getAuthority();
String path = uri.getPath();
String query = uri.getQuery();
String fragment = uri.getFragment();
try
{
if (fragment != null && path != null && path.equals("")
&& scheme == null && authority == null && query == null)
return new URI(this.scheme, this.schemeSpecificPart, fragment);
if (authority == null)
{
authority = this.authority;
if (path == null)
path = "";
if (! (path.startsWith("/")))
{
StringBuffer basepath = new StringBuffer(this.path);
int i = this.path.lastIndexOf('/');
if (i >= 0)
basepath.delete(i + 1, basepath.length());
basepath.append(path);
path = basepath.toString();
}
}
return new URI(this.scheme, authority, path, query, fragment);
}
catch (URISyntaxException e)
{
return null;
}
}
public URI resolve(String str) throws IllegalArgumentException
{
return resolve(create(str));
}
public URI relativize(URI uri)
{
return null;
}
public URL toURL() throws IllegalArgumentException, MalformedURLException
{
if (isAbsolute())
return new URL(this.toString());
throw new IllegalArgumentException("not absolute");
}
public String getScheme()
{
return scheme;
}
public boolean isAbsolute()
{
return scheme != null;
}
public boolean isOpaque()
{
return ((scheme != null) && ! (schemeSpecificPart.startsWith("/")));
}
public String getRawSchemeSpecificPart()
{
return rawSchemeSpecificPart;
}
public String getSchemeSpecificPart()
{
return schemeSpecificPart;
}
public String getRawAuthority()
{
return rawAuthority;
}
public String getAuthority()
{
return authority;
}
public String getRawUserInfo()
{
return rawUserInfo;
}
public String getUserInfo()
{
return userInfo;
}
public String getHost()
{
return host;
}
public int getPort()
{
return port;
}
public String getRawPath()
{
return rawPath;
}
public String getPath()
{
return path;
}
public String getRawQuery()
{
return rawQuery;
}
public String getQuery()
{
return query;
}
public String getRawFragment()
{
return rawFragment;
}
public String getFragment()
{
return fragment;
}
public boolean equals(Object obj)
{
return false;
}
public int hashCode()
{
return 0;
}
public int compareTo(Object obj) throws ClassCastException
{
return 0;
}
public String toString()
{
return (getScheme() == null ? "" : getScheme() + ":")
+ (getRawAuthority() == null ? "" : "//" + getRawAuthority())
+ (getRawPath() == null ? "" : getRawPath())
+ (getRawQuery() == null ? "" : "?" + getRawQuery())
+ (getRawFragment() == null ? "" : "#" + getRawFragment());
}
public String toASCIIString()
{
return "";
}
}