Finding data nodes in choices and cases. 43/3243/1
authorJozef Gloncak <jgloncak@cisco.com>
Fri, 29 Nov 2013 09:46:51 +0000 (10:46 +0100)
committerJozef Gloncak <jgloncak@cisco.com>
Fri, 29 Nov 2013 11:46:28 +0000 (12:46 +0100)
Feature was rewritten. It is no more taken into account if schemas for data
nodes at the same level are in the same case for concrete choice. This check should be done in system which takes Json as input

Change-Id: I12e9d2dd9bba21e5ec59a6864a41c4b82cb4f43f
Signed-off-by: Jozef Gloncak <jgloncak@cisco.com>
opendaylight/md-sal/sal-rest-connector/src/main/java/org/opendaylight/controller/sal/rest/impl/JsonMapper.java
opendaylight/md-sal/sal-rest-connector/src/main/java/org/opendaylight/controller/sal/rest/impl/SchemaLocation.java [deleted file]
opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/test/ToJsonChoiceCaseTest.java
opendaylight/md-sal/sal-rest-connector/src/test/resources/yang-to-json-conversion/choice/choice.yang
opendaylight/md-sal/sal-rest-connector/src/test/resources/yang-to-json-conversion/choice/xml/data_case_defined_without_case.xml [new file with mode: 0644]
opendaylight/md-sal/sal-rest-connector/src/test/resources/yang-to-json-conversion/choice/xml/data_more_choices_same_level.xml
opendaylight/md-sal/sal-rest-connector/src/test/resources/yang-to-json-conversion/choice/xml/data_more_choices_same_level_various_paths_err.xml [new file with mode: 0644]
opendaylight/md-sal/sal-rest-connector/src/test/resources/yang-to-json-conversion/choice/xml/data_three_choices_same_level.xml [new file with mode: 0644]
opendaylight/md-sal/sal-rest-connector/src/test/resources/yang-to-json-conversion/choice/xml/data_various_path_err.xml [moved from opendaylight/md-sal/sal-rest-connector/src/test/resources/yang-to-json-conversion/choice/xml/data_various_path.xml with 100% similarity]

index 36b46a171cde4706a1b7e22d17ed4c7e00ccdc90..9608d65e41ca82a13e2dada78b5ce5dfeb0728e7 100644 (file)
@@ -47,26 +47,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 +84,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 +93,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;
diff --git a/opendaylight/md-sal/sal-rest-connector/src/main/java/org/opendaylight/controller/sal/rest/impl/SchemaLocation.java b/opendaylight/md-sal/sal-rest-connector/src/main/java/org/opendaylight/controller/sal/rest/impl/SchemaLocation.java
deleted file mode 100644 (file)
index 24055ce..0000000
+++ /dev/null
@@ -1,28 +0,0 @@
-package org.opendaylight.controller.sal.rest.impl;
-
-import java.util.*;
-
-import org.opendaylight.yangtools.yang.model.api.DataSchemaNode;
-
-class SchemaLocation {
-    final private List<String> location = new ArrayList<>();
-    final private DataSchemaNode schema;
-
-    public SchemaLocation(DataSchemaNode schema) {
-        this.schema = schema;
-    }
-
-    DataSchemaNode getSchema() {
-        return schema;
-    }
-
-    List<String> getLocation() {
-        return location;
-    }
-
-    SchemaLocation addPathPart(String partOfPath) {
-        location.add(partOfPath);
-        return this;
-    }
-
-}
index 141ffdb75467f8db326c03763e83ce4cb2d27b74..8e3ff1d2ed4a998997181a897a1c8ff648099aaa 100644 (file)
@@ -25,39 +25,56 @@ public class ToJsonChoiceCaseTest {
     }
 
     /**
-     * Test when some data are in one case node and other in another. Exception
-     * expected!!
+     * Test when some data are in one case node and other in another. This isn't
+     * correct. Next Json validator should return error because nodes has to be
+     * from one case below concrete choice.
+     * 
      */
     @Test
