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%2FAbstractIetfYangUtil.java;h=86fa3a4efe745683e59844d46ed0974b5cfe93b1;hb=7cbd12d8894b1703b19e70b07436a937a7b8d0bf;hp=c2748a596cb552ba20b87ba5db72e312bd75c72b;hpb=be97010a32253ce4fb5c1be4c5c7eb003c2e9f8e;p=mdsal.git diff --git a/model/ietf/ietf-type-util/src/main/java/org/opendaylight/mdsal/model/ietf/util/AbstractIetfYangUtil.java b/model/ietf/ietf-type-util/src/main/java/org/opendaylight/mdsal/model/ietf/util/AbstractIetfYangUtil.java index c2748a596c..86fa3a4efe 100644 --- a/model/ietf/ietf-type-util/src/main/java/org/opendaylight/mdsal/model/ietf/util/AbstractIetfYangUtil.java +++ b/model/ietf/ietf-type-util/src/main/java/org/opendaylight/mdsal/model/ietf/util/AbstractIetfYangUtil.java @@ -7,21 +7,28 @@ */ package org.opendaylight.mdsal.model.ietf.util; +import static com.google.common.base.Preconditions.checkArgument; + import com.google.common.annotations.Beta; -import com.google.common.base.Preconditions; import java.util.Arrays; -import javax.annotation.Nonnull; -import org.opendaylight.yangtools.yang.binding.util.StringValueObjectFactory; +import java.util.UUID; +import org.eclipse.jdt.annotation.NonNull; +import org.opendaylight.mdsal.binding.spec.reflect.StringValueObjectFactory; /** * Abstract utility class for dealing with MAC addresses as defined in the ietf-yang-types model. This class is * used by revision-specific classes. + * + * @param mac-address type + * @param

phys-address type */ @Beta -public abstract class AbstractIetfYangUtil { +public abstract class AbstractIetfYangUtil { private static final int MAC_BYTE_LENGTH = 6; private static final char[] HEX_CHARS = "0123456789abcdef".toCharArray(); - private static final byte[] HEX_VALUES; + private static final byte @NonNull[] EMPTY_BYTES = new byte[0]; + private static final byte @NonNull[] HEX_VALUES; + static { final byte[] b = new byte['f' + 1]; Arrays.fill(b, (byte)-1); @@ -39,16 +46,135 @@ public abstract class AbstractIetfYangUtil { HEX_VALUES = b; } - private final StringValueObjectFactory factory; + private final StringValueObjectFactory macFactory; + private final StringValueObjectFactory

physFactory; + private final StringValueObjectFactory hexFactory; + private final StringValueObjectFactory quadFactory; + private final StringValueObjectFactory uuidFactory; + + protected AbstractIetfYangUtil(final Class macClass, final Class

physClass, final Class hexClass, + final Class quadClass, final Class uuidClass) { + this.macFactory = StringValueObjectFactory.create(macClass, "00:00:00:00:00:00"); + this.physFactory = StringValueObjectFactory.create(physClass, "00:00"); + this.hexFactory = StringValueObjectFactory.create(hexClass, "00"); + this.quadFactory = StringValueObjectFactory.create(quadClass, "0.0.0.0"); + this.uuidFactory = StringValueObjectFactory.create(uuidClass, "f81d4fae-7dec-11d0-a765-00a0c91e6bf6"); + } + + /** + * Convert the value of a MacAddress into the canonical representation. + * + * @param macAddress Input MAC address + * @return A MacAddress containing the canonical representation. + * @throws NullPointerException if macAddress is null + */ + public final @NonNull M canonizeMacAddress(final @NonNull M macAddress) { + final char[] input = getValue(macAddress).toCharArray(); + return ensureLowerCase(input) ? macFactory.newInstance(String.valueOf(input)) : macAddress; + } + + /** + * Create a MacAddress object holding the canonical representation of the 6 bytes + * passed in as argument. + * @param bytes 6-byte input array + * @return MacAddress with canonical string derived from input bytes + * @throws NullPointerException if bytes is null + * @throws IllegalArgumentException if length of input is not 6 bytes + */ + public final @NonNull M macAddressFor(final byte @NonNull[] bytes) { + checkArgument(bytes.length == MAC_BYTE_LENGTH, "MAC address should have 6 bytes, not %s", + bytes.length); + return macFactory.newInstance(bytesToString(bytes, 17)); + } + + public final byte @NonNull[] macAddressBytes(final @NonNull M macAddress) { + return stringToBytes(getValue(macAddress), MAC_BYTE_LENGTH); + } + + /** + * Convert the value of a PhysAddress into the canonical representation. + * + * @param physAddress Input MAC address + * @return A PhysAddress containing the canonical representation. + * @throws NullPointerException if physAddress is null + */ + public final @NonNull P canonizePhysAddress(final @NonNull P physAddress) { + final char[] input = getPhysValue(physAddress).toCharArray(); + return ensureLowerCase(input) ? physFactory.newInstance(String.valueOf(input)) : physAddress; + } + + /** + * Create a PhysAddress object holding the canonical representation of the bytes passed in as argument. + * + * @param bytes input array + * @return PhysAddress with canonical string derived from input bytes + * @throws NullPointerException if bytes is null + * @throws IllegalArgumentException if length of input is not at least 1 byte + */ + public final @NonNull P physAddressFor(final byte @NonNull[] bytes) { + checkArgument(bytes.length > 0, "Physical address should have at least one byte"); + return physFactory.newInstance(bytesToString(bytes, bytes.length * 3 - 1)); + } + + public final byte @NonNull[] physAddressBytes(final @NonNull P physAddress) { + final String str = getPhysValue(physAddress); + return str.isEmpty() ? EMPTY_BYTES : stringToBytes(str, str.length() / 3 + 1); + } + + @Deprecated + public final byte @NonNull[] bytesFor(final @NonNull M macAddress) { + return macAddressBytes(macAddress); + } + + public final @NonNull H hexStringFor(final byte @NonNull[] bytes) { + checkArgument(bytes.length > 0, "Hex string should have at least one byte"); + return hexFactory.newInstance(bytesToString(bytes, bytes.length * 3 - 1)); + } + + public final byte @NonNull[] hexStringBytes(final @NonNull H hexString) { + final String str = getHexValue(hexString); + return stringToBytes(str, str.length() / 3 + 1); + } + + public final @NonNull Q dottedQuadFor(final byte @NonNull[] bytes) { + checkArgument(bytes.length == 4, "Dotted-quad should have 4 bytes"); + return quadFactory.newInstance(AbstractIetfInetUtil.addressStringV4(bytes)); + } + + public final byte @NonNull[] dottedQuadBytes(final @NonNull Q hexString) { + final String str = getQuadValue(hexString); + final byte[] bytes = new byte[4]; + Ipv4Utils.fillIpv4Bytes(bytes, 0, str, 0, str.length()); + return bytes; + } - protected AbstractIetfYangUtil(final Class clazz) { - this.factory = StringValueObjectFactory.create(clazz, "00:00:00:00:00:00"); + public final @NonNull U uuidFor(final @NonNull UUID uuid) { + return uuidFactory.newInstance(uuid.toString()); } - private static final void appendHexByte(final StringBuilder sb, final byte b) { - final int v = Byte.toUnsignedInt(b); - sb.append(HEX_CHARS[v >>> 4]); - sb.append(HEX_CHARS[v & 15]); + protected abstract String getValue(M macAddress); + + protected abstract String getPhysValue(P physAddress); + + protected abstract String getHexValue(H hexString); + + protected abstract String getQuadValue(Q dottedQuad); + + static byte hexValue(final char ch) { + byte value; + try { + // Performance optimization: access the array and rely on the VM for catching + // illegal access (which boils down to illegal character, which should never happen. + value = HEX_VALUES[ch]; + } catch (IndexOutOfBoundsException e) { + value = -1; + } + + if (value < 0) { + throw new IllegalArgumentException("Invalid character '" + ch + "' encountered"); + } + + return value; } /** @@ -60,7 +186,7 @@ public abstract class AbstractIetfYangUtil { * @return True if the array has been modified * @throws NullPointerException if input is null */ - private static boolean ensureLowerCase(@Nonnull final char[] chars) { + private static boolean ensureLowerCase(final char @NonNull[] chars) { boolean ret = false; for (int i = 0; i < chars.length; ++i) { @@ -79,79 +205,31 @@ public abstract class AbstractIetfYangUtil { * lower-case digits each, separated by colons. * * @param bytes Input bytes, may not be null + * @param charHint Hint at how many characters are needed * @return Canonical MAC address string * @throws NullPointerException if input is null * @throws IllegalArgumentException if length of input is not 6 bytes */ - @Nonnull private static String bytesToString(@Nonnull final byte[] bytes) { - Preconditions.checkArgument(bytes.length == MAC_BYTE_LENGTH, "MAC address should have 6 bytes, not %s", - bytes.length); - - final StringBuilder sb = new StringBuilder(17); + private static @NonNull String bytesToString(final byte @NonNull[] bytes, final int charHint) { + final StringBuilder sb = new StringBuilder(charHint); appendHexByte(sb, bytes[0]); - for (int i = 1; i < MAC_BYTE_LENGTH; ++i) { - sb.append(':'); - appendHexByte(sb, bytes[i]); + for (int i = 1; i < bytes.length; ++i) { + appendHexByte(sb.append(':'), bytes[i]); } return sb.toString(); } - /** - * Convert the value of a MacAddress into the canonical representation. - * - * @param macAddress Input MAC address - * @return A MacAddress containing the canonical representation. - * @throws NullPointerException if macAddress is null - */ - @Nonnull public final T canonizeMacAddress(@Nonnull final T macAddress) { - final char[] input = getValue(macAddress).toCharArray(); - if (ensureLowerCase(input)) { - return factory.newInstance(input.toString()); - } else { - return macAddress; - } - } - - /** - * Create a MacAddress object holding the canonical representation of the 6 bytes - * passed in as argument. - * @param bytes 6-byte input array - * @return MacAddress with canonical string derived from input bytes - * @throws NullPointerException if bytes is null - * @throws IllegalArgumentException if length of input is not 6 bytes - */ - @Nonnull public final T macAddressFor(@Nonnull final byte[] bytes) { - return factory.newInstance(bytesToString(bytes)); - } - - private static byte hexValue(final char c) { - byte v; - try { - // Performance optimization: access the array and rely on the VM for catching - // illegal access (which boils down to illegal character, which should never happen. - v = HEX_VALUES[c]; - } catch (IndexOutOfBoundsException e) { - v = -1; - } - - if (v < 0) { - throw new IllegalArgumentException("Invalid character '" + c + "' encountered"); - } - - return v; + private static void appendHexByte(final StringBuilder sb, final byte byteVal) { + final int intVal = Byte.toUnsignedInt(byteVal); + sb.append(HEX_CHARS[intVal >>> 4]).append(HEX_CHARS[intVal & 15]); } - @Nonnull public final byte[] bytesFor(@Nonnull final T macAddress) { - final String mac = getValue(macAddress); - final byte[] ret = new byte[MAC_BYTE_LENGTH]; - - for (int i = 0, base = 0; i < MAC_BYTE_LENGTH; ++i, base += 3) { - ret[i] = (byte) ((hexValue(mac.charAt(base)) << 4) | hexValue(mac.charAt(base + 1))); + private static byte @NonNull[] stringToBytes(final String str, final int length) { + final byte[] ret = new byte[length]; + for (int i = 0, base = 0; i < length; ++i, base += 3) { + ret[i] = (byte) (hexValue(str.charAt(base)) << 4 | hexValue(str.charAt(base + 1))); } - return ret; } - - protected abstract String getValue(T macAddress); }