Restapi-call-node: Faster conversion of context data 74/103674/1
authorsb5356 <sb5356@att.com>
Fri, 13 Mar 2020 14:24:03 +0000 (10:24 -0400)
committersb5356 <sb5356@att.com>
Fri, 13 Mar 2020 14:24:46 +0000 (10:24 -0400)
Issue-ID: CCSDK-2173
Signed-off-by: Stan Bonev <sb5356@att.com>
Change-Id: I57ea81f3ee69b4185627d074e73a480833c60bae

restapi-call-node/provider/src/main/java/org/onap/ccsdk/sli/plugins/restapicall/XmlJsonUtil.java

index ff32248..5e293d4 100644 (file)
@@ -22,6 +22,7 @@
 package org.onap.ccsdk.sli.plugins.restapicall;
 
 import java.util.ArrayList;
+import java.util.Collections;
 import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
@@ -31,6 +32,7 @@ import org.slf4j.LoggerFactory;
 
 public final class XmlJsonUtil {
 
+    @SuppressWarnings("unused")
     private static final Logger log = LoggerFactory.getLogger(XmlJsonUtil.class);
 
     private XmlJsonUtil() {
@@ -67,73 +69,178 @@ public final class XmlJsonUtil {
 
     private static Object createStructure(Map<String, String> flatmap, String var) {
         if (flatmap.containsKey(var)) {
-            if (var.endsWith("_length") || var.endsWith("].key")) {
-                return null;
-            }
             return flatmap.get(var);
         }
 
         Map<String, Object> mm = new HashMap<>();
-        for (String k : flatmap.keySet()) {
-            if (k.startsWith(var + ".")) {
-                int i1 = k.indexOf('.', var.length() + 1);
-                int i2 = k.indexOf('[', var.length() + 1);
-                int i3 = k.length();
-                if (i1 > 0 && i1 < i3) {
-                    i3 = i1;
-                }
-                if (i2 > 0 && i2 < i3) {
-                    i3 = i2;
-                }
-                String k1 = k.substring(var.length() + 1, i3);
-                String var1 = k.substring(0, i3);
-                if (!mm.containsKey(k1)) {
-                    Object str = createStructure(flatmap, var1);
-                    if (str != null && (!(str instanceof String) || ((String) str).trim().length() > 0)) {
-                        mm.put(k1, str);
-                    }
-                }
+        List<Object> ll = new ArrayList<>();
+
+        for (Map.Entry<String, String> e : flatmap.entrySet()) {
+            String key = e.getKey();
+            String value = e.getValue();
+
+            if (key.endsWith("_length") || key.endsWith("].key")) {
+                continue;
+            }
+
+            if (key.startsWith(var + "[")) {
+                String newKey = key.substring(var.length());
+                set(ll, newKey, value);
+            } else if (var == null || var.isEmpty()) {
+                set(mm, key, value);
+            } else if (key.startsWith(var + ".")) {
+                String newKey = key.substring(var.length() + 1);
+                set(mm, newKey, value);
             }
         }
+
         if (!mm.isEmpty()) {
             return mm;
         }
+        if (!ll.isEmpty()) {
+            return ll;
+        }
+        return null;
+    }
 
-        boolean arrayFound = false;
-        for (String k : flatmap.keySet()) {
-            if (k.startsWith(var + "[")) {
-                arrayFound = true;
-                break;
-            }
+    @SuppressWarnings("unchecked")
+    public static void set(Object struct, String compositeKey, Object value) {
+        if (struct == null) {
+            throw new IllegalArgumentException("Null argument: struct");
         }
 
-        if (arrayFound) {
-            List<Object> ll = new ArrayList<>();
+        if (compositeKey == null || compositeKey.length() == 0) {
+            throw new IllegalArgumentException("Null or empty argument: compositeKey");
+        }
 
-            int length = Integer.MAX_VALUE;
-            String lengthStr = flatmap.get(var + "_length");
-            if (lengthStr != null) {
-                try {
-                    length = Integer.parseInt(lengthStr);
-                } catch (Exception e) {
-                    log.warn("Invalid number for {}_length:{}", var, lengthStr, e);
+        if (value == null) {
+            return;
+        }
+
+        List<Object> keys = splitCompositeKey(compositeKey);
+        Object currentValue = struct;
+        String currentKey = "";
+
+        for (int i = 0; i < keys.size() - 1; i++) {
+            Object key = keys.get(i);
+
+            if (key instanceof Integer) {
+                if (!(currentValue instanceof List)) {
+                    throw new IllegalArgumentException("Cannot resolve: " + compositeKey + ": References list '" + currentKey + "', but '" + currentKey + "' is not a list");
+                }
+
+                Integer keyi = (Integer) key;
+                List<Object> currentValueL = (List<Object>) currentValue;
+                int size = currentValueL.size();
+
+                if (keyi >= size) {
+                    for (int k = 0; k < keyi - size + 1; k++) {
+                        currentValueL.add(null);
+                    }
+                }
+
+                Object newValue = currentValueL.get(keyi);
+                if (newValue == null) {
+                    Object nextKey = keys.get(i + 1);
+                    if (nextKey instanceof Integer) {
+                        newValue = new ArrayList<>();
+                    } else {
+                        newValue = new HashMap<>();
+                    }
+                    currentValueL.set(keyi, newValue);
+                }
+
+                currentValue = newValue;
+                currentKey += "[" + key + "]";
+
+            } else {
+                if (!(currentValue instanceof Map)) {
+                    throw new IllegalArgumentException("Cannot resolve: " + compositeKey + ": References map '" + currentKey + "', but '" + currentKey + "' is not a map");
                 }
+
+                Object newValue = ((Map<String, Object>) currentValue).get(key);
+                if (newValue == null) {
+                    Object nextKey = keys.get(i + 1);
+                    if (nextKey instanceof Integer) {
+                        newValue = new ArrayList<>();
+                    } else {
+                        newValue = new HashMap<>();
+                    }
+                    ((Map<String, Object>) currentValue).put((String) key, newValue);
+                }
+
+                currentValue = newValue;
+                currentKey += "." + key;
             }
+        }
 
-            for (int i = 0; i < length; i++) {
-                Object v = createStructure(flatmap, var + '[' + i + ']');
-                if (v == null) {
-                    break;
+        Object key = keys.get(keys.size() - 1);
+        if (key instanceof Integer) {
+            if (!(currentValue instanceof List)) {
+                throw new IllegalArgumentException("Cannot resolve: " + compositeKey + ": References list '" + currentKey + "', but '" + currentKey + "' is not a list");
+            }
+
+            Integer keyi = (Integer) key;
+            List<Object> currentValueL = (List<Object>) currentValue;
+            int size = currentValueL.size();
+
+            if (keyi >= size) {
+                for (int k = 0; k < keyi - size + 1; k++) {
+                    currentValueL.add(null);
                 }
-                ll.add(v);
             }
 
-            if (!ll.isEmpty()) {
-                return ll;
+            currentValueL.set(keyi, value);
+
+        } else {
+            if (!(currentValue instanceof Map)) {
+                throw new IllegalArgumentException("Cannot resolve: " + compositeKey + ": References map '" + currentKey + "', but '" + currentKey + "' is not a map");
             }
+
+            ((Map<String, Object>) currentValue).put((String) key, value);
         }
+    }
 
-        return null;
+    private static List<Object> splitCompositeKey(String compositeKey) {
+        if (compositeKey == null) {
+            return Collections.emptyList();
+        }
+
+        String[] ss = compositeKey.split("\\.");
+        List<Object> ll = new ArrayList<>();
+        for (String s : ss) {
+            if (s.length() == 0) {
+                continue;
+            }
+
+            int i1 = s.indexOf('[');
+            if (i1 < 0) {
+                ll.add(s);
+            } else {
+                if (!s.endsWith("]")) {
+                    throw new IllegalArgumentException("Invalid composite key: " + compositeKey + ": No matching ] found");
+                }
+
+                String s1 = s.substring(0, i1);
+                if (s1.length() > 0) {
+                    ll.add(s1);
+                }
+
+                String s2 = s.substring(i1 + 1, s.length() - 1);
+                try {
+                    int n = Integer.parseInt(s2);
+                    if (n < 0) {
+                        throw new IllegalArgumentException("Invalid composite key: " + compositeKey + ": Index must be >= 0: " + n);
+                    }
+
+                    ll.add(n);
+                } catch (NumberFormatException e) {
+                    throw new IllegalArgumentException("Invalid composite key: " + compositeKey + ": Index not a number: " + s2);
+                }
+            }
+        }
+
+        return ll;
     }
 
     @SuppressWarnings("unchecked")