Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is it ever possible for the getPath method of a java.net.URI object to return null? (If so, when?)

Tags:

java

uri

null

According to the URI javadoc the getPath method returns "the decoded path component of this URI, or null if the path is undefined" (emphasis added). This would lead me to believe that if my application relies on the return value of getPath, I might need to check if it is null. However, it seems that this can never happen.

The following code shows my attempts to construct a URI object for which getPath returns null, but as you can see, I have not yet found such a case. Could someone please explain how this might happen?

EDIT: It has come to my attention that a mailto URI does not have a path. However, what I am really asking is: Can there be a URI that uses http, https, ftp, or file scheme that has an undefined/null path?

import java.net.URI;
import java.net.URISyntaxException;

public class URIGetPathNullTest {

    public static void main(String []args) throws Exception {
        test1();
        test2();
        test3();
        test4();
        test5();
        test6();
        test7();
    }


    public static void test1() throws URISyntaxException {
        String urlString = "";
        URI uri = new URI(urlString);
        printUri(uri); 
        // Output:
        //  toString() --> 
        //  getPath --> 
        //  getPath null? false         
    }

    public static void test2() throws URISyntaxException{
        String scheme = null;
        String ssp = null;
        String fragment = null;
        URI uri = new URI(
                scheme,
                ssp,
                fragment
            );
        printUri(uri);       
        // Output:
        //  toString() --> 
        //  getPath --> 
        //  getPath null? false
    }

    public static void test3() throws URISyntaxException {
        String scheme = null;
        String userInfo = null;
        String host = null;
        int port = -1;
        String path = null;
        String query = null;
        String fragment = null;
        URI uri = new URI(
                scheme,
                userInfo,
                host,
                port,
                path,
                query,
                fragment             
            );
        printUri(uri);       
        // Output:
        //  toString() --> 
        //  getPath --> 
        //  getPath null? false

    }

    public static void test4() throws URISyntaxException {
        String scheme = null;
        String host = null;
        String path = null;
        String fragment = null;
        URI uri = new URI(
                scheme,
                host,
                path,
                fragment             
            );
        printUri(uri);       
        // Output:
        //  toString() --> 
        //  getPath --> 
        //  getPath null? false
    }

    public static void test5() throws URISyntaxException {
        String scheme = null;
        String authority = null;
        String path = null;
        String query = null;
        String fragment = null;
        URI uri = new URI(
                scheme,
                authority,
                path,
                query,
                fragment             
            );
        printUri(uri);       
        // Output:
        //  toString() --> 
        //  getPath --> 
        //  getPath null? false
    }

    public static void test6() throws URISyntaxException {
        String urlString = "?some-query";
        URI uri = new URI(urlString);
        printUri(uri); 
        // Output:
        //  toString() --> ?some-query
        //  getPath --> 
        //  getPath null? false         
    }

    public static void test7() throws URISyntaxException {
        String urlString = "#some-fragment";
        URI uri = new URI(urlString);
        printUri(uri); 
        // Output:
        //  toString() --> #some-fragment
        //  getPath --> 
        //  getPath null? false         
    }

    public static void printUri(URI uri) {
        System.out.println("toString() --> " + uri.toString());
        System.out.println("getPath --> " + uri.getPath());
        System.out.println("getPath null? " + (uri.getPath() == null));
    }
}
like image 761
jacobq Avatar asked Aug 29 '13 19:08

jacobq


1 Answers

I was reading over RFC2956 and noticed that I was only thinking of URIs corresponding to http/ftp/file schemes. A mailto URI is an example of one that does not have a path.

public static void test8() throws URISyntaxException {
    String urlString = "mailto:[email protected]";
    URI uri = new URI(urlString);
    printUri(uri); 
    // Output:
    //  toString() --> mailto:[email protected]
    //  getPath --> null
    //  getPath null? true          
}

EDIT: Likewise with the news scheme.

public static void test9() throws URISyntaxException {
    String urlString = "news:comp.infosystems.www.servers.unix";
    URI uri = new URI(urlString);
    printUri(uri); 
    // Output:
    //  toString() --> news:comp.infosystems.www.servers.unix
    //  getPath --> null
    //  getPath null? true          
}

(I've combined my other answer below)

There's a good clue at the beginning of the URI javadoc:

An opaque URI is an absolute URI whose scheme-specific part does not begin with a slash character ('/'). Opaque URIs are not subject to further parsing. Some examples of opaque URIs are:

mailto:[email protected]
news:comp.lang.java
urn:isbn:096139210x

It seems that getPath returns null if and only if the URI is opaque, which is easy to check with the isOpaque method. So if I ensure that the URI is not opaque then I should not need to check the result of getPath for null.

Looking at the source for java.net.URI in openjdk 7-b147, I noticed a comment by the path field then looked at the source for isOpaque, which seems to confirm this:

private transient String path;  // null ==> opaque

// ...

public boolean isOpaque() {
    return path == null;
}
like image 194
jacobq Avatar answered Oct 05 '22 17:10

jacobq