Merge "Fix two neutron service defects"
[controller.git] / opendaylight / md-sal / sal-rest-connector / src / main / java / org / opendaylight / controller / sal / rest / impl / JsonMapper.java
index 55751e5ac7c33a583ea8d4ea36fdf2a4dbe2ce14..5a1b42fd8009d074613407088c94359bac5dc6d9 100644 (file)
@@ -7,6 +7,8 @@ import java.util.HashSet;
 import java.util.List;
 import java.util.Set;
 
+import javax.activation.UnsupportedDataTypeException;
+
 import org.opendaylight.yangtools.yang.data.api.CompositeNode;
 import org.opendaylight.yangtools.yang.data.api.Node;
 import org.opendaylight.yangtools.yang.data.api.SimpleNode;
@@ -24,6 +26,7 @@ import org.opendaylight.yangtools.yang.model.api.type.InstanceIdentifierTypeDefi
 import org.opendaylight.yangtools.yang.model.api.type.IntegerTypeDefinition;
 import org.opendaylight.yangtools.yang.model.api.type.UnsignedIntegerTypeDefinition;
 
+import com.google.common.base.Preconditions;
 import com.google.gson.stream.JsonWriter;
 
 class JsonMapper {
@@ -32,9 +35,23 @@ class JsonMapper {
     private final Set<ListSchemaNode> foundLists = new HashSet<>();
     
     public void write(JsonWriter writer, CompositeNode data, DataNodeContainer schema) throws IOException {
+        Preconditions.checkNotNull(writer);
+        Preconditions.checkNotNull(data);
+        Preconditions.checkNotNull(schema);
+
         writer.beginObject();
-        writeChildrenOfParent(writer, data, schema);
+        
+        if (schema instanceof ContainerSchemaNode) {
+            writeContainer(writer, data, (ContainerSchemaNode) schema);
+        } else if (schema instanceof ListSchemaNode) {
+            writeList(writer, data, (ListSchemaNode) schema);
+        } else {
+            throw new UnsupportedDataTypeException(
+                    "Schema can be ContainerSchemaNode or ListSchemaNode. Other types are not supported yet.");
+        }
+        
         writer.endObject();
+        
         foundLeafLists.clear();
         foundLists.clear();
     }
@@ -44,26 +61,42 @@ class JsonMapper {
         checkNotNull(parentSchema);
         
         for (Node<?> child : parent.getChildren()) {
-            DataSchemaNode childSchema = findSchemaForNode(child, parentSchema.getChildNodes());
+            DataSchemaNode childSchema = findFirstSchemaForNode(child, parentSchema.getChildNodes());
+            if (childSchema == null) {
+                throw new UnsupportedDataTypeException("Probably the data node \"" + child.getNodeType().getLocalName()
+                        + "\" is not conform to schema");
+            }
+            
             if (childSchema instanceof ContainerSchemaNode) {
+                Preconditions.checkState(child instanceof CompositeNode,
+                        "Data representation of Container should be CompositeNode - " + child.getNodeType());
                 writeContainer(writer, (CompositeNode) child, (ContainerSchemaNode) childSchema);
             } else if (childSchema instanceof ListSchemaNode) {
                 if (!foundLists.contains(childSchema)) {
+                    Preconditions.checkState(child instanceof CompositeNode,
+                            "Data representation of List should be CompositeNode - " + child.getNodeType());
                     foundLists.add((ListSchemaNode) childSchema);
                     writeList(writer, (CompositeNode) child, (ListSchemaNode) childSchema);
                 }
             } else if (childSchema instanceof LeafListSchemaNode) {
                 if (!foundLeafLists.contains(childSchema)) {
+                    Preconditions.checkState(child instanceof SimpleNode<?>,
+                            "Data representation of LeafList should be SimpleNode - " + child.getNodeType());
                     foundLeafLists.add((LeafListSchemaNode) childSchema);
                     writeLeafList(writer, (SimpleNode<?>) child, (LeafListSchemaNode) childSchema);
                 }
             } else if (childSchema instanceof LeafSchemaNode) {
+                Preconditions.checkState(child instanceof SimpleNode<?>,
+                        "Data representation of LeafList should be SimpleNode - " + child.getNodeType());
                 writeLeaf(writer, (SimpleNode<?>) child, (LeafSchemaNode) childSchema);
+            } else {
+                throw new UnsupportedDataTypeException("Schema can be ContainerSchemaNode, ListSchemaNode, "
+                        + "LeafListSchemaNode, or LeafSchemaNode. Other types are not supported yet.");
             }
         }
         
         for (Node<?> child : parent.getChildren()) {
-            DataSchemaNode childSchema = findSchemaForNode(child, parentSchema.getChildNodes());
+            DataSchemaNode childSchema = findFirstSchemaForNode(child, parentSchema.getChildNodes());
             if (childSchema instanceof LeafListSchemaNode) {
                 foundLeafLists.remove((LeafListSchemaNode) childSchema);
             } else if (childSchema instanceof ListSchemaNode) {
@@ -72,7 +105,7 @@ class JsonMapper {
         }
     }
     
-    private DataSchemaNode findSchemaForNode(Node<?> node, Set<DataSchemaNode> dataSchemaNode) {
+    private DataSchemaNode findFirstSchemaForNode(Node<?> node, Set<DataSchemaNode> dataSchemaNode) {
         for (DataSchemaNode dsn : dataSchemaNode) {
             if (node.getNodeType().getLocalName().equals(dsn.getQName().getLocalName())) {
                 return dsn;
@@ -145,9 +178,11 @@ class JsonMapper {
         } else if (type instanceof BooleanTypeDefinition) {
             writer.value(Boolean.parseBoolean(value));
         } else if (type instanceof EmptyTypeDefinition) {
-            writer.value("[null]");
+            writer.beginArray();
+            writer.nullValue();
+            writer.endArray();
         } else {
-            writer.value(value);
+            writer.value(value != null ? value : "");
         }
     }