Bug 1010: Implement restconf error responses
[controller.git] / opendaylight / md-sal / sal-rest-connector / src / main / java / org / opendaylight / controller / sal / rest / impl / JsonMapper.java
index ea0f149d296887f4c713ba32e675ee8e4b8fbf54..1e5bfbd6b93e7fe540931a0f6f828625a4a963c1 100644 (file)
@@ -11,6 +11,7 @@ import static com.google.common.base.Preconditions.checkNotNull;
 
 import java.io.IOException;
 import java.net.URI;
+import java.util.Collections;
 import java.util.HashSet;
 import java.util.List;
 import java.util.Set;
@@ -84,17 +85,22 @@ class JsonMapper {
     private void writeChildrenOfParent(final JsonWriter writer, final CompositeNode parent, final DataNodeContainer parentSchema)
             throws IOException {
         checkNotNull(parent);
-        checkNotNull(parentSchema);
+
+        Set<DataSchemaNode> parentSchemaChildNodes = parentSchema == null ?
+                                   Collections.<DataSchemaNode>emptySet() : parentSchema.getChildNodes();
+
 
         for (Node<?> child : parent.getValue()) {
-            DataSchemaNode childSchema = findFirstSchemaForNode(child, parentSchema.getChildNodes());
+            DataSchemaNode childSchema = findFirstSchemaForNode(child, parentSchemaChildNodes);
 
             if (childSchema == null) {
-                throw new UnsupportedDataTypeException("Probably the data node \"" + child.getNodeType().getLocalName()
-                        + "\" is not conform to schema");
-            }
+                // Node may not conform to schema or allows "anyxml" - we'll process it.
 
-            if (childSchema instanceof ContainerSchemaNode) {
+                logger.debug( "No schema found for data node \"" + child.getNodeType() );
+
+                handleNoSchemaFound( writer, child, parent );
+            }
+            else if (childSchema instanceof ContainerSchemaNode) {
                 Preconditions.checkState(child instanceof CompositeNode,
                         "Data representation of Container should be CompositeNode - " + child.getNodeType());
                 writeContainer(writer, (CompositeNode) child, (ContainerSchemaNode) childSchema);
@@ -123,7 +129,7 @@ class JsonMapper {
         }
 
         for (Node<?> child : parent.getValue()) {
-            DataSchemaNode childSchema = findFirstSchemaForNode(child, parentSchema.getChildNodes());
+            DataSchemaNode childSchema = findFirstSchemaForNode(child, parentSchemaChildNodes);
             if (childSchema instanceof LeafListSchemaNode) {
                 foundLeafLists.remove(childSchema);
             } else if (childSchema instanceof ListSchemaNode) {
@@ -132,6 +138,22 @@ class JsonMapper {
         }
     }
 
+    private void handleNoSchemaFound( final JsonWriter writer, final Node<?> node,
+                                      final CompositeNode parent ) throws IOException {
+        if( node instanceof SimpleNode<?> ) {
+            writeName( node, null, writer );
+            Object value = node.getValue();
+            if( value != null ) {
+                writer.value( String.valueOf( value ) );
+            }
+        } else { // CompositeNode
+            Preconditions.checkState( node instanceof CompositeNode,
+                    "Data representation of Container should be CompositeNode - " + node.getNodeType() );
+
+            writeContainer( writer, (CompositeNode) node, null );
+        }
+    }
+
     private DataSchemaNode findFirstSchemaForNode(final Node<?> node, final Set<DataSchemaNode> dataSchemaNode) {
         for (DataSchemaNode dsn : dataSchemaNode) {
             if (node.getNodeType().equals(dsn.getQName())) {
@@ -301,7 +323,7 @@ class JsonMapper {
 
     private void writeName(final Node<?> node, final DataSchemaNode schema, final JsonWriter writer) throws IOException {
         String nameForOutput = node.getNodeType().getLocalName();
-        if (schema.isAugmenting()) {
+        if ( schema != null && schema.isAugmenting()) {
             ControllerContext contContext = ControllerContext.getInstance();
             CharSequence moduleName = null;
             if (mountPoint == null) {