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
|
group = org.xbib
|
||||||
name = net
|
name = net
|
||||||
version = 3.0.0
|
version = 3.0.1
|
||||||
|
|
||||||
org.gradle.warning.mode = ALL
|
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.nio.charset.StandardCharsets;
|
||||||
import java.util.regex.Matcher;
|
import java.util.regex.Matcher;
|
||||||
import java.util.regex.Pattern;
|
import java.util.regex.Pattern;
|
||||||
|
|
||||||
import org.xbib.net.scheme.Scheme;
|
import org.xbib.net.scheme.Scheme;
|
||||||
import org.xbib.net.scheme.SchemeRegistry;
|
import org.xbib.net.scheme.SchemeRegistry;
|
||||||
import org.xbib.net.util.CharUtils;
|
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
|
* The reason for the name {@code URL} is merely because of the popularity of the name, which
|
||||||
* overweighs the URI or IRI popularity.
|
* overweighs the URI or IRI popularity.
|
||||||
*
|
*
|
||||||
* [source,java]
|
|
||||||
* --
|
|
||||||
* URL url = URL.http().resolveFromHost("google.com").build();
|
* URL url = URL.http().resolveFromHost("google.com").build();
|
||||||
* --
|
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
public class URL implements Comparable<URL> {
|
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 com.fasterxml.jackson.databind.ObjectReader;
|
||||||
import org.junit.jupiter.api.Test;
|
import org.junit.jupiter.api.Test;
|
||||||
|
|
||||||
|
import java.text.Normalizer;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||||
|
import static org.junit.jupiter.api.Assertions.assertNotEquals;
|
||||||
import static org.junit.jupiter.api.Assertions.fail;
|
import static org.junit.jupiter.api.Assertions.fail;
|
||||||
|
|
||||||
class URLTest {
|
class URLTest {
|
||||||
|
@ -116,4 +118,168 @@ class URLTest {
|
||||||
boolean skip;
|
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.URI;
|
||||||
import java.net.URISyntaxException;
|
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.assertEquals;
|
||||||
import static org.junit.jupiter.api.Assertions.assertFalse;
|
import static org.junit.jupiter.api.Assertions.assertFalse;
|
||||||
|
import static org.junit.jupiter.api.Assertions.assertNotEquals;
|
||||||
|
|
||||||
@Disabled
|
class IRITest {
|
||||||
public class OtherIRITest {
|
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testSimple() throws Exception {
|
public void testSimple() throws Exception {
|
||||||
|
@ -199,4 +201,3 @@ public class OtherIRITest {
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -23,6 +23,7 @@ include 'net'
|
||||||
include 'net-bouncycastle'
|
include 'net-bouncycastle'
|
||||||
include 'net-mime'
|
include 'net-mime'
|
||||||
include 'net-path'
|
include 'net-path'
|
||||||
|
include 'net-resource'
|
||||||
include 'net-security'
|
include 'net-security'
|
||||||
include 'net-socket'
|
include 'net-socket'
|
||||||
include 'benchmark'
|
include 'benchmark'
|
||||||
|
|
Loading…
Reference in a new issue