FileDocCategorySizeDatePackage
URI.javaAPI DocAndroid 1.5 API61651Wed May 06 22:41:04 BST 2009java.net

URI

public final class URI extends Object implements Comparable, Serializable
This class represents an instance of a URI as defined by RFC 2396.
since
Android 1.0

Fields Summary
private static final long
serialVersionUID
static final String
unreserved
static final String
punct
static final String
reserved
static final String
someLegal
static final String
allLegal
private String
string
private transient String
scheme
private transient String
schemespecificpart
private transient String
authority
private transient String
userinfo
private transient String
host
private transient int
port
private transient String
path
private transient String
query
private transient String
fragment
private transient boolean
opaque
private transient boolean
absolute
private transient boolean
serverAuthority
private transient int
hash
Constructors Summary
private URI()


      
    
public URI(String uri)
Creates a new URI instance according to the given string {@code uri}.

param
uri the textual URI representation to be parsed into a URI object.
throws
URISyntaxException if the given string {@code uri} doesn't fit to the specification RFC2396 or could not be parsed correctly.
since
Android 1.0

        new Helper().parseURI(uri, false);
    
public URI(String scheme, String ssp, String frag)
Creates a new URI instance using the given arguments. This constructor first creates a temporary URI string from the given components. This string will be parsed later on to create the URI instance.

