blob: cff16cdb81daa6d6fe3eb2eb03aa21d865925629 [file] [log] [blame]
/*
* Copyright 2017-present Open Networking Foundation
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.onosproject.yang.serializers.json;
import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.node.JsonNodeType;
import com.fasterxml.jackson.databind.node.ObjectNode;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
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;
/**
* Represents implementation of interfaces to build and obtain JSON data tree.
*/
public class DefaultJsonBuilder implements JsonBuilder {
private static final String LEFT_BRACE = "{";
private static final String RIGHT_BRACE = "}";
private static final String LEFT_BRACKET = "[";
private static final String RIGHT_BRACKET = "]";
private static final String COMMA = ",";
private static final String COLON = ":";
private static final String QUOTE = "\"";
private static final String ROOT_MODULE_NAME = "ROOT";
private Logger log = LoggerFactory.getLogger(getClass());
private StringBuilder treeString;
private Stack<String> moduleNameStack;
public DefaultJsonBuilder(String rootName) {
checkNotNull(rootName);
treeString = new StringBuilder(rootName);
moduleNameStack = new Stack<>();
}
public DefaultJsonBuilder() {
treeString = new StringBuilder();
moduleNameStack = new Stack<>();
}
@Override
public void addNodeTopHalf(String nodeName, JsonNodeType nodeType) {
appendField(nodeName);
switch (nodeType) {
case OBJECT:
treeString.append(LEFT_BRACE);
break;
case ARRAY:
treeString.append(LEFT_BRACKET);
break;
default:
log.error("Unknown support type {} for this method.", nodeType);
}
}
@Override
public void addNodeWithValueTopHalf(String nodeName, String value,
String valNamespace) {
if (isNullOrEmpty(nodeName)) {
return;
}
appendField(nodeName);
treeString.append(QUOTE);
if (valNamespace != null) {
treeString.append(valNamespace);
treeString.append(COLON);
}
treeString.append(value);
treeString.append(QUOTE);
treeString.append(COMMA);
}
@Override
public void addNodeWithSetTopHalf(String nodeName, Set<String> sets) {
if (isNullOrEmpty(nodeName)) {
return;
}
appendField(nodeName);
treeString.append(LEFT_BRACKET);
for (String el : sets) {
treeString.append(QUOTE);
treeString.append(el);
treeString.append(QUOTE);
treeString.append(COMMA);
}
}
@Override
public void addValueToLeafListNode(String value, String valNamespace) {
if (isNullOrEmpty(value)) {
return;
}
treeString.append(QUOTE);
treeString.append(value);
if (valNamespace != null) {
treeString.append(COLON);
treeString.append(valNamespace);
}
treeString.append(QUOTE);
treeString.append(COMMA);
}
@Override
public void addNodeBottomHalf(JsonNodeType nodeType) {
switch (nodeType) {
case OBJECT:
removeCommaIfExist();
treeString.append(RIGHT_BRACE);
treeString.append(COMMA);
break;
case ARRAY:
removeCommaIfExist();
treeString.append(RIGHT_BRACKET);
treeString.append(COMMA);
break;
case BINARY:
case BOOLEAN:
case MISSING:
case NULL:
case NUMBER:
case POJO:
case STRING:
break;
default:
log.info("Unknown json node type {}", nodeType);
}
}
@Override
public String getTreeString() {
return treeString.toString();
}
private void removeFirstFieldNameIfExist() {
int index1 = treeString.indexOf(LEFT_BRACE);
int index2 = treeString.indexOf(LEFT_BRACKET);
if (index1 < 0 && index2 < 0) {
return;
}
int index;
if (index1 < 0) {
index = index2;
} else if (index2 < 0) {
index = index1;
} else {
index = (index1 < index2) ? index1 : index2;
}
treeString.delete(0, index);
}
@Override
public ObjectNode getTreeNode() {
ObjectNode node = null;
try {
ObjectMapper m = new ObjectMapper();
m.configure(JsonParser.Feature.ALLOW_UNQUOTED_CONTROL_CHARS, true);
node = (ObjectNode) m.readTree(getTreeString());
} catch (IOException e) {
e.printStackTrace();
}
return node;
}
@Override
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(boolean isRootTypeMultiInstance) {
removeCommaIfExist();
if (isRootTypeMultiInstance) {
/*
* If the root node of the JSON tree is an array
* type, we need to close the array with the right
* bracket.
*/
treeString.append(RIGHT_BRACKET);
}
treeString.append(RIGHT_BRACE);
}
private void appendField(String fieldName) {
if (fieldName != null && !fieldName.isEmpty()) {
treeString.append(QUOTE);
treeString.append(fieldName);
treeString.append(QUOTE);
treeString.append(COLON);
}
}
private void removeCommaIfExist() {
if (treeString.charAt(treeString.length() - 1) == COMMA.charAt(0)) {
treeString.deleteCharAt(treeString.length() - 1);
}
}
}