Fixed RESTConf support for identity-ref build-in datatype
[controller.git] / opendaylight / md-sal / sal-rest-connector / src / main / java / org / opendaylight / controller / sal / rest / impl / JsonReader.java
index fa00908e4d54c41245332ebc5d6dedc8f78492d9..f4c5034776ec1e83fa5022c7a68223d139d3060a 100644 (file)
@@ -2,11 +2,14 @@ package org.opendaylight.controller.sal.rest.impl;
 
 import java.io.InputStream;
 import java.io.InputStreamReader;
+import java.net.URI;
 import java.util.Map.Entry;
 import java.util.Set;
 
 import org.opendaylight.controller.sal.restconf.impl.CompositeNodeWrapper;
+import org.opendaylight.controller.sal.restconf.impl.EmptyNodeWrapper;
 import org.opendaylight.controller.sal.restconf.impl.SimpleNodeWrapper;
+import org.opendaylight.controller.sal.restconf.impl.IdentityValuesDTO;
 
 import com.google.common.collect.Lists;
 import com.google.gson.JsonElement;
@@ -16,17 +19,17 @@ import com.google.gson.JsonPrimitive;
 
 class JsonReader {
 
-    public CompositeNodeWrapper read(InputStream entityStream) throws UnsupportedJsonFormatException {
+    public CompositeNodeWrapper read(InputStream entityStream) throws UnsupportedFormatException {
         JsonParser parser = new JsonParser();
-        
+
         JsonElement rootElement = parser.parse(new InputStreamReader(entityStream));
         if (!rootElement.isJsonObject()) {
-            throw new UnsupportedJsonFormatException("Root element of Json has to be Object");
+            throw new UnsupportedFormatException("Root element of Json has to be Object");
         }
-        
+
         Set<Entry<String, JsonElement>> entrySetsOfRootJsonObject = rootElement.getAsJsonObject().entrySet();
         if (entrySetsOfRootJsonObject.size() != 1) {
-            throw new UnsupportedJsonFormatException("Json Object should contain one element");
+            throw new UnsupportedFormatException("Json Object should contain one element");
         } else {
             Entry<String, JsonElement> childEntry = Lists.newArrayList(entrySetsOfRootJsonObject).get(0);
             String firstElementName = childEntry.getKey();
@@ -40,42 +43,74 @@ class JsonReader {
                     if (firstElementInArray.isJsonObject()) {
                         return createStructureWithRoot(firstElementName, firstElementInArray.getAsJsonObject());
                     }
-                    throw new UnsupportedJsonFormatException("Array as the first element in Json Object can have only Object element");
+                    throw new UnsupportedFormatException(
+                            "Array as the first element in Json Object can have only Object element");
                 }
             }
-            throw new UnsupportedJsonFormatException("First element in Json Object has to be \"Object\" or \"Array with one Object element\". Other scenarios are not supported yet.");
+            throw new UnsupportedFormatException(
+                    "First element in Json Object has to be \"Object\" or \"Array with one Object element\". Other scenarios are not supported yet.");
         }
     }
-    
+
     private CompositeNodeWrapper createStructureWithRoot(String rootObjectName, JsonObject rootObject) {
-        CompositeNodeWrapper firstNode = new CompositeNodeWrapper(rootObjectName);
+        CompositeNodeWrapper firstNode = new CompositeNodeWrapper(getNamespaceFor(rootObjectName),
+                getLocalNameFor(rootObjectName));
         for (Entry<String, JsonElement> childOfFirstNode : rootObject.entrySet()) {
             addChildToParent(childOfFirstNode.getKey(), childOfFirstNode.getValue(), firstNode);
         }
         return firstNode;
     }
-    
+
     private void addChildToParent(String childName, JsonElement childType, CompositeNodeWrapper parent) {
         if (childType.isJsonObject()) {
-            CompositeNodeWrapper child = new CompositeNodeWrapper(childName);
+            CompositeNodeWrapper child = new CompositeNodeWrapper(getNamespaceFor(childName),
+                    getLocalNameFor(childName));
             parent.addValue(child);
             for (Entry<String, JsonElement> childOfChild : childType.getAsJsonObject().entrySet()) {
                 addChildToParent(childOfChild.getKey(), childOfChild.getValue(), child);
             }
         } else if (childType.isJsonArray()) {
-            for (JsonElement childOfChildType : childType.getAsJsonArray()) {
-                addChildToParent(childName, childOfChildType, parent);
+            if (childType.getAsJsonArray().size() == 1 && childType.getAsJsonArray().get(0).isJsonNull()) {
+                parent.addValue(new EmptyNodeWrapper(getNamespaceFor(childName), getLocalNameFor(childName)));
+
+            } else {
+                for (JsonElement childOfChildType : childType.getAsJsonArray()) {
+                    addChildToParent(childName, childOfChildType, parent);
+                }
             }
         } else if (childType.isJsonPrimitive()) {
             JsonPrimitive childPrimitive = childType.getAsJsonPrimitive();
             String value = childPrimitive.getAsString();
-            SimpleNodeWrapper child = null;
-            if (value.equals("[null]")) {
-                child = new SimpleNodeWrapper(childName, null);
-            } else {
-                child = new SimpleNodeWrapper(childName, value);
-            }
-            parent.addValue(child);
+            parent.addValue(new SimpleNodeWrapper(getNamespaceFor(childName), getLocalNameFor(childName),
+                    resolveValueOfElement(value)));
         }
     }
+
+    private URI getNamespaceFor(String jsonElementName) {
+        String[] moduleNameAndLocalName = jsonElementName.split(":");
+        if (moduleNameAndLocalName.length != 2) { // it is not "moduleName:localName"
+            return null;
+        }
+        return URI.create(moduleNameAndLocalName[0]);
+    }
+
+    private String getLocalNameFor(String jsonElementName) {
+        String[] moduleNameAndLocalName = jsonElementName.split(":");
+        if (moduleNameAndLocalName.length != 2) { // it is not "moduleName:localName"
+            return jsonElementName;
+        }
+        return moduleNameAndLocalName[1];
+    }
+
+    /**
+     * @param value
+     *            value of json element
+     * @return if value is "moduleName:localName" then {@link IdentityValuesDTO} else
+     *         the same string as parameter "value"
+     */
+    private Object resolveValueOfElement(String value) {
+        URI namespace = getNamespaceFor(value);
+        return namespace == null ? value : new IdentityValuesDTO(namespace.toString(), getLocalNameFor(value), null);
+    }
+
 }