Skip to content
Commits on Source (3)
wildfly-common (1.4.0-1) unstable; urgency=medium
* New upstream version 1.4.0.
-- Markus Koschany <apo@debian.org> Tue, 15 May 2018 14:53:05 +0200
wildfly-common (1.3.2-1) unstable; urgency=medium
* New upstream version 1.3.2.
......
......@@ -25,7 +25,7 @@
<groupId>org.wildfly.common</groupId>
<artifactId>wildfly-common</artifactId>
<version>1.3.2.Final</version>
<version>1.4.0.Final</version>
<parent>
<groupId>org.jboss</groupId>
......@@ -197,6 +197,9 @@
<configuration>
<archive>
<manifestFile>${project.build.outputDirectory}/META-INF/MANIFEST.MF</manifestFile>
<manifestEntries>
<Multi-Release>true</Multi-Release>
</manifestEntries>
</archive>
</configuration>
</plugin>
......
......@@ -80,6 +80,9 @@ public interface CommonMessages {
@Message(id = 12, value = "Invalid address length of %d; must be 4 or 16")
IllegalArgumentException invalidAddressBytes(int length);
@Message(id = 13, value = "Invalid address string \"%s\"")
IllegalArgumentException invalidAddress(String address);
// execution path validation
@Message(id = 100, value = "Method \"%s\" of class \"%s\" is not implemented")
......
......@@ -277,6 +277,54 @@ public final class Functions {
return new ExceptionConsumerRunnable<T, E>(consumer, param);
}
/**
* Get a consumer which discards the values it is given.
*
* @param <T> the parameter type
* @return the discarding consumer
*/
@SuppressWarnings("unchecked")
public static <T> Consumer<T> discardingConsumer() {
return DiscardingConsumer.INSTANCE;
}
/**
* Get a consumer which discards the values it is given.
*
* @param <T> the parameter type
* @param <E> the exception type
* @return the discarding consumer
*/
@SuppressWarnings("unchecked")
public static <T, E extends Exception> ExceptionConsumer<T, E> discardingExceptionConsumer() {
return DiscardingConsumer.INSTANCE;
}
/**
* Get a consumer which discards the values it is given.
*
* @param <T> the first parameter type
* @param <U> the second parameter type
* @return the discarding consumer
*/
@SuppressWarnings("unchecked")
public static <T, U> BiConsumer<T, U> discardingBiConsumer() {
return DiscardingBiConsumer.INSTANCE;
}
/**
* Get a consumer which discards the values it is given.
*
* @param <T> the first parameter type
* @param <U> the second parameter type
* @param <E> the exception type
* @return the discarding consumer
*/
@SuppressWarnings("unchecked")
public static <T, U, E extends Exception> ExceptionBiConsumer<T, U, E> discardingExceptionBiConsumer() {
return DiscardingBiConsumer.INSTANCE;
}
static class RunnableConsumer implements Consumer<Runnable> {
static final Consumer<Runnable> INSTANCE = new RunnableConsumer();
......@@ -512,4 +560,24 @@ public final class Functions {
return String.format("%s(%s)", consumer, param);
}
}
static class DiscardingConsumer<T, E extends Exception> implements Consumer<T>, ExceptionConsumer<T, E> {
static final DiscardingConsumer INSTANCE = new DiscardingConsumer();
private DiscardingConsumer() {
}
public void accept(final T t) {
}
}
static class DiscardingBiConsumer<T, U, E extends Exception> implements BiConsumer<T, U>, ExceptionBiConsumer<T, U, E> {
static final DiscardingBiConsumer INSTANCE = new DiscardingBiConsumer();
private DiscardingBiConsumer() {
}
public void accept(final T t, final U u) {
}
}
}
......@@ -18,6 +18,8 @@
package org.wildfly.common.math;
import org.wildfly.common.Assert;
/**
* Routines which are useful for hashcode computation, among other things.
*
......@@ -30,6 +32,18 @@ public final class HashMath {
private HashMath() {
}
/**
* Round the given value up to the next positive power of two.
*
* @param value the value (must not be negative and must be less than or equal to {@code 2^31})
* @return the rounded power of two value
*/
public static int roundToPowerOfTwo(int value) {
Assert.checkMinimumParameter("value", 0, value);
Assert.checkMaximumParameter("value", 0x4000_0000, value);
return value <= 1 ? value : Integer.highestOneBit(value - 1) << 1;
}
/**
* A hash function which combines an accumulated hash with a next hash such that {@code f(f(k, p2, b), p1, a) ≠ₙ f(f(k, p1, a), p2, b)}.
* This function is suitable for object chains whose order affects the overall equality of the hash code.
......
......@@ -20,12 +20,14 @@ package org.wildfly.common.net;
import static java.security.AccessController.doPrivileged;
import java.lang.reflect.Array;
import java.net.Inet4Address;
import java.net.Inet6Address;
import java.net.InetAddress;
import java.net.InetSocketAddress;
import java.net.NetworkInterface;
import java.net.SocketException;
import java.net.URI;
import java.net.UnknownHostException;
import java.nio.ByteBuffer;
import java.security.PrivilegedAction;
......@@ -97,6 +99,51 @@ public final class Inet {
}
}
/**
* Get a string representation of the given address which is suitable for use as the host component of a URL.
*
* @param inetAddress the address (must not be {@code null})
* @param useHostNameIfPresent {@code true} to preserve the host name string in the address, {@code false} to always give
* an IP address string
* @return the string representation (not {@code null})
*/
public static String toURLString(InetAddress inetAddress, boolean useHostNameIfPresent) {
Assert.checkNotNullParam("inetAddress", inetAddress);
if (useHostNameIfPresent) {
final String hostName = getHostNameIfResolved(inetAddress);
if (hostName != null) {
if (inetAddress instanceof Inet6Address && isInet6Address(hostName)) {
return "[" + hostName + "]";
} else {
// return it even if it's an IP address or whatever
return hostName;
}
}
}
if (inetAddress instanceof Inet6Address) {
return "[" + toOptimalString(inetAddress) + "]";
} else {
return toOptimalString(inetAddress);
}
}
/**
* Get a string representation of the given address bytes which is suitable for use as the host component of a URL.
*
* @param addressBytes the address bytes (must not be {@code null})
* @return the string representation (not {@code null})
*/
public static String toURLString(byte[] addressBytes) {
Assert.checkNotNullParam("addressBytes", addressBytes);
if (addressBytes.length == 4) {
return (addressBytes[0] & 0xff) + "." + (addressBytes[1] & 0xff) + "." + (addressBytes[2] & 0xff) + "." + (addressBytes[3] & 0xff);
} else if (addressBytes.length == 16) {
return "[" + toOptimalStringV6(addressBytes) + "]";
} else {
throw CommonMessages.msg.invalidAddressBytes(addressBytes.length);
}
}
/**
* Get the IPv6 equivalent of the given address. If the address is IPv4 then it is returned as a compatibility
* address.
......@@ -139,6 +186,142 @@ public final class Inet {
return hostString;
}
/**
* Get a resolved socket address from the given URI.
*
* @param uri the URI (must not be {@code null})
* @param defaultPort the default port to use if none is given (must be in the range {@code 1 ≤ n ≤ 65535}
* @param addressType the class of the {@code InetAddress} to search for (must not be {@code null})
* @return the socket address, or {@code null} if the URI does not have a host component
* @throws UnknownHostException if address resolution failed
*/
public static InetSocketAddress getResolved(URI uri, int defaultPort, Class<? extends InetAddress> addressType) throws UnknownHostException {
Assert.checkNotNullParam("uri", uri);
Assert.checkMinimumParameter("defaultPort", 1, defaultPort);
Assert.checkMaximumParameter("defaultPort", 65535, defaultPort);
Assert.checkNotNullParam("addressType", addressType);
final String uriHost = uri.getHost();
if (uriHost == null) {
return null;
}
final InetAddress resolved = getAddressByNameAndType(uriHost, addressType);
final int uriPort = uri.getPort();
return uriPort != - 1 ? new InetSocketAddress(resolved, uriPort) : new InetSocketAddress(resolved, defaultPort);
}
/**
* Get the resolved socket address from the given URI.
*
* @param uri the URI (must not be {@code null})
* @param defaultPort the default port to use if none is given (must be in the range {@code 1 ≤ n ≤ 65535}
* @return the socket address, or {@code null} if the URI does not have a host component
* @throws UnknownHostException if address resolution failed
*/
public static InetSocketAddress getResolved(URI uri, int defaultPort) throws UnknownHostException {
return getResolved(uri, defaultPort, InetAddress.class);
}
/**
* Get a copy of the given socket address, but with a resolved address component.
*
* @param address the (possibly unresolved) address (must not be {@code null})
* @return the resolved address (not {@code null})
* @throws UnknownHostException if address resolution failed
*/
public static InetSocketAddress getResolved(InetSocketAddress address) throws UnknownHostException {
return getResolved(address, InetAddress.class);
}
/**
* Get a copy of the given socket address, but with a resolved address component of the given type.
*
* @param address the (possibly unresolved) address (must not be {@code null})
* @param addressType the class of the {@code InetAddress} to search for (must not be {@code null})
* @return the resolved address (not {@code null})
* @throws UnknownHostException if address resolution failed, or if no addresses of the given type were found, or
* if the given address was already resolved but is not of the given address type
*/
public static InetSocketAddress getResolved(InetSocketAddress address, Class<? extends InetAddress> addressType) throws UnknownHostException {
Assert.checkNotNullParam("address", address);
Assert.checkNotNullParam("addressType", addressType);
if (! address.isUnresolved()) {
if (! addressType.isInstance(address.getAddress())) {
// the address part does not match
throw new UnknownHostException(address.getHostString());
}
return address;
}
return new InetSocketAddress(getAddressByNameAndType(address.getHostString(), addressType), address.getPort());
}
/**
* Resolve the given host name, returning the first answer with the given address type.
*
* @param hostName the host name to resolve (must not be {@code null})
* @param addressType the class of the {@code InetAddress} to search for (must not be {@code null})
* @param <T> the type of the {@code InetAddress} to search for
* @return the resolved address (not {@code null})
* @throws UnknownHostException if address resolution failed or if no addresses of the given type were found
*/
public static <T extends InetAddress> T getAddressByNameAndType(String hostName, Class<T> addressType) throws UnknownHostException {
Assert.checkNotNullParam("hostName", hostName);
Assert.checkNotNullParam("addressType", addressType);
if (addressType == InetAddress.class) {
return addressType.cast(InetAddress.getByName(hostName));
}
for (InetAddress inetAddress : InetAddress.getAllByName(hostName)) {
if (addressType.isInstance(inetAddress)) {
return addressType.cast(inetAddress);
}
}
// no i18n here because this is a "standard" exception
throw new UnknownHostException(hostName);
}
/**
* Resolve the given host name, returning all answers with the given address type.
*
* @param hostName the host name to resolve (must not be {@code null})
* @param addressType the class of the {@code InetAddress} to search for (must not be {@code null})
* @param <T> the type of the {@code InetAddress} to search for
* @return the resolved addresses (not {@code null})
* @throws UnknownHostException if address resolution failed or if no addresses of the given type were found
*/
@SuppressWarnings("unchecked")
public static <T extends InetAddress> T[] getAllAddressesByNameAndType(String hostName, Class<T> addressType) throws UnknownHostException {
Assert.checkNotNullParam("hostName", hostName);
Assert.checkNotNullParam("addressType", addressType);
if (addressType == InetAddress.class) {
// safe because T == InetAddress
return (T[]) InetAddress.getAllByName(hostName);
}
final InetAddress[] addresses = InetAddress.getAllByName(hostName);
final int length = addresses.length;
int count = 0;
for (InetAddress inetAddress : addresses) {
if (addressType.isInstance(inetAddress)) {
count ++;
}
}
if (count == 0) {
// no i18n here because this is a "standard" exception
throw new UnknownHostException(hostName);
}
final T[] newArray = (T[]) Array.newInstance(addressType, count);
if (count == length) {
//noinspection SuspiciousSystemArraycopy
System.arraycopy(addresses, 0, newArray, 0, length);
} else {
int idx = 0;
for (InetAddress inetAddress : addresses) {
if (addressType.isInstance(inetAddress)) {
newArray[idx] = addressType.cast(inetAddress);
}
}
}
return newArray;
}
/**
* Get an IPv4 address from four integer segments. Each segment must be between 0 and 255.
*
......@@ -238,37 +421,77 @@ public final class Inet {
/**
* Parse an IPv6 address into an {@code Inet6Address} object.
*
* @param string the address to parse
* @param address the address to parse
* @return the parsed address, or {@code null} if the address is not valid
*/
public static Inet6Address parseInet6Address(String string) {
final byte[] bytes = parseInet6AddressToBytes(string);
public static Inet6Address parseInet6Address(String address) {
return parseInet6Address(address, null);
}
/**
* Parse an IPv6 address into an {@code Inet6Address} object.
*
* @param address the address to parse (must not be {@code null})
* @param hostName the host name to use in the resultant object, or {@code null} to use the string representation of
* the address
* @return the parsed address, or {@code null} if the address is not valid
*/
public static Inet6Address parseInet6Address(String address, String hostName) {
final byte[] bytes = parseInet6AddressToBytes(address);
if (bytes == null) {
return null;
}
int scopeId = 0;
Inet6Address address;
Inet6Address inetAddress;
try {
address = Inet6Address.getByAddress(string, bytes, 0);
inetAddress = Inet6Address.getByAddress(hostName == null ? toOptimalStringV6(bytes) : hostName, bytes, 0);
} catch (UnknownHostException e) {
// not possible
throw new IllegalStateException(e);
}
final int pctIdx = string.indexOf('%');
final int pctIdx = address.indexOf('%');
if (pctIdx != -1) {
scopeId = getScopeId(string.substring(pctIdx + 1), address);
scopeId = getScopeId(address.substring(pctIdx + 1), inetAddress);
if (scopeId == 0) {
// address not valid after all...
return null;
}
try {
address = Inet6Address.getByAddress(string, bytes, scopeId);
inetAddress = Inet6Address.getByAddress(hostName == null ? toOptimalStringV6(bytes) : hostName, bytes, scopeId);
} catch (UnknownHostException e) {
// not possible
throw new IllegalStateException(e);
}
}
return address;
return inetAddress;
}
/**
* Parse an IPv6 address into an {@code Inet6Address} object, throwing an exception on failure.
*
* @param address the address to parse
* @return the parsed address (not {@code null})
* @throws IllegalArgumentException if the address is not valid
*/
public static Inet6Address parseInet6AddressOrFail(String address) {
final Inet6Address result = parseInet6Address(address, null);
if (result == null) throw CommonMessages.msg.invalidAddress(address);
return result;
}
/**
* Parse an IPv6 address into an {@code Inet6Address} object.
*
* @param address the address to parse (must not be {@code null})
* @param hostName the host name to use in the resultant object, or {@code null} to use the string representation of
* the address
* @return the parsed address (not {@code null})
* @throws IllegalArgumentException if the address is not valid
*/
public static Inet6Address parseInet6AddressOrFail(String address, String hostName) {
final Inet6Address result = parseInet6Address(address, hostName);
if (result == null) throw CommonMessages.msg.invalidAddress(address);
return result;
}
/**
......@@ -288,18 +511,58 @@ public final class Inet {
* @return the parsed address, or {@code null} if the address is not valid
*/
public static Inet4Address parseInet4Address(String address) {
return parseInet4Address(address, null);
}
/**
* Parse an IPv4 address into an {@code Inet4Address} object.
*
* @param address the address to parse
* @param hostName the host name to use in the resultant object, or {@code null} to use the string representation of
* the address
* @return the parsed address, or {@code null} if the address is not valid
*/
public static Inet4Address parseInet4Address(String address, String hostName) {
final byte[] bytes = parseInet4AddressToBytes(address);
if (bytes == null) {
return null;
}
try {
return (Inet4Address) Inet4Address.getByAddress(address, bytes);
return (Inet4Address) Inet4Address.getByAddress(hostName == null ? toOptimalString(bytes) : hostName, bytes);
} catch (UnknownHostException e) {
// not possible
throw new IllegalStateException(e);
}
}
/**
* Parse an IPv4 address into an {@code Inet4Address} object, throwing an exception on failure.
*
* @param address the address to parse
* @return the parsed address (not {@code null})
* @throws IllegalArgumentException if the address is not valid
*/
public static Inet4Address parseInet4AddressOrFail(String address) {
final Inet4Address result = parseInet4Address(address, null);
if (result == null) throw CommonMessages.msg.invalidAddress(address);
return result;
}
/**
* Parse an IPv4 address into an {@code Inet4Address} object.
*
* @param address the address to parse (must not be {@code null})
* @param hostName the host name to use in the resultant object, or {@code null} to use the string representation of
* the address
* @return the parsed address (not {@code null})
* @throws IllegalArgumentException if the address is not valid
*/
public static Inet4Address parseInet4AddressOrFail(String address, String hostName) {
final Inet4Address result = parseInet4Address(address, hostName);
if (result == null) throw CommonMessages.msg.invalidAddress(address);
return result;
}
/**
* Parse an IP address into an {@code InetAddress} object.
*
......@@ -307,12 +570,52 @@ public final class Inet {
* @return the parsed address, or {@code null} if the address is not valid
*/
public static InetAddress parseInetAddress(String address) {
return parseInetAddress(address, null);
}
/**
* Parse an IP address into an {@code InetAddress} object.
*
* @param address the address to parse
* @param hostName the host name to use in the resultant object, or {@code null} to use the string representation of
* the address
* @return the parsed address, or {@code null} if the address is not valid
*/
public static InetAddress parseInetAddress(String address, String hostName) {
// simple heuristic
if (address.indexOf(':') != -1) {
return parseInet6Address(address);
return parseInet6Address(address, hostName);
} else {
return parseInet4Address(address);
return parseInet4Address(address, hostName);
}
}
/**
* Parse an IP address into an {@code InetAddress} object, throwing an exception on failure.
*
* @param address the address to parse
* @return the parsed address (not {@code null})
* @throws IllegalArgumentException if the address is not valid
*/
public static InetAddress parseInetAddressOrFail(String address) {
final InetAddress result = parseInetAddress(address, null);
if (result == null) throw CommonMessages.msg.invalidAddress(address);
return result;
}
/**
* Parse an IP address into an {@code InetAddress} object.
*
* @param address the address to parse (must not be {@code null})
* @param hostName the host name to use in the resultant object, or {@code null} to use the string representation of
* the address
* @return the parsed address (not {@code null})
* @throws IllegalArgumentException if the address is not valid
*/
public static InetAddress parseInetAddressOrFail(String address, String hostName) {
final InetAddress result = parseInetAddress(address, hostName);
if (result == null) throw CommonMessages.msg.invalidAddress(address);
return result;
}
/**
......
......@@ -19,13 +19,32 @@
package org.wildfly.common.math;
import static org.junit.Assert.*;
import static org.wildfly.common.math.HashMath.multiHashOrdered;
import static org.wildfly.common.math.HashMath.multiHashUnordered;
import static org.wildfly.common.math.HashMath.*;
import org.junit.Test;
public class HashMathTestCase {
@Test
public void testPowerOfTwo() {
assertEquals(0, roundToPowerOfTwo(0));
assertEquals(1, roundToPowerOfTwo(1));
assertEquals(4, roundToPowerOfTwo(3));
assertEquals(4, roundToPowerOfTwo(4));
assertEquals(8, roundToPowerOfTwo(5));
assertEquals(8, roundToPowerOfTwo(7));
assertEquals(8, roundToPowerOfTwo(8));
assertEquals(128, roundToPowerOfTwo(128));
assertEquals(256, roundToPowerOfTwo(129));
assertEquals(256, roundToPowerOfTwo(200));
assertEquals(256, roundToPowerOfTwo(255));
assertEquals(256, roundToPowerOfTwo(256));
assertEquals(0x2000_0000, roundToPowerOfTwo(0x2000_0000));
assertEquals(0x4000_0000, roundToPowerOfTwo(0x2000_0001));
assertEquals(0x4000_0000, roundToPowerOfTwo(0x3FFF_FFFF));
assertEquals(0x4000_0000, roundToPowerOfTwo(0x4000_0000));
}
@Test
public void testOrderedCommutative() {
final int ab = multiHashOrdered(multiHashOrdered(1234, 65537, 13), 16633, 5342);
......