From e4cf48df5652933f751d0a9f2d8f27b6a4cf4fd4 Mon Sep 17 00:00:00 2001 From: Robert Varga Date: Tue, 24 Jul 2018 01:11:36 +0200 Subject: [PATCH] Add PhysAddress support This adds converions required for efficient PhysAddress support. Change-Id: Ia07e07361fc0fdea3cc2a2b96e65643d60aef003 Signed-off-by: Robert Varga --- .../model/ietf/util/AbstractIetfYangUtil.java | 166 ++++++++++-------- .../ietf/util/AbstractIetfYangUtilTest.java | 6 +- .../mdsal/model/ietf/util/MacClass.java | 5 +- .../mdsal/model/ietf/util/MacUtil.java | 9 +- .../mdsal/model/ietf/util/PhysClass.java | 26 +++ .../yang/types/rev130715/IetfYangUtil.java | 9 +- 6 files changed, 141 insertions(+), 80 deletions(-) create mode 100644 model/ietf/ietf-type-util/src/test/java/org/opendaylight/mdsal/model/ietf/util/PhysClass.java 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 0e01cc3976..e9c6f33433 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,8 +7,9 @@ */ 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.mdsal.binding.spec.reflect.StringValueObjectFactory; @@ -16,9 +17,12 @@ 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; @@ -39,92 +43,81 @@ public abstract class AbstractIetfYangUtil { HEX_VALUES = b; } - private final StringValueObjectFactory factory; + private final StringValueObjectFactory macFactory; + private final StringValueObjectFactory

