8147462: URI.toURL could be more efficient for most non-opaque URIs
Reviewed-by: alanb, chegar
This commit is contained in:
parent
37ceaefd4b
commit
7ae729a77f
@ -1080,11 +1080,8 @@ public final class URI
|
|||||||
* If a protocol handler for the URL could not be found,
|
* If a protocol handler for the URL could not be found,
|
||||||
* or if some other error occurred while constructing the URL
|
* or if some other error occurred while constructing the URL
|
||||||
*/
|
*/
|
||||||
public URL toURL()
|
public URL toURL() throws MalformedURLException {
|
||||||
throws MalformedURLException {
|
return URL.fromURI(this);
|
||||||
if (!isAbsolute())
|
|
||||||
throw new IllegalArgumentException("URI is not absolute");
|
|
||||||
return new URL(toString());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// -- Component access methods --
|
// -- Component access methods --
|
||||||
|
@ -659,6 +659,42 @@ public final class URL implements java.io.Serializable {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a URL from a URI, as if by invoking {@code uri.toURL()}.
|
||||||
|
*
|
||||||
|
* @see java.net.URI#toURL()
|
||||||
|
*/
|
||||||
|
static URL fromURI(URI uri) throws MalformedURLException {
|
||||||
|
if (!uri.isAbsolute()) {
|
||||||
|
throw new IllegalArgumentException("URI is not absolute");
|
||||||
|
}
|
||||||
|
String protocol = uri.getScheme();
|
||||||
|
if (!uri.isOpaque() && uri.getRawFragment() == null &&
|
||||||
|
!isOverrideable(protocol)) {
|
||||||
|
// non-opaque URIs will have already validated the components,
|
||||||
|
// so using the component-based URL constructor here is safe.
|
||||||
|
//
|
||||||
|
// All URL constructors will properly check if the scheme
|
||||||
|
// maps to a valid protocol handler
|
||||||
|
|
||||||
|
String query = uri.getRawQuery();
|
||||||
|
String path = uri.getRawPath();
|
||||||
|
String file = (query == null) ? path : path + "?" + query;
|
||||||
|
|
||||||
|
// URL represent undefined host as empty string while URI use null
|
||||||
|
String host = uri.getHost();
|
||||||
|
if (host == null) {
|
||||||
|
host = "";
|
||||||
|
}
|
||||||
|
|
||||||
|
int port = uri.getPort();
|
||||||
|
|
||||||
|
return new URL(protocol, host, port, file, null);
|
||||||
|
} else {
|
||||||
|
return new URL((URL)null, uri.toString(), null);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Returns true if specified string is a valid protocol name.
|
* Returns true if specified string is a valid protocol name.
|
||||||
*/
|
*/
|
||||||
@ -1275,11 +1311,28 @@ public final class URL implements java.io.Serializable {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static final String[] NON_OVERRIDEABLE_PROTOCOLS = {"file", "jrt"};
|
|
||||||
private static boolean isOverrideable(String protocol) {
|
/**
|
||||||
for (String p : NON_OVERRIDEABLE_PROTOCOLS)
|
* Non-overrideable protocols: "jrt" and "file"
|
||||||
if (protocol.equalsIgnoreCase(p))
|
*
|
||||||
|
* Character-based comparison for performance reasons; also ensures
|
||||||
|
* case-insensitive comparison in a locale-independent fashion.
|
||||||
|
*/
|
||||||
|
static boolean isOverrideable(String protocol) {
|
||||||
|
if (protocol.length() == 3) {
|
||||||
|
if ((Character.toLowerCase(protocol.charAt(0)) == 'j') &&
|
||||||
|
(Character.toLowerCase(protocol.charAt(1)) == 'r') &&
|
||||||
|
(Character.toLowerCase(protocol.charAt(2)) == 't')) {
|
||||||
return false;
|
return false;
|
||||||
|
}
|
||||||
|
} else if (protocol.length() == 4) {
|
||||||
|
if ((Character.toLowerCase(protocol.charAt(0)) == 'f') &&
|
||||||
|
(Character.toLowerCase(protocol.charAt(1)) == 'i') &&
|
||||||
|
(Character.toLowerCase(protocol.charAt(2)) == 'l') &&
|
||||||
|
(Character.toLowerCase(protocol.charAt(3)) == 'e')) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -23,13 +23,16 @@
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* @test
|
* @test
|
||||||
* @bug 4768755 4677045
|
* @bug 4768755 4677045 8147462
|
||||||
* @summary URL.equal(URL) is inconsistant for opaque URI.toURL()
|
* @summary URL.equal(URL) is inconsistent for opaque URI.toURL()
|
||||||
* and new URL(URI.toString)
|
* and new URL(URI.toString)
|
||||||
* URI.toURL() does not always work as specified
|
* URI.toURL() does not always work as specified
|
||||||
|
* Ensure URIs representing invalid/malformed URLs throw similar
|
||||||
|
* exception with new URL(URI.toString()) and URI.toURL()
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import java.net.*;
|
import java.net.*;
|
||||||
|
import java.util.Objects;
|
||||||
|
|
||||||
public class URItoURLTest {
|
public class URItoURLTest {
|
||||||
|
|
||||||
@ -39,19 +42,43 @@ public class URItoURLTest {
|
|||||||
URL classUrl = testClass.getClass().
|
URL classUrl = testClass.getClass().
|
||||||
getResource("/java/lang/Object.class");
|
getResource("/java/lang/Object.class");
|
||||||
|
|
||||||
String[] uris = { "mailto:xyz@abc.de",
|
String[] uris = {
|
||||||
|
"mailto:xyz@abc.de",
|
||||||
"file:xyz#ab",
|
"file:xyz#ab",
|
||||||
"http:abc/xyz/pqr",
|
"http:abc/xyz/pqr",
|
||||||
|
"http:abc/xyz/pqr?id=x%0a&ca=true",
|
||||||
"file:/C:/v700/dev/unitTesting/tests/apiUtil/uri",
|
"file:/C:/v700/dev/unitTesting/tests/apiUtil/uri",
|
||||||
"http:///p",
|
"http:///p",
|
||||||
|
"file:/C:/v700/dev/unitTesting/tests/apiUtil/uri",
|
||||||
|
"file:/C:/v700/dev%20src/unitTesting/tests/apiUtil/uri",
|
||||||
|
"file:/C:/v700/dev%20src/./unitTesting/./tests/apiUtil/uri",
|
||||||
|
"http://localhost:80/abc/./xyz/../pqr?id=x%0a&ca=true",
|
||||||
|
"file:./test/./x",
|
||||||
|
"file:./././%20#i=3",
|
||||||
|
"file:?hmm",
|
||||||
|
"file:.#hmm",
|
||||||
classUrl.toExternalForm(),
|
classUrl.toExternalForm(),
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// Strings that represent valid URIs but invalid URLs that should throw
|
||||||
|
// MalformedURLException both when calling toURL and new URL(String)
|
||||||
|
String[] malformedUrls = {
|
||||||
|
"test:/test",
|
||||||
|
"fiel:test",
|
||||||
|
};
|
||||||
|
|
||||||
|
// Non-absolute URIs should throw IAE when calling toURL but will throw
|
||||||
|
// MalformedURLException when calling new URL
|
||||||
|
String[] illegalUris = {
|
||||||
|
"./test",
|
||||||
|
"/test",
|
||||||
|
};
|
||||||
|
|
||||||
boolean isTestFailed = false;
|
boolean isTestFailed = false;
|
||||||
boolean isURLFailed = false;
|
boolean isURLFailed = false;
|
||||||
|
|
||||||
for (int i = 0; i < uris.length; i++) {
|
for (String uriString : uris) {
|
||||||
URI uri = URI.create(uris[i]);
|
URI uri = URI.create(uriString);
|
||||||
|
|
||||||
URL url1 = new URL(uri.toString());
|
URL url1 = new URL(uri.toString());
|
||||||
URL url2 = uri.toURL();
|
URL url2 = uri.toURL();
|
||||||
@ -107,6 +134,42 @@ public class URItoURLTest {
|
|||||||
System.out.println();
|
System.out.println();
|
||||||
isURLFailed = false;
|
isURLFailed = false;
|
||||||
}
|
}
|
||||||
|
for (String malformedUrl : malformedUrls) {
|
||||||
|
Exception toURLEx = null;
|
||||||
|
Exception newURLEx = null;
|
||||||
|
try {
|
||||||
|
new URI(malformedUrl).toURL();
|
||||||
|
} catch (Exception e) {
|
||||||
|
// expected
|
||||||
|
toURLEx = e;
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
new URL(new URI(malformedUrl).toString());
|
||||||
|
} catch (Exception e) {
|
||||||
|
// expected
|
||||||
|
newURLEx = e;
|
||||||
|
}
|
||||||
|
if (!(toURLEx instanceof MalformedURLException) ||
|
||||||
|
!(newURLEx instanceof MalformedURLException) ||
|
||||||
|
!toURLEx.getMessage().equals(newURLEx.getMessage())) {
|
||||||
|
isTestFailed = true;
|
||||||
|
System.out.println("Expected the same MalformedURLException: " +
|
||||||
|
newURLEx + " vs " + toURLEx);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for (String illegalUri : illegalUris) {
|
||||||
|
try {
|
||||||
|
new URI(illegalUri).toURL();
|
||||||
|
} catch (IllegalArgumentException e) {
|
||||||
|
// pass
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
new URL(illegalUri);
|
||||||
|
} catch (MalformedURLException e) {
|
||||||
|
// pass
|
||||||
|
}
|
||||||
|
}
|
||||||
if (isTestFailed) {
|
if (isTestFailed) {
|
||||||
throw new Exception("URI.toURL() test failed");
|
throw new Exception("URI.toURL() test failed");
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user