Convert base types to implement CanonicalValue 90/70990/6
authorRobert Varga <robert.varga@pantheon.tech>
Mon, 16 Apr 2018 16:27:54 +0000 (18:27 +0200)
committerRobert Varga <robert.varga@pantheon.tech>
Tue, 17 Apr 2018 00:27:57 +0000 (02:27 +0200)
With CanonicalValue concept defined we can now retrofit into our
base support types for YANG. Aside from the canonical representation
which these classes provided, this allows them to communicate
value validation as needed.

Change-Id: I3ea24ecc2cbf3c2e23a3020b722b7a038f62b321
Signed-off-by: Robert Varga <robert.varga@pantheon.tech>
yang/yang-common/src/main/java/org/opendaylight/yangtools/yang/common/Decimal64.java
yang/yang-common/src/main/java/org/opendaylight/yangtools/yang/common/Uint16.java
yang/yang-common/src/main/java/org/opendaylight/yangtools/yang/common/Uint32.java
yang/yang-common/src/main/java/org/opendaylight/yangtools/yang/common/Uint64.java
yang/yang-common/src/main/java/org/opendaylight/yangtools/yang/common/Uint8.java
yang/yang-common/src/test/java/org/opendaylight/yangtools/yang/common/Decimal64Test.java

index dc30514253f4a5a0060b17474cb6addf8162e6f9..5fba2e0e3fe8e700c621d38f3e90c770a3707ade 100644 (file)
@@ -14,7 +14,8 @@ import com.google.common.annotations.Beta;
 import com.google.common.annotations.VisibleForTesting;
 import com.google.common.base.Strings;
 import java.math.BigDecimal;
-import org.opendaylight.yangtools.concepts.Immutable;
+import org.eclipse.jdt.annotation.NonNullByDefault;
+import org.eclipse.jdt.annotation.Nullable;
 
 /**
  * Dedicated type for YANG's 'type decimal64' type. This class is similar to {@link BigDecimal}, but provides more
@@ -23,7 +24,20 @@ import org.opendaylight.yangtools.concepts.Immutable;
  * @author Robert Varga
  */
 @Beta
