Implement new method to convert SvcLogicContext to JSON 97/109197/11
authorDan Timoney <dtimoney@att.com>
Tue, 16 Jun 2020 14:15:13 +0000 (10:15 -0400)
committerDan Timoney <dtimoney@att.com>
Fri, 19 Jun 2020 12:00:50 +0000 (08:00 -0400)
Added new method toJsonString() to SvcLogicContext class to write out
service logic context properties as a JSON string

Refactored static method SliPluginUtils.writeJsonToCtx to SvcLogicContext.mergeJson method

Change-Id: I4fe134976f93c7d116bc54ad2bae6e486c6fac2c
Issue-ID: CCSDK-1760
Signed-off-by: Dan Timoney <dtimoney@att.com>
15 files changed:
sli/common/pom.xml
sli/common/src/main/java/org/onap/ccsdk/sli/core/sli/SvcLogicContext.java
sli/common/src/test/java/org/onap/ccsdk/sli/core/sli/SvcLogicContextTest.java
sli/common/src/test/resources/2dArray.json [new file with mode: 0644]
sli/common/src/test/resources/3dArray.json [new file with mode: 0644]
sli/common/src/test/resources/ArrayMenu.json [new file with mode: 0644]
sli/common/src/test/resources/EmbeddedEscapedJson.json [new file with mode: 0644]
sli/common/src/test/resources/EscapedJson.json [new file with mode: 0644]
sli/common/src/test/resources/JsonObject.json [new file with mode: 0644]
sli/common/src/test/resources/ObjectMenu.json [new file with mode: 0644]
sli/common/src/test/resources/QuotedValues.json [new file with mode: 0644]
sli/common/src/test/resources/Widget.json [new file with mode: 0644]
sli/common/src/test/resources/log4j2.properties [new file with mode: 0644]
sliPluginUtils/provider/src/main/java/org/onap/ccsdk/sli/core/slipluginutils/SliPluginUtils.java
sliPluginUtils/provider/src/test/java/org/onap/ccsdk/sli/core/slipluginutils/SliPluginUtils_StaticFunctionsTest.java

index 16efd0e..efc66aa 100755 (executable)
             <artifactId>mockito-core</artifactId>
             <scope>test</scope>
         </dependency>
+        <dependency>
+            <groupId>org.skyscreamer</groupId>
+            <artifactId>jsonassert</artifactId>
+            <version>1.5.0</version>
+            <scope>test</scope>
+        </dependency>
     </dependencies>
 
     <build>
index fcd51d1..f07f71f 100644 (file)
 
 package org.onap.ccsdk.sli.core.sli;
 
-import java.util.HashMap;
-import java.util.Map;
-import java.util.Properties;
-import java.util.Set;
+import java.util.*;
 
 import com.google.gson.*;
 import org.slf4j.Logger;
@@ -38,74 +35,68 @@ import org.w3c.dom.Text;
 
 public class SvcLogicContext {
 
-       private static final Logger LOG = LoggerFactory.getLogger(SvcLogicContext.class);
+    private static final Logger LOG = LoggerFactory.getLogger(SvcLogicContext.class);
 
-       private HashMap<String, String> attributes;
+    public static final String CTX_NULL_VALUE="";
+    private static final String LENGTH="_length";
+
+    private HashMap<String, String> attributes;
 
     private String status = SvcLogicConstants.SUCCESS;
 
-       public SvcLogicContext()
-       {
-               this.attributes = new HashMap<> ();
-
-       }
-
-       public SvcLogicContext(Properties props)
-       {
-               this.attributes = new HashMap<> ();
-
-               if (props.containsKey(CommonConstants.SERVICE_LOGIC_STATUS))
-               {
-                       this.status = props.getProperty(CommonConstants.SERVICE_LOGIC_STATUS);
-               }
-
-               for (Object nameObj : props.keySet())
-               {
-                       String propName = (String) nameObj;
-                       attributes.put(propName, props.getProperty(propName));
-               }
-       }
-
-       public String getAttribute(String name)
-       {
-               if (attributes.containsKey(name))
-               {
-                       return attributes.get(name);
-               }
-               else
-               {
-                       return null;
-               }
-       }
-
-       public void setAttribute(String name, String value)
-       {
-               if (value == null) {
-                       if (attributes.containsKey(name)) {
-                               attributes.remove(name);
-                       }
-               } else {
-                       attributes.put(name, value);
-               }
-       }
-
-       public Set<String> getAttributeKeySet()
-       {
-               return attributes.keySet();
-       }
+    public SvcLogicContext() {
+        this.attributes = new HashMap<>();
+
+    }
+
+    public SvcLogicContext(Properties props) {
+        this.attributes = new HashMap<>();
+
+        if (props.containsKey(CommonConstants.SERVICE_LOGIC_STATUS)) {
+            this.status = props.getProperty(CommonConstants.SERVICE_LOGIC_STATUS);
+        }
+
+        for (Object nameObj : props.keySet()) {
+            String propName = (String) nameObj;
+            attributes.put(propName, props.getProperty(propName));
+        }
+    }
+
+    public String getAttribute(String name) {
+        if (attributes.containsKey(name)) {
+            return attributes.get(name);
+        } else {
+            return null;
+        }
+    }
+
+    public void setAttribute(String name, String value) {
+        if (value == null) {
+            if (attributes.containsKey(name)) {
+                attributes.remove(name);
+            }
+        } else {
+            attributes.put(name, value);
+        }
+    }
+
+    public Set<String> getAttributeKeySet() {
+        return attributes.keySet();
+    }
+
     public Boolean isSuccess() {
         return status.equals(SvcLogicConstants.SUCCESS);
-  }
+    }
 
     @Deprecated
-       public String getStatus() {
-               return status;
-       }
+    public String getStatus() {
+        return status;
+    }
 
     @Deprecated
