better exception method signatures, avoid null URLs as return value, remove internal package with single class
This commit is contained in:
parent
286ab07793
commit
93e201db8b
13 changed files with 149 additions and 231 deletions
|
@ -1,6 +1,6 @@
|
|||
group = org.xbib
|
||||
name = net
|
||||
version = 1.0.1
|
||||
version = 1.0.2
|
||||
|
||||
junit.version = 4.12
|
||||
asciidoclet.version = 1.5.4
|
||||
|
|
|
@ -1,118 +0,0 @@
|
|||
package org.xbib.net;
|
||||
|
||||
import java.util.Enumeration;
|
||||
import java.util.HashSet;
|
||||
import java.util.Iterator;
|
||||
import java.util.Locale;
|
||||
import java.util.MissingResourceException;
|
||||
import java.util.ResourceBundle;
|
||||
import java.util.Set;
|
||||
import java.util.SortedMap;
|
||||
import java.util.TreeMap;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
/**
|
||||
* Contains a simple context for namespaces.
|
||||
*/
|
||||
public class SimpleNamespaceContext {
|
||||
|
||||
private static final Logger logger = Logger.getLogger(SimpleNamespaceContext.class.getName());
|
||||
|
||||
private static final String DEFAULT_RESOURCE =
|
||||
SimpleNamespaceContext.class.getPackage().getName().replace('.', '/') + '/' + "namespace";
|
||||
|
||||
private static final SimpleNamespaceContext DEFAULT_CONTEXT = newDefaultInstance();
|
||||
|
||||
// sort namespace by length in descending order, useful for compacting prefix
|
||||
protected final SortedMap<String, String> namespaces = new TreeMap<>();
|
||||
|
||||
private final SortedMap<String, Set<String>> prefixes = new TreeMap<>();
|
||||
|
||||
protected SimpleNamespaceContext() {
|
||||
}
|
||||
|
||||
protected SimpleNamespaceContext(ResourceBundle bundle) {
|
||||
Enumeration<String> en = bundle.getKeys();
|
||||
while (en.hasMoreElements()) {
|
||||
String prefix = en.nextElement();
|
||||
String namespace = bundle.getString(prefix);
|
||||
addNamespace(prefix, namespace);
|
||||
}
|
||||
}
|
||||
|
||||
public static SimpleNamespaceContext getInstance() {
|
||||
return DEFAULT_CONTEXT;
|
||||
}
|
||||
|
||||
/**
|
||||
* Empty namespace context.
|
||||
*
|
||||
* @return an XML namespace context
|
||||
*/
|
||||
public static SimpleNamespaceContext newInstance() {
|
||||
return new SimpleNamespaceContext();
|
||||
}
|
||||
|
||||
public static SimpleNamespaceContext newDefaultInstance() {
|
||||
return newInstance(DEFAULT_RESOURCE);
|
||||
}
|
||||
|
||||
/**
|
||||
* Use thread context class laoder to instantiate a namespace context.
|
||||
* @param bundleName the resource bundle name
|
||||
* @return XML namespace context
|
||||
*/
|
||||
public static SimpleNamespaceContext newInstance(String bundleName) {
|
||||
return newInstance(bundleName, Locale.getDefault(), Thread.currentThread().getContextClassLoader());
|
||||
}
|
||||
|
||||
public static SimpleNamespaceContext newInstance(String bundleName, Locale locale, ClassLoader classLoader) {
|
||||
try {
|
||||
return new SimpleNamespaceContext(ResourceBundle.getBundle(bundleName, locale, classLoader));
|
||||
} catch (MissingResourceException e) {
|
||||
logger.log(Level.WARNING, e.getMessage(), e);
|
||||
return new SimpleNamespaceContext();
|
||||
}
|
||||
}
|
||||
|
||||
public void addNamespace(String prefix, String namespace) {
|
||||
namespaces.put(prefix, namespace);
|
||||
if (prefixes.containsKey(namespace)) {
|
||||
prefixes.get(namespace).add(prefix);
|
||||
} else {
|
||||
Set<String> set = new HashSet<>();
|
||||
set.add(prefix);
|
||||
prefixes.put(namespace, set);
|
||||
}
|
||||
}
|
||||
|
||||
public SortedMap<String, String> getNamespaces() {
|
||||
return namespaces;
|
||||
}
|
||||
|
||||
public String getNamespaceURI(String prefix) {
|
||||
if (prefix == null) {
|
||||
return null;
|
||||
}
|
||||
return namespaces.getOrDefault(prefix, null);
|
||||
}
|
||||
|
||||
public String getPrefix(String namespaceURI) {
|
||||
Iterator<String> it = getPrefixes(namespaceURI);
|
||||
return it != null && it.hasNext() ? it.next() : null;
|
||||
}
|
||||
|
||||
public Iterator<String> getPrefixes(String namespace) {
|
||||
if (namespace == null) {
|
||||
throw new IllegalArgumentException("namespace URI cannot be null");
|
||||
}
|
||||
return prefixes.containsKey(namespace) ?
|
||||
prefixes.get(namespace).iterator() : null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return namespaces.toString();
|
||||
}
|
||||
}
|
|
@ -22,9 +22,21 @@ import java.util.logging.Level;
|
|||
import java.util.logging.Logger;
|
||||
|
||||
/**
|
||||
* {@link URL} is a Java implementation of the Uniform Resource Identifier ({@code RFC 3986})
|
||||
*
|
||||
* A Uniform Resource Locator (URL) is a compact representation of the
|
||||
* location and access method for a resource available via the Internet.
|
||||
*
|
||||
* Historically, there are many different forms of internet resource representations, for example,
|
||||
* the URL (RFC 1738 as of 1994), the URI (RFC 2396 as of 1998), and IRI (RFC 3987 as of 2005),
|
||||
* and most of them have updated specifications.
|
||||
*
|
||||
* {@link URL} is a Java implementation that serves as a universal point of handling all
|
||||
* different forms. It follows the syntax of the Uniform Resource Identifier ({@code RFC 3986})
|
||||
* in accordance with the link:https://url.spec.whatwg.org/[{@code WHATWG} URL standard].
|
||||
*
|
||||
* The reason for the name {@code URL} is merely because of the popularity of the name, which
|
||||
* overweighs the URI or IRI popularity.
|
||||
*
|
||||
* [source,java]
|
||||
* --
|
||||
* URL url = URL.http().resolveFromHost("google.com").build();
|
||||
|
@ -87,6 +99,9 @@ public class URL implements Serializable {
|
|||
this.fragment = encodeFragment();
|
||||
}
|
||||
|
||||
/**
|
||||
* A special, scheme-less URL denoting the fact that this URL should be considered as invalid.
|
||||
*/
|
||||
public static final URL INVALID = URL.builder().build();
|
||||
|
||||
public static Builder file() {
|
||||
|
@ -224,7 +239,7 @@ public class URL implements Serializable {
|
|||
public static URL from(String input) {
|
||||
try {
|
||||
return parser().parse(input, true);
|
||||
} catch (CharacterCodingException e) {
|
||||
} catch (URLSyntaxException e) {
|
||||
throw new IllegalArgumentException(e);
|
||||
}
|
||||
}
|
||||
|
@ -232,13 +247,25 @@ public class URL implements Serializable {
|
|||
public static URL create(String input) {
|
||||
try {
|
||||
return parser().parse(input, false);
|
||||
} catch (CharacterCodingException e) {
|
||||
} catch (URLSyntaxException e) {
|
||||
throw new IllegalArgumentException(e);
|
||||
}
|
||||
}
|
||||
|
||||
public URL resolve(String spec) {
|
||||
try {
|
||||
return new Resolver(this).resolve(spec);
|
||||
} catch (URLSyntaxException e) {
|
||||
throw new IllegalArgumentException(e);
|
||||
}
|
||||
}
|
||||
|
||||
public URL resolve(URL spec) {
|
||||
try {
|
||||
return new Resolver(this).resolve(spec);
|
||||
} catch (URLSyntaxException e) {
|
||||
throw new IllegalArgumentException(e);
|
||||
}
|
||||
}
|
||||
|
||||
public String decode(String input) {
|
||||
|
@ -627,7 +654,7 @@ public class URL implements Serializable {
|
|||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* The URL Builder embedded class is for building an URL by fluent API methods.
|
||||
*/
|
||||
public static class Builder {
|
||||
|
||||
|
@ -706,7 +733,7 @@ public class URL implements Serializable {
|
|||
return this;
|
||||
}
|
||||
|
||||
public Builder resolveFromHost(String hostname) throws CharacterCodingException {
|
||||
public Builder resolveFromHost(String hostname) {
|
||||
if (hostname == null) {
|
||||
return this;
|
||||
}
|
||||
|
@ -729,8 +756,12 @@ public class URL implements Serializable {
|
|||
if (e.getMessage() != null && !e.getMessage().endsWith("invalid IPv6 address") &&
|
||||
hostname.charAt(0) != '[' &&
|
||||
hostname.charAt(hostname.length() - 1) != ']') {
|
||||
try {
|
||||
String idna = IDN.toASCII(percentDecoder.decode(hostname));
|
||||
host(idna, ProtocolVersion.NONE);
|
||||
} catch (CharacterCodingException e2) {
|
||||
throw new IllegalArgumentException(e2);
|
||||
}
|
||||
}
|
||||
}
|
||||
return this;
|
||||
|
@ -863,27 +894,26 @@ public class URL implements Serializable {
|
|||
*/
|
||||
public static class Parser {
|
||||
|
||||
private final PercentDecoder percentDecoder;
|
||||
private final Builder builder;
|
||||
|
||||
private Parser() {
|
||||
percentDecoder = new PercentDecoder();
|
||||
builder = new Builder();
|
||||
}
|
||||
|
||||
public URL parse(String input) throws CharacterCodingException {
|
||||
public URL parse(String input) throws URLSyntaxException {
|
||||
return parse(input, true);
|
||||
}
|
||||
|
||||
public URL parse(String input, boolean resolve) throws CharacterCodingException {
|
||||
public URL parse(String input, boolean resolve) throws URLSyntaxException {
|
||||
if (isNullOrEmpty(input)) {
|
||||
return null;
|
||||
return INVALID;
|
||||
}
|
||||
if (input.indexOf('\n') >= 0) {
|
||||
return null;
|
||||
return INVALID;
|
||||
}
|
||||
if (input.indexOf('\t') >= 0) {
|
||||
return null;
|
||||
return INVALID;
|
||||
}
|
||||
Builder builder = new Builder();
|
||||
String remaining = parseScheme(builder, input);
|
||||
if (remaining != null) {
|
||||
remaining = remaining.replace('\\', SEPARATOR_CHAR);
|
||||
|
@ -906,7 +936,11 @@ public class URL implements Serializable {
|
|||
}
|
||||
}
|
||||
if (!isNullOrEmpty(remaining)) {
|
||||
try {
|
||||
parsePathWithQueryAndFragment(builder, remaining);
|
||||
} catch (CharacterCodingException e) {
|
||||
throw new URLSyntaxException(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
return builder.build();
|
||||
|
@ -933,7 +967,7 @@ public class URL implements Serializable {
|
|||
return remaining;
|
||||
}
|
||||
|
||||
private void parseHostAndPort(Builder builder, String host, boolean resolve) throws CharacterCodingException {
|
||||
private void parseHostAndPort(Builder builder, String host, boolean resolve) throws URLSyntaxException {
|
||||
if (host.indexOf('[') == 0) {
|
||||
int i = host.lastIndexOf(']');
|
||||
if (i >= 0) {
|
||||
|
@ -954,7 +988,7 @@ public class URL implements Serializable {
|
|||
}
|
||||
}
|
||||
|
||||
private Integer parsePort(String portStr) {
|
||||
private Integer parsePort(String portStr) throws URLSyntaxException {
|
||||
if (portStr == null || portStr.isEmpty()) {
|
||||
return null;
|
||||
}
|
||||
|
@ -970,20 +1004,21 @@ public class URL implements Serializable {
|
|||
if (port > 0 && port < 65536) {
|
||||
return port;
|
||||
} else {
|
||||
throw new IllegalArgumentException("invalid port");
|
||||
throw new URLSyntaxException("invalid port");
|
||||
}
|
||||
} catch (NumberFormatException e) {
|
||||
throw new IllegalArgumentException("no numeric port: " + portStr);
|
||||
throw new URLSyntaxException("no numeric port: " + portStr);
|
||||
}
|
||||
}
|
||||
|
||||
void parsePathWithQueryAndFragment(Builder builder, String input) throws CharacterCodingException {
|
||||
private void parsePathWithQueryAndFragment(Builder builder, String input)
|
||||
throws MalformedInputException, UnmappableCharacterException {
|
||||
if (input == null) {
|
||||
return;
|
||||
}
|
||||
int i = input.lastIndexOf(NUMBER_SIGN_CHAR);
|
||||
if (i >= 0) {
|
||||
builder.fragment(percentDecoder.decode(input.substring(i + 1)));
|
||||
builder.fragment(builder.percentDecoder.decode(input.substring(i + 1)));
|
||||
input = input.substring(0, i);
|
||||
}
|
||||
i = input.indexOf(QUESTION_CHAR);
|
||||
|
@ -1006,7 +1041,8 @@ public class URL implements Serializable {
|
|||
Pair<String, String> pathWithMatrixElem = indexOf(SEMICOLON_CHAR, t);
|
||||
String matrixElem = pathWithMatrixElem.getFirst();
|
||||
Pair<String, String> p = indexOf(EQUAL_CHAR, matrixElem);
|
||||
builder.matrixParam(percentDecoder.decode(p.getFirst()), percentDecoder.decode(p.getSecond()));
|
||||
builder.matrixParam(builder.percentDecoder.decode(p.getFirst()),
|
||||
builder.percentDecoder.decode(p.getSecond()));
|
||||
t = pathWithMatrixElem.getSecond();
|
||||
}
|
||||
} else {
|
||||
|
@ -1016,10 +1052,11 @@ public class URL implements Serializable {
|
|||
Pair<String, String> pathWithMatrixElem = indexOf(SEMICOLON_CHAR, t);
|
||||
String segment = pathWithMatrixElem.getFirst();
|
||||
if (i == 0) {
|
||||
builder.pathSegment(percentDecoder.decode(segment));
|
||||
builder.pathSegment(builder.percentDecoder.decode(segment));
|
||||
} else {
|
||||
Pair<String, String> p = indexOf(EQUAL_CHAR, segment);
|
||||
builder.matrixParam(percentDecoder.decode(p.getFirst()), percentDecoder.decode(p.getSecond()));
|
||||
builder.matrixParam(builder.percentDecoder.decode(p.getFirst()),
|
||||
builder.percentDecoder.decode(p.getSecond()));
|
||||
}
|
||||
t = pathWithMatrixElem.getSecond();
|
||||
i++;
|
||||
|
@ -1033,7 +1070,8 @@ public class URL implements Serializable {
|
|||
}
|
||||
}
|
||||
|
||||
private void parseQuery(Builder builder, String query) throws CharacterCodingException {
|
||||
private void parseQuery(Builder builder, String query)
|
||||
throws MalformedInputException, UnmappableCharacterException {
|
||||
if (query == null) {
|
||||
return;
|
||||
}
|
||||
|
@ -1042,18 +1080,19 @@ public class URL implements Serializable {
|
|||
Pair<String, String> p = indexOf(AMPERSAND_CHAR, s);
|
||||
Pair<String, String> param = indexOf(EQUAL_CHAR, p.getFirst());
|
||||
if (!isNullOrEmpty(param.getFirst())) {
|
||||
builder.queryParam(percentDecoder.decode(param.getFirst()), percentDecoder.decode(param.getSecond()));
|
||||
builder.queryParam(builder.percentDecoder.decode(param.getFirst()),
|
||||
builder.percentDecoder.decode(param.getSecond()));
|
||||
}
|
||||
s = p.getSecond();
|
||||
}
|
||||
if (builder.queryParams.isEmpty()) {
|
||||
builder.query(percentDecoder.decode(query));
|
||||
builder.query(builder.percentDecoder.decode(query));
|
||||
} else {
|
||||
builder.query(query);
|
||||
}
|
||||
}
|
||||
|
||||
Pair<String, String> indexOf(char ch, String input) {
|
||||
private Pair<String, String> indexOf(char ch, String input) {
|
||||
int i = input.indexOf(ch);
|
||||
String k = i >= 0 ? input.substring(0, i) : input;
|
||||
String v = i >= 0 ? input.substring(i + 1) : null;
|
||||
|
@ -1062,7 +1101,8 @@ public class URL implements Serializable {
|
|||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* The URL resolver class is an embedded class for resolving a relative URL specification to
|
||||
* a base URL.
|
||||
*/
|
||||
public static class Resolver {
|
||||
|
||||
|
@ -1072,27 +1112,23 @@ public class URL implements Serializable {
|
|||
this.base = base;
|
||||
}
|
||||
|
||||
public URL resolve(String relative) {
|
||||
public URL resolve(String relative) throws URLSyntaxException {
|
||||
if (relative == null) {
|
||||
return null;
|
||||
}
|
||||
if (relative.isEmpty()) {
|
||||
return base;
|
||||
}
|
||||
try {
|
||||
URL url = parser().parse(relative);
|
||||
return url != null ? resolve(url) : null;
|
||||
} catch (CharacterCodingException e) {
|
||||
throw new IllegalArgumentException(e);
|
||||
}
|
||||
return resolve(url);
|
||||
}
|
||||
|
||||
public URL resolve(URL relative) throws CharacterCodingException {
|
||||
if (relative == null) {
|
||||
return null;
|
||||
public URL resolve(URL relative) throws URLSyntaxException {
|
||||
if (relative == null || relative == INVALID) {
|
||||
throw new URLSyntaxException("relative URL is invalid");
|
||||
}
|
||||
if (!base.isAbsolute()) {
|
||||
throw new IllegalArgumentException("base is not absolute");
|
||||
throw new URLSyntaxException("base URL is not absolute");
|
||||
}
|
||||
Builder builder = new Builder();
|
||||
if (relative.isOpaque()) {
|
||||
|
|
|
@ -3,15 +3,15 @@ package org.xbib.net;
|
|||
/**
|
||||
*
|
||||
*/
|
||||
public class IRISyntaxException extends RuntimeException {
|
||||
public class URLSyntaxException extends Exception {
|
||||
|
||||
private static final long serialVersionUID = 1813084470937980392L;
|
||||
|
||||
IRISyntaxException(String message) {
|
||||
URLSyntaxException(String message) {
|
||||
super(message);
|
||||
}
|
||||
|
||||
IRISyntaxException(Throwable cause) {
|
||||
URLSyntaxException(Throwable cause) {
|
||||
super(cause);
|
||||
}
|
||||
|
|
@ -1,26 +0,0 @@
|
|||
package org.xbib.net.internal;
|
||||
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* A simple LRU cache, based on a {@link LinkedHashMap}.
|
||||
*
|
||||
* @param <K> the key type parameter
|
||||
* @param <V> the vale type parameter
|
||||
*/
|
||||
public class LRUCache<K, V> extends LinkedHashMap<K, V> {
|
||||
|
||||
private static final long serialVersionUID = -2795566703268944901L;
|
||||
|
||||
private final int cacheSize;
|
||||
|
||||
public LRUCache(int cacheSize) {
|
||||
super(16, 0.75f, true);
|
||||
this.cacheSize = cacheSize;
|
||||
}
|
||||
|
||||
protected boolean removeEldestEntry(Map.Entry<K, V> eldest) {
|
||||
return size() >= cacheSize;
|
||||
}
|
||||
}
|
|
@ -1,4 +0,0 @@
|
|||
/**
|
||||
* Classes for internal use in the {@code org.xbib.net} package.
|
||||
*/
|
||||
package org.xbib.net.internal;
|
|
@ -1,11 +1,11 @@
|
|||
package org.xbib.net.path;
|
||||
|
||||
import org.xbib.net.QueryParameters;
|
||||
import org.xbib.net.internal.LRUCache;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.Comparator;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.StringTokenizer;
|
||||
|
@ -16,9 +16,11 @@ public class PathMatcher {
|
|||
|
||||
private static final String DEFAULT_PATH_SEPARATOR = "/";
|
||||
|
||||
private final Map<String, List<String>> tokenizedPatternCache = Collections.synchronizedMap(new LRUCache<>(1024));
|
||||
private final Map<String, List<String>> tokenizedPatternCache =
|
||||
Collections.synchronizedMap(new LRUCache<>(1024));
|
||||
|
||||
private final Map<String, PathStringMatcher> stringMatcherCache = Collections.synchronizedMap(new LRUCache<>(1024));
|
||||
private final Map<String, PathStringMatcher> stringMatcherCache =
|
||||
Collections.synchronizedMap(new LRUCache<>(1024));
|
||||
|
||||
private String pathSeparator;
|
||||
|
||||
|
@ -28,8 +30,6 @@ public class PathMatcher {
|
|||
|
||||
private boolean trimTokens = true;
|
||||
|
||||
private volatile boolean cachePatterns = true;
|
||||
|
||||
public PathMatcher() {
|
||||
this(DEFAULT_PATH_SEPARATOR);
|
||||
}
|
||||
|
@ -60,10 +60,6 @@ public class PathMatcher {
|
|||
return queryParameters;
|
||||
}
|
||||
|
||||
public void setCachePatterns(boolean cachePatterns) {
|
||||
this.cachePatterns = cachePatterns;
|
||||
}
|
||||
|
||||
public Map<String, PathStringMatcher> stringMatcherCache() {
|
||||
return stringMatcherCache;
|
||||
}
|
||||
|
@ -274,9 +270,7 @@ public class PathMatcher {
|
|||
}
|
||||
|
||||
private List<String> tokenizePattern(String pattern) {
|
||||
return cachePatterns ?
|
||||
tokenizedPatternCache.computeIfAbsent(pattern, this::tokenizePath) :
|
||||
tokenizePath(pattern);
|
||||
return tokenizedPatternCache.computeIfAbsent(pattern, this::tokenizePath);
|
||||
}
|
||||
|
||||
private List<String> tokenizePath(String path) {
|
||||
|
@ -306,8 +300,28 @@ public class PathMatcher {
|
|||
}
|
||||
|
||||
private PathStringMatcher getStringMatcher(String pattern) {
|
||||
return cachePatterns ?
|
||||
stringMatcherCache.computeIfAbsent(pattern, p -> new PathStringMatcher(p, this.caseSensitive)) :
|
||||
new PathStringMatcher(pattern, this.caseSensitive);
|
||||
return stringMatcherCache.computeIfAbsent(pattern, p -> new PathStringMatcher(p, this.caseSensitive));
|
||||
}
|
||||
|
||||
/**
|
||||
* A simple LRU cache, based on a {@link LinkedHashMap}.
|
||||
*
|
||||
* @param <K> the key type parameter
|
||||
* @param <V> the vale type parameter
|
||||
*/
|
||||
private static class LRUCache<K, V> extends LinkedHashMap<K, V> {
|
||||
|
||||
private static final long serialVersionUID = -2795566703268944901L;
|
||||
|
||||
private final int cacheSize;
|
||||
|
||||
LRUCache(int cacheSize) {
|
||||
super(16, 0.75f, true);
|
||||
this.cacheSize = cacheSize;
|
||||
}
|
||||
|
||||
protected boolean removeEldestEntry(Map.Entry<K, V> eldest) {
|
||||
return size() >= cacheSize;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -3,7 +3,6 @@ package org.xbib.net.scheme;
|
|||
/**
|
||||
* The mailto scheme.
|
||||
*
|
||||
* @see <a href="https://tools.ietf.org/html/rfc2368">mailto RFC</a>
|
||||
*/
|
||||
public class MailtoScheme extends AbstractScheme {
|
||||
|
||||
|
|
|
@ -261,6 +261,13 @@ public class URLBuilderTest {
|
|||
assertEquals("http://foo.com?q%23%2B", s);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testNewBuilder() {
|
||||
URL.Builder builder = URL.from("http://google.com:8008/foobar").newBuilder();
|
||||
builder.scheme("https");
|
||||
assertEquals("https://google.com:8008/foobar", builder.build().toString());
|
||||
}
|
||||
|
||||
private void assertUrl(String urlString, String expected) throws Exception {
|
||||
assertEquals(expected, urlString);
|
||||
assertEquals(expected, URL.from(urlString).toExternalForm());
|
||||
|
|
|
@ -15,17 +15,17 @@ public class URLParserTest {
|
|||
|
||||
@Test
|
||||
public void testNull() {
|
||||
assertNull(URL.from(null));
|
||||
assertEquals(URL.INVALID, URL.from(null));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testEmpty() {
|
||||
assertNull(URL.from(""));
|
||||
assertEquals(URL.INVALID, URL.from(""));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testNewline() {
|
||||
assertNull(URL.from("\n"));
|
||||
assertEquals(URL.INVALID, URL.from("\n"));
|
||||
}
|
||||
|
||||
@Test(expected = IllegalArgumentException.class)
|
||||
|
|
|
@ -4,17 +4,34 @@ import org.junit.Test;
|
|||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
|
||||
import java.net.URI;
|
||||
|
||||
/**
|
||||
*/
|
||||
public class URLResolverTest {
|
||||
|
||||
@Test
|
||||
public void testResolve() throws Exception {
|
||||
URL base = URL.create("http://example.org/foo/");
|
||||
public void testResolveURI() throws Exception {
|
||||
URI base = URI.create("http://example.org/foo");
|
||||
assertEquals("http://example.org/", base.resolve("/").toString());
|
||||
resolve("http://foo.bar", "foobar", "http://foo.bar/foobar");
|
||||
resolve("http://foo.bar/", "foobar", "http://foo.bar/foobar");
|
||||
resolve("http://foo.bar/foobar", "foobar", "http://foo.bar/foobar");
|
||||
assertEquals("http://example.org/foobar", base.resolve("/foobar").toString());
|
||||
assertEquals("http://example.org/foobar", base.resolve("foobar").toString());
|
||||
base = URI.create("http://example.org/foo/");
|
||||
assertEquals("http://example.org/", base.resolve("/").toString());
|
||||
assertEquals("http://example.org/foobar", base.resolve("/foobar").toString());
|
||||
assertEquals("http://example.org/foo/foobar", base.resolve("foobar").toString());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testResolveURL() throws Exception {
|
||||
URL base = URL.create("http://example.org/foo");
|
||||
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());
|
||||
base = URL.create("http://example.org/foo/");
|
||||
assertEquals("http://example.org/", base.resolve("/").toString());
|
||||
assertEquals("http://example.org/foobar", base.resolve("/foobar").toString());
|
||||
assertEquals("http://example.org/foo/foobar", base.resolve("foobar").toString());
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@ -69,7 +86,7 @@ public class URLResolverTest {
|
|||
resolve("http://a/b/c/d;p?q", "http:", "http:");
|
||||
}
|
||||
|
||||
private void resolve(String inputBase, String relative, String expected) {
|
||||
private void resolve(String inputBase, String relative, String expected) throws URLSyntaxException {
|
||||
assertEquals(expected, URL.base(inputBase).resolve(relative).toExternalForm());
|
||||
}
|
||||
}
|
||||
|
|
|
@ -37,8 +37,8 @@ public class URLTest {
|
|||
}
|
||||
} else {
|
||||
if (base != null && input != null) {
|
||||
try {
|
||||
URL url = URL.base(base).resolve(input);
|
||||
if (url != null) {
|
||||
System.err.println("resolved: " + url.toString());
|
||||
if (test.protocol != null) {
|
||||
assertEquals(test.protocol, url.getScheme() + ":");
|
||||
|
@ -54,8 +54,8 @@ public class URLTest {
|
|||
// assertEquals(test.pathname, url.getPath());
|
||||
//}
|
||||
System.err.println("passed: " + base + " " + input);
|
||||
} else {
|
||||
System.err.println("unable to resolve: " + base + " " + input);
|
||||
} catch (URLSyntaxException e) {
|
||||
System.err.println("unable to resolve: " + base + " " + input + " reason: " + e.getMessage());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -453,7 +453,7 @@ public class PathMatcherTest {
|
|||
@Test
|
||||
public void patternComparatorSort() {
|
||||
Comparator<String> comparator = pathMatcher.getPatternComparator("/hotels/new");
|
||||
List<String> paths = new ArrayList<String>(3);
|
||||
List<String> paths = new ArrayList<>(3);
|
||||
paths.add(null);
|
||||
paths.add("/hotels/new");
|
||||
paths.sort(comparator);
|
||||
|
@ -561,13 +561,6 @@ public class PathMatcherTest {
|
|||
assertTrue(pathMatcher.match("/Group/{groupName}/Members", "/group/Sales/members"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void cachePatternsSetToFalse() {
|
||||
pathMatcher.setCachePatterns(false);
|
||||
match();
|
||||
assertTrue(pathMatcher.stringMatcherCache().isEmpty());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void extensionMappingWithDotPathSeparator() {
|
||||
pathMatcher.setPathSeparator(".");
|
||||
|
|
Loading…
Reference in a new issue