Make sure root JSON context is properly flushed 68/82868/9
authorAnna Bencurova <Anna.Bencurova@pantheon.tech>
Mon, 1 Jul 2019 13:34:05 +0000 (15:34 +0200)
committerRobert Varga <robert.varga@pantheon.tech>
Thu, 4 Jul 2019 11:27:33 +0000 (13:27 +0200)
If we are dealing with an exclusive context which contains
only children which can be skipped, we can end up attempting
to close the context without it first having been emitted,
leading to a GSON splat.

In order to fix this, we need make sure we do not directly
emitEnd(), but rather endNode() -- so that the context can
emit its starts if it has not done so.

JIRA: YANGTOOLS-1008
Change-Id: I02452abe24c7a42b83246a113f284990f6211d9f
Signed-off-by: Anna Bencurova <Anna.Bencurova@pantheon.tech>
Signed-off-by: Robert Varga <robert.varga@pantheon.tech>
yang/yang-data-codec-gson/src/main/java/org/opendaylight/yangtools/yang/data/codec/gson/JSONNormalizedNodeStreamWriter.java
yang/yang-data-codec-gson/src/main/java/org/opendaylight/yangtools/yang/data/codec/gson/JSONStreamWriterExclusiveRootContext.java
yang/yang-data-codec-gson/src/main/java/org/opendaylight/yangtools/yang/data/codec/gson/JSONStreamWriterRootContext.java
yang/yang-data-codec-gson/src/main/java/org/opendaylight/yangtools/yang/data/codec/gson/JSONStreamWriterSharedRootContext.java
yang/yang-data-codec-gson/src/main/java/org/opendaylight/yangtools/yang/data/codec/gson/JSONStreamWriterURIContext.java
yang/yang-data-codec-gson/src/test/java/org/opendaylight/yangtools/yang/data/codec/gson/NormalizedNodeToJsonStreamTest.java
yang/yang-data-codec-gson/src/test/java/org/opendaylight/yangtools/yang/data/codec/gson/TestUtils.java
yang/yang-data-codec-gson/src/test/java/org/opendaylight/yangtools/yang/data/codec/gson/TestingNormalizedNodeStructuresCreator.java
yang/yang-data-codec-gson/src/test/resources/complexjson/yang/complexjson.yang

index 354f108d74b282f2f6cb68353ef6211d6db482e5..8503b47c2020a2be07500475702740d9ff2eb0de 100644 (file)
@@ -323,7 +323,7 @@ public abstract class JSONNormalizedNodeStreamWriter implements NormalizedNodeSt
         context = context.endNode(codecs.getSchemaContext(), writer);
 
         if (context instanceof JSONStreamWriterRootContext) {
-            context.emitEnd(writer);
+            context.endNode(codecs.getSchemaContext(), writer);
         }
     }
 
