add IRI implementation
This commit is contained in:
parent
99ba51369d
commit
cdc4639347
21 changed files with 15531 additions and 225 deletions
|
@ -1,5 +1,5 @@
|
|||
group = org.xbib
|
||||
name = net
|
||||
version = 3.0.0
|
||||
version = 3.0.1
|
||||
|
||||
org.gradle.warning.mode = ALL
|
||||
|
|
3
net-resource/NOTICE.txt
Normal file
3
net-resource/NOTICE.txt
Normal file
|
@ -0,0 +1,3 @@
|
|||
This IRI implementation is taken from Daniel Fuchs' writeup for java.net.IRI
|
||||
|
||||
http://cr.openjdk.java.net/%7Edfuchs/writeups/updating-uri/
|
4
net-resource/src/main/java/module-info.java
Normal file
4
net-resource/src/main/java/module-info.java
Normal file
|
@ -0,0 +1,4 @@
|
|||
|
||||
module org.xbib.net.resource {
|
||||
exports org.xbib.net.resource;
|
||||
}
|
|
@ -0,0 +1,287 @@
|
|||
/*
|
||||
* Copyright (c) 2004, 2005, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package org.xbib.net.resource;
|
||||
|
||||
public class IPAddressUtil {
|
||||
private final static int INADDR4SZ = 4;
|
||||
private final static int INADDR16SZ = 16;
|
||||
private final static int INT16SZ = 2;
|
||||
|
||||
/*
|
||||
* Converts IPv4 address in its textual presentation form
|
||||
* into its numeric binary form.
|
||||
*
|
||||
* @param src a String representing an IPv4 address in standard format
|
||||
* @return a byte array representing the IPv4 numeric address
|
||||
*/
|
||||
@SuppressWarnings("fallthrough")
|
||||
public static byte[] textToNumericFormatV4(String src)
|
||||
{
|
||||
byte[] res = new byte[INADDR4SZ];
|
||||
|
||||
long tmpValue = 0;
|
||||
int currByte = 0;
|
||||
|
||||
int len = src.length();
|
||||
if (len == 0 || len > 15) {
|
||||
return null;
|
||||
}
|
||||
/*
|
||||
* When only one part is given, the value is stored directly in
|
||||
* the network address without any byte rearrangement.
|
||||
*
|
||||
* When a two part address is supplied, the last part is
|
||||
* interpreted as a 24-bit quantity and placed in the right
|
||||
* most three bytes of the network address. This makes the
|
||||
* two part address format convenient for specifying Class A
|
||||
* network addresses as net.host.
|
||||
*
|
||||
* When a three part address is specified, the last part is
|
||||
* interpreted as a 16-bit quantity and placed in the right
|
||||
* most two bytes of the network address. This makes the
|
||||
* three part address format convenient for specifying
|
||||
* Class B net- work addresses as 128.net.host.
|
||||
*
|
||||
* When four parts are specified, each is interpreted as a
|
||||
* byte of data and assigned, from left to right, to the
|
||||
* four bytes of an IPv4 address.
|
||||
*
|
||||
* We determine and parse the leading parts, if any, as single
|
||||
* byte values in one pass directly into the resulting byte[],
|
||||
* then the remainder is treated as a 8-to-32-bit entity and
|
||||
* translated into the remaining bytes in the array.
|
||||
*/
|
||||
for (int i = 0; i < len; i++) {
|
||||
char c = src.charAt(i);
|
||||
if (c == '.') {
|
||||
if (tmpValue < 0 || tmpValue > 0xff || currByte == 3) {
|
||||
return null;
|
||||
}
|
||||
res[currByte++] = (byte) (tmpValue & 0xff);
|
||||
tmpValue = 0;
|
||||
} else {
|
||||
int digit = Character.digit(c, 10);
|
||||
if (digit < 0) {
|
||||
return null;
|
||||
}
|
||||
tmpValue *= 10;
|
||||
tmpValue += digit;
|
||||
}
|
||||
}
|
||||
if (tmpValue < 0 || tmpValue >= (1L << ((4 - currByte) * 8))) {
|
||||
return null;
|
||||
}
|
||||
switch (currByte) {
|
||||
case 0:
|
||||
res[0] = (byte) ((tmpValue >> 24) & 0xff);
|
||||
case 1:
|
||||
res[1] = (byte) ((tmpValue >> 16) & 0xff);
|
||||
case 2:
|
||||
res[2] = (byte) ((tmpValue >> 8) & 0xff);
|
||||
case 3:
|
||||
res[3] = (byte) ((tmpValue >> 0) & 0xff);
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
/*
|
||||
* Convert IPv6 presentation level address to network order binary form.
|
||||
* credit:
|
||||
* Converted from C code from Solaris 8 (inet_pton)
|
||||
*
|
||||
* Any component of the string following a per-cent % is ignored.
|
||||
*
|
||||
* @param src a String representing an IPv6 address in textual format
|
||||
* @return a byte array representing the IPv6 numeric address
|
||||
*/
|
||||
public static byte[] textToNumericFormatV6(String src)
|
||||
{
|
||||
// Shortest valid string is "::", hence at least 2 chars
|
||||
if (src.length() < 2) {
|
||||
return null;
|
||||
}
|
||||
|
||||
int colonp;
|
||||
char ch;
|
||||
boolean saw_xdigit;
|
||||
int val;
|
||||
char[] srcb = src.toCharArray();
|
||||
byte[] dst = new byte[INADDR16SZ];
|
||||
|
||||
int srcb_length = srcb.length;
|
||||
int pc = src.indexOf ("%");
|
||||
if (pc == srcb_length -1) {
|
||||
return null;
|
||||
}
|
||||
|
||||
if (pc != -1) {
|
||||
srcb_length = pc;
|
||||
}
|
||||
|
||||
colonp = -1;
|
||||
int i = 0, j = 0;
|
||||
/* Leading :: requires some special handling. */
|
||||
if (srcb[i] == ':')
|
||||
if (srcb[++i] != ':')
|
||||
return null;
|
||||
int curtok = i;
|
||||
saw_xdigit = false;
|
||||
val = 0;
|
||||
while (i < srcb_length) {
|
||||
ch = srcb[i++];
|
||||
int chval = Character.digit(ch, 16);
|
||||
if (chval != -1) {
|
||||
val <<= 4;
|
||||
val |= chval;
|
||||
if (val > 0xffff)
|
||||
return null;
|
||||
saw_xdigit = true;
|
||||
continue;
|
||||
}
|
||||
if (ch == ':') {
|
||||
curtok = i;
|
||||
if (!saw_xdigit) {
|
||||
if (colonp != -1)
|
||||
return null;
|
||||
colonp = j;
|
||||
continue;
|
||||
} else if (i == srcb_length) {
|
||||
return null;
|
||||
}
|
||||
if (j + INT16SZ > INADDR16SZ)
|
||||
return null;
|
||||
dst[j++] = (byte) ((val >> 8) & 0xff);
|
||||
dst[j++] = (byte) (val & 0xff);
|
||||
saw_xdigit = false;
|
||||
val = 0;
|
||||
continue;
|
||||
}
|
||||
if (ch == '.' && ((j + INADDR4SZ) <= INADDR16SZ)) {
|
||||
String ia4 = src.substring(curtok, srcb_length);
|
||||
/* check this IPv4 address has 3 dots, ie. A.B.C.D */
|
||||
int dot_count = 0, index=0;
|
||||
while ((index = ia4.indexOf ('.', index)) != -1) {
|
||||
dot_count ++;
|
||||
index ++;
|
||||
}
|
||||
if (dot_count != 3) {
|
||||
return null;
|
||||
}
|
||||
byte[] v4addr = textToNumericFormatV4(ia4);
|
||||
if (v4addr == null) {
|
||||
return null;
|
||||
}
|
||||
for (int k = 0; k < INADDR4SZ; k++) {
|
||||
dst[j++] = v4addr[k];
|
||||
}
|
||||
saw_xdigit = false;
|
||||
break; /* '\0' was seen by inet_pton4(). */
|
||||
}
|
||||
return null;
|
||||
}
|
||||
if (saw_xdigit) {
|
||||
if (j + INT16SZ > INADDR16SZ)
|
||||
return null;
|
||||
dst[j++] = (byte) ((val >> 8) & 0xff);
|
||||
dst[j++] = (byte) (val & 0xff);
|
||||
}
|
||||
|
||||
if (colonp != -1) {
|
||||
int n = j - colonp;
|
||||
|
||||
if (j == INADDR16SZ)
|
||||
return null;
|
||||
for (i = 1; i <= n; i++) {
|
||||
dst[INADDR16SZ - i] = dst[colonp + n - i];
|
||||
dst[colonp + n - i] = 0;
|
||||
}
|
||||
j = INADDR16SZ;
|
||||
}
|
||||
if (j != INADDR16SZ)
|
||||
return null;
|
||||
byte[] newdst = convertFromIPv4MappedAddress(dst);
|
||||
if (newdst != null) {
|
||||
return newdst;
|
||||
} else {
|
||||
return dst;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param src a String representing an IPv4 address in textual format
|
||||
* @return a boolean indicating whether src is an IPv4 literal address
|
||||
*/
|
||||
public static boolean isIPv4LiteralAddress(String src) {
|
||||
return textToNumericFormatV4(src) != null;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param src a String representing an IPv6 address in textual format
|
||||
* @return a boolean indicating whether src is an IPv6 literal address
|
||||
*/
|
||||
public static boolean isIPv6LiteralAddress(String src) {
|
||||
return textToNumericFormatV6(src) != null;
|
||||
}
|
||||
|
||||
/*
|
||||
* Convert IPv4-Mapped address to IPv4 address. Both input and
|
||||
* returned value are in network order binary form.
|
||||
*
|
||||
* @param src a String representing an IPv4-Mapped address in textual format
|
||||
* @return a byte array representing the IPv4 numeric address
|
||||
*/
|
||||
public static byte[] convertFromIPv4MappedAddress(byte[] addr) {
|
||||
if (isIPv4MappedAddress(addr)) {
|
||||
byte[] newAddr = new byte[INADDR4SZ];
|
||||
System.arraycopy(addr, 12, newAddr, 0, INADDR4SZ);
|
||||
return newAddr;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Utility routine to check if the InetAddress is an
|
||||
* IPv4 mapped IPv6 address.
|
||||
*
|
||||
* @return a <code>boolean</code> indicating if the InetAddress is
|
||||
* an IPv4 mapped IPv6 address; or false if address is IPv4 address.
|
||||
*/
|
||||
private static boolean isIPv4MappedAddress(byte[] addr) {
|
||||
if (addr.length < INADDR16SZ) {
|
||||
return false;
|
||||
}
|
||||
if ((addr[0] == 0x00) && (addr[1] == 0x00) &&
|
||||
(addr[2] == 0x00) && (addr[3] == 0x00) &&
|
||||
(addr[4] == 0x00) && (addr[5] == 0x00) &&
|
||||
(addr[6] == 0x00) && (addr[7] == 0x00) &&
|
||||
(addr[8] == 0x00) && (addr[9] == 0x00) &&
|
||||
(addr[10] == (byte)0xff) &&
|
||||
(addr[11] == (byte)0xff)) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
5780
net-resource/src/main/java/org/xbib/net/resource/IRI.java
Normal file
5780
net-resource/src/main/java/org/xbib/net/resource/IRI.java
Normal file
File diff suppressed because it is too large
Load diff
|
@ -0,0 +1,204 @@
|
|||
/*
|
||||
* Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package org.xbib.net.resource;
|
||||
|
||||
/**
|
||||
* Represents an abstract Resource Identifier reference.
|
||||
*
|
||||
* <p> The particular conformance with any standards, parsing and construction
|
||||
* behaviour, and operational aspects of the Resource Identifier are specified
|
||||
* by a concrete subtype. This class does not have a public accessible
|
||||
* constructor, therefore the only valid subtypes are those that are defined
|
||||
* by the Java Platform. The only known subtypes are {@link URI} ( that conforms
|
||||
* to the obsoleted <i>RFC 2396</i>) and {@link IRI} ( that conforms to the
|
||||
* more recent <i>RFC 3986 / STD 66</i> and <i>RFC 3987</i> ).
|
||||
*
|
||||
* <p> The components of the Resource Identifier are retrievable through the
|
||||
* methods of this class. Both the raw and decoded forms of the components are
|
||||
* retrievable. The raw form of a component is the value of the component
|
||||
* without any interpretation or conversation. The decoded form of a component
|
||||
* is the value of the raw form after a single decoding pass that decodes UTF-8
|
||||
* percent-encoded triplets. A concrete subtype will further define the specific
|
||||
* set of allowable characters within each component.
|
||||
*
|
||||
*/
|
||||
public abstract class ResourceIdentifier {
|
||||
|
||||
/* package-private */ ResourceIdentifier() { }
|
||||
|
||||
/**
|
||||
* Tells whether or not this resource identifier is absolute.
|
||||
*
|
||||
* <p> A resource identifier is absolute if, and only if, it has a
|
||||
* scheme component.
|
||||
*
|
||||
* @return {@code true} if, and only if, this resource identifier
|
||||
* is absolute
|
||||
*/
|
||||
public abstract boolean isAbsolute();
|
||||
|
||||
/**
|
||||
* Tells whether or not this resource identifier is considered opaque.
|
||||
*
|
||||
* @return {@code true} if, and only if, this resource identifier
|
||||
* is considered opaque
|
||||
*/
|
||||
public abstract boolean isOpaque();
|
||||
|
||||
/**
|
||||
* Returns the scheme component of this resource identifier.
|
||||
*
|
||||
* @return The scheme component of this resource identifier,
|
||||
* or {@code null} if the scheme is undefined
|
||||
*/
|
||||
public abstract String getScheme();
|
||||
|
||||
/**
|
||||
* Returns the raw authority component of this resource identifier.
|
||||
*
|
||||
* @return The raw authority component of this resource identifier,
|
||||
* or {@code null} if the authority is undefined
|
||||
*/
|
||||
public abstract String getRawAuthority();
|
||||
|
||||
/**
|
||||
* Returns the decoded authority component of this resource identifier.
|
||||
*
|
||||
* @return The decoded authority component of this resource identifier,
|
||||
* or {@code null} if the authority is undefined
|
||||
*/
|
||||
public abstract String getAuthority();
|
||||
|
||||
/**
|
||||
* Returns the raw user-information component of this resource identifier.
|
||||
*
|
||||
* @return The raw user-information component of this resource identifier,
|
||||
* or {@code null} if the user information is undefined
|
||||
*/
|
||||
public abstract String getRawUserInfo();
|
||||
|
||||
/**
|
||||
* Returns the decoded user-information component of this resource identifier.
|
||||
*
|
||||
* @return The decoded user-information component of this resource identifier,
|
||||
* or {@code null} if the user information is undefined
|
||||
*/
|
||||
public abstract String getUserInfo();
|
||||
|
||||
/**
|
||||
* Returns the host component of this resource identifier.
|
||||
*
|
||||
* @return The host component of this resource identifier,
|
||||
* or {@code null} if the host is undefined, or does
|
||||
* not parse as a syntactically valid internet name.
|
||||
*/
|
||||
public abstract String getHost();
|
||||
|
||||
/**
|
||||
* Returns the port number of this resource identifier.
|
||||
*
|
||||
* @return The port component of this resource identifier,
|
||||
* or {@code -1} if the port is undefined
|
||||
*/
|
||||
public abstract int getPort();
|
||||
|
||||
/**
|
||||
* Returns the raw path component of this resource identifier.
|
||||
*
|
||||
* @apiNote
|
||||
*
|
||||
* Different subclasses may return {@code null} on different
|
||||
* conditions. For instance {@code java.net.URI} will always
|
||||
* return {@code null} if the URI is opaque, while {@code
|
||||
* java.net.IRI} will simply return the opaque path.
|
||||
*
|
||||
* @return The path component of this resource identifier,
|
||||
* or {@code null} if the path is undefined
|
||||
*/
|
||||
public abstract String getRawPath();
|
||||
|
||||
/**
|
||||
* Returns the decoded path component of this resource identifier.
|
||||
*
|
||||
* @apiNote
|
||||
*
|
||||
* Different subclasses may return {@code null} on different
|
||||
* conditions. For instance {@code java.net.URI} will always
|
||||
* return {@code null} if the URI is opaque, while {@code
|
||||
* java.net.IRI} will simply return the decoded opaque path.
|
||||
*
|
||||
* @return The decoded path component of this resource identifier,
|
||||
* or {@code null} if the path is undefined
|
||||
*/
|
||||
public abstract String getPath();
|
||||
|
||||
/**
|
||||
* Returns the raw query component of this resource identifier.
|
||||
*
|
||||
* @return The raw query component of this resource identifier,
|
||||
* or {@code null} if the query is undefined
|
||||
*/
|
||||
public abstract String getRawQuery();
|
||||
|
||||
/**
|
||||
* Returns the decoded query component of this resource identifier.
|
||||
*
|
||||
* @apiNote
|
||||
*
|
||||
* Different subclasses may return {@code null} on different
|
||||
* conditions. For instance {@code java.net.URI} will always
|
||||
* return {@code null} if the URI is opaque.
|
||||
*
|
||||
* @return The decoded query component of this resource identifier,
|
||||
* or {@code null} if the query is undefined
|
||||
*/
|
||||
public abstract String getQuery();
|
||||
|
||||
/**
|
||||
* Returns the raw fragment component of this resource identifier.
|
||||
*
|
||||
* @return The raw fragment component of this resource identifier,
|
||||
* or {@code null} if the fragment is undefined
|
||||
*/
|
||||
public abstract String getRawFragment();
|
||||
|
||||
/**
|
||||
* Returns the decoded fragment component of this resource identifier.
|
||||
*
|
||||
* @return The decoded fragment component of this URresource identifierI,
|
||||
* or {@code null} if the fragment is undefined
|
||||
*/
|
||||
public abstract String getFragment();
|
||||
|
||||
/**
|
||||
* Returns the content of this resource identifier as a US-ASCII string.
|
||||
*
|
||||
* @return The string form of this resource identifier, encoded as needed
|
||||
* so that it only contains characters in the US-ASCII charset
|
||||
*/
|
||||
public abstract String toASCIIString();
|
||||
|
||||
}
|
|
@ -0,0 +1,136 @@
|
|||
/*
|
||||
* Copyright (c) 2001, 2011, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
|
||||
package org.xbib.net.resource;
|
||||
|
||||
import java.nio.charset.*;
|
||||
|
||||
|
||||
/**
|
||||
* Utility class for caching per-thread decoders and encoders.
|
||||
*/
|
||||
|
||||
public class ThreadLocalCoders {
|
||||
|
||||
private static final int CACHE_SIZE = 3;
|
||||
|
||||
private static abstract class Cache {
|
||||
|
||||
// Thread-local reference to array of cached objects, in LRU order
|
||||
private final ThreadLocal<Object[]> cache = new ThreadLocal<>();
|
||||
private final int size;
|
||||
|
||||
Cache(int size) {
|
||||
this.size = size;
|
||||
}
|
||||
|
||||
abstract Object create(Object name);
|
||||
|
||||
private void moveToFront(Object[] oa, int i) {
|
||||
Object ob = oa[i];
|
||||
for (int j = i; j > 0; j--)
|
||||
oa[j] = oa[j - 1];
|
||||
oa[0] = ob;
|
||||
}
|
||||
|
||||
abstract boolean hasName(Object ob, Object name);
|
||||
|
||||
Object forName(Object name) {
|
||||
Object[] oa = cache.get();
|
||||
if (oa == null) {
|
||||
oa = new Object[size];
|
||||
cache.set(oa);
|
||||
} else {
|
||||
for (int i = 0; i < oa.length; i++) {
|
||||
Object ob = oa[i];
|
||||
if (ob == null)
|
||||
continue;
|
||||
if (hasName(ob, name)) {
|
||||
if (i > 0)
|
||||
moveToFront(oa, i);
|
||||
return ob;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Create a new object
|
||||
Object ob = create(name);
|
||||
oa[oa.length - 1] = ob;
|
||||
moveToFront(oa, oa.length - 1);
|
||||
return ob;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private static Cache decoderCache = new Cache(CACHE_SIZE) {
|
||||
boolean hasName(Object ob, Object name) {
|
||||
if (name instanceof String)
|
||||
return (((CharsetDecoder)ob).charset().name().equals(name));
|
||||
if (name instanceof Charset)
|
||||
return ((CharsetDecoder)ob).charset().equals(name);
|
||||
return false;
|
||||
}
|
||||
Object create(Object name) {
|
||||
if (name instanceof String)
|
||||
return Charset.forName((String)name).newDecoder();
|
||||
if (name instanceof Charset)
|
||||
return ((Charset)name).newDecoder();
|
||||
assert false;
|
||||
return null;
|
||||
}
|
||||
};
|
||||
|
||||
public static CharsetDecoder decoderFor(Object name) {
|
||||
CharsetDecoder cd = (CharsetDecoder)decoderCache.forName(name);
|
||||
cd.reset();
|
||||
return cd;
|
||||
}
|
||||
|
||||
private static Cache encoderCache = new Cache(CACHE_SIZE) {
|
||||
boolean hasName(Object ob, Object name) {
|
||||
if (name instanceof String)
|
||||
return (((CharsetEncoder)ob).charset().name().equals(name));
|
||||
if (name instanceof Charset)
|
||||
return ((CharsetEncoder)ob).charset().equals(name);
|
||||
return false;
|
||||
}
|
||||
Object create(Object name) {
|
||||
if (name instanceof String)
|
||||
return Charset.forName((String)name).newEncoder();
|
||||
if (name instanceof Charset)
|
||||
return ((Charset)name).newEncoder();
|
||||
assert false;
|
||||
return null;
|
||||
}
|
||||
};
|
||||
|
||||
public static CharsetEncoder encoderFor(Object name) {
|
||||
CharsetEncoder ce = (CharsetEncoder)encoderCache.forName(name);
|
||||
ce.reset();
|
||||
return ce;
|
||||
}
|
||||
|
||||
}
|
3726
net-resource/src/main/java/org/xbib/net/resource/URI.java
Normal file
3726
net-resource/src/main/java/org/xbib/net/resource/URI.java
Normal file
File diff suppressed because it is too large
Load diff
1074
net-resource/src/test/java/org/xbib/net/resource/BuilderTest.java
Normal file
1074
net-resource/src/test/java/org/xbib/net/resource/BuilderTest.java
Normal file
File diff suppressed because it is too large
Load diff
|
@ -0,0 +1,186 @@
|
|||
package org.xbib.net.resource;/*
|
||||
* Copyright (c) 2002, 2019, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @test
|
||||
* @bug 4768755 4677045 8147462
|
||||
* @summary URL.equal(URL) is inconsistent for opaque IRI.toURL()
|
||||
* and new URL(IRI.toString)
|
||||
* IRI.toURL() does not always work as specified
|
||||
* Ensure URIs representing invalid/malformed URLs throw similar
|
||||
* exception with new URL(IRI.toString()) and IRI.toURL()
|
||||
*/
|
||||
|
||||
import java.net.MalformedURLException;
|
||||
import java.net.URL;
|
||||
|
||||
public class IRItoURLTest {
|
||||
|
||||
public static void main(String args[]) throws Exception {
|
||||
|
||||
URL classUrl = new URL("jrt:/java.base/java/lang/Object.class");
|
||||
|
||||
String[] uris = {
|
||||
"mailto:xyz@abc.de",
|
||||
"file:xyz#ab",
|
||||
"http:abc/xyz/pqr",
|
||||
"http:abc/xyz/pqr?id=x%0a&ca=true",
|
||||
"file:/C:/v700/dev/unitTesting/tests/apiUtil/uri",
|
||||
"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(),
|
||||
};
|
||||
|
||||
// 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 isURLFailed = false;
|
||||
|
||||
for (String uriString : uris) {
|
||||
IRI uri = IRI.of(uriString);
|
||||
|
||||
URL url1 = new URL(uri.toString());
|
||||
URL url2 = uri.toURL();
|
||||
System.out.println("Testing URI " + uri);
|
||||
|
||||
if (!url1.equals(url2)) {
|
||||
System.out.println("equals() FAILED");
|
||||
isURLFailed = true;
|
||||
}
|
||||
if (url1.hashCode() != url2.hashCode()) {
|
||||
System.out.println("hashCode() DIDN'T MATCH");
|
||||
isURLFailed = true;
|
||||
}
|
||||
if (!url1.sameFile(url2)) {
|
||||
System.out.println("sameFile() FAILED");
|
||||
isURLFailed = true;
|
||||
}
|
||||
|
||||
if (!equalsComponents("getPath()", url1.getPath(),
|
||||
url2.getPath())) {
|
||||
isURLFailed = true;
|
||||
}
|
||||
if (!equalsComponents("getFile()", url1.getFile(),
|
||||
url2.getFile())) {
|
||||
isURLFailed = true;
|
||||
}
|
||||
if (!equalsComponents("getHost()", url1.getHost(),
|
||||
url2.getHost())) {
|
||||
isURLFailed = true;
|
||||
}
|
||||
if (!equalsComponents("getAuthority()",
|
||||
url1.getAuthority(), url2.getAuthority())) {
|
||||
isURLFailed = true;
|
||||
}
|
||||
if (!equalsComponents("getRef()", url1.getRef(),
|
||||
url2.getRef())) {
|
||||
isURLFailed = true;
|
||||
}
|
||||
if (!equalsComponents("getUserInfo()", url1.getUserInfo(),
|
||||
url2.getUserInfo())) {
|
||||
isURLFailed = true;
|
||||
}
|
||||
if (!equalsComponents("toString()", url1.toString(),
|
||||
url2.toString())) {
|
||||
isURLFailed = true;
|
||||
}
|
||||
|
||||
if (isURLFailed) {
|
||||
isTestFailed = true;
|
||||
} else {
|
||||
System.out.println("PASSED ..");
|
||||
}
|
||||
System.out.println();
|
||||
isURLFailed = false;
|
||||
}
|
||||
for (String malformedUrl : malformedUrls) {
|
||||
Exception toURLEx = null;
|
||||
Exception newURLEx = null;
|
||||
try {
|
||||
IRI.parseIRI(malformedUrl).toURL();
|
||||
} catch (Exception e) {
|
||||
// expected
|
||||
toURLEx = e;
|
||||
}
|
||||
try {
|
||||
new URL(IRI.parseIRI(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 {
|
||||
IRI.parseIRI(illegalUri).toURL();
|
||||
} catch (IllegalArgumentException e) {
|
||||
// pass
|
||||
}
|
||||
|
||||
try {
|
||||
new URL(illegalUri);
|
||||
} catch (MalformedURLException e) {
|
||||
// pass
|
||||
}
|
||||
}
|
||||
if (isTestFailed) {
|
||||
throw new Exception("URI.toURL() test failed");
|
||||
}
|
||||
}
|
||||
|
||||
static boolean equalsComponents(String method, String comp1, String comp2) {
|
||||
if ((comp1 != null) && (!comp1.equals(comp2))) {
|
||||
System.out.println(method + " DIDN'T MATCH" +
|
||||
" ===>");
|
||||
System.out.println(" URL(URI.toString()) returns:" + comp1);
|
||||
System.out.println(" URI.toURL() returns:" + comp2);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,61 @@
|
|||
package org.xbib.net.resource;
|
||||
/*
|
||||
* Copyright (c) 2003, 2019 Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
/**
|
||||
* @test
|
||||
* @bug 4866303
|
||||
* @summary URI.resolve escapes characters in parameter URI
|
||||
*/
|
||||
|
||||
import java.io.File;
|
||||
import java.net.URISyntaxException;
|
||||
import java.util.Objects;
|
||||
|
||||
public class RelativeEncoding {
|
||||
public static void main(String[] args) {
|
||||
try {
|
||||
IRI one = IRI.parseIRI("Relative%20with%20spaces");
|
||||
// TODO: add a File.toIRI() method?
|
||||
IRI two = IRI.parseIRI((new File("/tmp/dir with spaces/File with spaces")).toURI().toString());
|
||||
IRI three = two.resolve(one);
|
||||
if (three.isOpaque())
|
||||
throw new RuntimeException("Bad encoding on IRI.resolve: should not be opaque");
|
||||
System.out.println(String.format("resolved path is: \"%s\" [\"%s\"]",
|
||||
three.getPath(), three.getRawPath()));
|
||||
checkEquals("/tmp/dir with spaces/Relative with spaces",
|
||||
three.getPath(), "path");
|
||||
checkEquals("/tmp/dir%20with%20spaces/Relative%20with%20spaces",
|
||||
three.getRawPath(), "raw path");
|
||||
} catch (URISyntaxException e) {
|
||||
throw new RuntimeException("Unexpected exception: " + e);
|
||||
}
|
||||
}
|
||||
|
||||
static void checkEquals(String expected, String found, String name) {
|
||||
if (!Objects.equals(expected, found)) {
|
||||
throw new RuntimeException(
|
||||
String.format("Unexpected %s: \"%s\"\n\t expected \"%s\"",
|
||||
name, found, expected));
|
||||
}
|
||||
}
|
||||
}
|
3894
net-resource/src/test/java/org/xbib/net/resource/Test.java
Normal file
3894
net-resource/src/test/java/org/xbib/net/resource/Test.java
Normal file
File diff suppressed because it is too large
Load diff
|
@ -1,8 +0,0 @@
|
|||
package org.xbib.net;
|
||||
|
||||
public interface Context<Req, Resp> {
|
||||
|
||||
Req request();
|
||||
|
||||
Resp response();
|
||||
}
|
|
@ -1,10 +0,0 @@
|
|||
package org.xbib.net;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
@SuppressWarnings("rawtypes")
|
||||
@FunctionalInterface
|
||||
public interface Handler<C extends Context> {
|
||||
|
||||
void handle(C context) throws IOException;
|
||||
}
|
|
@ -1,21 +0,0 @@
|
|||
package org.xbib.net;
|
||||
|
||||
@SuppressWarnings("serial")
|
||||
public class HandlerException extends RuntimeException {
|
||||
|
||||
public HandlerException() {
|
||||
super();
|
||||
}
|
||||
|
||||
public HandlerException(String message) {
|
||||
super(message);
|
||||
}
|
||||
|
||||
public HandlerException(Exception e) {
|
||||
super(e);
|
||||
}
|
||||
|
||||
public HandlerException(String message, Exception e) {
|
||||
super(message, e);
|
||||
}
|
||||
}
|
|
@ -8,6 +8,7 @@ import java.net.URISyntaxException;
|
|||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
import org.xbib.net.scheme.Scheme;
|
||||
import org.xbib.net.scheme.SchemeRegistry;
|
||||
import org.xbib.net.util.CharUtils;
|
||||
|
|
|
@ -38,10 +38,7 @@ import java.util.Objects;
|
|||
* 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();
|
||||
* --
|
||||
*
|
||||
*/
|
||||
public class URL implements Comparable<URL> {
|
||||
|
|
|
@ -1,176 +0,0 @@
|
|||
package org.xbib.net;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import java.text.Normalizer;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
import static org.junit.jupiter.api.Assertions.assertNotEquals;
|
||||
|
||||
class IRITest {
|
||||
|
||||
@Test
|
||||
void testIpv4() {
|
||||
URL iri = URL.create("http://127.0.0.1");
|
||||
assertEquals("http://127.0.0.1", iri.toExternalForm());
|
||||
}
|
||||
|
||||
@Test
|
||||
void testIpv6() {
|
||||
URL iri = URL.from("http://[2001:0db8:85a3:08d3:1319:8a2e:0370:7344]");
|
||||
assertEquals(iri.getProtocolVersion(), ProtocolVersion.IPV6);
|
||||
assertEquals("http://[2001:db8:85a3:8d3:1319:8a2e:370:7344]", iri.toString());
|
||||
}
|
||||
|
||||
@Test
|
||||
void testIpv6Invalid() {
|
||||
URL iri = URL.from("http://[2001:0db8:85a3:08d3:1319:8a2e:0370:734o]");
|
||||
assertEquals(URL.nullUrl(), iri);
|
||||
}
|
||||
|
||||
@Test
|
||||
void testSimple() {
|
||||
URL iri = URL.create("http://validator.w3.org/check?uri=http%3A%2F%2Fr\u00E9sum\u00E9.example.org");
|
||||
assertEquals("http://validator.w3.org/check?uri=http%3A%2F%2Fr\u00E9sum\u00E9.example.org", iri.toString());
|
||||
}
|
||||
|
||||
@Test
|
||||
void testFile() throws Exception {
|
||||
URL iri = URL.create("file:///tmp/test/foo");
|
||||
assertEquals("", iri.getHost());
|
||||
assertEquals("/tmp/test/foo", iri.getPath());
|
||||
assertEquals("file:///tmp/test/foo", iri.toExternalForm());
|
||||
assertEquals("file:///tmp/test/foo", iri.toString());
|
||||
}
|
||||
|
||||
@Test
|
||||
void testSimple2() throws Exception {
|
||||
URL iri = URL.create("http://www.example.org/red%09ros\u00E9#red");
|
||||
assertEquals("http://www.example.org/red%09ros%C3%A9#red", iri.toExternalForm());
|
||||
}
|
||||
|
||||
@Test
|
||||
void testNotSoSimple() throws Exception {
|
||||
URL iri = URL.create("http://example.com/\uD800\uDF00\uD800\uDF01\uD800\uDF02");
|
||||
assertEquals("http://example.com/%F0%90%8C%80%F0%90%8C%81%F0%90%8C%82", iri.toExternalForm());
|
||||
}
|
||||
|
||||
@Test
|
||||
void testIRItoURI() throws Exception {
|
||||
URL iri = URL.from("http://\u7D0D\u8C46.example.org/%E2%80%AE");
|
||||
assertEquals("http://xn--99zt52a.example.org/%E2%80%AE", iri.toExternalForm());
|
||||
}
|
||||
|
||||
@Test
|
||||
void testComparison() {
|
||||
URL url1 = URL.create("http://www.example.org/");
|
||||
URL url2 = URL.create("http://www.example.org/..");
|
||||
URL url3 = URL.create("http://www.Example.org:80");
|
||||
assertNotEquals(url1, url2);
|
||||
assertNotEquals(url1, url3);
|
||||
assertNotEquals(url2, url1);
|
||||
assertNotEquals(url2, url3);
|
||||
assertNotEquals(url3, url1);
|
||||
assertNotEquals(url3, url2);
|
||||
assertEquals(url1.normalize(), url2.normalize());
|
||||
assertEquals(url1.normalize(), url3.normalize());
|
||||
assertEquals(url2.normalize(), url1.normalize());
|
||||
assertEquals(url2.normalize(), url3.normalize());
|
||||
assertEquals(url3.normalize(), url1.normalize());
|
||||
assertEquals(url3.normalize(), url2.normalize());
|
||||
}
|
||||
|
||||
@Test
|
||||
void testUCN() {
|
||||
URL iri1 = URL.create("http://www.example.org/r\u00E9sum\u00E9.html");
|
||||
String s = Normalizer.normalize("http://www.example.org/re\u0301sume\u0301.html", Normalizer.Form.NFC);
|
||||
URL iri2 = URL.create(s);
|
||||
assertEquals(iri2, iri1);
|
||||
}
|
||||
|
||||
@Test
|
||||
void testNormalizePath() {
|
||||
URL iri1 = URL.create("http://example.org/%7e%2Fuser%2f");
|
||||
URL iri2 = URL.create("http://example.org/%7E%2fuser/");
|
||||
assertEquals(iri1.normalize(), iri2.normalize());
|
||||
}
|
||||
|
||||
@Test
|
||||
void testIDN() {
|
||||
URL iri1 = URL.from("http://r\u00E9sum\u00E9.example.org");
|
||||
assertEquals("xn--rsum-bpad.example.org", iri1.getHost());
|
||||
}
|
||||
|
||||
@Test
|
||||
void testResolveRelative() {
|
||||
URL base = URL.create("http://example.org/foo/");
|
||||
assertEquals("http://example.org/", base.resolve("/").toString());
|
||||
assertEquals("http://example.org/test", base.resolve("/test").toString());
|
||||
assertEquals("http://example.org/foo/test", base.resolve("test").toString());
|
||||
assertEquals("http://example.org/test", base.resolve("../test").toString());
|
||||
assertEquals("http://example.org/foo/test", base.resolve("./test").toString());
|
||||
assertEquals("http://example.org/foo/", base.resolve("test/test/../../").toString());
|
||||
assertEquals("http://example.org/foo/?test", base.resolve("?test").toString());
|
||||
assertEquals("http://example.org/foo/#test", base.resolve("#test").toString());
|
||||
assertEquals("http://example.org/foo/", base.resolve(".").toString());
|
||||
}
|
||||
|
||||
@Test
|
||||
void testSchemes() {
|
||||
URL iri = URL.create("http://a:b@c.org:80/d/e?f#g");
|
||||
assertEquals("http", iri.getScheme());
|
||||
assertEquals("a:b", iri.getUserInfo());
|
||||
assertEquals("c.org", iri.getHost());
|
||||
assertEquals(Integer.valueOf(80), iri.getPort());
|
||||
assertEquals("/d/e", iri.getPath());
|
||||
assertEquals("f", iri.getQuery());
|
||||
assertEquals("g", iri.getFragment());
|
||||
iri = URL.create("https://a:b@c.org:80/d/e?f#g");
|
||||
assertEquals("https", iri.getScheme());
|
||||
assertEquals("a:b", iri.getUserInfo());
|
||||
assertEquals("c.org", iri.getHost());
|
||||
assertEquals(Integer.valueOf(80), iri.getPort());
|
||||
assertEquals("/d/e", iri.getPath());
|
||||
assertEquals("f", iri.getQuery());
|
||||
assertEquals("g", iri.getFragment());
|
||||
iri = URL.create("ftp://a:b@c.org:80/d/e?f#g");
|
||||
assertEquals("ftp", iri.getScheme());
|
||||
assertEquals("a:b", iri.getUserInfo());
|
||||
assertEquals("c.org", iri.getHost());
|
||||
assertEquals(Integer.valueOf(80), iri.getPort());
|
||||
assertEquals("/d/e", iri.getPath());
|
||||
assertEquals("f", iri.getQuery());
|
||||
assertEquals("g", iri.getFragment());
|
||||
iri = URL.create("mailto:joe@example.org?subject=foo");
|
||||
assertEquals("mailto", iri.getScheme());
|
||||
assertEquals(null, iri.getUserInfo());
|
||||
assertEquals(null, iri.getHost());
|
||||
assertEquals(null, iri.getPort());
|
||||
assertEquals("joe@example.org?subject=foo", iri.getSchemeSpecificPart());
|
||||
assertEquals(null, iri.getFragment());
|
||||
iri = URL.create("tag:example.org,2006:foo");
|
||||
assertEquals("tag", iri.getScheme());
|
||||
assertEquals(null, iri.getUserInfo());
|
||||
assertEquals(null, iri.getHost());
|
||||
assertEquals(null, iri.getPort());
|
||||
assertEquals("example.org,2006:foo", iri.getSchemeSpecificPart());
|
||||
assertEquals(null, iri.getQuery());
|
||||
assertEquals(null, iri.getFragment());
|
||||
iri = URL.create("urn:lsid:ibm.com:example:82437234964354895798234d");
|
||||
assertEquals("urn", iri.getScheme());
|
||||
assertEquals(null, iri.getUserInfo());
|
||||
assertEquals(null, iri.getHost());
|
||||
assertEquals(null, iri.getPort());
|
||||
assertEquals("lsid:ibm.com:example:82437234964354895798234d", iri.getSchemeSpecificPart());
|
||||
assertEquals(null, iri.getQuery());
|
||||
assertEquals(null, iri.getFragment());
|
||||
iri = URL.create("data:image/gif;base64,R0lGODdhMAAwAPAAAAAAAP");
|
||||
assertEquals("data", iri.getScheme());
|
||||
assertEquals(null, iri.getUserInfo());
|
||||
assertEquals(null, iri.getHost());
|
||||
assertEquals(null, iri.getPort());
|
||||
assertEquals("image/gif;base64,R0lGODdhMAAwAPAAAAAAAP", iri.getSchemeSpecificPart());
|
||||
assertEquals(null, iri.getQuery());
|
||||
assertEquals(null, iri.getFragment());
|
||||
}
|
||||
}
|
|
@ -6,10 +6,12 @@ import com.fasterxml.jackson.databind.ObjectMapper;
|
|||
import com.fasterxml.jackson.databind.ObjectReader;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import java.text.Normalizer;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
import static org.junit.jupiter.api.Assertions.assertNotEquals;
|
||||
import static org.junit.jupiter.api.Assertions.fail;
|
||||
|
||||
class URLTest {
|
||||
|
@ -116,4 +118,168 @@ class URLTest {
|
|||
boolean skip;
|
||||
}
|
||||
|
||||
@Test
|
||||
void testIpv4() {
|
||||
URL iri = URL.create("http://127.0.0.1");
|
||||
assertEquals("http://127.0.0.1", iri.toExternalForm());
|
||||
}
|
||||
|
||||
@Test
|
||||
void testIpv6() {
|
||||
URL iri = URL.from("http://[2001:0db8:85a3:08d3:1319:8a2e:0370:7344]");
|
||||
assertEquals(iri.getProtocolVersion(), ProtocolVersion.IPV6);
|
||||
assertEquals("http://[2001:db8:85a3:8d3:1319:8a2e:370:7344]", iri.toString());
|
||||
}
|
||||
|
||||
@Test
|
||||
void testIpv6Invalid() {
|
||||
URL iri = URL.from("http://[2001:0db8:85a3:08d3:1319:8a2e:0370:734o]");
|
||||
assertEquals(URL.nullUrl(), iri);
|
||||
}
|
||||
|
||||
@Test
|
||||
void testSimple() {
|
||||
URL iri = URL.create("http://validator.w3.org/check?uri=http%3A%2F%2Fr\u00E9sum\u00E9.example.org");
|
||||
assertEquals("http://validator.w3.org/check?uri=http%3A%2F%2Fr\u00E9sum\u00E9.example.org", iri.toString());
|
||||
}
|
||||
|
||||
@Test
|
||||
void testFile() throws Exception {
|
||||
URL iri = URL.create("file:///tmp/test/foo");
|
||||
assertEquals("", iri.getHost());
|
||||
assertEquals("/tmp/test/foo", iri.getPath());
|
||||
assertEquals("file:///tmp/test/foo", iri.toExternalForm());
|
||||
assertEquals("file:///tmp/test/foo", iri.toString());
|
||||
}
|
||||
|
||||
@Test
|
||||
void testSimple2() throws Exception {
|
||||
URL iri = URL.create("http://www.example.org/red%09ros\u00E9#red");
|
||||
assertEquals("http://www.example.org/red%09ros%C3%A9#red", iri.toExternalForm());
|
||||
}
|
||||
|
||||
@Test
|
||||
void testNotSoSimple() throws Exception {
|
||||
URL iri = URL.create("http://example.com/\uD800\uDF00\uD800\uDF01\uD800\uDF02");
|
||||
assertEquals("http://example.com/%F0%90%8C%80%F0%90%8C%81%F0%90%8C%82", iri.toExternalForm());
|
||||
}
|
||||
|
||||
@Test
|
||||
void testIRItoURI() throws Exception {
|
||||
URL iri = URL.from("http://\u7D0D\u8C46.example.org/%E2%80%AE");
|
||||
assertEquals("http://xn--99zt52a.example.org/%E2%80%AE", iri.toExternalForm());
|
||||
}
|
||||
|
||||
@Test
|
||||
void testComparison() {
|
||||
URL url1 = URL.create("http://www.example.org/");
|
||||
URL url2 = URL.create("http://www.example.org/..");
|
||||
URL url3 = URL.create("http://www.Example.org:80");
|
||||
assertNotEquals(url1, url2);
|
||||
assertNotEquals(url1, url3);
|
||||
assertNotEquals(url2, url1);
|
||||
assertNotEquals(url2, url3);
|
||||
assertNotEquals(url3, url1);
|
||||
assertNotEquals(url3, url2);
|
||||
assertEquals(url1.normalize(), url2.normalize());
|
||||
assertEquals(url1.normalize(), url3.normalize());
|
||||
assertEquals(url2.normalize(), url1.normalize());
|
||||
assertEquals(url2.normalize(), url3.normalize());
|
||||
assertEquals(url3.normalize(), url1.normalize());
|
||||
assertEquals(url3.normalize(), url2.normalize());
|
||||
}
|
||||
|
||||
@Test
|
||||
void testUCN() {
|
||||
URL iri1 = URL.create("http://www.example.org/r\u00E9sum\u00E9.html");
|
||||
String s = Normalizer.normalize("http://www.example.org/re\u0301sume\u0301.html", Normalizer.Form.NFC);
|
||||
URL iri2 = URL.create(s);
|
||||
assertEquals(iri2, iri1);
|
||||
}
|
||||
|
||||
@Test
|
||||
void testNormalizePath() {
|
||||
URL iri1 = URL.create("http://example.org/%7e%2Fuser%2f");
|
||||
URL iri2 = URL.create("http://example.org/%7E%2fuser/");
|
||||
assertEquals(iri1.normalize(), iri2.normalize());
|
||||
}
|
||||
|
||||
@Test
|
||||
void testIDN() {
|
||||
URL iri1 = URL.from("http://r\u00E9sum\u00E9.example.org");
|
||||
assertEquals("xn--rsum-bpad.example.org", iri1.getHost());
|
||||
}
|
||||
|
||||
@Test
|
||||
void testResolveRelative() {
|
||||
URL base = URL.create("http://example.org/foo/");
|
||||
assertEquals("http://example.org/", base.resolve("/").toString());
|
||||
assertEquals("http://example.org/test", base.resolve("/test").toString());
|
||||
assertEquals("http://example.org/foo/test", base.resolve("test").toString());
|
||||
assertEquals("http://example.org/test", base.resolve("../test").toString());
|
||||
assertEquals("http://example.org/foo/test", base.resolve("./test").toString());
|
||||
assertEquals("http://example.org/foo/", base.resolve("test/test/../../").toString());
|
||||
assertEquals("http://example.org/foo/?test", base.resolve("?test").toString());
|
||||
assertEquals("http://example.org/foo/#test", base.resolve("#test").toString());
|
||||
assertEquals("http://example.org/foo/", base.resolve(".").toString());
|
||||
}
|
||||
|
||||
@Test
|
||||
void testSchemes() {
|
||||
URL iri = URL.create("http://a:b@c.org:80/d/e?f#g");
|
||||
assertEquals("http", iri.getScheme());
|
||||
assertEquals("a:b", iri.getUserInfo());
|
||||
assertEquals("c.org", iri.getHost());
|
||||
assertEquals(Integer.valueOf(80), iri.getPort());
|
||||
assertEquals("/d/e", iri.getPath());
|
||||
assertEquals("f", iri.getQuery());
|
||||
assertEquals("g", iri.getFragment());
|
||||
iri = URL.create("https://a:b@c.org:80/d/e?f#g");
|
||||
assertEquals("https", iri.getScheme());
|
||||
assertEquals("a:b", iri.getUserInfo());
|
||||
assertEquals("c.org", iri.getHost());
|
||||
assertEquals(Integer.valueOf(80), iri.getPort());
|
||||
assertEquals("/d/e", iri.getPath());
|
||||
assertEquals("f", iri.getQuery());
|
||||
assertEquals("g", iri.getFragment());
|
||||
iri = URL.create("ftp://a:b@c.org:80/d/e?f#g");
|
||||
assertEquals("ftp", iri.getScheme());
|
||||
assertEquals("a:b", iri.getUserInfo());
|
||||
assertEquals("c.org", iri.getHost());
|
||||
assertEquals(Integer.valueOf(80), iri.getPort());
|
||||
assertEquals("/d/e", iri.getPath());
|
||||
assertEquals("f", iri.getQuery());
|
||||
assertEquals("g", iri.getFragment());
|
||||
iri = URL.create("mailto:joe@example.org?subject=foo");
|
||||
assertEquals("mailto", iri.getScheme());
|
||||
assertEquals(null, iri.getUserInfo());
|
||||
assertEquals(null, iri.getHost());
|
||||
assertEquals(null, iri.getPort());
|
||||
assertEquals("joe@example.org?subject=foo", iri.getSchemeSpecificPart());
|
||||
assertEquals(null, iri.getFragment());
|
||||
iri = URL.create("tag:example.org,2006:foo");
|
||||
assertEquals("tag", iri.getScheme());
|
||||
assertEquals(null, iri.getUserInfo());
|
||||
assertEquals(null, iri.getHost());
|
||||
assertEquals(null, iri.getPort());
|
||||
assertEquals("example.org,2006:foo", iri.getSchemeSpecificPart());
|
||||
assertEquals(null, iri.getQuery());
|
||||
assertEquals(null, iri.getFragment());
|
||||
iri = URL.create("urn:lsid:ibm.com:example:82437234964354895798234d");
|
||||
assertEquals("urn", iri.getScheme());
|
||||
assertEquals(null, iri.getUserInfo());
|
||||
assertEquals(null, iri.getHost());
|
||||
assertEquals(null, iri.getPort());
|
||||
assertEquals("lsid:ibm.com:example:82437234964354895798234d", iri.getSchemeSpecificPart());
|
||||
assertEquals(null, iri.getQuery());
|
||||
assertEquals(null, iri.getFragment());
|
||||
iri = URL.create("data:image/gif;base64,R0lGODdhMAAwAPAAAAAAAP");
|
||||
assertEquals("data", iri.getScheme());
|
||||
assertEquals(null, iri.getUserInfo());
|
||||
assertEquals(null, iri.getHost());
|
||||
assertEquals(null, iri.getPort());
|
||||
assertEquals("image/gif;base64,R0lGODdhMAAwAPAAAAAAAP", iri.getSchemeSpecificPart());
|
||||
assertEquals(null, iri.getQuery());
|
||||
assertEquals(null, iri.getFragment());
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,14 +1,16 @@
|
|||
package org.xbib.net;
|
||||
package org.xbib.net.resource;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.xbib.net.IRI;
|
||||
|
||||
import java.net.URI;
|
||||
import java.net.URISyntaxException;
|
||||
import org.junit.jupiter.api.Disabled;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
import static org.junit.jupiter.api.Assertions.assertFalse;
|
||||
import static org.junit.jupiter.api.Assertions.assertNotEquals;
|
||||
|
||||
@Disabled
|
||||
public class OtherIRITest {
|
||||
class IRITest {
|
||||
|
||||
@Test
|
||||
public void testSimple() throws Exception {
|
||||
|
@ -199,4 +201,3 @@ public class OtherIRITest {
|
|||
|
||||
}
|
||||
}
|
||||
|
|
@ -23,6 +23,7 @@ include 'net'
|
|||
include 'net-bouncycastle'
|
||||
include 'net-mime'
|
||||
include 'net-path'
|
||||
include 'net-resource'
|
||||
include 'net-security'
|
||||
include 'net-socket'
|
||||
include 'benchmark'
|
||||
|
|
Loading…
Reference in a new issue