physFactory; - protected AbstractIetfYangUtil(final Class clazz) { - this.factory = StringValueObjectFactory.create(clazz, "00:00:00:00:00:00"); + protected AbstractIetfYangUtil(final Class macClass, final Class

physClass) { + this.macFactory = StringValueObjectFactory.create(macClass, "00:00:00:00:00:00"); + this.physFactory = StringValueObjectFactory.create(physClass, "00:00"); } - 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]); - } /** - * Make sure an array of characters does not include capital letters. This method assumes input conforms to - * MAC address format, e.g. it is composed of 6 groups of hexadecimal digits separated by colons. Behavior is - * undefined if the input does not meet this criteria. + * Convert the value of a MacAddress into the canonical representation. * - * @param chars Input characters, may not be null - * @return True if the array has been modified - * @throws NullPointerException if input is null + * @param macAddress Input MAC address + * @return A MacAddress containing the canonical representation. + * @throws NullPointerException if macAddress is null */ - private static boolean ensureLowerCase(@Nonnull final char[] chars) { - boolean ret = false; - - for (int i = 0; i < chars.length; ++i) { - final char c = chars[i]; - if (c >= 'A' && c <= 'F') { - chars[i] = Character.toLowerCase(c); - ret = true; - } - } - - return ret; + @Nonnull public final M canonizeMacAddress(@Nonnull final M macAddress) { + final char[] input = getValue(macAddress).toCharArray(); + return ensureLowerCase(input) ? macFactory.newInstance(String.valueOf(input)) : macAddress; } /** - * Convert an array of 6 bytes into canonical MAC address representation, that is 6 groups of two hexadecimal - * lower-case digits each, separated by colons. - * - * @param bytes Input bytes, may not be null - * @return Canonical MAC address string - * @throws NullPointerException if input is null + * 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 private static String bytesToString(@Nonnull final byte[] bytes) { - Preconditions.checkArgument(bytes.length == MAC_BYTE_LENGTH, "MAC address should have 6 bytes, not %s", + @Nonnull public final M macAddressFor(@Nonnull final byte[] bytes) { + checkArgument(bytes.length == MAC_BYTE_LENGTH, "MAC address should have 6 bytes, not %s", bytes.length); - - final StringBuilder sb = new StringBuilder(17); - appendHexByte(sb, bytes[0]); - for (int i = 1; i < MAC_BYTE_LENGTH; ++i) { - sb.append(':'); - appendHexByte(sb, bytes[i]); - } - - return sb.toString(); + return macFactory.newInstance(bytesToString(bytes, 17)); } /** - * Convert the value of a MacAddress into the canonical representation. + * Convert the value of a PhysAddress into the canonical representation. * - * @param macAddress Input MAC address - * @return A MacAddress containing the canonical representation. - * @throws NullPointerException if macAddress is null + * @param physAddress Input MAC address + * @return A PhysAddress containing the canonical representation. + * @throws NullPointerException if physAddress 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()); - } - - return macAddress; + @Nonnull public final P canonizePhysAddress(@Nonnull final P physAddress) { + final char[] input = getPhysValue(physAddress).toCharArray(); + return ensureLowerCase(input) ? physFactory.newInstance(String.valueOf(input)) : physAddress; } /** - * 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 + * 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 6 bytes + * @throws IllegalArgumentException if length of input is not at least 1 byte */ - @Nonnull public final T macAddressFor(@Nonnull final byte[] bytes) { - return factory.newInstance(bytesToString(bytes)); + @Nonnull public final P physAddressFor(@Nonnull final byte[] bytes) { + checkArgument(bytes.length > 0, "Physical address should have at least one byte"); + return physFactory.newInstance(bytesToString(bytes, (bytes.length + 1) / 3)); + } + + @Nonnull public final byte[] bytesFor(@Nonnull final M 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))); + } + + return ret; } + protected abstract String getValue(M macAddress); + + protected abstract String getPhysValue(P physAddress); + static byte hexValue(final char c) { byte v; try { @@ -142,16 +135,51 @@ public abstract class AbstractIetfYangUtil { return v; } - @Nonnull public final byte[] bytesFor(@Nonnull final T macAddress) { - final String mac = getValue(macAddress); - final byte[] ret = new byte[MAC_BYTE_LENGTH]; + /** + * Make sure an array of characters does not include capital letters. This method assumes input conforms to + * MAC address format, e.g. it is composed of 6 groups of hexadecimal digits separated by colons. Behavior is + * undefined if the input does not meet this criteria. + * + * @param chars Input characters, may not be null + * @return True if the array has been modified + * @throws NullPointerException if input is null + */ + private static boolean ensureLowerCase(@Nonnull final char[] chars) { + boolean ret = false; - 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))); + for (int i = 0; i < chars.length; ++i) { + final char c = chars[i]; + if (c >= 'A' && c <= 'F') { + chars[i] = Character.toLowerCase(c); + ret = true; + } } return ret; } - protected abstract String getValue(T macAddress); + /** + * Convert an array of 6 bytes into canonical MAC address representation, that is 6 groups of two hexadecimal + * 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, final int charHint) { + final StringBuilder sb = new StringBuilder(charHint); + appendHexByte(sb, bytes[0]); + for (int i = 1; i < bytes.length; ++i) { + appendHexByte(sb.append(':'), bytes[i]); + } + + return sb.toString(); + } + + private static final void appendHexByte(final StringBuilder sb, final byte b) { + final int v = Byte.toUnsignedInt(b); + sb.append(HEX_CHARS[v >>> 4]).append(HEX_CHARS[v & 15]); + } } diff --git a/model/ietf/ietf-type-util/src/test/java/org/opendaylight/mdsal/model/ietf/util/AbstractIetfYangUtilTest.java b/model/ietf/ietf-type-util/src/test/java/org/opendaylight/mdsal/model/ietf/util/AbstractIetfYangUtilTest.java index fa9484e7a4..a9e5b7bf49 100644 --- a/model/ietf/ietf-type-util/src/test/java/org/opendaylight/mdsal/model/ietf/util/AbstractIetfYangUtilTest.java +++ b/model/ietf/ietf-type-util/src/test/java/org/opendaylight/mdsal/model/ietf/util/AbstractIetfYangUtilTest.java @@ -9,7 +9,6 @@ package org.opendaylight.mdsal.model.ietf.util; import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertTrue; import static org.junit.Assert.fail; @@ -38,8 +37,7 @@ public class AbstractIetfYangUtilTest { @Test public void canonizeMACTest() throws Exception { - assertFalse(UTIL.canonizeMacAddress(new MacClass("01:02:1E:5A:FB:88")).getValue() - .equals(UTIL.canonizeMacAddress(new MacClass(CANON)).getValue())); + assertEquals(CANON, UTIL.canonizeMacAddress(new MacClass("01:02:1E:5A:FB:88")).getValue()); } @Test(expected = IllegalArgumentException.class) @@ -47,4 +45,4 @@ public class AbstractIetfYangUtilTest { AbstractIetfYangUtil.hexValue(Character.highSurrogate(1000)); fail("Expected invalid character exception"); } -} \ No newline at end of file +} diff --git a/model/ietf/ietf-type-util/src/test/java/org/opendaylight/mdsal/model/ietf/util/MacClass.java b/model/ietf/ietf-type-util/src/test/java/org/opendaylight/mdsal/model/ietf/util/MacClass.java index 13577d665e..d08fbdd635 100644 --- a/model/ietf/ietf-type-util/src/test/java/org/opendaylight/mdsal/model/ietf/util/MacClass.java +++ b/model/ietf/ietf-type-util/src/test/java/org/opendaylight/mdsal/model/ietf/util/MacClass.java @@ -5,16 +5,15 @@ * terms of the Eclipse Public License v1.0 which accompanies this distribution, * and is available at http://www.eclipse.org/legal/epl-v10.html */ - package org.opendaylight.mdsal.model.ietf.util; -import com.google.common.base.Preconditions; +import static java.util.Objects.requireNonNull; public final class MacClass { private final String _value; public MacClass(final String value) { - this._value = Preconditions.checkNotNull(value); + this._value = requireNonNull(value); } public MacClass(final MacClass template) { diff --git a/model/ietf/ietf-type-util/src/test/java/org/opendaylight/mdsal/model/ietf/util/MacUtil.java b/model/ietf/ietf-type-util/src/test/java/org/opendaylight/mdsal/model/ietf/util/MacUtil.java index e5ca1a7553..6861734aaa 100644 --- a/model/ietf/ietf-type-util/src/test/java/org/opendaylight/mdsal/model/ietf/util/MacUtil.java +++ b/model/ietf/ietf-type-util/src/test/java/org/opendaylight/mdsal/model/ietf/util/MacUtil.java @@ -8,13 +8,18 @@ package org.opendaylight.mdsal.model.ietf.util; -final class MacUtil extends AbstractIetfYangUtil { +final class MacUtil extends AbstractIetfYangUtil { MacUtil() { - super(MacClass.class); + super(MacClass.class, PhysClass.class); } @Override protected String getValue(final MacClass macAddress) { return macAddress.getValue(); } + + @Override + protected String getPhysValue(PhysClass physAddress) { + return physAddress.getValue(); + } } \ No newline at end of file diff --git a/model/ietf/ietf-type-util/src/test/java/org/opendaylight/mdsal/model/ietf/util/PhysClass.java b/model/ietf/ietf-type-util/src/test/java/org/opendaylight/mdsal/model/ietf/util/PhysClass.java new file mode 100644 index 0000000000..3cd1b0158c --- /dev/null +++ b/model/ietf/ietf-type-util/src/test/java/org/opendaylight/mdsal/model/ietf/util/PhysClass.java @@ -0,0 +1,26 @@ +/* + * Copyright (c) 2018 Pantheon Technologies, s.r.o. and others. All rights reserved. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License v1.0 which accompanies this distribution, + * and is available at http://www.eclipse.org/legal/epl-v10.html + */ +package org.opendaylight.mdsal.model.ietf.util; + +import static java.util.Objects.requireNonNull; + +public final class PhysClass { + private final String _value; + + public PhysClass(final String value) { + this._value = requireNonNull(value); + } + + public PhysClass(final PhysClass template) { + this._value = template._value; + } + + String getValue() { + return _value; + } +} \ No newline at end of file diff --git a/model/ietf/ietf-yang-types-20130715/src/main/java/org/opendaylight/yang/gen/v1/urn/ietf/params/xml/ns/yang/ietf/yang/types/rev130715/IetfYangUtil.java b/model/ietf/ietf-yang-types-20130715/src/main/java/org/opendaylight/yang/gen/v1/urn/ietf/params/xml/ns/yang/ietf/yang/types/rev130715/IetfYangUtil.java index 7ce9a0170c..d10452e19d 100644 --- a/model/ietf/ietf-yang-types-20130715/src/main/java/org/opendaylight/yang/gen/v1/urn/ietf/params/xml/ns/yang/ietf/yang/types/rev130715/IetfYangUtil.java +++ b/model/ietf/ietf-yang-types-20130715/src/main/java/org/opendaylight/yang/gen/v1/urn/ietf/params/xml/ns/yang/ietf/yang/types/rev130715/IetfYangUtil.java @@ -14,15 +14,20 @@ import org.opendaylight.mdsal.model.ietf.util.AbstractIetfYangUtil; * Utility methods for working with types defined in ietf-yang-types. */ @Beta -public final class IetfYangUtil extends AbstractIetfYangUtil { +public final class IetfYangUtil extends AbstractIetfYangUtil { public static final IetfYangUtil INSTANCE = new IetfYangUtil(); private IetfYangUtil() { - super(MacAddress.class); + super(MacAddress.class, PhysAddress.class); } @Override protected String getValue(final MacAddress macAddress) { return macAddress.getValue(); } + + @Override + protected String getPhysValue(final PhysAddress physAddress) { + return physAddress.getValue(); + } } -- 2.36.6