Convert YAML Double to Integer/Long 47/116347/1
authorJim Hahn <jrh3@att.com>
Mon, 14 Dec 2020 16:36:50 +0000 (11:36 -0500)
committerJim Hahn <jrh3@att.com>
Mon, 14 Dec 2020 16:39:55 +0000 (11:39 -0500)
When a YAML number is decoded directly to type Object.class using the
decode() or fromJson() methods of the StandardYamlCoder, the number is
left as a Double.  It should be converted to an Integer or Long, where
possible.

Issue-ID: POLICY-2900
Change-Id: I7707ac5c54167cbc3a4b23985c6e5fa1a507324e
Signed-off-by: Jim Hahn <jrh3@att.com>
utils/src/main/java/org/onap/policy/common/utils/coder/StandardYamlCoder.java
utils/src/main/java/org/onap/policy/common/utils/coder/YamlJsonTranslator.java
utils/src/test/java/org/onap/policy/common/utils/coder/StandardYamlCoderTest.java

index c437596..d94ddca 100644 (file)
@@ -34,7 +34,12 @@ public class StandardYamlCoder extends StandardCoder {
      * Constructs the object.
      */
     public StandardYamlCoder() {
-        translator = new YamlJsonTranslator(gson);
+        translator = new YamlJsonTranslator(gson) {
+            @Override
+            protected <T> T convertFromDouble(Class<T> clazz, T value) {
+                return StandardYamlCoder.this.convertFromDouble(clazz, value);
+            }
+        };
     }
 
     @Override
index 906c9fd..7d61e63 100644 (file)
@@ -2,7 +2,7 @@
  * ============LICENSE_START=======================================================
  * ONAP
  * ================================================================================
- * Copyright (C) 2019 AT&T Intellectual Property. All rights reserved.
+ * Copyright (C) 2019-2020 AT&T Intellectual Property. All rights reserved.
  * ================================================================================
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -50,6 +50,11 @@ import org.yaml.snakeyaml.serializer.Serializer;
 /**
  * YAML-JSON translator. The methods may throw either of the runtime exceptions,
  * YAMLException or JsonSyntaxException.
+ * <p/>
+ * Note: if the invoker wishes Double to be converted to Integer/Long when type
+ * Object.class is requested, then a Gson object must be used that will perform the
+ * translation. In addition, the {@link #convertFromDouble(Class, Object)} method should
+ * be overridden with an appropriate conversion method.
  */
 public class YamlJsonTranslator {
 
@@ -147,7 +152,22 @@ public class YamlJsonTranslator {
      * @return a POJO representing the original element
      */
     protected <T> T fromJson(JsonElement jel, Class<T> clazz) {
-        return gson.fromJson(jel, clazz);
+        return convertFromDouble(clazz, gson.fromJson(jel, clazz));
+    }
+
+    /**
+     * Converts a value from Double to Integer/Long, walking the value's contents if it's
+     * a List/Map. Only applies if the specified class refers to the Object class.
+     * Otherwise, it leaves the value unchanged.
+     * <p/>
+     * The default method simply returns the original value.
+     *
+     * @param clazz class of object to be decoded
+     * @param value value to be converted
+     * @return the converted value
+     */
+    protected <T> T convertFromDouble(Class<T> clazz, T value) {
+        return value;
     }
 
     /**
index c770cd3..cadeb05 100644 (file)
@@ -96,6 +96,12 @@ public class StandardYamlCoderTest {
         YamlJsonTranslatorTest.verify(cont);
     }
 
+    @Test
+    public void testFromJsonDoubleToInteger() throws Exception {
+        Object value = coder.decode("20", Object.class);
+        assertEquals(Integer.valueOf(20), value);
+    }
+
     @Test
     public void testStandardTypeAdapter() throws Exception {
         String yaml = "abc: def\n";