blob: 9479d977fb29908752703f85ab5bf9044b6f9cfd [file] [log] [blame]
chengfanc58d4be2016-09-20 10:33:12 +08001/*
2 * Copyright 2016-present Open Networking Laboratory
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17package org.onosproject.protocol.restconf.server.utils.parser.json;
18
19import com.fasterxml.jackson.databind.node.JsonNodeType;
20import org.onosproject.protocol.restconf.server.utils.exceptions.YdtParseException;
21import org.onosproject.protocol.restconf.server.utils.parser.api.JsonBuilder;
22import org.onosproject.yms.ydt.YdtContext;
23import org.onosproject.yms.ydt.YdtListener;
24
25import static com.google.common.base.Strings.isNullOrEmpty;
Henry Yu528007c2016-11-01 15:49:59 -040026import static org.onosproject.protocol.restconf.server.utils.parser.json.ParserUtils.getJsonNameFromYdtNode;
chengfanc58d4be2016-09-20 10:33:12 +080027
28/**
29 * Represents implementation of codec YDT listener.
30 */
31public class YdtToJsonListener implements YdtListener {
32
33 private static final String EMPTY = "";
34 private JsonBuilder jsonBuilder;
35 //the root name of the json
36 //the input YdtContext is usually a total tree of a YANG resource
37 //this property is used to mark the start of the request node.
38 private String rootName;
39 //the parse state
40 private boolean isBegin;
41
42 /**
43 * Creates a listener for the process of a Ydt, the listener will try to
44 * transfer the Ydt to a JSON Object.
45 *
46 * @param rootName the name of a specific YdtContext begin to process
47 * @param jsonBuilder the JSON builder to build a JSON object
48 */
49 public YdtToJsonListener(String rootName, JsonBuilder jsonBuilder) {
50 this.jsonBuilder = jsonBuilder;
51 this.rootName = rootName;
52 this.isBegin = isNullOrEmpty(rootName);
53 }
54
55 @Override
56 public void enterYdtNode(YdtContext ydtContext) {
Henry Yu528007c2016-11-01 15:49:59 -040057 String name = getJsonNameFromYdtNode(ydtContext);
chengfanc58d4be2016-09-20 10:33:12 +080058
Henry Yu7dbfc202016-10-24 16:00:37 -040059 if (!isBegin && name != null && name.equals(rootName)) {
chengfanc58d4be2016-09-20 10:33:12 +080060 isBegin = true;
61 }
62 if (!isBegin) {
63 return;
64 }
65
66 switch (ydtContext.getYdtType()) {
67
68 case SINGLE_INSTANCE_NODE:
69 jsonBuilder.addNodeTopHalf(name, JsonNodeType.OBJECT);
70 break;
71 case MULTI_INSTANCE_NODE:
72 YdtContext preNode = ydtContext.getPreviousSibling();
Henry Yu528007c2016-11-01 15:49:59 -040073 if (preNode == null || !getJsonNameFromYdtNode(preNode).equals(name)) {
chengfanc58d4be2016-09-20 10:33:12 +080074 jsonBuilder.addNodeTopHalf(name, JsonNodeType.ARRAY);
75 }
76 jsonBuilder.addNodeTopHalf(EMPTY, JsonNodeType.OBJECT);
77 break;
78 case SINGLE_INSTANCE_LEAF_VALUE_NODE:
79 jsonBuilder.addNodeWithValueTopHalf(name, ydtContext.getValue());
80 break;
81 case MULTI_INSTANCE_LEAF_VALUE_NODE:
82 jsonBuilder.addNodeWithSetTopHalf(name, ydtContext.getValueSet());
83 break;
Henry Yu52a8a722016-12-19 14:50:50 -050084 case LOGICAL_ROOT_NODE:
85 break;
chengfanc58d4be2016-09-20 10:33:12 +080086 default:
87 throw new YdtParseException("unknown Ydt type " +
88 ydtContext.getYdtType());
89 }
90
91 }
92
93 @Override
94 public void exitYdtNode(YdtContext ydtContext) {
95
96 if (!isBegin) {
97 return;
98 }
99
Henry Yu528007c2016-11-01 15:49:59 -0400100 String curName = getJsonNameFromYdtNode(ydtContext);
chengfanc58d4be2016-09-20 10:33:12 +0800101 YdtContext nextNode = ydtContext.getNextSibling();
102 switch (ydtContext.getYdtType()) {
103
104 case SINGLE_INSTANCE_NODE:
105 jsonBuilder.addNodeBottomHalf(JsonNodeType.OBJECT);
106 break;
107 case MULTI_INSTANCE_NODE:
Henry Yu528007c2016-11-01 15:49:59 -0400108 if (nextNode == null || !getJsonNameFromYdtNode(nextNode).equals(curName)) {
chengfanc58d4be2016-09-20 10:33:12 +0800109 jsonBuilder.addNodeBottomHalf(JsonNodeType.OBJECT);
110 jsonBuilder.addNodeBottomHalf(JsonNodeType.ARRAY);
111 } else {
112 jsonBuilder.addNodeBottomHalf(JsonNodeType.OBJECT);
113 }
114 break;
115 case SINGLE_INSTANCE_LEAF_VALUE_NODE:
116 jsonBuilder.addNodeBottomHalf(JsonNodeType.STRING);
117 break;
118 case MULTI_INSTANCE_LEAF_VALUE_NODE:
119 jsonBuilder.addNodeBottomHalf(JsonNodeType.ARRAY);
120 break;
Henry Yu52a8a722016-12-19 14:50:50 -0500121 case LOGICAL_ROOT_NODE:
122 break;
chengfanc58d4be2016-09-20 10:33:12 +0800123 default:
124 throw new YdtParseException("Unknown Ydt type " +
125 ydtContext.getYdtType());
126 }
127 if (curName.equals(rootName) &&
Henry Yu528007c2016-11-01 15:49:59 -0400128 (nextNode == null || !getJsonNameFromYdtNode(nextNode).equals(rootName))) {
chengfanc58d4be2016-09-20 10:33:12 +0800129 isBegin = false;
130 }
131 }
Henry Yu528007c2016-11-01 15:49:59 -0400132}