1 package org.opendaylight.controller.sal.rest.impl;
3 import static com.google.common.base.Preconditions.checkNotNull;
5 import java.io.IOException;
6 import java.util.HashSet;
10 import javax.activation.UnsupportedDataTypeException;
12 import org.opendaylight.yangtools.yang.data.api.CompositeNode;
13 import org.opendaylight.yangtools.yang.data.api.Node;
14 import org.opendaylight.yangtools.yang.data.api.SimpleNode;
15 import org.opendaylight.yangtools.yang.model.api.ContainerSchemaNode;
16 import org.opendaylight.yangtools.yang.model.api.DataNodeContainer;
17 import org.opendaylight.yangtools.yang.model.api.DataSchemaNode;
18 import org.opendaylight.yangtools.yang.model.api.LeafListSchemaNode;
19 import org.opendaylight.yangtools.yang.model.api.LeafSchemaNode;
20 import org.opendaylight.yangtools.yang.model.api.ListSchemaNode;
21 import org.opendaylight.yangtools.yang.model.api.TypeDefinition;
22 import org.opendaylight.yangtools.yang.model.api.type.BooleanTypeDefinition;
23 import org.opendaylight.yangtools.yang.model.api.type.DecimalTypeDefinition;
24 import org.opendaylight.yangtools.yang.model.api.type.EmptyTypeDefinition;
25 import org.opendaylight.yangtools.yang.model.api.type.InstanceIdentifierTypeDefinition;
26 import org.opendaylight.yangtools.yang.model.api.type.IntegerTypeDefinition;
27 import org.opendaylight.yangtools.yang.model.api.type.UnsignedIntegerTypeDefinition;
29 import com.google.gson.stream.JsonWriter;
33 private final Set<LeafListSchemaNode> foundLeafLists = new HashSet<>();
34 private final Set<ListSchemaNode> foundLists = new HashSet<>();
36 public void write(JsonWriter writer, CompositeNode data, DataNodeContainer schema) throws IOException {
39 if (schema instanceof ContainerSchemaNode) {
40 writeContainer(writer, (CompositeNode) data, (ContainerSchemaNode) schema);
41 } else if (schema instanceof ListSchemaNode) {
42 writeList(writer, (CompositeNode) data, (ListSchemaNode) schema);
44 throw new UnsupportedDataTypeException(
45 "Schema can be ContainerSchemaNode or ListSchemaNode. Other types are not supported yet.");
50 foundLeafLists.clear();
54 private void writeChildrenOfParent(JsonWriter writer, CompositeNode parent, DataNodeContainer parentSchema) throws IOException {
56 checkNotNull(parentSchema);
58 for (Node<?> child : parent.getChildren()) {
59 DataSchemaNode childSchema = findSchemaForNode(child, parentSchema.getChildNodes());
60 if (childSchema == null) {
61 throw new UnsupportedDataTypeException("Probably the data node \"" + child.getNodeType().getLocalName()
62 + "\" is not conform to schema");
65 if (childSchema instanceof ContainerSchemaNode) {
66 writeContainer(writer, (CompositeNode) child, (ContainerSchemaNode) childSchema);
67 } else if (childSchema instanceof ListSchemaNode) {
68 if (!foundLists.contains(childSchema)) {
69 foundLists.add((ListSchemaNode) childSchema);
70 writeList(writer, (CompositeNode) child, (ListSchemaNode) childSchema);
72 } else if (childSchema instanceof LeafListSchemaNode) {
73 if (!foundLeafLists.contains(childSchema)) {
74 foundLeafLists.add((LeafListSchemaNode) childSchema);
75 writeLeafList(writer, (SimpleNode<?>) child, (LeafListSchemaNode) childSchema);
77 } else if (childSchema instanceof LeafSchemaNode) {
78 writeLeaf(writer, (SimpleNode<?>) child, (LeafSchemaNode) childSchema);
80 throw new UnsupportedDataTypeException("Schema can be ContainerSchemaNode, ListSchemaNode, "
81 + "LeafListSchemaNode, or LeafSchemaNode. Other types are not supported yet.");
85 for (Node<?> child : parent.getChildren()) {
86 DataSchemaNode childSchema = findSchemaForNode(child, parentSchema.getChildNodes());
87 if (childSchema instanceof LeafListSchemaNode) {
88 foundLeafLists.remove((LeafListSchemaNode) childSchema);
89 } else if (childSchema instanceof ListSchemaNode) {
90 foundLists.remove((ListSchemaNode) childSchema);
95 private DataSchemaNode findSchemaForNode(Node<?> node, Set<DataSchemaNode> dataSchemaNode) {
96 for (DataSchemaNode dsn : dataSchemaNode) {
97 if (node.getNodeType().getLocalName().equals(dsn.getQName().getLocalName())) {
104 private void writeContainer(JsonWriter writer, CompositeNode node, ContainerSchemaNode schema) throws IOException {
105 writer.name(node.getNodeType().getLocalName());
106 writer.beginObject();
107 writeChildrenOfParent(writer, node, schema);
111 private void writeList(JsonWriter writer, CompositeNode node, ListSchemaNode schema) throws IOException {
112 writer.name(node.getNodeType().getLocalName());
115 if (node.getParent() != null) {
116 CompositeNode parent = node.getParent();
117 List<CompositeNode> nodeLists = parent.getCompositesByName(node.getNodeType());
118 for (CompositeNode nodeList : nodeLists) {
119 writer.beginObject();
120 writeChildrenOfParent(writer, nodeList, schema);
124 writer.beginObject();
125 writeChildrenOfParent(writer, node, schema);
132 private void writeLeafList(JsonWriter writer, SimpleNode<?> node, LeafListSchemaNode schema) throws IOException {
133 writer.name(node.getNodeType().getLocalName());
136 CompositeNode parent = node.getParent();
137 List<SimpleNode<?>> nodeLeafLists = parent.getSimpleNodesByName(node.getNodeType());
138 for (SimpleNode<?> nodeLeafList : nodeLeafLists) {
139 writeValueOfNodeByType(writer, nodeLeafList, schema.getType());
145 private void writeLeaf(JsonWriter writer, SimpleNode<?> node, LeafSchemaNode schema) throws IOException {
146 writer.name(node.getNodeType().getLocalName());
147 writeValueOfNodeByType(writer, node, schema.getType());
150 private void writeValueOfNodeByType(JsonWriter writer, SimpleNode<?> node, TypeDefinition<?> type) throws IOException {
151 if (!(node.getValue() instanceof String)) {
152 throw new IllegalStateException("Value in SimpleNode should be type String");
155 String value = (String) node.getValue();
156 // TODO check Leafref, InstanceIdentifierTypeDefinition, IdentityrefTypeDefinition, UnionTypeDefinition
157 if (type.getBaseType() != null) {
158 writeValueOfNodeByType(writer, node, type.getBaseType());
159 } else if (type instanceof InstanceIdentifierTypeDefinition) {
160 writer.value(((InstanceIdentifierTypeDefinition) type).getPathStatement().toString());
161 } else if (type instanceof DecimalTypeDefinition
162 || type instanceof IntegerTypeDefinition
163 || type instanceof UnsignedIntegerTypeDefinition) {
164 writer.value(new NumberForJsonWriter(value));
165 } else if (type instanceof BooleanTypeDefinition) {
166 writer.value(Boolean.parseBoolean(value));
167 } else if (type instanceof EmptyTypeDefinition) {
176 private static final class NumberForJsonWriter extends Number {
178 private static final long serialVersionUID = -3147729419814417666L;
179 private final String value;
181 public NumberForJsonWriter(String value) {
186 public int intValue() {
187 throw new IllegalStateException("Should not be invoked");
191 public long longValue() {
192 throw new IllegalStateException("Should not be invoked");
196 public float floatValue() {
197 throw new IllegalStateException("Should not be invoked");
201 public double doubleValue() {
202 throw new IllegalStateException("Should not be invoked");
206 public String toString() {