{@code [scheme:]scheme-specific-part[#fragment]}

param
scheme the scheme part of the URI.
param
ssp the scheme-specific-part of the URI.
param
frag the fragment part of the URI.
throws
URISyntaxException if the temporary created string doesn't fit to the specification RFC2396 or could not be parsed correctly.
since
Android 1.0

        StringBuffer uri = new StringBuffer();
        if (scheme != null) {
            uri.append(scheme);
            uri.append(':");
        }
        if (ssp != null) {
            // QUOTE ILLEGAL CHARACTERS
            uri.append(quoteComponent(ssp, allLegal));
        }
        if (frag != null) {
            uri.append('#");
            // QUOTE ILLEGAL CHARACTERS
            uri.append(quoteComponent(frag, allLegal));
        }

        new Helper().parseURI(uri.toString(), false);
    
public URI(String scheme, String userinfo, String host, int port, String path, String query, String fragment)
Creates a new URI instance using the given arguments. This constructor first creates a temporary URI string from the given components. This string will be parsed later on to create the URI instance.

{@code [scheme:][user-info@]host[:port][path][?query][#fragment]}

param
scheme the scheme part of the URI.
param
userinfo the user information of the URI for authentication and authorization.
param
host the host name of the URI.
param
port the port number of the URI.
param
path the path to the resource on the host.
param
query the query part of the URI to specify parameters for the resource.
param
fragment the fragment part of the URI.
throws
URISyntaxException if the temporary created string doesn't fit to the specification RFC2396 or could not be parsed correctly.
since
Android 1.0


        if (scheme == null && userinfo == null && host == null && path == null
                && query == null && fragment == null) {
            this.path = ""; //$NON-NLS-1$
            return;
        }

        if (scheme != null && path != null && path.length() > 0
                && path.charAt(0) != '/") {
            throw new URISyntaxException(path, Msg.getString("K0302")); //$NON-NLS-1$
        }

        StringBuffer uri = new StringBuffer();
        if (scheme != null) {
            uri.append(scheme);
            uri.append(':");
        }

        if (userinfo != null || host != null || port != -1) {
            uri.append("//"); //$NON-NLS-1$
        }

        if (userinfo != null) {
            // QUOTE ILLEGAL CHARACTERS in userinfo
            uri.append(quoteComponent(userinfo, someLegal));
            uri.append('@");
        }

        if (host != null) {
            // check for ipv6 addresses that hasn't been enclosed
            // in square brackets
            if (host.indexOf(':") != -1 && host.indexOf(']") == -1
                    && host.indexOf('[") == -1) {
                host = "[" + host + "]"; //$NON-NLS-1$ //$NON-NLS-2$
            }
            uri.append(host);
        }

        if (port != -1) {
            uri.append(':");
            uri.append(port);
        }

        if (path != null) {
            // QUOTE ILLEGAL CHARS
            uri.append(quoteComponent(path, "/@" + someLegal)); //$NON-NLS-1$
        }

        if (query != null) {
            uri.append('?");
            // QUOTE ILLEGAL CHARS
            uri.append(quoteComponent(query, allLegal));
        }

        if (fragment != null) {
            // QUOTE ILLEGAL CHARS
            uri.append('#");
            uri.append(quoteComponent(fragment, allLegal));
        }

        new Helper().parseURI(uri.toString(), true);
    
public URI(String scheme, String host, String path, String fragment)
Creates a new URI instance using the given arguments. This constructor first creates a temporary URI string from the given components. This string will be parsed later on to create the URI instance.

{@code [scheme:]host[path][#fragment]}

param
scheme the scheme part of the URI.
param
host the host name of the URI.
param
path the path to the resource on the host.
param
fragment the fragment part of the URI.
throws
URISyntaxException if the temporary created string doesn't fit to the specification RFC2396 or could not be parsed correctly.
since
Android 1.0

        this(scheme, null, host, -1, path, null, fragment);
    
public URI(String scheme, String authority, String path, String query, String fragment)
Creates a new URI instance using the given arguments. This constructor first creates a temporary URI string from the given components. This string will be parsed later on to create the URI instance.

{@code [scheme:][//authority][path][?query][#fragment]}

param
scheme the scheme part of the URI.
param
authority the authority part of the URI.
param
path the path to the resource on the host.
param
query the query part of the URI to specify parameters for the resource.
param
fragment the fragment part of the URI.
throws
URISyntaxException if the temporary created string doesn't fit to the specification RFC2396 or could not be parsed correctly.
since
Android 1.0

        if (scheme != null && path != null && path.length() > 0
                && path.charAt(0) != '/") {
            throw new URISyntaxException(path, Msg.getString("K0302")); //$NON-NLS-1$
        }

        StringBuffer uri = new StringBuffer();
        if (scheme != null) {
            uri.append(scheme);
            uri.append(':");
        }
        if (authority != null) {
            uri.append("//"); //$NON-NLS-1$
            // QUOTE ILLEGAL CHARS
            uri.append(quoteComponent(authority, "@[]" + someLegal)); //$NON-NLS-1$
        }

        if (path != null) {
            // QUOTE ILLEGAL CHARS
            uri.append(quoteComponent(path, "/@" + someLegal)); //$NON-NLS-1$
        }
        if (query != null) {
            // QUOTE ILLEGAL CHARS
            uri.append('?");
            uri.append(quoteComponent(query, allLegal));
        }
        if (fragment != null) {
            // QUOTE ILLEGAL CHARS
            uri.append('#");
            uri.append(quoteComponent(fragment, allLegal));
        }

        new Helper().parseURI(uri.toString(), false);
    
Methods Summary
public intcompareTo(java.net.URI uri)
Compares this URI with the given argument {@code uri}. This method will return a negative value if this URI instance is less than the given argument and a positive value if this URI instance is greater than the given argument. The return value {@code 0} indicates that the two instances represent the same URI. To define the order the single parts of the URI are compared with each other. String components will be orderer in the natural case-sensitive way. A hierarchical URI is less than an opaque URI and if one part is {@code null} the URI with the undefined part is less than the other one.

param
uri the URI this instance has to compare with.
return
the value representing the order of the two instances.
since
Android 1.0

        int ret = 0;

        // compare schemes
        if (scheme == null && uri.scheme != null) {
            return -1;
        } else if (scheme != null && uri.scheme == null) {
            return 1;
        } else if (scheme != null && uri.scheme != null) {
            ret = scheme.compareToIgnoreCase(uri.scheme);
            if (ret != 0) {
                return ret;
            }
        }

        // compare opacities
        if (!opaque && uri.opaque) {
            return -1;
        } else if (opaque && !uri.opaque) {
            return 1;
        } else if (opaque && uri.opaque) {
            ret = schemespecificpart.compareTo(uri.schemespecificpart);
            if (ret != 0) {
                return ret;
            }
        } else {

            // otherwise both must be hierarchical

            // compare authorities
            if (authority != null && uri.authority == null) {
                return 1;
            } else if (authority == null && uri.authority != null) {
                return -1;
            } else if (authority != null && uri.authority != null) {
                if (host != null && uri.host != null) {
                    // both are server based, so compare userinfo, host, port
                    if (userinfo != null && uri.userinfo == null) {
                        return 1;
                    } else if (userinfo == null && uri.userinfo != null) {
                        return -1;
                    } else if (userinfo != null && uri.userinfo != null) {
                        ret = userinfo.compareTo(uri.userinfo);
                        if (ret != 0) {
                            return ret;
                        }
                    }

                    // userinfo's are the same, compare hostname
                    ret = host.compareToIgnoreCase(uri.host);
                    if (ret != 0) {
                        return ret;
                    }

                    // compare port
                    if (port != uri.port) {
                        return port - uri.port;
                    }
                } else { // one or both are registry based, compare the whole
                    // authority
                    ret = authority.compareTo(uri.authority);
                    if (ret != 0) {
                        return ret;
                    }
                }
            }

            // authorities are the same
            // compare paths
            ret = path.compareTo(uri.path);
            if (ret != 0) {
                return ret;
            }

            // compare queries

            if (query != null && uri.query == null) {
                return 1;
            } else if (query == null && uri.query != null) {
                return -1;
            } else if (query != null && uri.query != null) {
                ret = query.compareTo(uri.query);
                if (ret != 0) {
                    return ret;
                }
            }
        }

        // everything else is identical, so compare fragments
        if (fragment != null && uri.fragment == null) {
            return 1;
        } else if (fragment == null && uri.fragment != null) {
            return -1;
        } else if (fragment != null && uri.fragment != null) {
            ret = fragment.compareTo(uri.fragment);
            if (ret != 0) {
                return ret;
            }
        }

        // identical
        return 0;
    
private java.lang.StringconvertHexToLowerCase(java.lang.String s)

        StringBuffer result = new StringBuffer(""); //$NON-NLS-1$
        if (s.indexOf('%") == -1) {
            return s;
        }

        int index = 0, previndex = 0;
        while ((index = s.indexOf('%", previndex)) != -1) {
            result.append(s.substring(previndex, index + 1));
            result.append(s.substring(index + 1, index + 3).toLowerCase());
            index += 3;
            previndex = index;
        }
        return result.toString();
    
public static java.net.URIcreate(java.lang.String uri)
Parses the given argument {@code uri} and creates an appropriate URI instance.

param
uri the string which has to be parsed to create the URI instance.
return
the created instance representing the given URI.
since
Android 1.0

        URI result = null;
        try {
            result = new URI(uri);
        } catch (URISyntaxException e) {
            throw new IllegalArgumentException(e.getMessage());
        }
        return result;
    
private java.lang.Stringdecode(java.lang.String s)

        if (s == null) {
            return s;
        }

        try {
            return URIEncoderDecoder.decode(s);
        } catch (UnsupportedEncodingException e) {
            throw new RuntimeException(e.toString());
        }
    
private java.net.URIduplicate()

        URI clone = new URI();
        clone.absolute = absolute;
        clone.authority = authority;
        clone.fragment = fragment;
        clone.host = host;
        clone.opaque = opaque;
        clone.path = path;
        clone.port = port;
        clone.query = query;
        clone.scheme = scheme;
        clone.schemespecificpart = schemespecificpart;
        clone.userinfo = userinfo;
        clone.serverAuthority = serverAuthority;
        return clone;
    
private java.lang.StringencodeOthers(java.lang.String s)

        try {
            /*
             * Use a different encoder than URLEncoder since: 1. chars like "/",
             * "#", "@" etc needs to be preserved instead of being encoded, 2.
             * UTF-8 char set needs to be used for encoding instead of default
             * platform one 3. Only other chars need to be converted
             */
            return URIEncoderDecoder.encodeOthers(s);
        } catch (UnsupportedEncodingException e) {
            throw new RuntimeException(e.toString());
        }
    
public booleanequals(java.lang.Object o)
Compares this URI instance with the given argument {@code o} and determines if both are equal. Two URI instances are equal if all single parts are identical in their meaning.

param
o the URI this instance has to be compared with.
return
{@code true} if both URI instances point to the same resource, {@code false} otherwise.
since
Android 1.0

        if (!(o instanceof URI)) {
            return false;
        }
        URI uri = (URI) o;

        if (uri.fragment == null && fragment != null || uri.fragment != null
                && fragment == null) {
            return false;
        } else if (uri.fragment != null && fragment != null) {
            if (!equalsHexCaseInsensitive(uri.fragment, fragment)) {
                return false;
            }
        }

        if (uri.scheme == null && scheme != null || uri.scheme != null
                && scheme == null) {
            return false;
        } else if (uri.scheme != null && scheme != null) {
            if (!uri.scheme.equalsIgnoreCase(scheme)) {
                return false;
            }
        }

        if (uri.opaque && opaque) {
            return equalsHexCaseInsensitive(uri.schemespecificpart,
                    schemespecificpart);
        } else if (!uri.opaque && !opaque) {
            if (!equalsHexCaseInsensitive(path, uri.path)) {
                return false;
            }

            if (uri.query != null && query == null || uri.query == null
                    && query != null) {
                return false;
            } else if (uri.query != null && query != null) {
                if (!equalsHexCaseInsensitive(uri.query, query)) {
                    return false;
                }
            }

            if (uri.authority != null && authority == null
                    || uri.authority == null && authority != null) {
                return false;
            } else if (uri.authority != null && authority != null) {
                if (uri.host != null && host == null || uri.host == null
                        && host != null) {
                    return false;
                } else if (uri.host == null && host == null) {
                    // both are registry based, so compare the whole authority
                    return equalsHexCaseInsensitive(uri.authority, authority);
                } else { // uri.host != null && host != null, so server-based
                    if (!host.equalsIgnoreCase(uri.host)) {
                        return false;
                    }

                    if (port != uri.port) {
                        return false;
                    }

                    if (uri.userinfo != null && userinfo == null
                            || uri.userinfo == null && userinfo != null) {
                        return false;
                    } else if (uri.userinfo != null && userinfo != null) {
                        return equalsHexCaseInsensitive(userinfo, uri.userinfo);
                    } else {
                        return true;
                    }
                }
            } else {
                // no authority
                return true;
            }

        } else {
            // one is opaque, the other hierarchical
            return false;
        }
    
private booleanequalsHexCaseInsensitive(java.lang.String first, java.lang.String second)

        if (first.indexOf('%") != second.indexOf('%")) {
            return first.equals(second);
        }

        int index = 0, previndex = 0;
        while ((index = first.indexOf('%", previndex)) != -1
                && second.indexOf('%", previndex) == index) {
            boolean match = first.substring(previndex, index).equals(
                    second.substring(previndex, index));
            if (!match) {
                return false;
            }

            match = first.substring(index + 1, index + 3).equalsIgnoreCase(
                    second.substring(index + 1, index + 3));
            if (!match) {
                return false;
            }

            index += 3;
            previndex = index;
        }
        return first.substring(previndex).equals(second.substring(previndex));
    
public java.lang.StringgetAuthority()
Gets the decoded authority part of this URI.

return
the decoded authority part or {@code null} if undefined.
since
Android 1.0

        return decode(authority);
    
public java.lang.StringgetFragment()
Gets the decoded fragment part of this URI.

return
the decoded fragment part or {@code null} if undefined.
since
Android 1.0

        return decode(fragment);
    
private java.lang.StringgetHashString()

        StringBuffer result = new StringBuffer();
        if (scheme != null) {
            result.append(scheme.toLowerCase());
            result.append(':");
        }
        if (opaque) {
            result.append(schemespecificpart);
        } else {
            if (authority != null) {
                result.append("//"); //$NON-NLS-1$
                if (host == null) {
                    result.append(authority);
                } else {
                    if (userinfo != null) {
                        result.append(userinfo + "@"); //$NON-NLS-1$
                    }
                    result.append(host.toLowerCase());
                    if (port != -1) {
                        result.append(":" + port); //$NON-NLS-1$
                    }
                }
            }

            if (path != null) {
                result.append(path);
            }

            if (query != null) {
                result.append('?");
                result.append(query);
            }
        }

        if (fragment != null) {
            result.append('#");
            result.append(fragment);
        }

        return convertHexToLowerCase(result.toString());
    
public java.lang.StringgetHost()
Gets the host part of this URI.

return
the host part or {@code null} if undefined.
since
Android 1.0

        return host;
    
public java.lang.StringgetPath()
Gets the decoded path part of this URI.

return
the decoded path part or {@code null} if undefined.
since
Android 1.0

        return decode(path);
    
public intgetPort()
Gets the port number of this URI.

return
the port number or {@code -1} if undefined.
since
Android 1.0

        return port;
    
public java.lang.StringgetQuery()
Gets the decoded query part of this URI.

return
the decoded query part or {@code null} if undefined.
since
Android 1.0

        return decode(query);
    
public java.lang.StringgetRawAuthority()
Gets the authority part of this URI in raw form.

return
the encoded authority part or {@code null} if undefined.
since
Android 1.0

        return authority;
    
public java.lang.StringgetRawFragment()
Gets the fragment part of this URI in raw form.

return
the encoded fragment part or {@code null} if undefined.
since
Android 1.0

        return fragment;
    
public java.lang.StringgetRawPath()
Gets the path part of this URI in raw form.

return
the encoded path part or {@code null} if undefined.
since
Android 1.0

        return path;
    
public java.lang.StringgetRawQuery()
Gets the query part of this URI in raw form.

return
the encoded query part or {@code null} if undefined.
since
Android 1.0

        return query;
    
public java.lang.StringgetRawSchemeSpecificPart()
Gets the scheme-specific part of this URI in raw form.

return
the encoded scheme-specific part or {@code null} if undefined.
since
Android 1.0

        return schemespecificpart;
    
public java.lang.StringgetRawUserInfo()
Gets the user-info part of this URI in raw form.

return
the encoded user-info part or {@code null} if undefined.
since
Android 1.0

        return userinfo;
    
public java.lang.StringgetScheme()
Gets the scheme part of this URI.

return
the scheme part or {@code null} if undefined.
since
Android 1.0

        return scheme;
    
public java.lang.StringgetSchemeSpecificPart()
Gets the decoded scheme-specific part of this URI.

return
the decoded scheme-specific part or {@code null} if undefined.
since
Android 1.0

        return decode(schemespecificpart);
    
public java.lang.StringgetUserInfo()
Gets the decoded user-info part of this URI.

return
the decoded user-info part or {@code null} if undefined.
since
Android 1.0

        return decode(userinfo);
    
public inthashCode()
Gets the hashcode value of this URI instance.

return
the appropriate hashcode value.
since
Android 1.0

        if (hash == -1) {
            hash = getHashString().hashCode();
        }
        return hash;
    
public booleanisAbsolute()
Indicates whether this URI is absolute, which means that a scheme part is defined in this URI.

return
{@code true} if this URI is absolute, {@code false} otherwise.
since
Android 1.0

        return absolute;
    
public booleanisOpaque()
Indicates whether this URI is opaque or not. An opaque URI is absolute and has a scheme-specific part which does not start with a slash character. All parts except scheme, scheme-specific and fragment are undefined.

return
{@code true} if the URI is opaque, {@code false} otherwise.
since
Android 1.0

        return opaque;
    
private java.lang.Stringnormalize(java.lang.String path)

        // count the number of '/'s, to determine number of segments
        int index = -1;
        int pathlen = path.length();
        int size = 0;
        if (pathlen > 0 && path.charAt(0) != '/") {
            size++;
        }
        while ((index = path.indexOf('/", index + 1)) != -1) {
            if (index + 1 < pathlen && path.charAt(index + 1) != '/") {
                size++;
            }
        }

        String[] seglist = new String[size];
        boolean[] include = new boolean[size];

        // break the path into segments and store in the list
        int current = 0;
        int index2 = 0;
        index = (pathlen > 0 && path.charAt(0) == '/") ? 1 : 0;
        while ((index2 = path.indexOf('/", index + 1)) != -1) {
            seglist[current++] = path.substring(index, index2);
            index = index2 + 1;
        }

        // if current==size, then the last character was a slash
        // and there are no more segments
        if (current < size) {
            seglist[current] = path.substring(index);
        }

        // determine which segments get included in the normalized path
        for (int i = 0; i < size; i++) {
            include[i] = true;
            if (seglist[i].equals("..")) { //$NON-NLS-1$
                int remove = i - 1;
                // search back to find a segment to remove, if possible
                while (remove > -1 && !include[remove]) {
                    remove--;
                }
                // if we find a segment to remove, remove it and the ".."
                // segment
                if (remove > -1 && !seglist[remove].equals("..")) { //$NON-NLS-1$
                    include[remove] = false;
                    include[i] = false;
                }
            } else if (seglist[i].equals(".")) { //$NON-NLS-1$
                include[i] = false;
            }
        }

        // put the path back together
        StringBuffer newpath = new StringBuffer();
        if (path.startsWith("/")) { //$NON-NLS-1$
            newpath.append('/");
        }

        for (int i = 0; i < seglist.length; i++) {
            if (include[i]) {
                newpath.append(seglist[i]);
                newpath.append('/");
            }
        }

        // if we used at least one segment and the path previously ended with
        // a slash and the last segment is still used, then delete the extra
        // trailing '/'
        if (!path.endsWith("/") && seglist.length > 0 //$NON-NLS-1$
                && include[seglist.length - 1]) {
            newpath.deleteCharAt(newpath.length() - 1);
        }

        String result = newpath.toString();

        // check for a ':' in the first segment if one exists,
        // prepend "./" to normalize
        index = result.indexOf(':");
        index2 = result.indexOf('/");
        if (index != -1 && (index < index2 || index2 == -1)) {
            newpath.insert(0, "./"); //$NON-NLS-1$
            result = newpath.toString();
        }
        return result;
    
public java.net.URInormalize()
Normalizes the path part of this URI.

return
an URI object which represents this instance with a normalized path.
since
Android 1.0

        if (opaque) {
            return this;
        }
        String normalizedPath = normalize(path);
        // if the path is already normalized, return this
        if (path.equals(normalizedPath)) {
            return this;
        }
        // get an exact copy of the URI re-calculate the scheme specific part
        // since the path of the normalized URI is different from this URI.
        URI result = duplicate();
        result.path = normalizedPath;
        result.setSchemeSpecificPart();
        return result;
    
public java.net.URIparseServerAuthority()
Tries to parse the authority component of this URI to divide it into the host, port, and user-info. If this URI is already determined as a ServerAuthority this instance will be returned without changes.

return
this instance with the components of the parsed server authority.
throws
URISyntaxException if the authority part could not be parsed as a server-based authority.
since
Android 1.0

        if (!serverAuthority) {
            new Helper().parseAuthority(true);
        }
        return this;
    
private java.lang.StringquoteComponent(java.lang.String component, java.lang.String legalset)

        try {
            /*
             * Use a different encoder than URLEncoder since: 1. chars like "/",
             * "#", "@" etc needs to be preserved instead of being encoded, 2.
             * UTF-8 char set needs to be used for encoding instead of default
             * platform one
             */
            return URIEncoderDecoder.quoteIllegal(component, legalset);
        } catch (UnsupportedEncodingException e) {
            throw new RuntimeException(e.toString());
        }
    
private voidreadObject(java.io.ObjectInputStream in)

        in.defaultReadObject();
        try {
            new Helper().parseURI(string, false);
        } catch (URISyntaxException e) {
            throw new IOException(e.toString());
        }
    
public java.net.URIrelativize(java.net.URI relative)
Makes the given URI {@code relative} to a relative URI against the URI represented by this instance.

param
relative the URI which has to be relativized against this URI.
return
the relative URI.
since
Android 1.0

        if (relative.opaque || opaque) {
            return relative;
        }

        if (scheme == null ? relative.scheme != null : !scheme
                .equals(relative.scheme)) {
            return relative;
        }

        if (authority == null ? relative.authority != null : !authority
                .equals(relative.authority)) {
            return relative;
        }

        // normalize both paths
        String thisPath = normalize(path);
        String relativePath = normalize(relative.path);

        /*
         * if the paths aren't equal, then we need to determine if this URI's
         * path is a parent path (begins with) the relative URI's path
         */
        if (!thisPath.equals(relativePath)) {
            // if this URI's path doesn't end in a '/', add one
            if (!thisPath.endsWith("/")) { //$NON-NLS-1$
                thisPath = thisPath + '/";
            }
            /*
             * if the relative URI's path doesn't start with this URI's path,
             * then just return the relative URI; the URIs have nothing in
             * common
             */
            if (!relativePath.startsWith(thisPath)) {
                return relative;
            }
        }

        URI result = new URI();
        result.fragment = relative.fragment;
        result.query = relative.query;
        // the result URI is the remainder of the relative URI's path
        result.path = relativePath.substring(thisPath.length());
        return result;
    
public java.net.URIresolve(java.net.URI relative)
Resolves the given URI {@code relative} against the URI represented by this instance.

param
relative the URI which has to be resolved against this URI.
return
the resolved URI.
since
Android 1.0

        if (relative.absolute || opaque) {
            return relative;
        }

        URI result;
        if (relative.path.equals("") && relative.scheme == null //$NON-NLS-1$
                && relative.authority == null && relative.query == null
                && relative.fragment != null) {
            // if the relative URI only consists of fragment,
            // the resolved URI is very similar to this URI,
            // except that it has the fragement from the relative URI.
            result = duplicate();
            result.fragment = relative.fragment;
            // no need to re-calculate the scheme specific part,
            // since fragment is not part of scheme specific part.
            return result;
        }

        if (relative.authority != null) {
            // if the relative URI has authority,
            // the resolved URI is almost the same as the relative URI,
            // except that it has the scheme of this URI.
            result = relative.duplicate();
            result.scheme = scheme;
            result.absolute = absolute;
        } else {
            // since relative URI has no authority,
            // the resolved URI is very similar to this URI,
            // except that it has the query and fragment of the relative URI,
            // and the path is different.
            result = duplicate();
            result.fragment = relative.fragment;
            result.query = relative.query;
            if (relative.path.startsWith("/")) { //$NON-NLS-1$
                result.path = relative.path;
            } else {
                // resolve a relative reference
                int endindex = path.lastIndexOf('/") + 1;
                result.path = normalize(path.substring(0, endindex)
                        + relative.path);
            }
            // re-calculate the scheme specific part since
            // query and path of the resolved URI is different from this URI.
            result.setSchemeSpecificPart();
        }
        return result;
    
public java.net.URIresolve(java.lang.String relative)
Creates a new URI instance by parsing the given string {@code relative} and resolves the created URI against the URI represented by this instance.

param
relative the given string to create the new URI instance which has to be resolved later on.
return
the created and resolved URI.
since
Android 1.0

        return resolve(create(relative));
    
private voidsetSchemeSpecificPart()
Helper method used to re-calculate the scheme specific part of the resolved or normalized URIs

        // ssp = [//authority][path][?query]
        StringBuffer ssp = new StringBuffer();
        if (authority != null) {
            ssp.append("//" + authority); //$NON-NLS-1$
        }
        if (path != null) {
            ssp.append(path);
        }
        if (query != null) {
            ssp.append("?" + query); //$NON-NLS-1$
        }
        schemespecificpart = ssp.toString();
        // reset string, so that it can be re-calculated correctly when asked.
        string = null;
    
public java.lang.StringtoASCIIString()
Returns the textual string representation of this URI instance using the US-ASCII encoding.

return
the US-ASCII string representation of this URI.
since
Android 1.0

        return encodeOthers(toString());
    
public java.lang.StringtoString()
Returns the textual string representation of this URI instance.

return
the textual string representation of this URI.
since
Android 1.0

        if (string == null) {
            StringBuffer result = new StringBuffer();
            if (scheme != null) {
                result.append(scheme);
                result.append(':");
            }
            if (opaque) {
                result.append(schemespecificpart);
            } else {
                if (authority != null) {
                    result.append("//"); //$NON-NLS-1$
                    result.append(authority);
                }

                if (path != null) {
                    result.append(path);
                }

                if (query != null) {
                    result.append('?");
                    result.append(query);
                }
            }

            if (fragment != null) {
                result.append('#");
                result.append(fragment);
            }

            string = result.toString();
        }
        return string;
    
public java.net.URLtoURL()
Converts this URI instance to a URL.

return
the created URL representing the same resource as this URI.
throws
MalformedURLException if an error occurs while creating the URL or no protocol handler could be found.
since
Android 1.0

        if (!absolute) {
            throw new IllegalArgumentException(Msg.getString("K0312") + ": " //$NON-NLS-1$//$NON-NLS-2$
                    + toString());
        }
        return new URL(toString());
    
private voidwriteObject(java.io.ObjectOutputStream out)

        // call toString() to ensure the value of string field is calculated
        toString();
        out.defaultWriteObject();