X-Git-Url: https://git.opendaylight.org/gerrit/gitweb?a=blobdiff_plain;f=model%2Fietf%2Fietf-type-util%2Fsrc%2Fmain%2Fjava%2Forg%2Fopendaylight%2Fmdsal%2Fmodel%2Fietf%2Futil%2FAbstractIetfInetUtil.java;h=88da958305a9e62cec3b41cf9c465939010027fd;hb=98143cfc18f95eb4057587c1bdb4aa3b5e3b2e20;hp=51e9638791c933f8a1f8e4f9ca9efa1260622d8b;hpb=c4301c2e5439da8538769bdee0cf6c9bb56209ef;p=mdsal.git diff --git a/model/ietf/ietf-type-util/src/main/java/org/opendaylight/mdsal/model/ietf/util/AbstractIetfInetUtil.java b/model/ietf/ietf-type-util/src/main/java/org/opendaylight/mdsal/model/ietf/util/AbstractIetfInetUtil.java index 51e9638791..88da958305 100644 --- a/model/ietf/ietf-type-util/src/main/java/org/opendaylight/mdsal/model/ietf/util/AbstractIetfInetUtil.java +++ b/model/ietf/ietf-type-util/src/main/java/org/opendaylight/mdsal/model/ietf/util/AbstractIetfInetUtil.java @@ -7,8 +7,10 @@ */ package org.opendaylight.mdsal.model.ietf.util; +import static com.google.common.base.Preconditions.checkArgument; +import static java.util.Objects.requireNonNull; + import com.google.common.annotations.Beta; -import com.google.common.base.Preconditions; import com.google.common.net.InetAddresses; import java.net.Inet4Address; import java.net.Inet6Address; @@ -16,43 +18,64 @@ import java.net.InetAddress; import java.net.UnknownHostException; import java.util.AbstractMap.SimpleImmutableEntry; import java.util.Map.Entry; -import javax.annotation.Nonnull; -import javax.annotation.Nullable; -import org.opendaylight.yangtools.yang.binding.util.StringValueObjectFactory; +import org.eclipse.jdt.annotation.NonNull; +import org.eclipse.jdt.annotation.Nullable; +import org.opendaylight.mdsal.binding.spec.reflect.StringValueObjectFactory; /** * A set of utility methods to efficiently instantiate various ietf-inet-types DTOs. */ @Beta +@SuppressWarnings("checkstyle:classTypeParameterName") public abstract class AbstractIetfInetUtil { - protected static final int INET4_LENGTH = 4; - protected static final int INET6_LENGTH = 16; - private final StringValueObjectFactory nozone4Factory; + private static final int INET4_LENGTH = 4; + private static final int INET6_LENGTH = 16; + + private final StringValueObjectFactory address4Factory; + private final StringValueObjectFactory address4NoZoneFactory; private final StringValueObjectFactory prefix4Factory; - private final StringValueObjectFactory nozone6Factory; + private final StringValueObjectFactory address6Factory; + private final StringValueObjectFactory address6NoZoneFactory; private final StringValueObjectFactory prefix6Factory; - protected AbstractIetfInetUtil(final Class nozone4Class, final Class prefix4Class, - final Class nozone6Class, final Class prefix6Class) { - this.nozone4Factory = StringValueObjectFactory.create(nozone4Class, "0.0.0.0"); + protected AbstractIetfInetUtil(final Class addr4Class, final Class addr4nzClass, + final Class prefix4Class, final Class addr6Class, final Class addr6nzClass, + final Class prefix6Class) { + this.address4Factory = StringValueObjectFactory.create(addr4Class, "0.0.0.0"); + this.address4NoZoneFactory = StringValueObjectFactory.create(addr4nzClass, "0.0.0.0"); this.prefix4Factory = StringValueObjectFactory.create(prefix4Class, "0.0.0.0/0"); - this.nozone6Factory = StringValueObjectFactory.create(nozone6Class, "::0"); + this.address6Factory = StringValueObjectFactory.create(addr6Class, "::0"); + this.address6NoZoneFactory = StringValueObjectFactory.create(addr6nzClass, "::0"); this.prefix6Factory = StringValueObjectFactory.create(prefix6Class, "::0/0"); } - @Nonnull protected abstract A ipv4Address(@Nonnull A4 addr); - @Nonnull protected abstract A ipv6Address(@Nonnull A6 addr); - @Nonnull protected abstract ANZ ipv4AddressNoZone(@Nonnull A4NZ addr); - @Nonnull protected abstract ANZ ipv6AddressNoZone(@Nonnull A6NZ addr); + protected abstract @NonNull A ipv4Address(@NonNull A4 addr); + + protected abstract @NonNull ANZ ipv4AddressNoZone(@NonNull A4NZ addr); + + protected abstract @NonNull A ipv6Address(@NonNull A6 addr); + + protected abstract @NonNull ANZ ipv6AddressNoZone(@NonNull A6NZ addr); + + protected abstract @Nullable A4 maybeIpv4Address(@NonNull A addr); + + protected abstract @Nullable A4NZ maybeIpv4AddressNoZone(@NonNull ANZ addr); + + protected abstract @Nullable A6 maybeIpv6Address(@NonNull A addr); + + protected abstract @Nullable A6NZ maybeIpv6AddressNoZone(@NonNull ANZ addr); + + protected abstract @NonNull P ipv4Prefix(@NonNull P4 addr); + + protected abstract @NonNull P ipv6Prefix(@NonNull P6 addr); + + protected abstract @NonNull String ipv4AddressString(@NonNull A4 addr); + + protected abstract @NonNull String ipv6AddressString(@NonNull A6 addr); - @Nonnull protected abstract P ipv4Prefix(@Nonnull P4 addr); - @Nonnull protected abstract P ipv6Prefix(@Nonnull P6 addr); - @Nullable protected abstract A4 maybeIpv4Address(@Nonnull A addr); - @Nullable protected abstract A6 maybeIpv6Address(@Nonnull A addr); - @Nonnull protected abstract String ipv4AddressString(@Nonnull A4 addr); - @Nonnull protected abstract String ipv6AddressString(@Nonnull A6 addr); - @Nonnull protected abstract String ipv4PrefixString(@Nonnull P4 prefix); - @Nonnull protected abstract String ipv6PrefixString(@Nonnull P6 prefix); + protected abstract @NonNull String ipv4PrefixString(@NonNull P4 prefix); + + protected abstract @NonNull String ipv6PrefixString(@NonNull P6 prefix); /** * Create an IpAddress by interpreting input bytes as an IPv4 or IPv6 address, based on array length. @@ -62,7 +85,7 @@ public abstract class AbstractIetfInetUtil= 0 && mask <= 32, "Invalid mask %s", mask); - return prefix4Factory.newInstance(addr.getHostAddress() + '/' + mask); + public final @NonNull P4 ipv4PrefixFor(final @NonNull InetAddress addr, final int mask) { + requireNonNull(addr, "Address must not be null"); + checkArgument(addr instanceof Inet4Address, "Address has to be an Inet4Address"); + return newIpv4Prefix(addr.getHostAddress(), mask); + } + + public final @NonNull P4 ipv4PrefixFor(final @NonNull A4 addr) { + requireNonNull(addr, "Address must not be null"); + return prefix4Factory.newInstance(stripZone(ipv4AddressString(addr)) + "/32"); } - @Nonnull public final P4 ipv4PrefixFor(@Nonnull final A4 addr) { - Preconditions.checkNotNull(addr, "Address must not be null"); + public final @NonNull P4 ipv4PrefixFor(final @NonNull A4 addr, final int mask) { + requireNonNull(addr, "Address must not be null"); + return newIpv4Prefix(stripZone(ipv4AddressString(addr)), mask); + } + + public final @NonNull P4 ipv4PrefixForNoZone(final @NonNull A4NZ addr) { + requireNonNull(addr, "Address must not be null"); return prefix4Factory.newInstance(ipv4AddressString(addr) + "/32"); } - @Nonnull public final P4 ipv4PrefixFor(@Nonnull final A4 addr, final int mask) { - Preconditions.checkNotNull(addr, "Address must not be null"); - Preconditions.checkArgument(mask >= 0 && mask <= 32, "Invalid mask %s", mask); - return prefix4Factory.newInstance(ipv4AddressString(addr) + '/' + mask); + public final @NonNull P4 ipv4PrefixForNoZone(final @NonNull A4NZ addr, final int mask) { + requireNonNull(addr, "Address must not be null"); + return newIpv4Prefix(ipv4AddressString(addr), mask); + } + + public final @NonNull P4 ipv4PrefixForShort(final byte @NonNull[] address, final int mask) { + if (mask == 0) { + // Easy case, reuse the template + return prefix4Factory.getTemplate(); + } + + return v4PrefixForShort(address, 0, mask / Byte.SIZE + (mask % Byte.SIZE == 0 ? 0 : 1), mask); } - @Nonnull public final Entry splitIpv4Prefix(@Nonnull final P4 prefix) { - return splitPrefix(nozone4Factory, ipv4PrefixString(prefix)); + public final @NonNull P4 ipv4PrefixForShort(final byte @NonNull[] array, final int startOffset, final int mask) { + if (mask == 0) { + // Easy case, reuse the template + return prefix4Factory.getTemplate(); + } + + return v4PrefixForShort(array, startOffset, mask / Byte.SIZE + (mask % Byte.SIZE == 0 ? 0 : 1), mask); } - @Nonnull public final byte[] ipv4PrefixToBytes(@Nonnull final P4 prefix) { + private static String stripZone(final String str) { + final int percent = str.indexOf('%'); + return percent == -1 ? str : str.substring(0, percent); + } + + private @NonNull P4 newIpv4Prefix(final String addr, final int mask) { + checkArgument(mask >= 0 && mask <= 32, "Invalid mask %s", mask); + return prefix4Factory.newInstance(addr + '/' + mask); + } + + public final @NonNull Entry splitIpv4Prefix(final @NonNull P4 prefix) { + return splitPrefix(address4Factory, ipv4PrefixString(prefix)); + } + + public final @NonNull Entry splitIpv4PrefixNoZone(final @NonNull P4 prefix) { + return splitPrefix(address4NoZoneFactory, ipv4PrefixString(prefix)); + } + + public final byte @NonNull[] ipv4PrefixToBytes(final @NonNull P4 prefix) { final String str = ipv4PrefixString(prefix); final int slash = str.lastIndexOf('/'); @@ -329,8 +487,8 @@ public abstract class AbstractIetfInetUtil= 0 && mask <= 128, "Invalid mask %s", mask); + public final @NonNull P6 ipv6PrefixFor(final byte @NonNull[] address, final int mask) { + checkArgument(mask >= 0 && mask <= 128, "Invalid mask %s", mask); return prefix6Factory.newInstance(addressStringV6(address) + '/' + mask); } - @Nonnull public final P6 ipv6PrefixForShort(@Nonnull final byte[] address, final int mask) { - return ipv6PrefixForShort(address, 0, mask); - } - - @Nonnull public final P6 ipv6PrefixForShort(@Nonnull final byte[] array, final int startOffset, final int mask) { - if (mask == 0) { - // Easy case, reuse the template - return prefix6Factory.getTemplate(); - } - - Preconditions.checkArgument(mask > 0 && mask <= 128, "Invalid mask %s", mask); - final int size = mask / Byte.SIZE + (mask % Byte.SIZE == 0 ? 0 : 1); - - // Until we can instantiate an IPv6 address for a partial array, use a temporary buffer - byte[] tmp = new byte[INET6_LENGTH]; - System.arraycopy(array, startOffset, tmp, 0, size); - return ipv6PrefixFor(tmp, mask); - } - /** * Create a /128 Ipv6Prefix by interpreting input bytes as an IPv4 address. * @@ -419,7 +592,7 @@ public abstract class AbstractIetfInetUtil= 0 && mask <= 128, "Invalid mask %s", mask); + public final @NonNull P6 ipv6PrefixFor(final @NonNull InetAddress addr, final int mask) { + requireNonNull(addr, "Address must not be null"); + checkArgument(addr instanceof Inet6Address, "Address has to be an Inet6Address"); + checkArgument(mask >= 0 && mask <= 128, "Invalid mask %s", mask); return prefix6Factory.newInstance(addressStringV6(addr) + '/' + mask); } - @Nonnull public final P6 ipv6PrefixFor(@Nonnull final A6 addr) { - Preconditions.checkNotNull(addr, "Address must not be null"); + public final @NonNull P6 ipv6PrefixFor(final @NonNull A6 addr) { + requireNonNull(addr, "Address must not be null"); + return prefix6Factory.newInstance(stripZone(ipv6AddressString(addr)) + "/128"); + } + + public final @NonNull P6 ipv6PrefixFor(final @NonNull A6 addr, final int mask) { + requireNonNull(addr, "Address must not be null"); + return newIpv6Prefix(stripZone(ipv6AddressString(addr)), mask); + } + + public final @NonNull P6 ipv6PrefixForNoZone(final @NonNull A6NZ addr) { + requireNonNull(addr, "Address must not be null"); return prefix6Factory.newInstance(ipv6AddressString(addr) + "/128"); } - @Nonnull public final P6 ipv6PrefixFor(@Nonnull final A6 addr, final int mask) { - Preconditions.checkNotNull(addr, "Address must not be null"); - Preconditions.checkArgument(mask >= 0 && mask <= 128, "Invalid mask %s", mask); - return prefix6Factory.newInstance(ipv6AddressString(addr) + '/' + mask); + public final @NonNull P6 ipv6PrefixForNoZone(final @NonNull A6NZ addr, final int mask) { + requireNonNull(addr, "Address must not be null"); + return newIpv6Prefix(ipv6AddressString(addr), mask); } - @Nonnull public final Entry splitIpv6Prefix(@Nonnull final P6 prefix) { - return splitPrefix(nozone6Factory, ipv6PrefixString(prefix)); + public final @NonNull P6 ipv6PrefixForShort(final byte @NonNull[] address, final int mask) { + return ipv6PrefixForShort(address, 0, mask); } - private static T prefixToAddress(final StringValueObjectFactory factory, final String str) { + public final @NonNull P6 ipv6PrefixForShort(final byte @NonNull[] array, final int startOffset, final int mask) { + if (mask == 0) { + // Easy case, reuse the template + return prefix6Factory.getTemplate(); + } + + checkArgument(mask > 0 && mask <= 128, "Invalid mask %s", mask); + final int size = mask / Byte.SIZE + (mask % Byte.SIZE == 0 ? 0 : 1); + + // Until we can instantiate an IPv6 address for a partial array, use a temporary buffer + byte[] tmp = new byte[INET6_LENGTH]; + System.arraycopy(array, startOffset, tmp, 0, size); + return ipv6PrefixFor(tmp, mask); + } + + private P6 newIpv6Prefix(final String addr, final int mask) { + checkArgument(mask >= 0 && mask <= 128, "Invalid mask %s", mask); + return prefix6Factory.newInstance(addr + '/' + mask); + } + + public final @NonNull Entry splitIpv6Prefix(final @NonNull P6 prefix) { + return splitPrefix(address6Factory, ipv6PrefixString(prefix)); + } + + public final @NonNull Entry splitIpv6PrefixNoZone(final @NonNull P6 prefix) { + return splitPrefix(address6NoZoneFactory, ipv6PrefixString(prefix)); + } + + private static @NonNull T prefixToAddress(final StringValueObjectFactory factory, final String str) { return factory.newInstance(str.substring(0, str.lastIndexOf('/'))); } - private static Entry splitPrefix(final StringValueObjectFactory factory, final String str) { + private static @NonNull Entry splitPrefix(final StringValueObjectFactory factory, + final String str) { final int slash = str.lastIndexOf('/'); return new SimpleImmutableEntry<>(factory.newInstance(str.substring(0, slash)), Integer.valueOf(str.substring(slash + 1))); } - @Nonnull public final byte[] ipv6PrefixToBytes(@Nonnull final P6 prefix) { + public final byte @NonNull[] ipv6PrefixToBytes(final @NonNull P6 prefix) { final String str = ipv6PrefixString(prefix); final byte[] bytes = new byte[INET6_LENGTH + 1]; final int slash = str.lastIndexOf('/'); @@ -475,24 +686,32 @@ public abstract class AbstractIetfInetUtil>> 24).append('.') + .append(bits >>> 16 & 0xFF).append('.') + .append(bits >>> 8 & 0xFF).append('.') + .append(bits & 0xFF) + .toString(); + } + + static String addressStringV4(final byte @NonNull[] bytes) { final StringBuilder sb = new StringBuilder(15); appendIpv4String(sb, bytes); return sb.toString(); } - private static String addressStringV6(final byte[] bytes) { - Preconditions.checkArgument(bytes.length == INET6_LENGTH, "IPv6 address length is 16 bytes"); + private static String addressStringV6(final byte @NonNull[] bytes) { + checkArgument(bytes.length == INET6_LENGTH, "IPv6 address length is 16 bytes"); try { return addressStringV6(Inet6Address.getByAddress(bytes)); @@ -505,24 +724,21 @@ public abstract class AbstractIetfInetUtil= 0 && mask <= 32, "Invalid mask %s", mask); + private static String prefixStringV4(final byte @NonNull[] bytes, final int mask) { + checkArgument(mask >= 0 && mask <= 32, "Invalid mask %s", mask); final StringBuilder sb = new StringBuilder(18); appendIpv4String(sb, bytes); - sb.append('/'); - sb.append(mask); - return sb.toString(); + return sb.append('/').append(mask).toString(); } - private P4 v4PrefixForShort(@Nonnull final byte[] array, final int startOffset, final int size, final int mask) { + private P4 v4PrefixForShort(final byte @NonNull[] array, final int startOffset, final int size, final int mask) { if (startOffset == 0 && size == INET4_LENGTH && array.length == INET4_LENGTH) { // Easy case, fall back to non-short return ipv4PrefixFor(array, mask); @@ -533,8 +749,7 @@ public abstract class AbstractIetfInetUtil 0 && mask <= 32, "Invalid mask %s", mask); - sb.append('/'); - sb.append(mask); + checkArgument(mask > 0 && mask <= 32, "Invalid mask %s", mask); + sb.append('/').append(mask); return prefix4Factory.newInstance(sb.toString()); }