-public class Decimal64 extends Number implements Comparable<Decimal64>, Immutable {
+@NonNullByDefault
+public class Decimal64 extends Number implements CanonicalValue<Decimal64> {
+    private static final class Support extends AbstractCanonicalValueSupport<Decimal64> {
+        Support() {
+            super(Decimal64.class);
+        }
+
+        @Override
+        public Decimal64 fromString(final String str) {
+            return Decimal64.valueOf(str);
+        }
+    }
+
+    private static final CanonicalValueSupport<Decimal64> SUPPORT = new Support();
     private static final long serialVersionUID = 1L;
 
     private static final int MAX_FRACTION_DIGITS = 18;
@@ -301,6 +315,32 @@ public class Decimal64 extends Number implements Comparable<Decimal64>, Immutabl
         return Double.compare(doubleValue(), o.doubleValue());
     }
 
+    @Override
+    public final String toCanonicalString() {
+        // https://tools.ietf.org/html/rfc6020#section-9.3.2
+        //
+        // The canonical form of a positive decimal64 does not include the sign
+        // "+".  The decimal point is required.  Leading and trailing zeros are
+        // prohibited, subject to the rule that there MUST be at least one digit
+        // before and after the decimal point.  The value zero is represented as
+        // "0.0".
+        final StringBuilder sb = new StringBuilder(21).append(intPart()).append('.');
+        final long fracPart = fracPart();
+        if (fracPart != 0) {
+            // We may need to zero-pad the fraction part
+            sb.append(Strings.padStart(Long.toString(fracPart), scaleOffset + 1, '0'));
+        } else {
+            sb.append('0');
+        }
+
+        return sb.toString();
+    }
+
+    @Override
+    public final CanonicalValueSupport<Decimal64> support() {
+        return SUPPORT;
+    }
+
     @Override
     public final int hashCode() {
         // We need to normalize the results in order to be consistent with equals()
@@ -308,7 +348,7 @@ public class Decimal64 extends Number implements Comparable<Decimal64>, Immutabl
     }
 
     @Override
-    public final boolean equals(final Object obj) {
+    public final boolean equals(final @Nullable Object obj) {
         if (this == obj) {
             return true;
         }
@@ -326,23 +366,7 @@ public class Decimal64 extends Number implements Comparable<Decimal64>, Immutabl
 
     @Override
     public final String toString() {
-        // https://tools.ietf.org/html/rfc6020#section-9.3.2
-        //
-        // The canonical form of a positive decimal64 does not include the sign
-        // "+".  The decimal point is required.  Leading and trailing zeros are
-        // prohibited, subject to the rule that there MUST be at least one digit
-        // before and after the decimal point.  The value zero is represented as
-        // "0.0".
-        final StringBuilder sb = new StringBuilder(21).append(intPart()).append('.');
-        final long fracPart = fracPart();
-        if (fracPart != 0) {
-            // We may need to zero-pad the fraction part
-            sb.append(Strings.padStart(Long.toString(fracPart), scaleOffset + 1, '0'));
-        } else {
-            sb.append('0');
-        }
-
-        return sb.toString();
+        return toCanonicalString();
     }
 
     private long intPart() {
index 7b9e50f0cb6aa97ebce356ba7f0eaaa18db1cdd3..cc28bd1b3ba963663ca53986926a6d1d07231a40 100644 (file)
@@ -13,7 +13,8 @@ import com.google.common.annotations.Beta;
 import com.google.common.cache.CacheBuilder;
 import com.google.common.cache.CacheLoader;
 import com.google.common.cache.LoadingCache;
-import org.opendaylight.yangtools.concepts.Immutable;
+import org.eclipse.jdt.annotation.NonNullByDefault;
+import org.eclipse.jdt.annotation.Nullable;
 
 /**
  * Dedicated type for YANG's 'type uint16' type.
@@ -21,7 +22,20 @@ import org.opendaylight.yangtools.concepts.Immutable;
  * @author Robert Varga
  */
 @Beta
-public class Uint16 extends Number implements Comparable<Uint16>, Immutable {
+@NonNullByDefault
+public class Uint16 extends Number implements CanonicalValue<Uint16> {
+    private static final class Support extends AbstractCanonicalValueSupport<Uint16> {
+        Support() {
+            super(Uint16.class);
+        }
+
+        @Override
+        public Uint16 fromString(final String str) {
+            return Uint16.valueOf(str);
+        }
+    }
+
+    private static final CanonicalValueSupport<Uint16> SUPPORT = new Support();
     private static final long serialVersionUID = 1L;
     private static final int MIN_VALUE = 0;
     private static final int MAX_VALUE = 65535;
@@ -173,19 +187,29 @@ public class Uint16 extends Number implements Comparable<Uint16>, Immutable {
         return Integer.compare(intValue(), o.intValue());
     }
 
+    @Override
+    public final String toCanonicalString() {
+        return String.valueOf(intValue());
+    }
+
+    @Override
+    public final CanonicalValueSupport<Uint16> support() {
+        return SUPPORT;
+    }
+
     @Override
     public final int hashCode() {
         return Short.hashCode(value);
     }
 
     @Override
-    public final boolean equals(final Object obj) {
+    public final boolean equals(final @Nullable Object obj) {
         return this == obj || obj instanceof Uint16 && value == ((Uint16)obj).value;
     }
 
     @Override
     public final String toString() {
-        return String.valueOf(intValue());
+        return toCanonicalString();
     }
 
     private Object readResolve() {
index 5dfe09921204c81227709cdd5dd5d439aee40578..d5ddd002aa2e5defd3cc29c239b4f3a3313834ca 100644 (file)
@@ -14,7 +14,8 @@ import com.google.common.cache.CacheBuilder;
 import com.google.common.cache.CacheLoader;
 import com.google.common.cache.LoadingCache;
 import com.google.common.primitives.UnsignedInteger;
-import org.opendaylight.yangtools.concepts.Immutable;
+import org.eclipse.jdt.annotation.NonNullByDefault;
+import org.eclipse.jdt.annotation.Nullable;
 
 /**
  * Dedicated type for YANG's 'type uint32' type.
@@ -22,7 +23,20 @@ import org.opendaylight.yangtools.concepts.Immutable;
  * @author Robert Varga
  */
 @Beta
-public class Uint32 extends Number implements Comparable<Uint32>, Immutable {
+@NonNullByDefault
+public class Uint32 extends Number implements CanonicalValue<Uint32> {
+    private static final class Support extends AbstractCanonicalValueSupport<Uint32> {
+        Support() {
+            super(Uint32.class);
+        }
+
+        @Override
+        public Uint32 fromString(final String str) {
+            return Uint32.valueOf(str);
+        }
+    }
+
+    private static final CanonicalValueSupport<Uint32> SUPPORT = new Support();
     private static final long serialVersionUID = 1L;
     private static final long MIN_VALUE = 0;
     private static final long MAX_VALUE = 0xffffffffL;
@@ -179,19 +193,29 @@ public class Uint32 extends Number implements Comparable<Uint32>, Immutable {
         return Integer.compareUnsigned(value, o.value);
     }
 
+    @Override
+    public final String toCanonicalString() {
+        return Integer.toUnsignedString(value);
+    }
+
+    @Override
+    public final CanonicalValueSupport<Uint32> support() {
+        return SUPPORT;
+    }
+
     @Override
     public final int hashCode() {
         return Integer.hashCode(value);
     }
 
     @Override
-    public final boolean equals(final Object obj) {
+    public final boolean equals(final @Nullable Object obj) {
         return this == obj || obj instanceof Uint32 && value == ((Uint32)obj).value;
     }
 
     @Override
     public final String toString() {
-        return Integer.toUnsignedString(value);
+        return toCanonicalString();
     }
 
     private Object readResolve() {
index 3480b938bc295186ee1f2235c363e962b68cf314..71af5e8c7270e706c77aa58a9040e7d32c5b88f0 100644 (file)
@@ -15,7 +15,8 @@ import com.google.common.cache.CacheLoader;
 import com.google.common.cache.LoadingCache;
 import com.google.common.primitives.UnsignedLong;
 import java.math.BigInteger;
-import org.opendaylight.yangtools.concepts.Immutable;
+import org.eclipse.jdt.annotation.NonNullByDefault;
+import org.eclipse.jdt.annotation.Nullable;
 
 /**
  * Dedicated type for YANG's 'type uint64' type.
@@ -23,7 +24,20 @@ import org.opendaylight.yangtools.concepts.Immutable;
  * @author Robert Varga
  */
 @Beta
-public class Uint64 extends Number implements Comparable<Uint64>, Immutable {
+@NonNullByDefault
+public class Uint64 extends Number implements CanonicalValue<Uint64> {
+    private static final class Support extends AbstractCanonicalValueSupport<Uint64> {
+        Support() {
+            super(Uint64.class);
+        }
+
+        @Override
+        public Uint64 fromString(final String str) {
+            return Uint64.valueOf(str);
+        }
+    }
+
+    private static final CanonicalValueSupport<Uint64> SUPPORT = new Support();
     private static final long serialVersionUID = 1L;
     private static final long MIN_VALUE = 0;
 
@@ -189,19 +203,29 @@ public class Uint64 extends Number implements Comparable<Uint64>, Immutable {
         return Long.compareUnsigned(value, o.value);
     }
 
+    @Override
+    public final String toCanonicalString() {
+        return Long.toUnsignedString(value);
+    }
+
+    @Override
+    public final CanonicalValueSupport<Uint64> support() {
+        return SUPPORT;
+    }
+
     @Override
     public final int hashCode() {
         return Long.hashCode(value);
     }
 
     @Override
-    public final boolean equals(final Object obj) {
+    public final boolean equals(final @Nullable Object obj) {
         return this == obj || obj instanceof Uint64 && value == ((Uint64)obj).value;
     }
 
     @Override
     public final String toString() {
-        return Long.toUnsignedString(value);
+        return toCanonicalString();
     }
 
     private Object readResolve() {
index 1def9c4759606965228a99d33758d2e2afb3f9ab..6dd45c4c64884c34c98e89f2bd5848c0443e319b 100644 (file)
@@ -10,7 +10,8 @@ package org.opendaylight.yangtools.yang.common;
 import static com.google.common.base.Preconditions.checkArgument;
 
 import com.google.common.annotations.Beta;
-import org.opendaylight.yangtools.concepts.Immutable;
+import org.eclipse.jdt.annotation.NonNullByDefault;
+import org.eclipse.jdt.annotation.Nullable;
 
 /**
  * Dedicated type for YANG's 'type uint8' type.
@@ -18,7 +19,21 @@ import org.opendaylight.yangtools.concepts.Immutable;
  * @author Robert Varga
  */
 @Beta
-public class Uint8 extends Number implements Comparable<Uint8>, Immutable {
+@NonNullByDefault
+public class Uint8 extends Number implements CanonicalValue<Uint8> {
+    private static final class Support extends AbstractCanonicalValueSupport<Uint8> {
+        Support() {
+            super(Uint8.class);
+        }
+
+        @Override
+        public Uint8 fromString(final String str) {
+            return Uint8.valueOf(str);
+        }
+    }
+
+    private static final CanonicalValueSupport<Uint8> SUPPORT = new Support();
+
     static final short MIN_VALUE = 0;
     static final short MAX_VALUE = 255;
 
@@ -127,19 +142,29 @@ public class Uint8 extends Number implements Comparable<Uint8>, Immutable {
         return intValue() - o.intValue();
     }
 
+    @Override
+    public final String toCanonicalString() {
+        return String.valueOf(intValue());
+    }
+
+    @Override
+    public final CanonicalValueSupport<Uint8> support() {
+        return SUPPORT;
+    }
+
     @Override
     public final int hashCode() {
         return Byte.hashCode(value);
     }
 
     @Override
-    public final boolean equals(final Object obj) {
+    public final boolean equals(final @Nullable Object obj) {
         return this == obj || obj instanceof Uint8 && value == ((Uint8)obj).value;
     }
 
     @Override
     public final String toString() {
-        return String.valueOf(intValue());
+        return toCanonicalString();
     }
 
     private Object readResolve() {
index c6a52b22c3254e52bd66b95eac196c47b3b36d8c..45b1234e99907975bc1eb48abf07e6bd7dcc0d31 100644 (file)
@@ -56,11 +56,6 @@ public class Decimal64Test {
         Decimal64.valueOf(".a");
     }
 
-    @Test(expected = NullPointerException.class)
-    public void testParseNull() {
-        Decimal64.valueOf((String)null);
-    }
-
     @Test(expected = NumberFormatException.class)
     public void testParseMinus() {
         Decimal64.valueOf("-");