-    public void compNodeDataOnVariousChoiceCasePathTest() {
-        boolean exceptionCatched = false;
+    public void nodeSchemasOnVariousChoiceCasePathTest() {
         try {
             TestUtils.writeCompNodeWithSchemaContextToJson(
-                    TestUtils.loadCompositeNode("/yang-to-json-conversion/choice/xml/data_various_path.xml"),
+                    TestUtils.loadCompositeNode("/yang-to-json-conversion/choice/xml/data_various_path_err.xml"),
                     "/yang-to-json-conversion/choice/xml", modules, dataSchemaNode);
-        } catch (UnsupportedDataTypeException e) {
-            exceptionCatched = true;
-
         } catch (WebApplicationException | IOException e) {
             // shouldn't end here
             assertTrue(false);
         }
+    }
 
-        assertTrue(exceptionCatched);
-
+    /**
+     * Test when some data are in one case node and other in another.
+     * Additionally data are loadef from various choices. This isn't
+     * correct. Next Json validator should return error because nodes has to be
+     * from one case below concrete choice.
+     * 
+     */
+    @Test
+    public void nodeSchemasOnVariousChoiceCasePathAndMultipleChoicesTest() {
+        try {
+            TestUtils
+                    .writeCompNodeWithSchemaContextToJson(
+                            TestUtils
+                                    .loadCompositeNode("/yang-to-json-conversion/choice/xml/data_more_choices_same_level_various_paths_err.xml"),
+                            "/yang-to-json-conversion/choice/xml", modules, dataSchemaNode);
+        } catch (WebApplicationException | IOException e) {
+            // shouldn't end here
+            assertTrue(false);
+        }
     }
 
     /**
      * Test when second level data are red first, then first and at the end
      * third level. Level represents pass through couple choice-case
      */
-    @Ignore
+
     @Test
-    public void compNodeDataWithRandomOrderAccordingLevel() {
+    public void nodeSchemasWithRandomOrderAccordingLevel() {
         try {
-            String jsonOutput = TestUtils.writeCompNodeWithSchemaContextToJson(
+            TestUtils.writeCompNodeWithSchemaContextToJson(
                     TestUtils.loadCompositeNode("/yang-to-json-conversion/choice/xml/data_random_level.xml"),
                     "/yang-to-json-conversion/choice/xml", modules, dataSchemaNode);
+
         } catch (WebApplicationException | IOException e) {
             // shouldn't end here
             assertTrue(false);
@@ -67,11 +84,10 @@ public class ToJsonChoiceCaseTest {
     /**
      * Test when element from no first case is used
      */
-    @Ignore
     @Test
-    public void compNodeDataNoFirstCase() {
+    public void nodeSchemasNotInFirstCase() {
         try {
-            String jsonOutput = TestUtils.writeCompNodeWithSchemaContextToJson(
+            TestUtils.writeCompNodeWithSchemaContextToJson(
                     TestUtils.loadCompositeNode("/yang-to-json-conversion/choice/xml/data_no_first_case.xml"),
                     "/yang-to-json-conversion/choice/xml", modules, dataSchemaNode);
         } catch (WebApplicationException | IOException e) {
@@ -83,11 +99,10 @@ public class ToJsonChoiceCaseTest {
     /**
      * Test when element in case is list
      */
-    @Ignore
     @Test
-    public void compNodeDataAsList() {
+    public void nodeSchemaAsList() {
         try {
-            String jsonOutput = TestUtils.writeCompNodeWithSchemaContextToJson(
+            TestUtils.writeCompNodeWithSchemaContextToJson(
                     TestUtils.loadCompositeNode("/yang-to-json-conversion/choice/xml/data_list.xml"),
                     "/yang-to-json-conversion/choice/xml", modules, dataSchemaNode);
         } catch (WebApplicationException | IOException e) {
@@ -99,11 +114,10 @@ public class ToJsonChoiceCaseTest {
     /**
      * Test when element in case is container
      */
-    @Ignore
     @Test
-    public void compNodeDataAsContainer() {
+    public void nodeSchemaAsContainer() {
         try {
-            String jsonOutput = TestUtils.writeCompNodeWithSchemaContextToJson(
+            TestUtils.writeCompNodeWithSchemaContextToJson(
                     TestUtils.loadCompositeNode("/yang-to-json-conversion/choice/xml/data_container.xml"),
                     "/yang-to-json-conversion/choice/xml", modules, dataSchemaNode);
         } catch (WebApplicationException | IOException e) {
@@ -113,13 +127,12 @@ public class ToJsonChoiceCaseTest {
     }
 
     /**
-     * Test when element in case is container
+     * Test when element in case is leaflist
      */
-    @Ignore
     @Test
-    public void compNodeDataAsLeafList() {
+    public void nodeSchemaAsLeafList() {
         try {
-            String jsonOutput = TestUtils.writeCompNodeWithSchemaContextToJson(
+            TestUtils.writeCompNodeWithSchemaContextToJson(
                     TestUtils.loadCompositeNode("/yang-to-json-conversion/choice/xml/data_leaflist.xml"),
                     "/yang-to-json-conversion/choice/xml", modules, dataSchemaNode);
         } catch (WebApplicationException | IOException e) {
@@ -128,4 +141,50 @@ public class ToJsonChoiceCaseTest {
         }
     }
 
+    /**
+     * 
+     */
+    @Test
+    public void nodeSchemasInMultipleChoicesTest() {
+        try {
+            TestUtils
+                    .writeCompNodeWithSchemaContextToJson(TestUtils
+                            .loadCompositeNode("/yang-to-json-conversion/choice/xml/data_more_choices_same_level.xml"),
+                            "/yang-to-json-conversion/choice/xml", modules, dataSchemaNode);
+        } catch (WebApplicationException | IOException e) {
+            // shouldn't end here
+            assertTrue(false);
+        }
+    }
+
+    /**
+     * Test whether is possible to find data schema for node which is specified
+     * as dirrect subnode of choice (case without CASE key word)
+     */
+    @Test
+    public void nodeSchemasInCaseNotDefinedWithCaseKeyword() {
+        try {
+            TestUtils.writeCompNodeWithSchemaContextToJson(TestUtils
+                    .loadCompositeNode("/yang-to-json-conversion/choice/xml/data_case_defined_without_case.xml"),
+                    "/yang-to-json-conversion/choice/xml", modules, dataSchemaNode);
+        } catch (WebApplicationException | IOException e) {
+            // shouldn't end here
+            assertTrue(false);
+        }
+    }
+
+    /**
+     * Test of multiple use of choices
+     */
+    @Test
+    public void nodeSchemasInThreeChoicesAtSameLevel() {
+        try {
+            TestUtils.writeCompNodeWithSchemaContextToJson(TestUtils
+                    .loadCompositeNode("/yang-to-json-conversion/choice/xml/data_three_choices_same_level.xml"),
+                    "/yang-to-json-conversion/choice/xml", modules, dataSchemaNode);
+        } catch (WebApplicationException | IOException e) {
+            // shouldn't end here
+            assertTrue(false);
+        }
+    }
 }
index 8b02a9297991a00ed66417fbc3b57f52dd417da4..a6a32df52ee762c1a395908a86af81e6378c56a5 100644 (file)
@@ -10,7 +10,7 @@ module choice-case-test {
                        type string;
                }               
                
-               choice choi1 {
+               choice choi1 {            
                        case a1 {
                                leaf lf1a {
                                        type uint16;    
@@ -59,6 +59,9 @@ module choice-case-test {
                                        type string;
                                }
                        }
+            leaf e1 {
+                type uint32;
+            }
                }
                
                choice choi2 {
@@ -73,6 +76,31 @@ module choice-case-test {
                                }
                        }
                }
+        
+        choice choi4 {
+            case a4 {
+                list lst4a {
+                    choice choi4aa {
+                        case aa1 {
+                            leaf lf4aa {
+                                type string;
+                            }
+                        }
+                        case ab2 {
+                            leaf lf4ab {
+                                type int16;
+                            }
+                        }
+                    }
+                }
+            }
+            case b4 {
+                leaf-list lflst4b {
+                    type uint32;
+                }
+            }
+            
+        }
                
 /*              equal identifiers in various cases are illegal 7.9.2 rfc6020 */
 /*             
diff --git a/opendaylight/md-sal/sal-rest-connector/src/test/resources/yang-to-json-conversion/choice/xml/data_case_defined_without_case.xml b/opendaylight/md-sal/sal-rest-connector/src/test/resources/yang-to-json-conversion/choice/xml/data_case_defined_without_case.xml
new file mode 100644 (file)
index 0000000..b669842
--- /dev/null
@@ -0,0 +1,4 @@
+<cont>
+       <e1>45</e1>
+       <lf2b>lf2b val</lf2b>
+</cont>
\ No newline at end of file
diff --git a/opendaylight/md-sal/sal-rest-connector/src/test/resources/yang-to-json-conversion/choice/xml/data_more_choices_same_level_various_paths_err.xml b/opendaylight/md-sal/sal-rest-connector/src/test/resources/yang-to-json-conversion/choice/xml/data_more_choices_same_level_various_paths_err.xml
new file mode 100644 (file)
index 0000000..331c8ae
--- /dev/null
@@ -0,0 +1,7 @@
+<cont>
+       <cont1c>
+               <lf11c>lf11c val</lf11c>
+       </cont1c>
+       <lf2b>lf2b value</lf2b>
+       <lf2a>lf2b value</lf2a>
+</cont>
\ No newline at end of file
diff --git a/opendaylight/md-sal/sal-rest-connector/src/test/resources/yang-to-json-conversion/choice/xml/data_three_choices_same_level.xml b/opendaylight/md-sal/sal-rest-connector/src/test/resources/yang-to-json-conversion/choice/xml/data_three_choices_same_level.xml
new file mode 100644 (file)
index 0000000..ecc0caa
--- /dev/null
@@ -0,0 +1,13 @@
+<cont>
+       <lf1aaa>lf1aaa value</lf1aaa>
+       <lf2b>lf2b value</lf2b>
+       <lst4a>
+               <lf4ab>33</lf4ab>
+       </lst4a>
+       <lst4a>
+               <lf4ab>33</lf4ab>
+       </lst4a>
+       <lst4a>
+               <lf4ab>37</lf4ab>
+       </lst4a>
+</cont>
\ No newline at end of file