JSON serializer fixes
* Removed redundant module name prefixes to comply with RFC 7951
* Added the top level JSON node, which was missing from RESTCONF's GET output
Change-Id: If8a022571b449b802750fb9f613d71c1e1db6262
diff --git a/serializers/json/src/main/java/org/onosproject/yang/serializers/json/DataNodeJsonVisitor.java b/serializers/json/src/main/java/org/onosproject/yang/serializers/json/DataNodeJsonVisitor.java
index 617f871..64120c1 100644
--- a/serializers/json/src/main/java/org/onosproject/yang/serializers/json/DataNodeJsonVisitor.java
+++ b/serializers/json/src/main/java/org/onosproject/yang/serializers/json/DataNodeJsonVisitor.java
@@ -40,7 +40,7 @@
/**
* Creates an instance of data node JSON visitor.
*
- * @param jb json builder
+ * @param jb json builder
* @param context yang serializer context
*/
public DataNodeJsonVisitor(JsonBuilder jb, YangSerializerContext context) {
@@ -51,7 +51,7 @@
@Override
public void enterDataNode(DataNode dataNode,
DataNodeSiblingPositionType siblingType) {
- String nodeName = getNodeNameWithModuleName(dataNode.key().schemaId());
+ String nodeName = getNodeName(dataNode);
switch (dataNode.type()) {
case SINGLE_INSTANCE_NODE:
jsonBuilder.addNodeTopHalf(nodeName, JsonNodeType.OBJECT);
@@ -79,17 +79,22 @@
default:
break;
}
+ jsonBuilder.pushModuleName(getModuleNameFromDataNode(dataNode));
}
- private String getNodeNameWithModuleName(SchemaId schemaId) {
+ private String getModuleNameFromDataNode(DataNode dataNode) {
+ String nameSpace = dataNode.key().schemaId().namespace();
+ return getModuleNameFromNameSpace(jsonSerializerContext, nameSpace);
+ }
+
+ private String getNodeName(DataNode dataNode) {
+ SchemaId schemaId = dataNode.key().schemaId();
String nodeName = schemaId.name();
- String nameSpace = schemaId.namespace();
- String moduleName = getModuleNameFromNameSpace(jsonSerializerContext,
- nameSpace);
+ String moduleName = getModuleNameFromDataNode(dataNode);
StringBuilder builder = new StringBuilder();
- if (nameSpace != null) {
+ if (moduleName != null && !moduleName.equals(jsonBuilder.subTreeModuleName())) {
builder.append(moduleName);
builder.append(COLON);
}
@@ -126,5 +131,6 @@
default:
break;
}
+ jsonBuilder.popModuleName();
}
}
diff --git a/serializers/json/src/main/java/org/onosproject/yang/serializers/json/DefaultJsonBuilder.java b/serializers/json/src/main/java/org/onosproject/yang/serializers/json/DefaultJsonBuilder.java
index 3dc0ff5..9492a15 100644
--- a/serializers/json/src/main/java/org/onosproject/yang/serializers/json/DefaultJsonBuilder.java
+++ b/serializers/json/src/main/java/org/onosproject/yang/serializers/json/DefaultJsonBuilder.java
@@ -25,6 +25,7 @@
import java.io.IOException;
import java.util.Set;
+import java.util.Stack;
import static com.google.common.base.Preconditions.checkNotNull;
import static com.google.common.base.Strings.isNullOrEmpty;
@@ -42,15 +43,19 @@
private static final String COMMA = ",";
private static final String COLON = ":";
private static final String QUOTE = "\"";
+ private static final String ROOT_MODULE_NAME = "ROOT";
+ private Stack<String> moduleNameStack;
public DefaultJsonBuilder(String rootName) {
checkNotNull(rootName);
- this.treeString = new StringBuilder(rootName);
+ treeString = new StringBuilder(rootName);
+ moduleNameStack = new Stack<>();
}
public DefaultJsonBuilder() {
- this.treeString = new StringBuilder();
+ treeString = new StringBuilder();
+ moduleNameStack = new Stack<>();
}
@Override
@@ -141,8 +146,6 @@
@Override
public String getTreeString() {
- removeCommaIfExist();
- removeFirstFieldNameIfExist();
return treeString.toString();
}
@@ -178,8 +181,34 @@
}
@Override
- public void removeExtraTerminator() {
+ public String subTreeModuleName() {
+ return moduleNameStack.peek();
+ }
+
+ @Override
+ public void pushModuleName(String moduleName) {
+ moduleNameStack.push(moduleName);
+ }
+
+ @Override
+ public void popModuleName() {
+ moduleNameStack.pop();
+ }
+
+ @Override
+ public void initializeJson() {
+ if (!moduleNameStack.empty()) {
+ moduleNameStack.removeAllElements();
+ }
+ moduleNameStack.push(ROOT_MODULE_NAME);
+ treeString.setLength(0);
+ treeString.append(LEFT_BRACE);
+ }
+
+ @Override
+ public void finalizeJson() {
removeCommaIfExist();
+ treeString.append(RIGHT_BRACE);
}
private void appendField(String fieldName) {
diff --git a/serializers/json/src/main/java/org/onosproject/yang/serializers/json/EncoderUtils.java b/serializers/json/src/main/java/org/onosproject/yang/serializers/json/EncoderUtils.java
index 2f9ca39..e78bf3e 100644
--- a/serializers/json/src/main/java/org/onosproject/yang/serializers/json/EncoderUtils.java
+++ b/serializers/json/src/main/java/org/onosproject/yang/serializers/json/EncoderUtils.java
@@ -59,12 +59,13 @@
checkNotNull(dataNode, "data node cannot be null");
JsonBuilder jsonBuilder = new DefaultJsonBuilder();
+ jsonBuilder.initializeJson();
DataNodeVisitor treeNodeListener = new DataNodeJsonVisitor(jsonBuilder, context);
DataNodeSiblingPositionType siblingType = NOT_MULTI_INSTANCE_NODE;
walkDataNodeTree(treeNodeListener, dataNode, siblingType);
- jsonBuilder.removeExtraTerminator();
+ jsonBuilder.finalizeJson();
ObjectNode resultData = jsonBuilder.getTreeNode();
return resultData;
}
diff --git a/serializers/json/src/main/java/org/onosproject/yang/serializers/json/JsonBuilder.java b/serializers/json/src/main/java/org/onosproject/yang/serializers/json/JsonBuilder.java
index cb53cdd..aff22db 100644
--- a/serializers/json/src/main/java/org/onosproject/yang/serializers/json/JsonBuilder.java
+++ b/serializers/json/src/main/java/org/onosproject/yang/serializers/json/JsonBuilder.java
@@ -88,5 +88,43 @@
*/
ObjectNode getTreeNode();
- void removeExtraTerminator();
+ /**
+ * Returns the YANG module name of the JSON subtree that the builder
+ * is currently building. The YANG module name represents the name
+ * space of the subtree.
+ *
+ * @return YANG module name
+ */
+ String subTreeModuleName();
+
+ /**
+ * Updates the YANG module name of the JSON subtree that the builder
+ * is currently building. The YANG module name represents the name
+ * space of the subtree. This function may be called when the builder
+ * starts to build a data node.
+ *
+ * @param moduleName YANG module name of the current subtree
+ */
+ void pushModuleName(String moduleName);
+
+ /**
+ * Removes the YANG module name of the JSON subtree that the builder
+ * is currently building. This function may be called when the builder
+ * finishes building a data node.
+ */
+ void popModuleName();
+
+ /**
+ * Initializes the output JSON and emits the JSON starting symbol
+ * (e.g., the left curly bracket). This method should be the first method
+ * to be called when a JSON building process starts.
+ */
+ void initializeJson();
+
+ /**
+ * Finalizes the output JSON and emits the JSON terminating symbol
+ * (e.g., the right curly bracket). This method should be the last method
+ * to be called when a JSON building process finishes.
+ */
+ void finalizeJson();
}