index 5359df81193f2aec3ca01580cccdf8548f11cc20..426d34fe8c2f26625e5425bfbbb2bb06c6a70faa 100644 (file)
@@ -14,7 +14,7 @@ import org.opendaylight.yangtools.yang.model.api.SchemaContext;
 
 final class JSONStreamWriterExclusiveRootContext extends JSONStreamWriterRootContext {
     JSONStreamWriterExclusiveRootContext(final URI namespace) {
-        super(namespace);
+        super(namespace, true);
     }
 
     @Override
index 1d5b340fab5d787e8b85ff480623f190b1bad1ef..0ac5aad36b46765f44cb4ce335116966f19935c1 100644 (file)
@@ -14,7 +14,7 @@ import java.net.URI;
  * It holds the base namespace and can never be removed from the stack.
  */
 abstract class JSONStreamWriterRootContext extends JSONStreamWriterURIContext {
-    JSONStreamWriterRootContext(final URI namespace) {
-        super(null, namespace);
+    JSONStreamWriterRootContext(final URI namespace, final boolean mandatory) {
+        super(null, namespace, mandatory);
     }
 }
index 8704cb6a8ebe2051f4e9edf42c0f8c4f3ab21ab5..858637af2b0b811b3b52c6b4390ba3983eea4959 100644 (file)
@@ -13,7 +13,7 @@ import java.net.URI;
 
 final class JSONStreamWriterSharedRootContext extends JSONStreamWriterRootContext {
     JSONStreamWriterSharedRootContext(final URI namespace) {
-        super(namespace);
+        super(namespace, false);
     }
 
     @Override
index 3c69eab073495059af5595243a9a29fc53f24af2..7caa4adbe6bd80b6982c0a5ad03a8a926c31f619 100644 (file)
@@ -19,8 +19,12 @@ import org.opendaylight.yangtools.yang.model.api.SchemaContext;
 abstract class JSONStreamWriterURIContext extends JSONStreamWriterContext {
     private final URI namespace;
 
-    protected JSONStreamWriterURIContext(final JSONStreamWriterContext parent, final URI namespace) {
-        super(parent, false);
+    JSONStreamWriterURIContext(final JSONStreamWriterContext parent, final URI namespace) {
+        this(parent, namespace, false);
+    }
+
+    JSONStreamWriterURIContext(final JSONStreamWriterContext parent, final URI namespace, final boolean mandatory) {
+        super(parent, mandatory);
         this.namespace = namespace;
     }
 
index 0a9c2708afac3bf804342e58cc71222622013b11..b718659756c0fe10bc396952765acf3ff0b6a7a7 100644 (file)
@@ -10,10 +10,12 @@ package org.opendaylight.yangtools.yang.data.codec.gson;
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertFalse;
 import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
 import static org.junit.Assert.assertTrue;
 import static org.opendaylight.yangtools.yang.data.codec.gson.TestUtils.childArray;
 import static org.opendaylight.yangtools.yang.data.codec.gson.TestUtils.childPrimitive;
 import static org.opendaylight.yangtools.yang.data.codec.gson.TestUtils.resolveCont1;
+import static org.opendaylight.yangtools.yang.data.codec.gson.TestUtils.resolveCont2;
 
 import com.google.common.collect.ImmutableSet;
 import com.google.gson.JsonArray;
@@ -24,14 +26,12 @@ import com.google.gson.JsonPrimitive;
 import java.io.IOException;
 import java.io.StringWriter;
 import java.io.Writer;
-import java.net.URISyntaxException;
 import java.util.HashSet;
 import java.util.Iterator;
 import org.junit.Test;
 import org.opendaylight.yangtools.yang.common.Empty;
 import org.opendaylight.yangtools.yang.common.QName;
-import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
-import org.opendaylight.yangtools.yang.data.api.schema.ContainerNode;
+import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeIdentifier;
 import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
 import org.opendaylight.yangtools.yang.data.api.schema.stream.NormalizedNodeStreamWriter;
 import org.opendaylight.yangtools.yang.data.api.schema.stream.NormalizedNodeWriter;
@@ -50,10 +50,9 @@ public class NormalizedNodeToJsonStreamTest extends AbstractComplexJsonTest {
     private static final QName EMPTY_LEAF = QName.create(CONT_1, "empty");
 
     @Test
-    public void leafNodeInContainer() throws IOException, URISyntaxException {
-        final Writer writer = new StringWriter();
-        final NormalizedNode<?, ?> leafNodeInContainer = TestingNormalizedNodeStructuresCreator.leafNodeInContainer();
-        final String jsonOutput = normalizedNodeToJsonStreamTransformation(writer, leafNodeInContainer);
+    public void leafNodeInContainer() throws IOException {
+        final String jsonOutput = normalizedNodeToJsonStreamTransformation(
+            TestingNormalizedNodeStructuresCreator.leafNodeInContainer());
         final JsonObject cont1 = resolveCont1(jsonOutput);
         assertNotNull(cont1);
 
@@ -64,11 +63,9 @@ public class NormalizedNodeToJsonStreamTest extends AbstractComplexJsonTest {
     }
 
     @Test
-    public void leafListNodeInContainerMultiline() throws IOException, URISyntaxException {
-        final Writer writer = new StringWriter();
-        final NormalizedNode<?, ?> leafListNodeInContainer = TestingNormalizedNodeStructuresCreator
-                .leafListNodeInContainerMultiline();
-        final String jsonOutput = normalizedNodeToJsonStreamTransformation(writer, leafListNodeInContainer);
+    public void leafListNodeInContainerMultiline() throws IOException {
+        final String jsonOutput = normalizedNodeToJsonStreamTransformation(
+            TestingNormalizedNodeStructuresCreator.leafListNodeInContainerMultiline());
         final JsonObject cont1 = resolveCont1(jsonOutput);
         assertNotNull(cont1);
         final JsonArray lflst11 = childArray(cont1, "complexjson:lflst11", "lflst11");
@@ -85,11 +82,9 @@ public class NormalizedNodeToJsonStreamTest extends AbstractComplexJsonTest {
     }
 
     @Test
-    public void leafNodeViaAugmentationInContainer() throws IOException, URISyntaxException {
-        final Writer writer = new StringWriter();
-        final NormalizedNode<?, ?> leafNodeViaAugmentationInContainer = TestingNormalizedNodeStructuresCreator
-                .leafNodeViaAugmentationInContainer();
-        final String jsonOutput = normalizedNodeToJsonStreamTransformation(writer, leafNodeViaAugmentationInContainer);
+    public void leafNodeViaAugmentationInContainer() throws IOException {
+        final String jsonOutput = normalizedNodeToJsonStreamTransformation(
+            TestingNormalizedNodeStructuresCreator.leafNodeViaAugmentationInContainer());
         final JsonObject cont1 = resolveCont1(jsonOutput);
         assertNotNull(cont1);
 
@@ -100,11 +95,9 @@ public class NormalizedNodeToJsonStreamTest extends AbstractComplexJsonTest {
     }
 
     @Test
-    public void leafListNodeInContainer() throws IOException, URISyntaxException {
-        final Writer writer = new StringWriter();
-        final NormalizedNode<?, ?> leafListNodeInContainer = TestingNormalizedNodeStructuresCreator
-                .leafListNodeInContainer();
-        final String jsonOutput = normalizedNodeToJsonStreamTransformation(writer, leafListNodeInContainer);
+    public void leafListNodeInContainer() throws IOException {
+        final String jsonOutput = normalizedNodeToJsonStreamTransformation(
+            TestingNormalizedNodeStructuresCreator.leafListNodeInContainer());
         final JsonObject cont1 = resolveCont1(jsonOutput);
         assertNotNull(cont1);
         final JsonArray lflst11 = childArray(cont1, "complexjson:lflst11", "lflst11");
@@ -120,11 +113,9 @@ public class NormalizedNodeToJsonStreamTest extends AbstractComplexJsonTest {
     }
 
     @Test
-    public void keyedListNodeInContainer() throws IOException, URISyntaxException {
-        final Writer writer = new StringWriter();
-        final NormalizedNode<?, ?> keyedListNodeInContainer = TestingNormalizedNodeStructuresCreator
-                .keyedListNodeInContainer();
-        final String jsonOutput = normalizedNodeToJsonStreamTransformation(writer, keyedListNodeInContainer);
+    public void keyedListNodeInContainer() throws IOException {
+        final String jsonOutput = normalizedNodeToJsonStreamTransformation(
+            TestingNormalizedNodeStructuresCreator.keyedListNodeInContainer());
         final JsonObject cont1 = resolveCont1(jsonOutput);
         assertNotNull(cont1);
         final JsonArray lst11 = childArray(cont1, "complexjson:lst11", "lst11");
@@ -153,11 +144,9 @@ public class NormalizedNodeToJsonStreamTest extends AbstractComplexJsonTest {
     }
 
     @Test
-    public void choiceNodeInContainer() throws IOException, URISyntaxException {
-        final Writer writer = new StringWriter();
-        final NormalizedNode<?, ?> choiceNodeInContainer = TestingNormalizedNodeStructuresCreator
-                .choiceNodeInContainer();
-        final String jsonOutput = normalizedNodeToJsonStreamTransformation(writer, choiceNodeInContainer);
+    public void choiceNodeInContainer() throws IOException {
+        final String jsonOutput = normalizedNodeToJsonStreamTransformation(
+            TestingNormalizedNodeStructuresCreator.choiceNodeInContainer());
         final JsonObject cont1 = resolveCont1(jsonOutput);
         assertNotNull(cont1);
         final JsonPrimitive lf13 = childPrimitive(cont1, "complexjson:lf13", "lf13");
@@ -176,12 +165,9 @@ public class NormalizedNodeToJsonStreamTest extends AbstractComplexJsonTest {
      * [ChoiceNodeImpl[qname=(ns:complex:json?revision=2014-08-11)choc11]]
      */
     @Test
-    public void caseNodeAugmentationInChoiceInContainer() throws IOException, URISyntaxException {
-        final Writer writer = new StringWriter();
-        final NormalizedNode<?, ?> caseNodeAugmentationInChoiceInContainer = TestingNormalizedNodeStructuresCreator
-                .caseNodeAugmentationInChoiceInContainer();
-        final String jsonOutput = normalizedNodeToJsonStreamTransformation(writer,
-                caseNodeAugmentationInChoiceInContainer);
+    public void caseNodeAugmentationInChoiceInContainer() throws IOException {
+        final String jsonOutput = normalizedNodeToJsonStreamTransformation(
+            TestingNormalizedNodeStructuresCreator.caseNodeAugmentationInChoiceInContainer());
         final JsonObject cont1 = resolveCont1(jsonOutput);
         assertNotNull(cont1);
 
@@ -210,12 +196,9 @@ public class NormalizedNodeToJsonStreamTest extends AbstractComplexJsonTest {
      * [ChoiceNodeImpl[qname=(ns:complex:json?revision=2014-08-11)choc11]]
      */
     @Test
-    public void caseNodeExternalAugmentationInChoiceInContainer() throws IOException, URISyntaxException {
-        final Writer writer = new StringWriter();
-        final NormalizedNode<?, ?> caseNodeExternalAugmentationInChoiceInContainer =
-                TestingNormalizedNodeStructuresCreator.caseNodeExternalAugmentationInChoiceInContainer();
-        final String jsonOutput = normalizedNodeToJsonStreamTransformation(writer,
-                caseNodeExternalAugmentationInChoiceInContainer);
+    public void caseNodeExternalAugmentationInChoiceInContainer() throws IOException {
+        final String jsonOutput = normalizedNodeToJsonStreamTransformation(
+            TestingNormalizedNodeStructuresCreator.caseNodeExternalAugmentationInChoiceInContainer());
         final JsonObject cont1 = resolveCont1(jsonOutput);
         assertNotNull(cont1);
 
@@ -246,11 +229,9 @@ public class NormalizedNodeToJsonStreamTest extends AbstractComplexJsonTest {
      * [ChoiceNodeImpl[qname=(ns:complex:json?revision=2014-08-11)choc11]]
      */
     @Test
-    public void choiceNodeAugmentationInContainer() throws IOException, URISyntaxException {
-        final Writer writer = new StringWriter();
-        final NormalizedNode<?, ?> choiceNodeAugmentationInContainer = TestingNormalizedNodeStructuresCreator
-                .choiceNodeAugmentationInContainer();
-        final String jsonOutput = normalizedNodeToJsonStreamTransformation(writer, choiceNodeAugmentationInContainer);
+    public void choiceNodeAugmentationInContainer() throws IOException {
+        final String jsonOutput = normalizedNodeToJsonStreamTransformation(
+            TestingNormalizedNodeStructuresCreator.choiceNodeAugmentationInContainer());
         final JsonObject cont1 = resolveCont1(jsonOutput);
         assertNotNull(cont1);
 
@@ -260,11 +241,9 @@ public class NormalizedNodeToJsonStreamTest extends AbstractComplexJsonTest {
     }
 
     @Test
-    public void unkeyedNodeInContainer() throws IOException, URISyntaxException {
-        final Writer writer = new StringWriter();
-        final NormalizedNode<?, ?> unkeyedNodeInContainer = TestingNormalizedNodeStructuresCreator
-                .unkeyedNodeInContainer();
-        final String jsonOutput = normalizedNodeToJsonStreamTransformation(writer, unkeyedNodeInContainer);
+    public void unkeyedNodeInContainer() throws IOException {
+        final String jsonOutput = normalizedNodeToJsonStreamTransformation(
+            TestingNormalizedNodeStructuresCreator.unkeyedNodeInContainer());
         final JsonObject cont1 = resolveCont1(jsonOutput);
         assertNotNull(cont1);
 
@@ -285,12 +264,11 @@ public class NormalizedNodeToJsonStreamTest extends AbstractComplexJsonTest {
     }
 
     @Test
-    public void emptyTypeTest() throws IOException, URISyntaxException {
-        final StringWriter writer = new StringWriter();
-        final ContainerNode emptyStructure = Builders.containerBuilder()
-                .withNodeIdentifier(new YangInstanceIdentifier.NodeIdentifier(CONT_1))
-                .addChild(ImmutableNodes.leafNode(EMPTY_LEAF, Empty.getInstance())).build();
-        final String jsonOutput = normalizedNodeToJsonStreamTransformation(writer, emptyStructure);
+    public void emptyTypeTest() throws IOException {
+        final String jsonOutput = normalizedNodeToJsonStreamTransformation(Builders.containerBuilder()
+            .withNodeIdentifier(new NodeIdentifier(CONT_1))
+            .addChild(ImmutableNodes.leafNode(EMPTY_LEAF, Empty.getInstance()))
+            .build());
         final JsonObject cont1 = resolveCont1(jsonOutput);
         final JsonElement emptyObj = cont1.get("empty");
         assertNotNull(emptyObj);
@@ -299,15 +277,39 @@ public class NormalizedNodeToJsonStreamTest extends AbstractComplexJsonTest {
         assertTrue(emptyObj.getAsJsonArray().get(0) instanceof JsonNull);
     }
 
-    private static String normalizedNodeToJsonStreamTransformation(final Writer writer,
-            final NormalizedNode<?, ?> inputStructure) throws IOException {
+    @Test
+    public void emptyNonPresenceContainerTest() throws IOException {
+        final String jsonOutput = normalizedNodeToJsonStreamTransformation(
+            TestingNormalizedNodeStructuresCreator.topLevelContainer());
+        final JsonObject cont1 = resolveCont1(jsonOutput);
+        assertNull(cont1);
+    }
+
+    @Test
+    public void emptyNonPresenceContainerInContainerTest() throws IOException {
+        final String jsonOutput = normalizedNodeToJsonStreamTransformation(
+            TestingNormalizedNodeStructuresCreator.emptyContainerInContainer());
+        final JsonObject cont1 = resolveCont1(jsonOutput);
+        assertNull(cont1);
+    }
 
+    @Test
+    public void emptyPresenceContainerTest() throws IOException {
+        final String jsonOutput = normalizedNodeToJsonStreamTransformation(
+            TestingNormalizedNodeStructuresCreator.cont2Node());
+        final JsonObject cont2 = resolveCont2(jsonOutput);
+        assertNotNull(cont2);
+    }
+
+    private static String normalizedNodeToJsonStreamTransformation(final NormalizedNode<?, ?> inputStructure)
+            throws IOException {
+        final Writer writer = new StringWriter();
         final NormalizedNodeStreamWriter jsonStream = JSONNormalizedNodeStreamWriter.createExclusiveWriter(
             lhotkaCodecFactory, SchemaPath.ROOT, null, JsonWriterFactory.createJsonWriter(writer, 2));
-        final NormalizedNodeWriter nodeWriter = NormalizedNodeWriter.forStreamWriter(jsonStream);
-        nodeWriter.write(inputStructure);
+        try (NormalizedNodeWriter nodeWriter = NormalizedNodeWriter.forStreamWriter(jsonStream)) {
+            nodeWriter.write(inputStructure);
+        }
 
-        nodeWriter.close();
         return writer.toString();
     }
 }
index 34e575ed54760883069cd10496df99a627d68778..607523115cc746a56b7553ad376755ba2f11b2b0 100644 (file)
@@ -107,12 +107,18 @@ public final class TestUtils {
     }
 
     static JsonObject resolveCont1(final String jsonOutput) {
-        final JsonParser parser = new JsonParser();
-        final JsonElement rootElement = parser.parse(jsonOutput);
+        final JsonElement rootElement = new JsonParser().parse(jsonOutput);
         assertTrue(rootElement.isJsonObject());
         final JsonObject rootObject = rootElement.getAsJsonObject();
         final JsonObject cont1 = childObject(rootObject, "complexjson:cont1", "cont1");
         return cont1;
     }
 
+    static JsonObject resolveCont2(final String jsonOutput) {
+        final JsonElement rootElement = new JsonParser().parse(jsonOutput);
+        assertTrue(rootElement.isJsonObject());
+        final JsonObject rootObject = rootElement.getAsJsonObject();
+        final JsonObject cont2 = childObject(rootObject, "complexjson:cont2", "cont2");
+        return cont2;
+    }
 }
index 00fd4487631e968d3e92c06acb4cc17b19a90abe..e9a25f578e6ce1e249685b5c7040cffccaf9d8be 100644 (file)
  */
 package org.opendaylight.yangtools.yang.data.codec.gson;
 
+import com.google.common.collect.ImmutableMap;
 import com.google.common.collect.ImmutableSet;
+import java.net.URI;
 import java.util.Arrays;
-import java.util.HashMap;
-import java.util.Map;
 import org.opendaylight.yangtools.yang.common.QName;
+import org.opendaylight.yangtools.yang.common.QNameModule;
+import org.opendaylight.yangtools.yang.common.Revision;
 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.AugmentationIdentifier;
 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeIdentifier;
 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeIdentifierWithPredicates;
 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeWithValue;
-import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.PathArgument;
 import org.opendaylight.yangtools.yang.data.api.schema.AugmentationNode;
 import org.opendaylight.yangtools.yang.data.api.schema.ChoiceNode;
 import org.opendaylight.yangtools.yang.data.api.schema.ContainerNode;
 import org.opendaylight.yangtools.yang.data.api.schema.DataContainerChild;
 import org.opendaylight.yangtools.yang.data.api.schema.LeafNode;
-import org.opendaylight.yangtools.yang.data.api.schema.LeafSetEntryNode;
-import org.opendaylight.yangtools.yang.data.api.schema.MapEntryNode;
-import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
+import org.opendaylight.yangtools.yang.data.api.schema.LeafSetNode;
+import org.opendaylight.yangtools.yang.data.api.schema.MapNode;
 import org.opendaylight.yangtools.yang.data.api.schema.UnkeyedListEntryNode;
 import org.opendaylight.yangtools.yang.data.api.schema.UnkeyedListNode;
 import org.opendaylight.yangtools.yang.data.impl.schema.Builders;
-import org.opendaylight.yangtools.yang.data.impl.schema.builder.api.CollectionNodeBuilder;
-import org.opendaylight.yangtools.yang.data.impl.schema.builder.api.DataContainerNodeBuilder;
-import org.opendaylight.yangtools.yang.data.impl.schema.builder.api.ListNodeBuilder;
 
 public final class TestingNormalizedNodeStructuresCreator {
+    private static final QNameModule COMPLEX_JSON = QNameModule.create(URI.create("ns:complex:json"),
+        Revision.of("2014-08-11"));
+    private static final QNameModule COMPLEX_JSON_AUG = QNameModule.create(URI.create("ns:complex:json:augmentation"),
+        Revision.of("2014-08-14"));
+
     private TestingNormalizedNodeStructuresCreator() {
         throw new UnsupportedOperationException();
     }
 
     @SafeVarargs
-    static NormalizedNode<?, ?> cont1Node(
-            final DataContainerChild<? extends PathArgument, ?>... children) {
-        DataContainerNodeBuilder<NodeIdentifier, ContainerNode> cont1 = Builders.containerBuilder();
-        cont1.withNodeIdentifier(new NodeIdentifier(QName.create("ns:complex:json", "2014-08-11", "cont1")));
+    static ContainerNode cont1Node(final DataContainerChild<?, ?>... children) {
+        return Builders.containerBuilder()
+                .withNodeIdentifier(new NodeIdentifier(QName.create(COMPLEX_JSON, "cont1")))
+                .withValue(Arrays.asList(children))
+                .build();
+    }
 
-        cont1.withValue(Arrays.asList(children));
-        return cont1.build();
+    static ContainerNode cont2Node() {
+        return Builders.containerBuilder()
+                .withNodeIdentifier(new NodeIdentifier(QName.create(COMPLEX_JSON, "cont2")))
+                .build();
     }
 
-    private static DataContainerChild<? extends PathArgument, ?> lst12Node() {
-        CollectionNodeBuilder<UnkeyedListEntryNode, UnkeyedListNode> lst12Builder = Builders.unkeyedListBuilder()
-                .withNodeIdentifier(new NodeIdentifier(QName.create("ns:complex:json", "2014-08-11", "lst12")));
-        lst12Builder.withChild(lst12Entry1Node());
-        return lst12Builder.build();
+    private static UnkeyedListNode lst12Node() {
+        return Builders.unkeyedListBuilder()
+                .withNodeIdentifier(new NodeIdentifier(QName.create(COMPLEX_JSON, "lst12")))
+                .withChild(lst12Entry1Node())
+                .build();
     }
 
     private static UnkeyedListEntryNode lst12Entry1Node() {
-        DataContainerNodeBuilder<NodeIdentifier, UnkeyedListEntryNode> lst12Entry1Builder = Builders
-                .unkeyedListEntryBuilder();
-        lst12Entry1Builder
-                .withNodeIdentifier(new NodeIdentifier(QName.create("ns:complex:json", "2014-08-11", "lst12")));
-        lst12Entry1Builder.withChild(Builders.leafBuilder()
-                .withNodeIdentifier(new NodeIdentifier(QName.create("ns:complex:json", "2014-08-11", "lf121")))
-                .withValue("lf121 value").build());
-        return lst12Entry1Builder.build();
+        return Builders.unkeyedListEntryBuilder()
+                .withNodeIdentifier(new NodeIdentifier(QName.create(COMPLEX_JSON, "lst12")))
+                .withChild(Builders.leafBuilder()
+                    .withNodeIdentifier(new NodeIdentifier(QName.create(COMPLEX_JSON, "lf121")))
+                    .withValue("lf121 value").build())
+                .build();
     }
 
-    private static DataContainerChild<? extends PathArgument, ?> choc12Node() {
-        DataContainerNodeBuilder<NodeIdentifier, ChoiceNode> choc12Builder = Builders.choiceBuilder()
-                .withNodeIdentifier(new NodeIdentifier(QName.create("ns:complex:json", "2014-08-11", "choc12")));
-
-        choc12Builder.withChild(lf17Node());
-        return choc12Builder.build();
+    private static ChoiceNode choc12Node() {
+        return Builders.choiceBuilder()
+                .withNodeIdentifier(new NodeIdentifier(QName.create(COMPLEX_JSON, "choc12")))
+                .withChild(lf17Node())
+                .build();
     }
 
     protected static LeafNode<Object> lf17Node() {
         return Builders.leafBuilder()
-                .withNodeIdentifier(new NodeIdentifier(QName.create("ns:complex:json", "2014-08-11", "lf17")))
+                .withNodeIdentifier(new NodeIdentifier(QName.create(COMPLEX_JSON, "lf17")))
                 .withValue("lf17 value").build();
     }
 
-    private static DataContainerChild<? extends PathArgument, ?> externalAugmentC11AWithLf15_11AndLf15_12Node() {
-        DataContainerNodeBuilder<AugmentationIdentifier, AugmentationNode> augmentationBuilder = Builders
-                .augmentationBuilder();
-        augmentationBuilder.withNodeIdentifier(new AugmentationIdentifier(ImmutableSet.of(
-                QName.create("ns:complex:json:augmentation", "2014-08-14", "lf15_11"),
-                QName.create("ns:complex:json:augmentation", "2014-08-14", "lf15_12"))));
-        augmentationBuilder.withChild(lf15_11NodeExternal());
-        augmentationBuilder.withChild(lf15_12NodeExternal());
-        return augmentationBuilder.build();
+    private static AugmentationNode externalAugmentC11AWithLf15_11AndLf15_12Node() {
+        return Builders.augmentationBuilder()
+                .withNodeIdentifier(new AugmentationIdentifier(ImmutableSet.of(
+                    QName.create(COMPLEX_JSON_AUG, "lf15_11"),
+                    QName.create(COMPLEX_JSON_AUG, "lf15_12"))))
+                .withChild(lf15_11NodeExternal())
+                .withChild(lf15_12NodeExternal())
+                .build();
     }
 
     private static LeafNode<Object> lf15_12NodeExternal() {
-        return Builders
-                .leafBuilder()
-                .withNodeIdentifier(
-                        new NodeIdentifier(QName.create("ns:complex:json:augmentation", "2014-08-14", "lf15_12")))
-                .withValue("lf15_12 value from augmentation").build();
+        return Builders.leafBuilder()
+                .withNodeIdentifier(new NodeIdentifier(QName.create(COMPLEX_JSON_AUG, "lf15_12")))
+                .withValue("lf15_12 value from augmentation")
+                .build();
     }
 
     private static LeafNode<Object> lf15_11NodeExternal() {
-        return Builders
-                .leafBuilder()
-                .withNodeIdentifier(
-                        new NodeIdentifier(QName.create("ns:complex:json:augmentation", "2014-08-14", "lf15_11")))
-                .withValue("lf15_11 value from augmentation").build();
+        return Builders.leafBuilder()
+                .withNodeIdentifier(new NodeIdentifier(QName.create(COMPLEX_JSON_AUG, "lf15_11")))
+                .withValue("lf15_11 value from augmentation")
+                .build();
     }
 
     @SafeVarargs
-    private static DataContainerChild<? extends PathArgument, ?> choc11Node(
-            final DataContainerChild<? extends PathArgument, ?>... children) {
-        DataContainerNodeBuilder<NodeIdentifier, ChoiceNode> choc11Builder = Builders.choiceBuilder()
-                .withNodeIdentifier(new NodeIdentifier(QName.create("ns:complex:json", "2014-08-11", "choc11")));
-        choc11Builder.withValue(Arrays.asList(children));
-        // choc11Builder.addChild(lf13Node());
-        // choc11Builder.addChild(augmentChoc11_c11A_lf1511AndLf1512Children());
-        // choc11Builder.addChild(augmentChoc11_c11_lf1521Children());
-        return choc11Builder.build();
+    private static ChoiceNode choc11Node(final DataContainerChild<?, ?>... children) {
+        return Builders.choiceBuilder()
+                .withNodeIdentifier(new NodeIdentifier(QName.create(COMPLEX_JSON, "choc11")))
+                .withValue(Arrays.asList(children))
+                // choc11Builder.addChild(lf13Node());
+                // choc11Builder.addChild(augmentChoc11_c11A_lf1511AndLf1512Children());
+                // choc11Builder.addChild(augmentChoc11_c11_lf1521Children());
+                .build();
     }
 
     private static LeafNode<Object> lf13Node() {
         return Builders.leafBuilder()
-                .withNodeIdentifier(new NodeIdentifier(QName.create("ns:complex:json", "2014-08-11", "lf13")))
+                .withNodeIdentifier(new NodeIdentifier(QName.create(COMPLEX_JSON, "lf13")))
                 .withValue("lf13 value").build();
     }
 
-    private static DataContainerChild<? extends PathArgument, ?> augmentC11AWithLf15_21Node() {
+    private static AugmentationNode augmentC11AWithLf15_21Node() {
         return Builders.augmentationBuilder().withNodeIdentifier(
-            new AugmentationIdentifier(ImmutableSet.of(QName.create("ns:complex:json", "2014-08-11", "lf15_21"))))
+            new AugmentationIdentifier(ImmutableSet.of(QName.create(COMPLEX_JSON, "lf15_21"))))
                 .withChild(lf15_21Node()).build();
     }
 
     private static LeafNode<Object> lf15_21Node() {
         return Builders.leafBuilder()
-                .withNodeIdentifier(new NodeIdentifier(QName.create("ns:complex:json", "2014-08-11", "lf15_21")))
+                .withNodeIdentifier(new NodeIdentifier(QName.create(COMPLEX_JSON, "lf15_21")))
                 .withValue("lf15_21 value").build();
     }
 
-    private static DataContainerChild<? extends PathArgument, ?> augmentC11AWithLf15_11AndLf15_12Node() {
+    private static AugmentationNode augmentC11AWithLf15_11AndLf15_12Node() {
         return Builders.augmentationBuilder()
                 .withNodeIdentifier(new AugmentationIdentifier(ImmutableSet.of(
-                    QName.create("ns:complex:json", "2014-08-11", "lf15_11"),
-                    QName.create("ns:complex:json", "2014-08-11", "lf15_12"))))
+                    QName.create(COMPLEX_JSON, "lf15_11"),
+                    QName.create(COMPLEX_JSON, "lf15_12"))))
                 .withChild(lf15_11Node())
                 .withChild(lf15_12Node())
                 .build();
@@ -149,143 +148,140 @@ public final class TestingNormalizedNodeStructuresCreator {
 
     private static LeafNode<Object> lf15_12Node() {
         return Builders.leafBuilder()
-                .withNodeIdentifier(new NodeIdentifier(QName.create("ns:complex:json", "2014-08-11", "lf15_12")))
-                .withValue(QName.create("ns:complex:json", "2014-08-11", "ident")).build();
+                .withNodeIdentifier(new NodeIdentifier(QName.create(COMPLEX_JSON, "lf15_12")))
+                .withValue(QName.create(COMPLEX_JSON, "ident")).build();
     }
 
     private static LeafNode<Object> lf15_11Node() {
         return Builders.leafBuilder()
-                .withNodeIdentifier(new NodeIdentifier(QName.create("ns:complex:json", "2014-08-11", "lf15_11")))
+                .withNodeIdentifier(new NodeIdentifier(QName.create(COMPLEX_JSON, "lf15_11")))
                 .withValue(ImmutableSet.of("one", "two")).build();
     }
 
-    private static DataContainerChild<? extends PathArgument, ?> lf12_1Node() {
-        DataContainerNodeBuilder<AugmentationIdentifier, AugmentationNode> augmentBuilder = Builders
-                .augmentationBuilder().withNodeIdentifier(
-                        new AugmentationIdentifier(ImmutableSet.of(
-                                QName.create("ns:complex:json", "2014-08-11", "lf12_1"),
-                                QName.create("ns:complex:json", "2014-08-11", "lf12_2"))));
-        augmentBuilder.withChild(Builders.leafBuilder()
-                .withNodeIdentifier(new NodeIdentifier(QName.create("ns:complex:json", "2014-08-11", "lf12_1")))
-                .withValue("lf12 value").build());
-        return augmentBuilder.build();
-    }
-
-    private static DataContainerChild<? extends PathArgument, ?> childLst11() {
-
-        DataContainerNodeBuilder<NodeIdentifierWithPredicates, MapEntryNode> lst11Entry1Builder = Builders
-                .mapEntryBuilder();
-
-        Map<QName, Object> key = new HashMap<>();
-        key.put(QName.create("ns:complex:json", "2014-08-11", "key111"), "key111 value");
-        key.put(QName.create("ns:complex:json", "2014-08-11", "lf111"), "lf111 value");
-
-        lst11Entry1Builder.withNodeIdentifier(NodeIdentifierWithPredicates.of(QName.create("ns:complex:json",
-                "2014-08-11", "lst11"), key));
-        lst11Entry1Builder.withChild(Builders.leafBuilder()
-                .withNodeIdentifier(new NodeIdentifier(QName.create("ns:complex:json", "2014-08-11", "key111")))
-                .withValue("key111 value").build());
-        lst11Entry1Builder.withChild(Builders.leafBuilder()
-                .withNodeIdentifier(new NodeIdentifier(QName.create("ns:complex:json", "2014-08-11", "lf112")))
-                .withValue(lf112Value()).build());
-        lst11Entry1Builder.withChild(Builders.leafBuilder()
-                .withNodeIdentifier(new NodeIdentifier(QName.create("ns:complex:json", "2014-08-11", "lf113")))
-                .withValue("lf113 value").build());
-        lst11Entry1Builder.withChild(Builders.leafBuilder()
-                .withNodeIdentifier(new NodeIdentifier(QName.create("ns:complex:json", "2014-08-11", "lf111")))
-                .withValue("lf111 value").build());
-        return Builders.mapBuilder().withNodeIdentifier(new NodeIdentifier(
-            QName.create("ns:complex:json", "2014-08-11", "lst11"))).withChild(lst11Entry1Builder.build()).build();
+    private static AugmentationNode lf12_1Node() {
+        return Builders.augmentationBuilder()
+                .withNodeIdentifier(new AugmentationIdentifier(ImmutableSet.of(
+                    QName.create(COMPLEX_JSON, "lf12_1"),
+                    QName.create(COMPLEX_JSON, "lf12_2"))))
+                .withChild(Builders.leafBuilder()
+                    .withNodeIdentifier(new NodeIdentifier(QName.create(COMPLEX_JSON, "lf12_1")))
+                    .withValue("lf12 value").build())
+                .build();
+    }
+
+    private static MapNode childLst11() {
+        return Builders.mapBuilder()
+                .withNodeIdentifier(new NodeIdentifier(QName.create(COMPLEX_JSON, "lst11")))
+                .withChild(Builders.mapEntryBuilder().withNodeIdentifier(
+                    NodeIdentifierWithPredicates.of(QName.create(COMPLEX_JSON, "lst11"), ImmutableMap.of(
+                        QName.create(COMPLEX_JSON, "key111"), "key111 value",
+                        QName.create(COMPLEX_JSON, "lf111"), "lf111 value")))
+                    .withChild(Builders.leafBuilder()
+                        .withNodeIdentifier(new NodeIdentifier(QName.create(COMPLEX_JSON, "key111")))
+                        .withValue("key111 value").build())
+                    .withChild(Builders.leafBuilder()
+                        .withNodeIdentifier(new NodeIdentifier(QName.create(COMPLEX_JSON, "lf112")))
+                        .withValue(lf112Value()).build())
+                    .withChild(Builders.leafBuilder()
+                        .withNodeIdentifier(new NodeIdentifier(QName.create(COMPLEX_JSON, "lf113")))
+                        .withValue("lf113 value").build())
+                    .withChild(Builders.leafBuilder()
+                        .withNodeIdentifier(new NodeIdentifier(QName.create(COMPLEX_JSON, "lf111")))
+                        .withValue("lf111 value").build())
+                    .build())
+                .build();
     }
 
     private static Object lf112Value() {
         return YangInstanceIdentifier.create(
-                new NodeIdentifier(QName.create("ns:complex:json", "2014-08-11", "cont1")),
-                new NodeIdentifier(QName.create("ns:complex:json", "2014-08-11", "lflst11")),
-                new NodeWithValue<>(QName.create("ns:complex:json", "2014-08-11", "lflst11"),"foo")
+                new NodeIdentifier(QName.create(COMPLEX_JSON, "cont1")),
+                new NodeIdentifier(QName.create(COMPLEX_JSON, "lflst11")),
+                new NodeWithValue<>(QName.create(COMPLEX_JSON, "lflst11"),"foo")
         );
     }
 
-    private static DataContainerChild<? extends PathArgument, ?> childLflst11() {
-        ListNodeBuilder<Object, LeafSetEntryNode<Object>> lflst11 = Builders.leafSetBuilder().withNodeIdentifier(
-                new NodeIdentifier(QName.create("ns:complex:json", "2014-08-11", "lflst11")));
-        lflst11.withChild(Builders
-                .leafSetEntryBuilder()
-                .withNodeIdentifier(new NodeWithValue<>(QName.create("ns:complex:json", "2014-08-11", "lflst11"),
-                        "lflst11 value1"))
-                .withValue("lflst11 value1").build());
-        lflst11.withChild(Builders
-                .leafSetEntryBuilder()
-                .withNodeIdentifier(new NodeWithValue<>(QName.create("ns:complex:json", "2014-08-11", "lflst11"),
-                        "lflst11 value2"))
-                .withValue("lflst11 value2").build());
-        return lflst11.build();
-    }
-
-    private static DataContainerChild<? extends PathArgument, ?> childLflst11Multiline() {
-        ListNodeBuilder<Object, LeafSetEntryNode<Object>> lflst11 = Builders.leafSetBuilder().withNodeIdentifier(
-                new NodeIdentifier(QName.create("ns:complex:json", "2014-08-11", "lflst11")));
-        lflst11.withChild(Builders
-                .leafSetEntryBuilder()
-                .withNodeIdentifier(new NodeWithValue<>(QName.create("ns:complex:json", "2014-08-11", "lflst11"),
-                        "lflst11 value1\nanother line 1"))
-                .withValue("lflst11 value1\nanother line 1").build());
-        lflst11.withChild(Builders
-                .leafSetEntryBuilder()
-                .withNodeIdentifier(new NodeWithValue<>(QName.create("ns:complex:json", "2014-08-11", "lflst11"),
-                        "lflst11 value2\r\nanother line 2"))
-                .withValue("lflst11 value2\r\nanother line 2").build());
-        return lflst11.build();
-    }
-
-    public static NormalizedNode<?, ?> leafNodeInContainer() {
-        LeafNode<Object> lf11 = Builders.leafBuilder()
-                .withNodeIdentifier(new NodeIdentifier(QName.create("ns:complex:json", "2014-08-11", "lf11")))
-                .withValue(453).build();
-        return cont1Node(lf11);
-    }
-
-    public static NormalizedNode<?, ?> leafListNodeInContainer() {
+    private static LeafSetNode<?> childLflst11() {
+        return Builders.leafSetBuilder()
+                .withNodeIdentifier(new NodeIdentifier(QName.create(COMPLEX_JSON, "lflst11")))
+                .withChild(Builders.leafSetEntryBuilder()
+                    .withNodeIdentifier(new NodeWithValue<>(QName.create(COMPLEX_JSON, "lflst11"), "lflst11 value1"))
+                    .withValue("lflst11 value1").build())
+                .withChild(Builders.leafSetEntryBuilder()
+                    .withNodeIdentifier(new NodeWithValue<>(QName.create(COMPLEX_JSON, "lflst11"), "lflst11 value2"))
+                    .withValue("lflst11 value2").build())
+                .build();
+    }
+
+    private static LeafSetNode<?> childLflst11Multiline() {
+        return Builders.leafSetBuilder()
+                .withNodeIdentifier(new NodeIdentifier(QName.create(COMPLEX_JSON, "lflst11")))
+                .withChild(Builders.leafSetEntryBuilder()
+                    .withNodeIdentifier(new NodeWithValue<>(QName.create(COMPLEX_JSON, "lflst11"),
+                            "lflst11 value1\nanother line 1"))
+                    .withValue("lflst11 value1\nanother line 1").build())
+                .withChild(Builders.leafSetEntryBuilder()
+                    .withNodeIdentifier(new NodeWithValue<>(QName.create(COMPLEX_JSON, "lflst11"),
+                            "lflst11 value2\r\nanother line 2"))
+                    .withValue("lflst11 value2\r\nanother line 2").build())
+                .build();
+    }
+
+    public static ContainerNode leafNodeInContainer() {
+        return cont1Node(Builders.leafBuilder()
+            .withNodeIdentifier(new NodeIdentifier(QName.create(COMPLEX_JSON, "lf11")))
+            .withValue(453).build());
+    }
+
+    public static ContainerNode leafListNodeInContainer() {
         return cont1Node(childLflst11());
     }
 
-    public static NormalizedNode<?, ?> leafListNodeInContainerMultiline() {
+    public static ContainerNode leafListNodeInContainerMultiline() {
         return cont1Node(childLflst11Multiline());
     }
 
-    public static NormalizedNode<?, ?> keyedListNodeInContainer() {
+    public static ContainerNode keyedListNodeInContainer() {
         return cont1Node(childLst11());
     }
 
-    public static NormalizedNode<?, ?> leafNodeViaAugmentationInContainer() {
+    public static ContainerNode leafNodeViaAugmentationInContainer() {
         return cont1Node(lf12_1Node());
     }
 
-    public static NormalizedNode<?, ?> choiceNodeInContainer() {
+    public static ContainerNode choiceNodeInContainer() {
         return cont1Node(choc11Node(lf13Node()));
     }
 
     /**
      * choc11 contains lf13, lf15_11 and lf15_12 are added via external augmentation.
      */
-    public static NormalizedNode<?, ?> caseNodeAugmentationInChoiceInContainer() {
+    public static ContainerNode caseNodeAugmentationInChoiceInContainer() {
         return cont1Node(choc11Node(augmentC11AWithLf15_11AndLf15_12Node(), lf13Node(), augmentC11AWithLf15_21Node()));
     }
 
-    public static NormalizedNode<?, ?> caseNodeExternalAugmentationInChoiceInContainer() {
+    public static ContainerNode caseNodeExternalAugmentationInChoiceInContainer() {
         return cont1Node(choc11Node(lf13Node(), augmentC11AWithLf15_11AndLf15_12Node(),
             externalAugmentC11AWithLf15_11AndLf15_12Node()));
     }
 
-    public static NormalizedNode<?, ?> choiceNodeAugmentationInContainer() {
+    public static ContainerNode choiceNodeAugmentationInContainer() {
         return cont1Node(choc12Node());
     }
 
-    public static NormalizedNode<?, ?> unkeyedNodeInContainer() {
+    public static ContainerNode unkeyedNodeInContainer() {
         return cont1Node(lst12Node());
     }
 
-    public static NormalizedNode<?, ?> topLevelContainer() {
+    public static ContainerNode topLevelContainer() {
         return cont1Node();
     }
+
+    public static ContainerNode emptyContainerInContainer() {
+        return cont1Node(Builders.augmentationBuilder()
+                .withNodeIdentifier(new AugmentationIdentifier(ImmutableSet.of(QName.create(COMPLEX_JSON, "cont11"))))
+                .withChild(Builders.containerBuilder()
+                    .withNodeIdentifier(new NodeIdentifier(QName.create(COMPLEX_JSON, "cont11")))
+                    .build())
+                .build());
+    }
 }
index 9d49d083fcea54f15a23e480109835eb72a3279e..2717bb1960a0cf6b93847701717f92b0e986199b 100644 (file)
@@ -73,6 +73,10 @@ module complexjson {
         }
     }
 
+    container cont2 {
+        presence "presence container";
+    }
+
     augment "/cont1/choc12" {
         case c12B {
             leaf lf17 {