Implementation of Data Format serializer
[ccsdk/sli/plugins.git] / restconf-client / provider / src / main / java / org / onap / ccsdk / sli / plugins / yangserializers / dfserializer / DefaultJsonWalker.java
1 /*-
2  * ============LICENSE_START=======================================================
3  * ONAP - CCSDK
4  * ================================================================================
5  * Copyright (C) 2018 Huawei Technologies Co., Ltd. All rights reserved.
6  * ================================================================================
7  * Licensed under the Apache License, Version 2.0 (the "License");
8  * you may not use this file except in compliance with the License.
9  * You may obtain a copy of the License at
10  *
11  *      http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing, software
14  * distributed under the License is distributed on an "AS IS" BASIS,
15  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16  * See the License for the specific language governing permissions and
17  * limitations under the License.
18  * ============LICENSE_END=========================================================
19  */
20
21 package org.onap.ccsdk.sli.plugins.yangserializers.dfserializer;
22
23 import com.fasterxml.jackson.databind.JsonNode;
24 import com.fasterxml.jackson.databind.node.ArrayNode;
25 import com.fasterxml.jackson.databind.node.JsonNodeType;
26 import org.onap.ccsdk.sli.core.sli.SvcLogicException;
27 import org.onap.ccsdk.sli.plugins.yangserializers.pnserializer.NodeType;
28
29 import java.util.Iterator;
30 import java.util.Map;
31
32 import static com.fasterxml.jackson.databind.node.JsonNodeType.NUMBER;
33 import static com.fasterxml.jackson.databind.node.JsonNodeType.STRING;
34 import static org.onap.ccsdk.sli.plugins.yangserializers.pnserializer.NodeType.MULTI_INSTANCE_LEAF_NODE;
35 import static org.onap.ccsdk.sli.plugins.yangserializers.pnserializer.NodeType.MULTI_INSTANCE_NODE;
36 import static org.onap.ccsdk.sli.plugins.yangserializers.pnserializer.NodeType.SINGLE_INSTANCE_LEAF_NODE;
37 import static org.onap.ccsdk.sli.plugins.yangserializers.pnserializer.NodeType.SINGLE_INSTANCE_NODE;
38
39 /**
40  * Implementation of JSON walker to walk through the nodes and process it.
41  */
42 public class DefaultJsonWalker implements JsonWalker {
43
44     @Override
45     public void walk(JsonListener listener, JsonNode jsonNode) throws
46             SvcLogicException {
47         Iterator<Map.Entry<String, JsonNode>> children = jsonNode.fields();
48         while (children.hasNext()) {
49             Map.Entry<String, JsonNode> child = children.next();
50             JsonNode value = child.getValue();
51             String key = child.getKey();
52             if (value.isArray()) {
53                 processMultiNodes(key, value, listener);
54             } else {
55                 processSingleNode(key, value, listener);
56             }
57         }
58     }
59
60     /**
61      * Processes single instance node or leaf, by adding the node to from
62      * JSON and walking through all its children recursively.
63      *
64      * @param key      JSON name
65      * @param value    JSON node
66      * @param listener JSON listener
67      * @throws SvcLogicException when processing the node fails
68      */
69     private void processSingleNode(String key, JsonNode value,
70                                    JsonListener listener)
71             throws SvcLogicException {
72         NodeType nodeType;
73         if (!value.isContainerNode()) {
74             nodeType = SINGLE_INSTANCE_LEAF_NODE;
75         } else {
76             nodeType = SINGLE_INSTANCE_NODE;
77         }
78         processNode(key, value, nodeType, listener);
79     }
80
81     /**
82      * Processes multi instance node or leaf, by adding the node to from JSON
83      * and walking through all its instance recursively.
84      *
85      * @param key      JSON name
86      * @param value    JSON node
87      * @param listener JSON listener
88      * @throws SvcLogicException when processing a single instance fails
89      */
90     private void processMultiNodes(String key, JsonNode value,
91                                    JsonListener listener)
92             throws SvcLogicException {
93         NodeType nodeType;
94         Iterator<JsonNode> multiNodes = value.elements();
95         while (multiNodes.hasNext()) {
96             if (isLeafListNode((ArrayNode) value)) {
97                 nodeType = MULTI_INSTANCE_LEAF_NODE;
98             } else {
99                 nodeType = MULTI_INSTANCE_NODE;
100             }
101             JsonNode multiNode = multiNodes.next();
102             processNode(key, multiNode, nodeType, listener);
103         }
104     }
105
106     /**
107      * Processes each node by first entering the JSON node through JSON
108      * listener, second a call back to walking the rest of the tree of the
109      * node and finally exiting the node.
110      *
111      * @param key      JSON name
112      * @param node     JSON node
113      * @param nodeType JSON node type
114      * @param listener JSON listener
115      * @throws SvcLogicException when entering a JSON node fails
116      */
117     private void processNode(String key, JsonNode node, NodeType nodeType,
118                              JsonListener listener) throws SvcLogicException {
119         listener.enterJsonNode(key, node, nodeType);
120         walk(listener, node);
121         listener.exitJsonNode(node);
122     }
123
124     /**
125      * Returns true if the node corresponds to a leaf-list node; false
126      * otherwise.
127      *
128      * @param node JSON node
129      * @return true if node corresponds to leaf-list node; false otherwise
130      */
131     private boolean isLeafListNode(ArrayNode node) {
132         Iterator<JsonNode> children = node.elements();
133         while (children.hasNext()) {
134             JsonNodeType type = children.next().getNodeType();
135             if (type != STRING && type != NUMBER) {
136                 return false;
137             }
138         }
139         return true;
140     }
141 }