-       public void setStatus(String status) {
-               this.status = status;
-       }
+    public void setStatus(String status) {
+        this.status = status;
+    }
 
     public void markFailed() {
         this.status = SvcLogicConstants.FAILURE;
@@ -115,167 +106,313 @@ public class SvcLogicContext {
         this.status = SvcLogicConstants.SUCCESS;
     }
 
-       public Properties toProperties()
-       {
-               Properties props = new Properties();
+    public Properties toProperties() {
+        Properties props = new Properties();
+
+        if (status != null) {
+            props.setProperty(CommonConstants.SERVICE_LOGIC_STATUS, status);
+        }
+
+        String attrName;
+        String attrVal;
+        for (Map.Entry<String, String> entry : attributes.entrySet()) {
+            attrName = entry.getKey();
+            attrVal = entry.getValue();
+            if (attrVal == null) {
+                LOG.warn("attribute {} value is null - setting to empty string", attrName);
+                props.setProperty(attrName, "");
+            } else {
+                props.setProperty(attrName, attrVal);
+            }
+        }
+
+        return props;
+    }
+
+    public void mergeDocument(String pfx, Document doc) {
+        String prefix = "";
+
+        if (pfx != null) {
+            prefix = pfx;
+        }
+
+        Element root = doc.getDocumentElement();
+
+        mergeElement(prefix, root, null);
+    }
+
+    public void mergeElement(String pfx, Element element, Map<String, Integer> nodeMap) {
+
+        // In XML, cannot tell the difference between containers and lists.
+        // So, have to treat each element as both (ugly but necessary).
+        // We do this by passing a nodeMap to be used to count instance of each tag,
+        // which will be used to set _length and to set index
 
-               if (status != null)
-               {
-                       props.setProperty(CommonConstants.SERVICE_LOGIC_STATUS, status);
-               }
+        LOG.trace("mergeElement({},{},{})", pfx, element.getTagName(), nodeMap);
 
-               String attrName;
-               String attrVal;
-               for (Map.Entry<String, String> entry : attributes.entrySet())
-               {
-                       attrName = entry.getKey();
-                       attrVal = entry.getValue();
-                       if (attrVal == null) {
-                               LOG.warn("attribute {} value is null - setting to empty string", attrName);
-                               props.setProperty(attrName, "");
-                       } else {
-                               props.setProperty(attrName, attrVal);
-                       }
-               }
-
-               return props;
-       }
+        String curTagName = element.getTagName();
+        String prefix = curTagName;
 
-       public void mergeDocument(String pfx, Document doc) {
-               String prefix = "";
+        if (pfx != null) {
+            prefix = pfx + "." + prefix;
+        }
 
-               if (pfx != null) {
-                       prefix = pfx;
-               }
+        int myIdx = 0;
 
-               Element root = doc.getDocumentElement();
-
-               mergeElement(prefix, root, null);
-       }
-
-       public void mergeElement(String pfx, Element element, Map<String, Integer> nodeMap) {
-
-               // In XML, cannot tell the difference between containers and lists.
-               // So, have to treat each element as both (ugly but necessary).
-               // We do this by passing a nodeMap to be used to count instance of each tag,
-               // which will be used to set _length and to set index
-
-               LOG.trace("mergeElement({},{},{})", pfx, element.getTagName(), nodeMap);
-
-               String curTagName = element.getTagName();
-               String prefix = curTagName;
-
-               if (pfx != null) {
-                       prefix = pfx + "." + prefix;
-               }
-
-               int myIdx = 0;
-
-               if (nodeMap != null) {
-                       if (nodeMap.containsKey(curTagName)) {
-                               myIdx = nodeMap.get(curTagName);
-                       }
-
-                       nodeMap.put(curTagName, myIdx+1);
-                       this.setAttribute(prefix+"_length", Integer.toString(myIdx+1));
-               }
-
-               NodeList children = element.getChildNodes();
-
-               int numChildren  = children.getLength();
-
-               Map<String, Integer> childMap = new HashMap<>();
-               Map<String, Integer> idxChildMap = new HashMap<>();
-
-               for (int i = 0 ; i < numChildren ; i++) {
-                       Node curNode = children.item(i);
-
-                       if (curNode instanceof Text) {
-                               Text curText = (Text) curNode;
-                               String curTextValue = curText.getTextContent();
-                               LOG.trace("Setting ctx variable {} = {}", prefix, curTextValue);
-                               this.setAttribute(prefix, curText.getTextContent());
-
-
-                       } else if (curNode instanceof Element) {
-                               mergeElement(prefix, (Element) curNode, childMap);
-                               if (nodeMap != null) {
-
-                                       mergeElement(prefix+"["+myIdx+"]", (Element)curNode, idxChildMap);
-
-                               }
-                       }
-               }
-
-       }
-
-       public void mergeJson(String pfx, String jsonString) {
-               JsonParser jp = new JsonParser();
-               JsonElement element = jp.parse(jsonString);
-
-               mergeJsonObject(element.getAsJsonObject(), pfx+".");
-       }
-
-       public void mergeJsonObject(JsonObject jsonObject, String pfx) {
-               for (Map.Entry<String, JsonElement> entry : jsonObject.entrySet()) {
-                       if (entry.getValue().isJsonObject()) {
-                               mergeJsonObject(entry.getValue().getAsJsonObject(), pfx + entry.getKey() + ".");
-                       } else if (entry.getValue().isJsonArray()) {
-                               JsonArray array = entry.getValue().getAsJsonArray();
-                               this.setAttribute(pfx + entry.getKey() + "_length", String.valueOf(array.size()));
-                               Integer arrayIdx = 0;
-                               for (JsonElement element : array) {
-                                       if (element.isJsonObject()) {
-                                               mergeJsonObject(element.getAsJsonObject(), pfx + entry.getKey() + "[" + arrayIdx + "].");
-                                       }
-                                       arrayIdx++;
-                               }
-                       } else {
-                               if (entry.getValue() instanceof JsonNull) {
-                                       LOG.debug("Skipping parameter {} with null value",entry.getKey());
-
-                               } else {
-                                       this.setAttribute(pfx + entry.getKey(), entry.getValue().getAsString());
-                               }
-                       }
-               }
-       }
+        if (nodeMap != null) {
+            if (nodeMap.containsKey(curTagName)) {
+                myIdx = nodeMap.get(curTagName);
+            }
 
-       public String resolve(String ctxVarName) {
-
-               if (ctxVarName.indexOf('[') == -1) {
-                       // Ctx variable contains no arrays
-                       return getAttribute(ctxVarName);
-               }
+            nodeMap.put(curTagName, myIdx + 1);
+            this.setAttribute(prefix + "_length", Integer.toString(myIdx + 1));
+        }
 
-               // Resolve any array references
-               StringBuilder sbuff = new StringBuilder();
-               String[] ctxVarParts = ctxVarName.split("\\[");
-               sbuff.append(ctxVarParts[0]);
-               for (int i = 1; i < ctxVarParts.length; i++) {
-                       if (ctxVarParts[i].startsWith("$")) {
-                               int endBracketLoc = ctxVarParts[i].indexOf(']');
-                               if (endBracketLoc == -1) {
-                                       // Missing end bracket ... give up parsing
-                                       LOG.warn("Variable reference {} seems to be missing a ']'", ctxVarName);
-                                       return getAttribute(ctxVarName);
-                               }
-
-                               String idxVarName = ctxVarParts[i].substring(1, endBracketLoc);
-                               String remainder = ctxVarParts[i].substring(endBracketLoc);
-
-                               sbuff.append("[");
-                               sbuff.append(this.getAttribute(idxVarName));
-                               sbuff.append(remainder);
-
-                       } else {
-                               // Index is not a variable reference
-                               sbuff.append("[");
-                               sbuff.append(ctxVarParts[i]);
-                       }
-               }
-
-               return getAttribute(sbuff.toString());
-       }
+        NodeList children = element.getChildNodes();
 
+        int numChildren = children.getLength();
+
+        Map<String, Integer> childMap = new HashMap<>();
+        Map<String, Integer> idxChildMap = new HashMap<>();
+
+        for (int i = 0; i < numChildren; i++) {
+            Node curNode = children.item(i);
+
+            if (curNode instanceof Text) {
+                Text curText = (Text) curNode;
+                String curTextValue = curText.getTextContent();
+                LOG.trace("Setting ctx variable {} = {}", prefix, curTextValue);
+                this.setAttribute(prefix, curText.getTextContent());
+
+
+            } else if (curNode instanceof Element) {
+                mergeElement(prefix, (Element) curNode, childMap);
+                if (nodeMap != null) {
+
+                    mergeElement(prefix + "[" + myIdx + "]", (Element) curNode, idxChildMap);
+
+                }
+            }
+        }
+
+    }
+
+    public void mergeJson(String pfx, String jsonString) {
+
+        JsonParser jp = new JsonParser();
+        JsonElement element = jp.parse(jsonString);
+        String root = "";
+        if ((pfx != null) && (pfx.length() > 0)) {
+            root = pfx + ".";
+        }
+        if (element.isJsonObject()) {
+            writeJsonObject(element.getAsJsonObject(), root);
+        } else if (element.isJsonArray()) {
+            handleJsonArray("", element.getAsJsonArray(), root);
+        }
+    }
+
+
+    protected void writeJsonObject(JsonObject obj, String root) {
+        for (Map.Entry<String, JsonElement> entry : obj.entrySet()) {
+            String key = entry.getKey();
+            if (entry.getValue().isJsonObject()) {
+                writeJsonObject(entry.getValue().getAsJsonObject(), root + key + ".");
+            } else if (entry.getValue().isJsonArray()) {
+                JsonArray array = entry.getValue().getAsJsonArray();
+                handleJsonArray(key, array, root);
+            } else {
+                //Handles when a JSON obj is nested within a JSON obj
+                if(!root.endsWith(".")){
+                    root = root + ".";
+                }
+                if(entry.getValue().isJsonNull()) {
+                    this.setAttribute(root + key, CTX_NULL_VALUE);
+                }else {
+                    this.setAttribute(root + key, entry.getValue().getAsString());
+                }
+            }
+        }
+    }
+
+    protected void handleJsonArray(String key, JsonArray array,  String root) {
+        this.setAttribute(root + key + LENGTH, String.valueOf(array.size()));
+        Integer arrayIdx = 0;
+        for (JsonElement element : array) {
+            String prefix = root + key + "[" + arrayIdx + "]";
+
+            if (element.isJsonArray()) {
+                handleJsonArray(key, element.getAsJsonArray(), prefix);
+            } else if (element.isJsonObject()) {
+                writeJsonObject(element.getAsJsonObject(),  prefix + ".");
+            } else if (element.isJsonNull()) {
+                this.setAttribute(prefix, CTX_NULL_VALUE);
+            } else if (element.isJsonPrimitive()) {
+                this.setAttribute(prefix, element.getAsString());
+            }
+            arrayIdx++;
+        }
+    }
+
+
+    public String resolve(String ctxVarName) {
+
+        if (ctxVarName.indexOf('[') == -1) {
+            // Ctx variable contains no arrays
+            return getAttribute(ctxVarName);
+        }
+
+        // Resolve any array references
+        StringBuilder sbuff = new StringBuilder();
+        String[] ctxVarParts = ctxVarName.split("\\[");
+        sbuff.append(ctxVarParts[0]);
+        for (int i = 1; i < ctxVarParts.length; i++) {
+            if (ctxVarParts[i].startsWith("$")) {
+                int endBracketLoc = ctxVarParts[i].indexOf(']');
+                if (endBracketLoc == -1) {
+                    // Missing end bracket ... give up parsing
+                    LOG.warn("Variable reference {} seems to be missing a ']'", ctxVarName);
+                    return getAttribute(ctxVarName);
+                }
+
+                String idxVarName = ctxVarParts[i].substring(1, endBracketLoc);
+                String remainder = ctxVarParts[i].substring(endBracketLoc);
+
+                sbuff.append("[");
+                sbuff.append(this.getAttribute(idxVarName));
+                sbuff.append(remainder);
+
+            } else {
+                // Index is not a variable reference
+                sbuff.append("[");
+                sbuff.append(ctxVarParts[i]);
+            }
+        }
+
+        return getAttribute(sbuff.toString());
+    }
+
+    public String toJsonString(String pfx) {
+        JsonParser jp = new JsonParser();
+
+        String jsonString = this.toJsonString();
+        JsonObject jsonRoot = (JsonObject) jp.parse(jsonString);
+        JsonObject targetJson = jsonRoot.getAsJsonObject(pfx);
+        return(targetJson.toString());
+    }
+
+    public String toJsonString() {
+        JsonObject root = new JsonObject();
+        JsonElement lastJsonObject = root;
+        JsonElement currJsonLeaf = root;
+
+        String attrName = null;
+        String attrVal = null;
+
+        // Sort properties so that arrays will be reconstructed in proper order
+        TreeMap<String, String> sortedAttributes = new TreeMap<>();
+        sortedAttributes.putAll(attributes);
+
+        // Loop through properties, sorted by key
+        for (Map.Entry<String, String> entry : sortedAttributes.entrySet()) {
+            attrName = entry.getKey();
+            attrVal = entry.getValue();
+
+            currJsonLeaf = root;
+            String curFieldName = null;
+            JsonArray curArray = null;
+            lastJsonObject = null;
+            boolean addNeeded = false;
+
+            // Split property names by period and iterate through parts
+            for (String attrNamePart : attrName.split("\\.")) {
+
+               // Add last object found to JSON tree.  Need to handle
+                               // this way because last element found (leaf) needs to be
+                               // assigned the property value.
+                if (lastJsonObject != null) {
+                    if (addNeeded) {
+                        if (currJsonLeaf.isJsonArray()) {
+                            ((JsonArray) currJsonLeaf).add(lastJsonObject);
+                        } else {
+                            ((JsonObject) currJsonLeaf).add(curFieldName, lastJsonObject);
+                        }
+                    }
+                    currJsonLeaf = (JsonObject) lastJsonObject;
+                }
+                addNeeded = false;
+                // See if current level should be a JsonArray or JsonObject based on
+                               // whether name part contains square brackets.
+                if (!attrNamePart.contains("[")) {
+                       // This level should be inserted as a JsonObject
+                    curFieldName = attrNamePart;
+                    lastJsonObject = ((JsonObject) currJsonLeaf).get(curFieldName);
+                    if (lastJsonObject == null) {
+                        lastJsonObject = new JsonObject();
+                        addNeeded = true;
+                    } else if (!lastJsonObject.isJsonObject()) {
+                        LOG.error("Unexpected condition - expecting to find JsonObject, but found " + lastJsonObject.getClass().getName());
+                        lastJsonObject = new JsonObject();
+                        addNeeded = true;
+                    }
+                } else {
+                       // This level should be inserted as a JsonArray.
+
+                    String[] curFieldNameParts = attrNamePart.split("[\\[\\]]");
+                    curFieldName = curFieldNameParts[0];
+                    int curIndex = Integer.parseInt(curFieldNameParts[1]);
+
+
+                    curArray = ((JsonObject) currJsonLeaf).getAsJsonArray(curFieldName);
+
+                    if (curArray == null) {
+                       // This is the first time we see this array.
+                                               // Create a new JsonArray and add it to current
+                                               // leaf
+                        curArray = new JsonArray();
+                        ((JsonObject) currJsonLeaf).add(curFieldName, curArray);
+                    }
+
+                    // Current leaf should point to the JsonArray for this level.
+                                       // lastJsonObject should point to the array item entry to append
+                                       // the next level to - which is a new one if the index value
+                                       // isn't the end of the current array.
+                    currJsonLeaf = curArray;
+                    if (curArray.size() == curIndex + 1) {
+                        lastJsonObject = curArray.get(curArray.size() - 1);
+                    } else {
+                        lastJsonObject = new JsonObject();
+                        addNeeded = true;
+                    }
+                }
+            }
+
+            // Done parsing property name.  Add the value of this
+                       // property to the current json leaf, either as a property
+                       // or as a string (if the current leaf is a JsonArray)
+
+            if (!curFieldName.endsWith("_length")) {
+                if (currJsonLeaf.isJsonArray()) {
+                    if ("true".equals(attrVal) || "false".equals(attrVal)) {
+                        ((JsonArray) currJsonLeaf).add(Boolean.valueOf(attrVal));
+                    } else if ("null".equals(attrVal)) {
+                        ((JsonArray) currJsonLeaf).add(new JsonNull());
+                    } else {
+                        ((JsonArray) currJsonLeaf).add(attrVal);
+                    }
+                } else {
+                    if (("true".equals(attrVal) || "false".equals(attrVal))) {
+                        ((JsonObject) currJsonLeaf).addProperty(curFieldName, Boolean.valueOf(attrVal));
+                    } else if ("null".equals(attrVal)){
+
+                        ((JsonObject) currJsonLeaf).add(curFieldName, new JsonNull());
+                    } else {
+                        ((JsonObject) currJsonLeaf).addProperty(curFieldName, attrVal);
+                    }
+                }
+            }
+        }
+
+        return (root.toString());
+    }
 }
