Add PhysAddress support 62/74362/7
authorRobert Varga <robert.varga@pantheon.tech>
Mon, 23 Jul 2018 23:11:36 +0000 (01:11 +0200)
committerRobert Varga <robert.varga@pantheon.tech>
Tue, 24 Jul 2018 09:46:14 +0000 (11:46 +0200)
This adds converions required for efficient PhysAddress support.

Change-Id: Ia07e07361fc0fdea3cc2a2b96e65643d60aef003
Signed-off-by: Robert Varga <robert.varga@pantheon.tech>
model/ietf/ietf-type-util/src/main/java/org/opendaylight/mdsal/model/ietf/util/AbstractIetfYangUtil.java
model/ietf/ietf-type-util/src/test/java/org/opendaylight/mdsal/model/ietf/util/AbstractIetfYangUtilTest.java
model/ietf/ietf-type-util/src/test/java/org/opendaylight/mdsal/model/ietf/util/MacClass.java
model/ietf/ietf-type-util/src/test/java/org/opendaylight/mdsal/model/ietf/util/MacUtil.java
model/ietf/ietf-type-util/src/test/java/org/opendaylight/mdsal/model/ietf/util/PhysClass.java [new file with mode: 0644]
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 0e01cc3976d75d335a7204b58d9008b4ac5b3a08..e9c6f33433313c4aea4d317d8998b659d1c5e875 100644 (file)
@@ -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 <M> mac-address type
+ * @param <P> phys-address type
  */
 @Beta
-public abstract class AbstractIetfYangUtil<T> {
+public abstract class AbstractIetfYangUtil<M, P> {
     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<T> {
         HEX_VALUES = b;
     }
 
-    private final StringValueObjectFactory<T> factory;
+    private final StringValueObjectFactory<M> macFactory;
+    private final StringValueObjectFactory<P> physFactory;
 
-    protected AbstractIetfYangUtil(final Class<T> clazz) {
-        this.factory = StringValueObjectFactory.create(clazz, "00:00:00:00:00:00");
+    protected AbstractIetfYangUtil(final Class<M> macClass, final Class<P> 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<T> {
         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]);
+    }
 }
index fa9484e7a4d687e9ff301af416d26e52fda85752..a9e5b7bf49df247268c62fe827b2f3e9d2076ef7 100644 (file)
@@ -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
+}
index 13577d665e1582739053aa52b7140d3aa54d931e..d08fbdd63512c0fae42fa19165d1bd61ac737ef8 100644 (file)
@@ -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) {
index e5ca1a75538f461758bff031d17c725ff99c8271..6861734aaa8f072f2f4ddfb745a852a9b275053f 100644 (file)
@@ -8,13 +8,18 @@
 
 package org.opendaylight.mdsal.model.ietf.util;
 
-final class MacUtil extends AbstractIetfYangUtil<MacClass> {
+final class MacUtil extends AbstractIetfYangUtil<MacClass, PhysClass> {
     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 (file)
index 0000000..3cd1b01
--- /dev/null
@@ -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
index 7ce9a0170c8aff5513332cadbef532d260f7942d..d10452e19d9f04de92c6299d6bd7ee754ee77782 100644 (file)
@@ -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<MacAddress> {
+public final class IetfYangUtil extends AbstractIetfYangUtil<MacAddress, PhysAddress> {
     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();
+    }
 }