Implementation of Data Format serializer
[ccsdk/sli/plugins.git] / restconf-client / provider / src / main / java / org / onap / ccsdk / sli / plugins / yangserializers / dfserializer / PropertiesNodeJsonListener.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.google.gson.stream.JsonWriter;
24 import org.onap.ccsdk.sli.core.sli.SvcLogicException;
25 import org.onap.ccsdk.sli.plugins.yangserializers.pnserializer.DefaultPropertiesNodeWalker;
26 import org.onap.ccsdk.sli.plugins.yangserializers.pnserializer.LeafNode;
27 import org.onap.ccsdk.sli.plugins.yangserializers.pnserializer.Namespace;
28 import org.onap.ccsdk.sli.plugins.yangserializers.pnserializer.PropertiesNode;
29 import org.onap.ccsdk.sli.plugins.yangserializers.pnserializer.PropertiesNodeListener;
30 import org.onap.ccsdk.sli.plugins.yangserializers.pnserializer.RootNode;
31
32 import java.io.IOException;
33 import java.io.StringWriter;
34 import java.io.Writer;
35 import java.util.Collection;
36 import java.util.Map;
37
38 import static com.google.common.base.Strings.repeat;
39 import static java.lang.String.format;
40 import static org.onap.ccsdk.sli.plugins.yangserializers.dfserializer.DfSerializerUtil.JSON_WRITE_ERR;
41 import static org.onap.ccsdk.sli.plugins.yangserializers.dfserializer.DfSerializerUtil.NODE_TYPE_ERR;
42
43 /**
44  * Representation of JSON implementation of properties node listener.
45  */
46 public class PropertiesNodeJsonListener implements PropertiesNodeListener{
47
48     /**
49      * JSON writer to write the JSON data format.
50      */
51     private JsonWriter jsonWriter;
52
53     /**
54      * Writer to write the JSON.
55      */
56     private Writer writer;
57
58     /**
59      * Creates the properties node JSON listener by instantiating and
60      * indenting the writer.
61      */
62     public PropertiesNodeJsonListener() {
63         writer = new StringWriter();
64         jsonWriter = new JsonWriter(writer);
65         jsonWriter.setIndent(repeat(" ", 4));
66     }
67
68     @Override
69     public void start(PropertiesNode node) throws SvcLogicException {
70         try {
71             jsonWriter.beginObject();
72         } catch (IOException e) {
73             throw new SvcLogicException(JSON_WRITE_ERR, e);
74         }
75     }
76
77     @Override
78     public void end(PropertiesNode node) throws SvcLogicException {
79         try {
80             jsonWriter.endObject();
81             jsonWriter.flush();
82         } catch (IOException e) {
83             throw new SvcLogicException(JSON_WRITE_ERR, e);
84         }
85     }
86
87     @Override
88     public void enterPropertiesNode(PropertiesNode node)
89             throws SvcLogicException {
90         String val;
91         String nodeName = getNodeName(node);
92         try {
93             switch (node.nodeType()) {
94                 case SINGLE_INSTANCE_NODE:
95                     jsonWriter.name(nodeName);
96                     jsonWriter.beginObject();
97                     break;
98
99                 case MULTI_INSTANCE_NODE:
100                     jsonWriter.beginObject();
101                     break;
102
103                 case SINGLE_INSTANCE_LEAF_NODE:
104                     val = getValueWithNs((LeafNode) node);
105                     jsonWriter.name(nodeName).value(val);
106                     break;
107
108                 case MULTI_INSTANCE_HOLDER_NODE:
109                 case MULTI_INSTANCE_LEAF_HOLDER_NODE:
110                     jsonWriter.name(nodeName);
111                     jsonWriter.beginArray();
112                     break;
113
114                 case MULTI_INSTANCE_LEAF_NODE:
115                     val = getValueWithNs((LeafNode) node);
116                     jsonWriter.value(val);
117                     break;
118
119                 default:
120                     throw new SvcLogicException(format(
121                             NODE_TYPE_ERR, node.nodeType().toString()));
122
123             }
124         } catch (IOException e) {
125             throw new SvcLogicException(JSON_WRITE_ERR, e);
126         }
127     }
128
129     @Override
130     public void exitPropertiesNode(PropertiesNode node) throws SvcLogicException {
131         walkAugmentationNode(node);
132         try {
133             switch (node.nodeType()) {
134                 case SINGLE_INSTANCE_NODE:
135                 case MULTI_INSTANCE_NODE:
136                     jsonWriter.endObject();
137                     break;
138
139                 case MULTI_INSTANCE_HOLDER_NODE:
140                 case MULTI_INSTANCE_LEAF_HOLDER_NODE:
141                     jsonWriter.endArray();
142                     break;
143
144                 case  SINGLE_INSTANCE_LEAF_NODE:
145                 case MULTI_INSTANCE_LEAF_NODE:
146                     break;
147
148                 default:
149                     throw new SvcLogicException(format(
150                             NODE_TYPE_ERR, node.nodeType().toString()));
151             }
152         } catch (IOException e) {
153             throw new SvcLogicException(JSON_WRITE_ERR, e);
154         }
155     }
156
157     /**
158      * Returns the writer.
159      *
160      * @return writer
161      */
162     public Writer getWriter() {
163         return writer;
164     }
165
166     /**
167      * Returns the abstract JSON node name to be used in JSON data format
168      * from the properties node.
169      *
170      * @param node properties node
171      * @return abstract JSON node
172      */
173     private String getNodeName(PropertiesNode node) {
174         PropertiesNode parent = node.parent();
175         if (parent instanceof RootNode || !parent.namespace().moduleName()
176                 .equals(node.namespace().moduleName())) {
177             return node.namespace().moduleName() + ":" + node.name();
178         }
179         return node.name();
180     }
181
182     /**
183      * Returns the value of JSON leaf node with module name if required.
184      *
185      * @param node properties node
186      * @return value with namespace
187      */
188     private String getValueWithNs(LeafNode node) {
189         Namespace valNs = node.valueNs();
190         String modName = (valNs == null) ? null : valNs.moduleName();
191         if (modName != null) {
192             return modName + ":" + node.value();
193         }
194         return node.value();
195     }
196
197     /**
198      * Gets all the augmentation of the given node and walks through it.
199      *
200      * @param node properties node
201      * @throws SvcLogicException when walking the properties node fails
202      */
203     private void walkAugmentationNode(PropertiesNode node)
204             throws SvcLogicException {
205         for (Map.Entry<Object, Collection<PropertiesNode>>
206                 augToChild : node.augmentations().asMap().entrySet()) {
207             Collection<PropertiesNode> augChild = augToChild.getValue();
208             if (!augChild.isEmpty()) {
209                 DefaultPropertiesNodeWalker walker = new
210                         DefaultPropertiesNodeWalker();
211                 for (PropertiesNode p : augChild) {
212                     enterPropertiesNode(p);
213                     walker.walkChildNode(this, p);
214                     exitPropertiesNode(p);
215                 }
216             }
217         }
218     }
219 }