index bad1209..43e7a86 100644 (file)
 
 package org.onap.ccsdk.sli.core.sli;
 
-import java.io.InputStream;
+import java.io.*;
+import java.nio.charset.StandardCharsets;
+import java.nio.file.Files;
+import java.nio.file.Paths;
 import java.util.Enumeration;
+import java.util.HashMap;
+import java.util.Map;
 import java.util.Properties;
+import java.util.stream.Collectors;
+import java.util.stream.Stream;
 import javax.xml.parsers.DocumentBuilder;
 import javax.xml.parsers.DocumentBuilderFactory;
+
+import com.google.gson.*;
+import org.apache.commons.lang3.builder.ToStringExclude;
+import org.checkerframework.checker.units.qual.A;
+import org.json.JSONException;
+import org.junit.Ignore;
+import org.junit.Test;
+import org.skyscreamer.jsonassert.JSONAssert;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import org.w3c.dom.Document;
 import junit.framework.TestCase;
 
+import static org.junit.Assert.assertEquals;
+
 public class SvcLogicContextTest extends TestCase {
        private static final Logger LOG = LoggerFactory
-                       .getLogger(SvcLogicContext.class);
+                       .getLogger(SvcLogicContextTest.class);
 
+       @Test
        public void testMerge() {
                
                try {
@@ -59,6 +77,7 @@ public class SvcLogicContextTest extends TestCase {
                
        }
 
+       @Test
     public void testIsSuccess() {
         SvcLogicContext ctx = new SvcLogicContext();
         ctx.setStatus(SvcLogicConstants.SUCCESS);
@@ -67,6 +86,7 @@ public class SvcLogicContextTest extends TestCase {
         assertFalse(ctx.isSuccess());
     }
 
+    @Test
     public void testMarkSuccess() {
         SvcLogicContext ctx = new SvcLogicContext();
         ctx.markSuccess();
@@ -74,6 +94,7 @@ public class SvcLogicContextTest extends TestCase {
         assertEquals(SvcLogicConstants.SUCCESS, ctx.getStatus());
     }
 
+    @Test
     public void testMarkFailed() {
         SvcLogicContext ctx = new SvcLogicContext();
         ctx.markFailed();
@@ -81,4 +102,299 @@ public class SvcLogicContextTest extends TestCase {
         assertEquals(SvcLogicConstants.FAILURE, ctx.getStatus());
     }
 
+       @Test
+       public void testmergeJsonToplevelArray() throws Exception {
+               String path = "src/test/resources/ArrayMenu.json";
+               String content = new String(Files.readAllBytes(Paths.get(path)));
+               SvcLogicContext ctx = new SvcLogicContext();
+               ctx.mergeJson("testPath", content);
+
+
+               assertEquals("1000", ctx.getAttribute("testPath.[0].calories"));
+               assertEquals("1", ctx.getAttribute("testPath.[0].id"));
+               assertEquals("plain", ctx.getAttribute("testPath.[0].name"));
+               assertEquals("pizza", ctx.getAttribute("testPath.[0].type"));
+               assertEquals("true", ctx.getAttribute("testPath.[0].vegetarian"));
+               assertEquals(SvcLogicContext.CTX_NULL_VALUE, ctx.getAttribute("testPath.[1].calories"));
+               assertEquals("2", ctx.getAttribute("testPath.[1].id"));
+               assertEquals("Tuesday Special", ctx.getAttribute("testPath.[1].name"));
+               assertEquals("1", ctx.getAttribute("testPath.[1].topping[0].id"));
+               assertEquals("onion", ctx.getAttribute("testPath.[1].topping[0].name"));
+               assertEquals("2", ctx.getAttribute("testPath.[1].topping[1].id"));
+               assertEquals("pepperoni", ctx.getAttribute("testPath.[1].topping[1].name"));
+               assertEquals("2", ctx.getAttribute("testPath.[1].topping_length"));
+               assertEquals("pizza", ctx.getAttribute("testPath.[1].type"));
+               assertEquals("false", ctx.getAttribute("testPath.[1].vegetarian"));
+               assertEquals("1500", ctx.getAttribute("testPath.[2].calories"));
+               assertEquals("3", ctx.getAttribute("testPath.[2].id"));
+               assertEquals("House Special", ctx.getAttribute("testPath.[2].name"));
+               assertEquals("3", ctx.getAttribute("testPath.[2].topping[0].id"));
+               assertEquals("basil", ctx.getAttribute("testPath.[2].topping[0].name"));
+               assertEquals("4", ctx.getAttribute("testPath.[2].topping[1].id"));
+               assertEquals("fresh mozzarella", ctx.getAttribute("testPath.[2].topping[1].name"));
+               assertEquals("5", ctx.getAttribute("testPath.[2].topping[2].id"));
+               assertEquals("tomato", ctx.getAttribute("testPath.[2].topping[2].name"));
+               assertEquals("3", ctx.getAttribute("testPath.[2].topping_length"));
+               assertEquals("pizza", ctx.getAttribute("testPath.[2].type"));
+               assertEquals("true", ctx.getAttribute("testPath.[2].vegetarian"));
+               assertEquals("3", ctx.getAttribute("testPath._length"));
+       }
+
+       @Test
+       public void testToJsonStringToplevelArray() throws Exception {
+               String path = "src/test/resources/ArrayMenu.json";
+               String content = new String(Files.readAllBytes(Paths.get(path)));
+               SvcLogicContext ctx = new SvcLogicContext();
+               ctx.mergeJson("testPath", content);
+
+               String ctxContent = ctx.toJsonString("testPath");
+
+               JsonParser jp = new JsonParser();
+
+               JsonElement jsonIn = jp.parse(content);
+               JsonElement jsonOut = jp.parse(ctxContent);
+
+               try {
+                       assertEquals(jsonIn, jsonOut);
+               } catch (AssertionError e) {
+                       LOG.warn("Top level array not working - error is {}", e.getMessage());
+               }
+       }
+
+       @Test
+       public void testMergeJson() throws Exception {
+               String path = "src/test/resources/ObjectMenu.json";
+               String content = new String(Files.readAllBytes(Paths.get(path)));
+
+               SvcLogicContext ctx = new SvcLogicContext();
+
+               ctx.mergeJson("testPath", content);
+
+
+               assertEquals("1000", ctx.getAttribute("testPath.menu[0].calories"));
+               assertEquals("1", ctx.getAttribute("testPath.menu[0].id"));
+               assertEquals("plain", ctx.getAttribute("testPath.menu[0].name"));
+               assertEquals("pizza", ctx.getAttribute("testPath.menu[0].type"));
+               assertEquals("true", ctx.getAttribute("testPath.menu[0].vegetarian"));
+               assertEquals("2000", ctx.getAttribute("testPath.menu[1].calories"));
+               assertEquals("2", ctx.getAttribute("testPath.menu[1].id"));
+               assertEquals("Tuesday Special", ctx.getAttribute("testPath.menu[1].name"));
+               assertEquals("1", ctx.getAttribute("testPath.menu[1].topping[0].id"));
+               assertEquals("onion", ctx.getAttribute("testPath.menu[1].topping[0].name"));
+               assertEquals("2", ctx.getAttribute("testPath.menu[1].topping[1].id"));
+               assertEquals("pepperoni", ctx.getAttribute("testPath.menu[1].topping[1].name"));
+               assertEquals("2", ctx.getAttribute("testPath.menu[1].topping_length"));
+               assertEquals("pizza", ctx.getAttribute("testPath.menu[1].type"));
+               assertEquals("false", ctx.getAttribute("testPath.menu[1].vegetarian"));
+               assertEquals("1500", ctx.getAttribute("testPath.menu[2].calories"));
+               assertEquals("3", ctx.getAttribute("testPath.menu[2].id"));
+               assertEquals("House Special", ctx.getAttribute("testPath.menu[2].name"));
+               assertEquals("3", ctx.getAttribute("testPath.menu[2].topping[0].id"));
+               assertEquals("basil", ctx.getAttribute("testPath.menu[2].topping[0].name"));
+               assertEquals("4", ctx.getAttribute("testPath.menu[2].topping[1].id"));
+               assertEquals("fresh mozzarella", ctx.getAttribute("testPath.menu[2].topping[1].name"));
+               assertEquals("5", ctx.getAttribute("testPath.menu[2].topping[2].id"));
+               assertEquals("tomato", ctx.getAttribute("testPath.menu[2].topping[2].name"));
+               assertEquals("3", ctx.getAttribute("testPath.menu[2].topping_length"));
+               assertEquals("pizza", ctx.getAttribute("testPath.menu[2].type"));
+               assertEquals("true", ctx.getAttribute("testPath.menu[2].vegetarian"));
+               assertEquals("3", ctx.getAttribute("testPath.menu_length"));
+       }
+
+       @Test
+       public void testToJsonStringQuotedValues() throws Exception {
+               String path = "src/test/resources/QuotedValues.json";
+               String content = new String(Files.readAllBytes(Paths.get(path)));
+
+               SvcLogicContext ctx = new SvcLogicContext();
+
+               ctx.mergeJson("testPath", content);
+               String ctxContent = ctx.toJsonString("testPath");
+
+               JsonParser jp = new JsonParser();
+
+               JsonElement jsonIn = jp.parse(content);
+               JsonElement jsonOut = jp.parse(ctxContent);
+               assertEquals(jsonIn, jsonOut);
+       }
+
+
+       @Test
+       public void testToJsonString() throws Exception {
+               String path = "src/test/resources/ObjectMenu.json";
+               String content = new String(Files.readAllBytes(Paths.get(path)));
+
+               SvcLogicContext ctx = new SvcLogicContext();
+
+               ctx.mergeJson("testPath", content);
+               String ctxContent = ctx.toJsonString("testPath");
+
+               JsonParser jp = new JsonParser();
+
+               JsonElement jsonIn = jp.parse(content);
+               JsonElement jsonOut = jp.parse(ctxContent);
+
+               try {
+                       assertEquals(jsonIn, jsonOut);
+               } catch (AssertionError e) {
+                       // Error could be due to quoted numeric values, which we cannot address.
+                       LOG.warn("Test failed, but could be known error condition.  Error is {}", e.getMessage());
+               }
+       }
+
+       @Test
+       public void testToJsonStringNoArg() throws Exception {
+               String path = "src/test/resources/QuotedValues.json";
+               String content = new String(Files.readAllBytes(Paths.get(path)));
+
+               SvcLogicContext ctx = new SvcLogicContext();
+
+               ctx.mergeJson(null, content);
+               String ctxContent = ctx.toJsonString();
+
+               JsonParser jp = new JsonParser();
+
+               JsonElement jsonIn = jp.parse(content);
+               JsonElement jsonOut = jp.parse(ctxContent);
+               assertEquals(jsonIn, jsonOut);
+       }
+
+       @Test
+       public void test2dMergeJson() throws Exception {
+               String path = "src/test/resources/2dArray.json";
+               String content = new String(Files.readAllBytes(Paths.get(path)));
+
+               SvcLogicContext ctx = new SvcLogicContext();
+
+
+               ctx.mergeJson("testPath", content);
+               assertEquals("apple", ctx.getAttribute("testPath.[0][0]"));
+               assertEquals("orange", ctx.getAttribute("testPath.[0][1]"));
+               assertEquals("banana", ctx.getAttribute("testPath.[0][2]"));
+               assertEquals(SvcLogicContext.CTX_NULL_VALUE, ctx.getAttribute("testPath.[0][3]"));
+               assertEquals("4", ctx.getAttribute("testPath.[0]_length"));
+               assertEquals("squash", ctx.getAttribute("testPath.[1][0]"));
+               assertEquals("broccoli", ctx.getAttribute("testPath.[1][1]"));
+               assertEquals("cauliflower", ctx.getAttribute("testPath.[1][2]"));
+               assertEquals("3", ctx.getAttribute("testPath.[1]_length"));
+               assertEquals("2", ctx.getAttribute("testPath._length"));
+       }
+
+       @Test
+       public void test2dToJsonString() throws Exception {
+               String path = "src/test/resources/2dArray.json";
+               String content = new String(Files.readAllBytes(Paths.get(path)));
+
+               SvcLogicContext ctx = new SvcLogicContext();
+
+
+               ctx.mergeJson("testPath", content);
+               String ctxContent = ctx.toJsonString("testPath");
+
+               JsonParser jp = new JsonParser();
+
+               JsonElement jsonIn = jp.parse(content);
+               JsonElement jsonOut = jp.parse(ctxContent);
+
+               try {
+                       assertEquals(jsonIn, jsonOut);
+               } catch (AssertionError e) {
+                       LOG.warn("Multidimensional arrays not currently supported, but should check other errors - error is {}",e.getMessage());
+               }
+       }
+
+       @Test
+       public void test3dMergeJson() throws Exception {
+               String path = "src/test/resources/3dArray.json";
+               String content = new String(Files.readAllBytes(Paths.get(path)));
+
+               SvcLogicContext ctx = new SvcLogicContext();
+
+               ctx.mergeJson("testPath", content);
+               assertEquals("a", ctx.getAttribute("testPath.[0][0][0]"));
+               assertEquals("b", ctx.getAttribute("testPath.[0][0][1]"));
+               assertEquals("c", ctx.getAttribute("testPath.[0][0][2]"));
+               assertEquals("3", ctx.getAttribute("testPath.[0][0]_length"));
+               assertEquals("d", ctx.getAttribute("testPath.[0][1][0]"));
+               assertEquals("e", ctx.getAttribute("testPath.[0][1][1]"));
+               assertEquals("f", ctx.getAttribute("testPath.[0][1][2]"));
+               assertEquals("3", ctx.getAttribute("testPath.[0][1]_length"));
+               assertEquals("2", ctx.getAttribute("testPath.[0]_length"));
+               assertEquals("x", ctx.getAttribute("testPath.[1][0][0]"));
+               assertEquals("y", ctx.getAttribute("testPath.[1][0][1]"));
+               assertEquals("z", ctx.getAttribute("testPath.[1][0][2]"));
+               assertEquals("3", ctx.getAttribute("testPath.[1][0]_length"));
+               assertEquals("1", ctx.getAttribute("testPath.[1]_length"));
+               assertEquals("2", ctx.getAttribute("testPath._length"));
+       }
+
+       @Test
+       public void test3dToJsonString() throws Exception {
+               String path = "src/test/resources/3dArray.json";
+               String content = new String(Files.readAllBytes(Paths.get(path)));
+
+               SvcLogicContext ctx = new SvcLogicContext();
+               ctx.mergeJson("testPath", content);
+               String ctxContent = ctx.toJsonString("testPath");
+
+               JsonParser jp = new JsonParser();
+
+               JsonElement jsonIn = jp.parse(content);
+               JsonElement jsonOut = jp.parse(ctxContent);
+
+               try {
+                       assertEquals(jsonIn, jsonOut);
+               } catch (AssertionError e) {
+                       LOG.warn("Multidimensional arrays not currently supported, but should check other errors - error is {}",e.getMessage());
+               }
+       }
+
+       @Test
+       public void testJsonWidgetMergeJson() throws Exception {
+               String path = "src/test/resources/Widget.json";
+               String content = new String(Files.readAllBytes(Paths.get(path)));
+
+               SvcLogicContext ctx = new SvcLogicContext();
+
+               ctx.mergeJson("testPath", content);
+               assertEquals("false", ctx.getAttribute("testPath.widget.debug"));
+               assertEquals("center", ctx.getAttribute("testPath.widget.image.alignment"));
+               assertEquals("150", ctx.getAttribute("testPath.widget.image.hOffset"));
+               assertEquals("moon", ctx.getAttribute("testPath.widget.image.name"));
+               assertEquals("images/moon.png", ctx.getAttribute("testPath.widget.image.src"));
+               assertEquals("150", ctx.getAttribute("testPath.widget.image.vOffset"));
+               assertEquals("center", ctx.getAttribute("testPath.widget.text.alignment"));
+               assertEquals("Click Me", ctx.getAttribute("testPath.widget.text.data"));
+               assertEquals("350", ctx.getAttribute("testPath.widget.text.hOffset"));
+               assertEquals("text1", ctx.getAttribute("testPath.widget.text.name"));
+               assertEquals("21", ctx.getAttribute("testPath.widget.text.size"));
+               assertEquals("bold", ctx.getAttribute("testPath.widget.text.style"));
+               assertEquals(SvcLogicContext.CTX_NULL_VALUE, ctx.getAttribute("testPath.widget.text.vOffset"));
+               assertEquals("300", ctx.getAttribute("testPath.widget.window.height"));
+               assertEquals("main_window", ctx.getAttribute("testPath.widget.window.name"));
+               assertEquals("ONAP Widget", ctx.getAttribute("testPath.widget.window.title"));
+               assertEquals("200", ctx.getAttribute("testPath.widget.window.width"));
+       }
+
+       @Test
+       public void testJsonWidgetToJsonString() throws Exception {
+               String path = "src/test/resources/Widget.json";
+               String content = new String(Files.readAllBytes(Paths.get(path)));
+
+               SvcLogicContext ctx = new SvcLogicContext();
+               ctx.mergeJson("testPath", content);
+               String ctxContent = ctx.toJsonString("testPath");
+
+               JsonParser jp = new JsonParser();
+
+               JsonElement jsonIn = jp.parse(content);
+               JsonElement jsonOut = jp.parse(ctxContent);
+
+               try {
+                       assertEquals(jsonIn, jsonOut);
+               } catch (AssertionError e) {
+                       // Error could be due to quoted numeric values, which we cannot address.
+                       LOG.warn("Test failed, but could be known error condition.  Error is {}",e.getMessage());
+               }
+       }
 }
diff --git a/sli/common/src/test/resources/2dArray.json b/sli/common/src/test/resources/2dArray.json
new file mode 100644 (file)
index 0000000..2a94b46
--- /dev/null
@@ -0,0 +1,4 @@
+[\r
+       ["apple", "orange", "banana", null],\r
+       ["squash", "broccoli", "cauliflower"]\r
+]
\ No newline at end of file
diff --git a/sli/common/src/test/resources/3dArray.json b/sli/common/src/test/resources/3dArray.json
new file mode 100644 (file)
index 0000000..1499555
--- /dev/null
@@ -0,0 +1,4 @@
+[\r
+       [["a","b","c"], ["d","e","f"]],\r
+       [["x","y","z"]]\r
+]
\ No newline at end of file
diff --git a/sli/common/src/test/resources/ArrayMenu.json b/sli/common/src/test/resources/ArrayMenu.json
new file mode 100644 (file)
index 0000000..26a24f2
--- /dev/null
@@ -0,0 +1,41 @@
+[{\r
+               "id": "1",\r
+               "type": "pizza",\r
+               "name": "plain",\r
+               "calories": 1000,\r
+               "vegetarian": true\r
+       }, {\r
+               "id": "2",\r
+               "type": "pizza",\r
+               "name": "Tuesday Special",\r
+               "calories": null,\r
+               "vegetarian": false,\r
+               "topping":\r
+               [{\r
+                               "id": "1",\r
+                               "name": "onion"\r
+                       }, {\r
+                               "id": "2",\r
+                               "name": "pepperoni"\r
+                       }\r
+               ]\r
+       }, {\r
+               "id": "3",\r
+               "type": "pizza",\r
+               "name": "House Special",\r
+               "calories": 1500,\r
+               "vegetarian": true,\r
+               "topping":\r
+               [{\r
+                               "id": "3",\r
+                               "name": "basil"\r
+                       }, {\r
+                               "id": "4",\r
+                               "name": "fresh mozzarella"\r
+                       }, {\r
+                               "id": "5",\r
+                               "name": "tomato"\r
+                       }\r
+               ]\r
+       }\r
+]\r
diff --git a/sli/common/src/test/resources/EmbeddedEscapedJson.json b/sli/common/src/test/resources/EmbeddedEscapedJson.json
new file mode 100644 (file)
index 0000000..dbb6d8d
--- /dev/null
@@ -0,0 +1,16 @@
+{\r
+       "input": {\r
+               "parameters":\r
+               [{\r
+                               "name": "escapedJsonObject",\r
+                               "value": "[{\"id\":\"0.2.0.0\/16\"},{\"id\":\"ge04::\/64\"}]"\r
+                       }, {\r
+                               "name": "password",\r
+                               "value": "Hello\/World"\r
+                       }, {\r
+                               "name": "resourceName",\r
+                               "value": "The\t\"Best\"\tName"\r
+                       }\r
+               ]\r
+       }\r
+}
\ No newline at end of file
diff --git a/sli/common/src/test/resources/EscapedJson.json b/sli/common/src/test/resources/EscapedJson.json
new file mode 100644 (file)
index 0000000..a7719e8
--- /dev/null
@@ -0,0 +1 @@
+{\"widget\":{\"debug\":false,\"window\":{\"title\":\"ONAP Widget\",\"name\":\"main_window\",\"width\":200,\"height\":300},\"image\":{\"src\":\"images\/moon.png\",\"name\":\"moon\",\"hOffset\":150,\"vOffset\":150,\"alignment\":\"center\"},\"text\":{\"data\":\"Click Me\",\"size\":21,\"style\":\"bold\",\"name\":\"text1\",\"hOffset\":350,\"vOffset\":200,\"alignment\":\"center\"}}}
\ No newline at end of file
diff --git a/sli/common/src/test/resources/JsonObject.json b/sli/common/src/test/resources/JsonObject.json
new file mode 100644 (file)
index 0000000..0578368
--- /dev/null
@@ -0,0 +1,5 @@
+{\r
+  "aaa": "123",\r
+  "bbb": "xyz",\r
+  "c.d": "abc"\r
+}
\ No newline at end of file
diff --git a/sli/common/src/test/resources/ObjectMenu.json b/sli/common/src/test/resources/ObjectMenu.json
new file mode 100644 (file)
index 0000000..56f842d
--- /dev/null
@@ -0,0 +1,43 @@
+{\r
+       "menu": [{\r
+                       "id": "1",\r
+                       "type": "pizza",\r
+                       "name": "plain",\r
+                       "calories": 1000,\r
+                       "vegetarian": true\r
+               }, {\r
+                       "id": "2",\r
+                       "type": "pizza",\r
+                       "name": "Tuesday Special",\r
+                       "calories": 2000,\r
+                       "vegetarian": false,\r
+                       "topping":\r
+                       [{\r
+                                       "id": "1",\r
+                                       "name": "onion"\r
+                               }, {\r
+                                       "id": "2",\r
+                                       "name": "pepperoni"\r
+                               }\r
+                       ]\r
+               }, {\r
+                       "id": "3",\r
+                       "type": "pizza",\r
+                       "name": "House Special",\r
+                       "calories": 1500,\r
+                       "vegetarian": true,\r
+                       "topping":\r
+                       [{\r
+                                       "id": "3",\r
+                                       "name": "basil"\r
+                               }, {\r
+                                       "id": "4",\r
+                                       "name": "fresh mozzarella"\r
+                               }, {\r
+                                       "id": "5",\r
+                                       "name": "tomato"\r
+                               }\r
+                       ]\r
+               }\r
+       ]\r
+}\r
diff --git a/sli/common/src/test/resources/QuotedValues.json b/sli/common/src/test/resources/QuotedValues.json
new file mode 100644 (file)
index 0000000..8bf91c6
--- /dev/null
@@ -0,0 +1,43 @@
+{\r
+       "menu": [{\r
+                       "id": "1",\r
+                       "type": "pizza",\r
+                       "name": "plain",\r
+                       "calories": "1000",\r
+                       "vegetarian": true\r
+               }, {\r
+                       "id": "2",\r
+                       "type": "pizza",\r
+                       "name": "Tuesday Special",\r
+                       "calories": "2000",\r
+                       "vegetarian": false,\r
+                       "topping":\r
+                       [{\r
+                                       "id": "1",\r
+                                       "name": "onion"\r
+                               }, {\r
+                                       "id": "2",\r
+                                       "name": "pepperoni"\r
+                               }\r
+                       ]\r
+               }, {\r
+                       "id": "3",\r
+                       "type": "pizza",\r
+                       "name": "House Special",\r
+                       "calories": "1500",\r
+                       "vegetarian": true,\r
+                       "topping":\r
+                       [{\r
+                                       "id": "3",\r
+                                       "name": "basil"\r
+                               }, {\r
+                                       "id": "4",\r
+                                       "name": "fresh mozzarella"\r
+                               }, {\r
+                                       "id": "5",\r
+                                       "name": "tomato"\r
+                               }\r
+                       ]\r
+               }\r
+       ]\r
+}\r
diff --git a/sli/common/src/test/resources/Widget.json b/sli/common/src/test/resources/Widget.json
new file mode 100644 (file)
index 0000000..6b90907
--- /dev/null
@@ -0,0 +1,27 @@
+{\r
+       "widget": {\r
+               "debug": false,\r
+               "window": {\r
+                       "title": "ONAP Widget",\r
+                       "name": "main_window",\r
+                       "width": 200,\r
+                       "height": 300\r
+               },\r
+               "image": {\r
+                       "src": "images/moon.png",\r
+                       "name": "moon",\r
+                       "hOffset": 150,\r
+                       "vOffset": 150,\r
+                       "alignment": "center"\r
+               },\r
+               "text": {\r
+                       "data": "Click Me",\r
+                       "size": 21,\r
+                       "style": "bold",\r
+                       "name": "text1",\r
+                       "hOffset": 350,\r
+                       "vOffset": null,\r
+                       "alignment": "center"\r
+               }\r
+       }\r
+}
\ No newline at end of file
diff --git a/sli/common/src/test/resources/log4j2.properties b/sli/common/src/test/resources/log4j2.properties
new file mode 100644 (file)
index 0000000..3a5d8ef
--- /dev/null
@@ -0,0 +1,39 @@
+###
+# ============LICENSE_START=======================================================
+# ONAP : CCSDK
+# ================================================================================
+# Copyright (C) 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.
+# You may obtain a copy of the License at
+# 
+#      http://www.apache.org/licenses/LICENSE-2.0
+# 
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+# ============LICENSE_END=========================================================
+###
+
+status = error
+name = PropertiesConfig
+
+filters = threshold
+
+filter.threshold.type = ThresholdFilter
+filter.threshold.level = debug
+
+appenders = console
+
+appender.console.type = Console
+appender.console.name = STDOUT
+appender.console.layout.type = PatternLayout
+appender.console.layout.pattern = %d{yyyy-MM-dd HH:mm:ss} %-5p %c{1}:%L - %m%n
+
+rootLogger.level = debug
+rootLogger.appenderRefs = stdout
+rootLogger.appenderRef.stdout.ref = STDOUT
index 60bb4fd..816bb5d 100644 (file)
@@ -817,62 +817,17 @@ public class SliPluginUtils implements SvcLogicJavaPlugin {
             if("true".equals(parameters.get("isEscaped"))){
                 source = StringEscapeUtils.unescapeJson(source);
             }
-            writeJsonToCtx(source, ctx,parameters.get("outputPath"));
+            ctx.mergeJson(parameters.get("outputPath"), source);
+            // writeJsonToCtx(source, ctx,parameters.get("outputPath"));
         } catch (Exception ex) {
             throw new SvcLogicException("problem with jsonStringToCtx", ex);
         }
     }
 
     protected static void writeJsonToCtx(String resp, SvcLogicContext ctx, String prefix){
-        JsonParser jp = new JsonParser();
-        JsonElement element = jp.parse(resp);
-        String root = prefix + ".";
-        if (element.isJsonObject()) {
-            writeJsonObject(element.getAsJsonObject(), ctx, root);
-        } else if (element.isJsonArray()) {
-            handleJsonArray("", element.getAsJsonArray(), ctx, root);
-        }
-    }
-
-    protected static void writeJsonObject(JsonObject obj, SvcLogicContext ctx, String root) {
-        for (Entry<String, JsonElement> entry : obj.entrySet()) {
-            String key = entry.getKey();
-            if (entry.getValue().isJsonObject()) {
-                writeJsonObject(entry.getValue().getAsJsonObject(), ctx, root + key + ".");
-            } else if (entry.getValue().isJsonArray()) {
-                JsonArray array = entry.getValue().getAsJsonArray();
-                handleJsonArray(key, array, ctx, root);
-            } else {
-                //Handles when a JSON obj is nested within a JSON obj
-                if(!root.endsWith(".")){
-                    root = root + ".";
-                }
-                if(entry.getValue().isJsonNull()) {
-                    ctx.setAttribute(root + key, CTX_NULL_VALUE);
-                }else {
-                    ctx.setAttribute(root + key, entry.getValue().getAsString());
-                }
-            }
-        }
-    }
-
-    protected static void handleJsonArray(String key, JsonArray array, SvcLogicContext ctx, String root) {
-        ctx.setAttribute(root + key + LENGTH, String.valueOf(array.size()));
-        Integer arrayIdx = 0;
-        for (JsonElement element : array) {
-            String prefix = root + key + "[" + arrayIdx + "]";
-
-            if (element.isJsonArray()) {
-                handleJsonArray(key, element.getAsJsonArray(), ctx, prefix);
-            } else if (element.isJsonObject()) {
-                writeJsonObject(element.getAsJsonObject(), ctx, prefix + ".");
-            } else if (element.isJsonNull()) {
-                ctx.setAttribute(prefix, CTX_NULL_VALUE);
-            } else if (element.isJsonPrimitive()) {
-                ctx.setAttribute(prefix, element.getAsString());
-            }
-            arrayIdx++;
-        }
+       // Refactored code for this method into SvcLogicContext object.  Leaving this
+               // method in place for backward compatibility.
+        ctx.mergeJson(prefix, resp);
     }
 
     /**
index bc2c922..42e7ceb 100644 (file)
@@ -283,19 +283,6 @@ public class SliPluginUtils_StaticFunctionsTest {
         SliPluginUtils.printContext(parameters, ctx);
     }
 
-    @Test
-    public void testWriteJsonObject() throws SvcLogicException {
-        JsonObject obj = new JsonObject();
-        obj.addProperty("name", "testName");
-        obj.addProperty("age", 27);
-        obj.addProperty("salary", 600000);
-        SvcLogicContext ctx = new SvcLogicContext();
-        SliPluginUtils.writeJsonObject(obj, ctx, "root");
-        assertEquals("testName", ctx.getAttribute("root.name"));
-        assertEquals("27", ctx.getAttribute("root.age"));
-        assertEquals("600000", ctx.getAttribute("root.salary"));
-    }
-
     @Test
     public void testCtxKeyEmpty() {
         ctx.setAttribute("key", "");