update to OpenJDK 11, bump to 2.0.0, add URL.parseQueryParams()

This commit is contained in:
Jörg Prante 2019-08-08 14:42:24 +02:00
parent e154bb2cb7
commit 98470dc638
8 changed files with 71 additions and 45 deletions

View file

@ -33,8 +33,8 @@ subprojects {
} }
compileJava { compileJava {
sourceCompatibility = JavaVersion.VERSION_1_8 sourceCompatibility = JavaVersion.VERSION_11
targetCompatibility = JavaVersion.VERSION_1_8 targetCompatibility = JavaVersion.VERSION_11
} }
compileTestJava { compileTestJava {

View file

@ -1,11 +1,13 @@
group = org.xbib group = org.xbib
name = net name = net
version = 1.3.4 version = 2.0.0
# test # test
jackson.version = 2.8.11 junit.version = 5.5.1
junit.version = 5.4.2
hamcrest.version = 2.1 hamcrest.version = 2.1
jackson.version = 2.9.9
# doc
asciidoclet.version = 1.5.4 asciidoclet.version = 1.5.4
org.gradle.warning.mode = all org.gradle.warning.mode = all

View file

@ -5,7 +5,7 @@ package org.xbib.net;
* @param <K> the key type parameter * @param <K> the key type parameter
* @param <V> the value type parameter * @param <V> the value type parameter
*/ */
public class Pair<K, V> { public class Pair<K, V> implements Comparable<Pair<K, V>> {
private final K first; private final K first;
@ -26,6 +26,11 @@ public class Pair<K, V> {
@Override @Override
public String toString() { public String toString() {
return first + ":" + second; return first + "=" + second;
}
@Override
public int compareTo(Pair<K, V> pair) {
return 0;
} }
} }

View file

@ -19,6 +19,7 @@ import java.util.Comparator;
import java.util.Iterator; import java.util.Iterator;
import java.util.List; import java.util.List;
import java.util.Locale; import java.util.Locale;
import java.util.Objects;
import java.util.logging.Level; import java.util.logging.Level;
import java.util.logging.Logger; import java.util.logging.Logger;
@ -253,7 +254,7 @@ public class URL implements Comparable<URL> {
/** /**
* Return a special URL denoting the fact that this URL should be considered as invalid. * Return a special URL denoting the fact that this URL should be considered as invalid.
* The URL has a null scheme. * The URL has no scheme.
* @return url * @return url
*/ */
public static URL nullUrl() { public static URL nullUrl() {
@ -317,10 +318,11 @@ public class URL implements Comparable<URL> {
return sb.toString(); return sb.toString();
} }
public String decode(String input) { public static QueryParameters parseQueryString(String query) {
Objects.requireNonNull(query);
try { try {
return builder.percentDecoder.decode(input); return URL.parser().parse(query.charAt(0) == QUESTION_CHAR ? query : QUESTION_CHAR + query).getQueryParams();
} catch (MalformedInputException | UnmappableCharacterException e) { } catch (URLSyntaxException | MalformedInputException | UnmappableCharacterException e) {
throw new IllegalArgumentException(e); throw new IllegalArgumentException(e);
} }
} }
@ -333,6 +335,14 @@ public class URL implements Comparable<URL> {
return new Builder(); return new Builder();
} }
private String decode(String input) {
try {
return builder.percentDecoder.decode(input);
} catch (MalformedInputException | UnmappableCharacterException e) {
throw new IllegalArgumentException(e);
}
}
private String toString(boolean withFragment) { private String toString(boolean withFragment) {
if (internalStringRepresentation != null) { if (internalStringRepresentation != null) {
return internalStringRepresentation; return internalStringRepresentation;

View file

@ -33,7 +33,7 @@ class URLParserTest {
} }
@Test @Test
void testScheme() throws Exception { void testScheme() {
URL url = URL.from("http://"); URL url = URL.from("http://");
assertEquals("http://", url.toExternalForm()); assertEquals("http://", url.toExternalForm());
assertEquals("http://", url.toString()); assertEquals("http://", url.toString());
@ -52,7 +52,7 @@ class URLParserTest {
} }
@Test @Test
void testOpaque() throws Exception { void testOpaque() {
URL url = URL.from("a:b"); URL url = URL.from("a:b");
assertEquals("a", url.getScheme()); assertEquals("a", url.getScheme());
assertEquals("b", url.getSchemeSpecificPart()); assertEquals("b", url.getSchemeSpecificPart());
@ -68,7 +68,7 @@ class URLParserTest {
} }
@Test @Test
void testWithoutDoubleSlash() throws Exception { void testWithoutDoubleSlash() {
URL url = URL.from("http:foo.com"); URL url = URL.from("http:foo.com");
assertEquals("http:foo.com", url.toExternalForm()); assertEquals("http:foo.com", url.toExternalForm());
assertEquals("http:foo.com", url.toString()); assertEquals("http:foo.com", url.toString());
@ -82,14 +82,14 @@ class URLParserTest {
} }
@Test @Test
void testSchemeHost() throws Exception { void testSchemeHost() {
URL url = URL.from("http://foo.bar"); URL url = URL.from("http://foo.bar");
assertEquals("http://foo.bar", url.toString()); assertEquals("http://foo.bar", url.toString());
assertRoundTrip(url.toExternalForm()); assertRoundTrip(url.toExternalForm());
} }
@Test @Test
void testSchemeHostPort() throws Exception { void testSchemeHostPort() {
URL url = URL.from("http://f:/c"); URL url = URL.from("http://f:/c");
assertEquals("http://f:/c", url.toString()); assertEquals("http://f:/c", url.toString());
assertRoundTrip(url.toExternalForm()); assertRoundTrip(url.toExternalForm());
@ -103,28 +103,28 @@ class URLParserTest {
} }
@Test @Test
void testSchemeHostAuthInfo() throws Exception { void testSchemeHostAuthInfo() {
URL url = URL.from("http://auth@foo.bar"); URL url = URL.from("http://auth@foo.bar");
assertEquals("http://auth@foo.bar", url.toString()); assertEquals("http://auth@foo.bar", url.toString());
assertRoundTrip(url.toExternalForm()); assertRoundTrip(url.toExternalForm());
} }
@Test @Test
void testSchemeHostAuthInfoPort() throws Exception { void testSchemeHostAuthInfoPort() {
URL url = URL.from("http://auth@foo.bar:1"); URL url = URL.from("http://auth@foo.bar:1");
assertEquals("http://auth@foo.bar:1", url.toString()); assertEquals("http://auth@foo.bar:1", url.toString());
assertRoundTrip(url.toExternalForm()); assertRoundTrip(url.toExternalForm());
} }
@Test @Test
void testSchemeHostAuthInfoPortPath() throws Exception { void testSchemeHostAuthInfoPortPath() {
URL url = URL.from("http://auth@foo.bar:1/path"); URL url = URL.from("http://auth@foo.bar:1/path");
assertEquals("http://auth@foo.bar:1/path", url.toString()); assertEquals("http://auth@foo.bar:1/path", url.toString());
assertRoundTrip(url.toExternalForm()); assertRoundTrip(url.toExternalForm());
} }
@Test @Test
void testTrailingSlash() throws Exception { void testTrailingSlash() {
URL url = URL.from("http://foo.bar/path/"); URL url = URL.from("http://foo.bar/path/");
assertEquals("http://foo.bar/path/", url.toString()); assertEquals("http://foo.bar/path/", url.toString());
assertRoundTrip(url.toExternalForm()); assertRoundTrip(url.toExternalForm());
@ -137,21 +137,21 @@ class URLParserTest {
} }
@Test @Test
void testQuery() throws Exception { void testQuery() {
URL url = URL.from("http://auth@foo.bar:1/path?query"); URL url = URL.from("http://auth@foo.bar:1/path?query");
assertEquals("http://auth@foo.bar:1/path?query", url.toString()); assertEquals("http://auth@foo.bar:1/path?query", url.toString());
assertRoundTrip(url.toExternalForm()); assertRoundTrip(url.toExternalForm());
} }
@Test @Test
void testFragment() throws Exception { void testFragment() {
URL url = URL.from("http://auth@foo.bar:1/path#fragment"); URL url = URL.from("http://auth@foo.bar:1/path#fragment");
assertEquals("http://auth@foo.bar:1/path#fragment", url.toString()); assertEquals("http://auth@foo.bar:1/path#fragment", url.toString());
assertRoundTrip(url.toExternalForm()); assertRoundTrip(url.toExternalForm());
} }
@Test @Test
void testReservedChar() throws Exception { void testReservedChar() {
URL url = URL.from("http://www.google.com/ig/calculator?q=1USD=?EUR"); URL url = URL.from("http://www.google.com/ig/calculator?q=1USD=?EUR");
if ("false".equals(System.getProperty("java.net.preferIPv6Addresses"))) { if ("false".equals(System.getProperty("java.net.preferIPv6Addresses"))) {
assertEquals("http://www.google.com/ig/calculator?q=1USD%3D?EUR", url.toString()); assertEquals("http://www.google.com/ig/calculator?q=1USD%3D?EUR", url.toString());
@ -160,7 +160,7 @@ class URLParserTest {
} }
@Test @Test
void testPassword() throws Exception { void testPassword() {
URL url = URL.from("ftp://aaa:b%2B1@www.google.com"); URL url = URL.from("ftp://aaa:b%2B1@www.google.com");
assertEquals("b+1", url.getPassword()); assertEquals("b+1", url.getPassword());
assertRoundTrip(url.toExternalForm()); assertRoundTrip(url.toExternalForm());
@ -170,21 +170,21 @@ class URLParserTest {
} }
@Test @Test
void testPlus() throws Exception { void testPlus() {
URL url = URL.from("http://foobar:8080/test/print?value=%EA%B0%80+%EB%82%98"); URL url = URL.from("http://foobar:8080/test/print?value=%EA%B0%80+%EB%82%98");
assertEquals("http://foobar:8080/test/print?value=%EA%B0%80%2B%EB%82%98", url.toExternalForm()); assertEquals("http://foobar:8080/test/print?value=%EA%B0%80%2B%EB%82%98", url.toExternalForm());
assertRoundTrip(url.toExternalForm()); assertRoundTrip(url.toExternalForm());
} }
@Test @Test
void testIPv6() throws Exception { void testIPv6() {
URL url = URL.from("http://[2001:db8:85a3::8a2e:370:7334]"); URL url = URL.from("http://[2001:db8:85a3::8a2e:370:7334]");
assertEquals("http://[2001:db8:85a3:0:0:8a2e:370:7334]", url.toString()); assertEquals("http://[2001:db8:85a3:0:0:8a2e:370:7334]", url.toString());
assertRoundTrip(url.toExternalForm()); assertRoundTrip(url.toExternalForm());
} }
@Test @Test
void testIPv6WithScope() throws Exception { void testIPv6WithScope() {
// test scope ID. Must be a valid IPv6 // test scope ID. Must be a valid IPv6
URL url = URL.from("http://[3002:0:0:0:20c:29ff:fe64:614a%2]:8080/resource"); URL url = URL.from("http://[3002:0:0:0:20c:29ff:fe64:614a%2]:8080/resource");
assertEquals("http://[3002:0:0:0:20c:29ff:fe64:614a%2]:8080/resource", url.toString()); assertEquals("http://[3002:0:0:0:20c:29ff:fe64:614a%2]:8080/resource", url.toString());
@ -192,7 +192,7 @@ class URLParserTest {
} }
@Test @Test
void testIPv6WithIPv4() throws Exception { void testIPv6WithIPv4() {
URL url = URL.from("http://[::192.168.1.1]:8080/resource"); URL url = URL.from("http://[::192.168.1.1]:8080/resource");
assertEquals("http://[0:0:0:0:0:0:c0a8:101]:8080/resource", url.toString()); assertEquals("http://[0:0:0:0:0:0:c0a8:101]:8080/resource", url.toString());
assertRoundTrip(url.toExternalForm()); assertRoundTrip(url.toExternalForm());
@ -265,12 +265,12 @@ class URLParserTest {
} }
@Test @Test
void testFromUrlMalformedQueryParamMultiValues() throws Exception { void testFromUrlMalformedQueryParamMultiValues() {
assertRoundTrip("http://foo.com/foo?q1=v1=v2"); assertRoundTrip("http://foo.com/foo?q1=v1=v2");
} }
@Test @Test
void testFromUrlQueryWithEscapedChars() throws Exception { void testFromUrlQueryWithEscapedChars() {
assertRoundTrip("http://foo.com/foo?query==&%23"); assertRoundTrip("http://foo.com/foo?query==&%23");
} }
@ -338,12 +338,21 @@ class URLParserTest {
@Test @Test
void testRelative() throws Exception { void testRelative() throws Exception {
URL url = URL.parser().parse("/foo/bar?foo=bar#fragment"); URL url = URL.parser().parse("/some/path?foo=bar#fragment");
assertNull(url.getScheme()); assertNull(url.getScheme());
assertEquals("", url.getHostInfo()); assertEquals("", url.getHostInfo());
assertEquals("/foo/bar", url.getPath()); assertEquals("/some/path", url.getPath());
assertEquals("foo=bar", url.getQuery()); assertEquals("foo=bar", url.getQuery());
assertEquals("fragment", url.getFragment()); assertEquals("fragment", url.getFragment());
assertEquals("[foo=bar]", url.getQueryParams().toString());
}
@Test
void testQueryParams() throws Exception {
URL url = URL.parser().parse("?foo=bar");
assertEquals("foo=bar", url.getQuery());
assertEquals("[foo=bar]", url.getQueryParams().toString());
assertEquals("[k1=v1, k2=v2]", URL.parseQueryString("k1=v1&k2=v2").toString());
} }
@Test @Test
@ -417,7 +426,7 @@ class URLParserTest {
assertEquals(s, new java.net.URL(url).toExternalForm()); assertEquals(s, new java.net.URL(url).toExternalForm());
} }
private void assertRoundTrip(String url) throws Exception { private void assertRoundTrip(String url) {
String s = URL.from(url).toExternalForm(); String s = URL.from(url).toExternalForm();
assertEquals(s, URL.from(s).toExternalForm()); assertEquals(s, URL.from(s).toExternalForm());
} }

View file

@ -11,7 +11,7 @@ import static org.junit.jupiter.api.Assertions.assertEquals;
class URLResolverTest { class URLResolverTest {
@Test @Test
void testResolveURI() throws Exception { void testResolveURI() {
URI base = URI.create("http://example.org/foo"); URI base = URI.create("http://example.org/foo");
assertEquals("http://example.org/", base.resolve("/").toString()); assertEquals("http://example.org/", base.resolve("/").toString());
assertEquals("http://example.org/foo", base.toString()); assertEquals("http://example.org/foo", base.toString());
@ -27,7 +27,7 @@ class URLResolverTest {
} }
@Test @Test
void testResolveURL() throws Exception { void testResolveURL() {
URL base = URL.create("http://example.org/foo"); URL base = URL.create("http://example.org/foo");
assertEquals("http://example.org/", base.resolve("/").toString()); assertEquals("http://example.org/", base.resolve("/").toString());
assertEquals("http://example.org/foobar", base.resolve("/foobar").toString()); assertEquals("http://example.org/foobar", base.resolve("/foobar").toString());
@ -39,7 +39,7 @@ class URLResolverTest {
} }
@Test @Test
void testMultiResolve() throws Exception { void testMultiResolve() {
URL base = URL.create("http://example:8080"); URL base = URL.create("http://example:8080");
String pathSpec = "foobar/"; String pathSpec = "foobar/";
String index = "index.html"; String index = "index.html";

View file

@ -25,7 +25,7 @@ class URLTest {
} }
if (test.failure) { if (test.failure) {
try { try {
URL url = URL.base(base).resolve(input); URL.base(base).resolve(input);
fail(); fail();
} catch (Exception e) { } catch (Exception e) {
// pass // pass

View file

@ -301,21 +301,21 @@ class PathMatcherTest {
@Test @Test
void extractUriTemplateVariables() throws Exception { void extractUriTemplateVariables() throws Exception {
QueryParameters result = pathMatcher.extractUriTemplateVariables("/hotels/{hotel}", "/hotels/1"); QueryParameters result = pathMatcher.extractUriTemplateVariables("/hotels/{hotel}", "/hotels/1");
assertEquals("[hotel:1]", result.toString()); assertEquals("[hotel=1]", result.toString());
result = pathMatcher.extractUriTemplateVariables("/h?tels/{hotel}", "/hotels/1"); result = pathMatcher.extractUriTemplateVariables("/h?tels/{hotel}", "/hotels/1");
assertEquals("[hotel:1]", result.toString()); assertEquals("[hotel=1]", result.toString());
result = pathMatcher.extractUriTemplateVariables("/hotels/{hotel}/bookings/{booking}", "/hotels/1/bookings/2"); result = pathMatcher.extractUriTemplateVariables("/hotels/{hotel}/bookings/{booking}", "/hotels/1/bookings/2");
assertEquals("[hotel:1, booking:2]", result.toString()); assertEquals("[hotel=1, booking=2]", result.toString());
result = pathMatcher.extractUriTemplateVariables("/**/hotels/**/{hotel}", "/foo/hotels/bar/1"); result = pathMatcher.extractUriTemplateVariables("/**/hotels/**/{hotel}", "/foo/hotels/bar/1");
assertEquals("[hotel:1]", result.toString()); assertEquals("[hotel=1]", result.toString());
result = pathMatcher.extractUriTemplateVariables("/{page}.html", "/42.html"); result = pathMatcher.extractUriTemplateVariables("/{page}.html", "/42.html");
assertEquals("[page:42]", result.toString()); assertEquals("[page=42]", result.toString());
result = pathMatcher.extractUriTemplateVariables("/{page}.*", "/42.html"); result = pathMatcher.extractUriTemplateVariables("/{page}.*", "/42.html");
assertEquals("[page:42]", result.toString()); assertEquals("[page=42]", result.toString());
result = pathMatcher.extractUriTemplateVariables("/A-{B}-C", "/A-b-C"); result = pathMatcher.extractUriTemplateVariables("/A-{B}-C", "/A-b-C");
assertEquals("[B:b]", result.toString()); assertEquals("[B=b]", result.toString());
result = pathMatcher.extractUriTemplateVariables("/{name}.{extension}", "/test.html"); result = pathMatcher.extractUriTemplateVariables("/{name}.{extension}", "/test.html");
assertEquals("[name:test, extension:html]", result.toString()); assertEquals("[name=test, extension=html]", result.toString());
} }
@Test @Test