Merge "Leafref and identityref types to Json"
[controller.git] / opendaylight / md-sal / sal-rest-connector / src / main / java / org / opendaylight / controller / sal / rest / impl / JsonMapper.java
index 36b46a171cde4706a1b7e22d17ed4c7e00ccdc90..a42c468c2af27ea5f2cb84887757ed8057a4466f 100644 (file)
@@ -8,6 +8,7 @@ import java.util.*;
 import javax.activation.UnsupportedDataTypeException;
 
 import org.opendaylight.controller.sal.restconf.impl.ControllerContext;
+import org.opendaylight.yangtools.yang.common.QName;
 import org.opendaylight.yangtools.yang.data.api.*;
 import org.opendaylight.yangtools.yang.model.api.*;
 import org.opendaylight.yangtools.yang.model.api.type.*;
@@ -47,26 +48,13 @@ class JsonMapper {
         checkNotNull(parent);
         checkNotNull(parentSchema);
 
-        List<String> longestPathToElementViaChoiceCase = new ArrayList<>();
         for (Node<?> child : parent.getChildren()) {
-            Deque<String> choiceCasePathStack = new ArrayDeque<>(longestPathToElementViaChoiceCase);
-            SchemaLocation schemaLocation = findFirstSchemaForNode(child, parentSchema.getChildNodes(),
-                    choiceCasePathStack);
-
-            if (schemaLocation == null) {
-                if (!choiceCasePathStack.isEmpty()) {
-                    throw new UnsupportedDataTypeException("On choice-case path " + choiceCasePathStack
-                            + " wasn't found data schema for " + child.getNodeType().getLocalName());
-                } else {
-                    throw new UnsupportedDataTypeException("Probably the data node \""
-                            + child.getNodeType().getLocalName() + "\" is not conform to schema");
-                }
-            }
-
-            longestPathToElementViaChoiceCase = resolveLongerPath(longestPathToElementViaChoiceCase,
-                    schemaLocation.getLocation());
+            DataSchemaNode childSchema = findFirstSchemaForNode(child, parentSchema.getChildNodes());
 
-            DataSchemaNode childSchema = schemaLocation.getSchema();
+            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,
@@ -97,10 +85,7 @@ class JsonMapper {
         }
 
         for (Node<?> child : parent.getChildren()) {
-            SchemaLocation schemaLocation = findFirstSchemaForNode(child, parentSchema.getChildNodes(),
-                    new ArrayDeque<>(longestPathToElementViaChoiceCase));
-
-            DataSchemaNode childSchema = schemaLocation.getSchema();
+            DataSchemaNode childSchema = findFirstSchemaForNode(child, parentSchema.getChildNodes());
             if (childSchema instanceof LeafListSchemaNode) {
                 foundLeafLists.remove((LeafListSchemaNode) childSchema);
             } else if (childSchema instanceof ListSchemaNode) {
@@ -109,45 +94,17 @@ class JsonMapper {
         }
     }
 
-    private List<String> resolveLongerPath(List<String> l1, List<String> l2) {
-        return l1.size() > l2.size() ? l1 : l2;
-    }
-
-    private SchemaLocation findFirstSchemaForNode(Node<?> node, Set<DataSchemaNode> dataSchemaNode,
-            Deque<String> pathIterator) {
-        Map<String, ChoiceNode> choiceSubnodes = new HashMap<>();
+    private DataSchemaNode findFirstSchemaForNode(Node<?> node, Set<DataSchemaNode> dataSchemaNode) {
         for (DataSchemaNode dsn : dataSchemaNode) {
-            if (dsn instanceof ChoiceNode) {
-                choiceSubnodes.put(dsn.getQName().getLocalName(), (ChoiceNode) dsn);
-            } else if (node.getNodeType().getLocalName().equals(dsn.getQName().getLocalName())) {
-                return new SchemaLocation(dsn);
-            }
-        }
-
-        for (ChoiceNode choiceSubnode : choiceSubnodes.values()) {
-            if ((!pathIterator.isEmpty() && pathIterator.peekLast().equals(choiceSubnode.getQName().getLocalName()))
-                    || pathIterator.isEmpty()) {
-                String pathPartChoice = pathIterator.pollLast();
-                for (ChoiceCaseNode concreteCase : choiceSubnode.getCases()) {
-                    if ((!pathIterator.isEmpty() && pathIterator.peekLast().equals(
-                            concreteCase.getQName().getLocalName()))
-                            || pathIterator.isEmpty()) {
-                        String pathPartCase = pathIterator.pollLast();
-                        SchemaLocation schemaLocation = findFirstSchemaForNode(node, concreteCase.getChildNodes(),
-                                pathIterator);
-                        if (schemaLocation != null) {
-                            schemaLocation.addPathPart(concreteCase.getQName().getLocalName());
-                            schemaLocation.addPathPart(choiceSubnode.getQName().getLocalName());
-                            return schemaLocation;
-                        }
-                        if (pathPartCase != null) {
-                            pathIterator.addLast(pathPartCase);
-                        }
+            if (node.getNodeType().getLocalName().equals(dsn.getQName().getLocalName())) {
+                return dsn;
+            } else if (dsn instanceof ChoiceNode) {
+                for (ChoiceCaseNode choiceCase : ((ChoiceNode) dsn).getCases()) {
+                    DataSchemaNode foundDsn = findFirstSchemaForNode(node, choiceCase.getChildNodes());
+                    if (foundDsn != null) {
+                        return foundDsn;
                     }
                 }
-                if (pathPartChoice != null) {
-                    pathIterator.addLast(pathPartChoice);
-                }
             }
         }
         return null;
@@ -188,25 +145,43 @@ class JsonMapper {
 
         List<SimpleNode<?>> nodeLeafLists = nodeParent.getSimpleNodesByName(node.getNodeType());
         for (SimpleNode<?> nodeLeafList : nodeLeafLists) {
-            writeValueOfNodeByType(writer, nodeLeafList, schema.getType());
+            writeValueOfNodeByType(writer, nodeLeafList, schema.getType(), schema);
         }
-
         writer.endArray();
     }
 
     private void writeLeaf(JsonWriter writer, SimpleNode<?> node, LeafSchemaNode schema) throws IOException {
         writeName(node, schema, writer);
-        writeValueOfNodeByType(writer, node, schema.getType());
+        writeValueOfNodeByType(writer, node, schema.getType(), schema);
     }
 
-    private void writeValueOfNodeByType(JsonWriter writer, SimpleNode<?> node, TypeDefinition<?> type)
-            throws IOException {
+    private void writeValueOfNodeByType(JsonWriter writer, SimpleNode<?> node, TypeDefinition<?> type,
+            DataSchemaNode schema) throws IOException {
 
         String value = String.valueOf(node.getValue());
-        // TODO check Leafref, InstanceIdentifierTypeDefinition,
-        // IdentityrefTypeDefinition, UnionTypeDefinition
         TypeDefinition<?> baseType = resolveBaseTypeFrom(type);
-        if (baseType instanceof InstanceIdentifierTypeDefinition) {
+
+        // TODO check InstanceIdentifierTypeDefinition,
+        // IdentityrefTypeDefinition
+        if (baseType instanceof IdentityrefTypeDefinition) {
+            if (node.getValue() instanceof QName) {
+                QName qName = (QName) node.getValue();
+
+                ControllerContext contContext = ControllerContext.getInstance();
+                String moduleName = contContext.findModuleByNamespace(qName.getNamespace());
+
+                writer.value(moduleName + ":" + qName.getLocalName());
+            }
+
+        } else if (baseType instanceof LeafrefTypeDefinition) {
+            ControllerContext contContext = ControllerContext.getInstance();
+            LeafSchemaNode lfSchemaNode = contContext.resolveTypeFromLeafref((LeafrefTypeDefinition) baseType, schema);
+            if (lfSchemaNode != null) {
+                writeValueOfNodeByType(writer, node, lfSchemaNode.getType(), lfSchemaNode);
+            } else {
+                writer.value(value);
+            }
+        } else if (baseType instanceof InstanceIdentifierTypeDefinition) {
             writer.value(((InstanceIdentifierTypeDefinition) baseType).getPathStatement().toString());
         } else if (baseType instanceof UnionTypeDefinition) {
             processTypeIsUnionType(writer, (UnionTypeDefinition) baseType, value);