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