f4c5034776ec1e83fa5022c7a68223d139d3060a
[controller.git] / opendaylight / md-sal / sal-rest-connector / src / main / java / org / opendaylight / controller / sal / rest / impl / JsonReader.java
1 package org.opendaylight.controller.sal.rest.impl;
2
3 import java.io.InputStream;
4 import java.io.InputStreamReader;
5 import java.net.URI;
6 import java.util.Map.Entry;
7 import java.util.Set;
8
9 import org.opendaylight.controller.sal.restconf.impl.CompositeNodeWrapper;
10 import org.opendaylight.controller.sal.restconf.impl.EmptyNodeWrapper;
11 import org.opendaylight.controller.sal.restconf.impl.SimpleNodeWrapper;
12 import org.opendaylight.controller.sal.restconf.impl.IdentityValuesDTO;
13
14 import com.google.common.collect.Lists;
15 import com.google.gson.JsonElement;
16 import com.google.gson.JsonObject;
17 import com.google.gson.JsonParser;
18 import com.google.gson.JsonPrimitive;
19
20 class JsonReader {
21
22     public CompositeNodeWrapper read(InputStream entityStream) throws UnsupportedFormatException {
23         JsonParser parser = new JsonParser();
24
25         JsonElement rootElement = parser.parse(new InputStreamReader(entityStream));
26         if (!rootElement.isJsonObject()) {
27             throw new UnsupportedFormatException("Root element of Json has to be Object");
28         }
29
30         Set<Entry<String, JsonElement>> entrySetsOfRootJsonObject = rootElement.getAsJsonObject().entrySet();
31         if (entrySetsOfRootJsonObject.size() != 1) {
32             throw new UnsupportedFormatException("Json Object should contain one element");
33         } else {
34             Entry<String, JsonElement> childEntry = Lists.newArrayList(entrySetsOfRootJsonObject).get(0);
35             String firstElementName = childEntry.getKey();
36             JsonElement firstElementType = childEntry.getValue();
37             if (firstElementType.isJsonObject()) { // container in yang
38                 return createStructureWithRoot(firstElementName, firstElementType.getAsJsonObject());
39             }
40             if (firstElementType.isJsonArray()) { // list in yang
41                 if (firstElementType.getAsJsonArray().size() == 1) {
42                     JsonElement firstElementInArray = firstElementType.getAsJsonArray().get(0);
43                     if (firstElementInArray.isJsonObject()) {
44                         return createStructureWithRoot(firstElementName, firstElementInArray.getAsJsonObject());
45                     }
46                     throw new UnsupportedFormatException(
47                             "Array as the first element in Json Object can have only Object element");
48                 }
49             }
50             throw new UnsupportedFormatException(
51                     "First element in Json Object has to be \"Object\" or \"Array with one Object element\". Other scenarios are not supported yet.");
52         }
53     }
54
55     private CompositeNodeWrapper createStructureWithRoot(String rootObjectName, JsonObject rootObject) {
56         CompositeNodeWrapper firstNode = new CompositeNodeWrapper(getNamespaceFor(rootObjectName),
57                 getLocalNameFor(rootObjectName));
58         for (Entry<String, JsonElement> childOfFirstNode : rootObject.entrySet()) {
59             addChildToParent(childOfFirstNode.getKey(), childOfFirstNode.getValue(), firstNode);
60         }
61         return firstNode;
62     }
63
64     private void addChildToParent(String childName, JsonElement childType, CompositeNodeWrapper parent) {
65         if (childType.isJsonObject()) {
66             CompositeNodeWrapper child = new CompositeNodeWrapper(getNamespaceFor(childName),
67                     getLocalNameFor(childName));
68             parent.addValue(child);
69             for (Entry<String, JsonElement> childOfChild : childType.getAsJsonObject().entrySet()) {
70                 addChildToParent(childOfChild.getKey(), childOfChild.getValue(), child);
71             }
72         } else if (childType.isJsonArray()) {
73             if (childType.getAsJsonArray().size() == 1 && childType.getAsJsonArray().get(0).isJsonNull()) {
74                 parent.addValue(new EmptyNodeWrapper(getNamespaceFor(childName), getLocalNameFor(childName)));
75
76             } else {
77                 for (JsonElement childOfChildType : childType.getAsJsonArray()) {
78                     addChildToParent(childName, childOfChildType, parent);
79                 }
80             }
81         } else if (childType.isJsonPrimitive()) {
82             JsonPrimitive childPrimitive = childType.getAsJsonPrimitive();
83             String value = childPrimitive.getAsString();
84             parent.addValue(new SimpleNodeWrapper(getNamespaceFor(childName), getLocalNameFor(childName),
85                     resolveValueOfElement(value)));
86         }
87     }
88
89     private URI getNamespaceFor(String jsonElementName) {
90         String[] moduleNameAndLocalName = jsonElementName.split(":");
91         if (moduleNameAndLocalName.length != 2) { // it is not "moduleName:localName"
92             return null;
93         }
94         return URI.create(moduleNameAndLocalName[0]);
95     }
96
97     private String getLocalNameFor(String jsonElementName) {
98         String[] moduleNameAndLocalName = jsonElementName.split(":");
99         if (moduleNameAndLocalName.length != 2) { // it is not "moduleName:localName"
100             return jsonElementName;
101         }
102         return moduleNameAndLocalName[1];
103     }
104
105     /**
106      * @param value
107      *            value of json element
108      * @return if value is "moduleName:localName" then {@link IdentityValuesDTO} else
109      *         the same string as parameter "value"
110      */
111     private Object resolveValueOfElement(String value) {
112         URI namespace = getNamespaceFor(value);
113         return namespace == null ? value : new IdentityValuesDTO(namespace.toString(), getLocalNameFor(value), null);
114     }
115
116 }