Close JSON root context when the writer is closed 81/84981/1
authorRobert Varga <robert.varga@pantheon.tech>
Mon, 7 Oct 2019 15:19:34 +0000 (17:19 +0200)
committerRobert Varga <robert.varga@pantheon.tech>
Mon, 7 Oct 2019 16:06:02 +0000 (18:06 +0200)
We should be closing the root context when we are closed, not when
a its child is closed -- otherwise it would be impossible to write
multiple children of the root context.

Since we are in the area, also centralize some QName/ContainerNode
creation.

JIRA: YANGTOOLS-1029
Change-Id: I599fb5ad1ad8e36a441dff761984d5406e401d55
Signed-off-by: Robert Varga <robert.varga@pantheon.tech>
(cherry picked from commit f8e3d9af24d8d5d1eeca6a714d29f9822537a773)

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/JSONStreamWriterContext.java
yang/yang-data-codec-gson/src/test/java/org/opendaylight/yangtools/yang/data/codec/gson/AbstractComplexJsonTest.java
yang/yang-data-codec-gson/src/test/java/org/opendaylight/yangtools/yang/data/codec/gson/AnyXmlSupportTest.java
yang/yang-data-codec-gson/src/test/java/org/opendaylight/yangtools/yang/data/codec/gson/JsonStreamToNormalizedNodeTest.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/YT1029Test.java [new file with mode: 0644]

index 6bac91c4a598ee937535c470346637cfa460b64e..a934e913edaedadc6814fb9ba2b34fcf0a5bdd41 100644 (file)
@@ -338,10 +338,6 @@ public abstract class JSONNormalizedNodeStreamWriter implements NormalizedNodeSt
     public final void endNode() throws IOException {
         tracker.endNode();
         context = context.endNode(codecs.getSchemaContext(), writer);
-
-        if (context instanceof JSONStreamWriterRootContext) {
-            context.endNode(codecs.getSchemaContext(), writer);
-        }
     }
 
     @Override
@@ -350,6 +346,11 @@ public abstract class JSONNormalizedNodeStreamWriter implements NormalizedNodeSt
     }
 
     final void closeWriter() throws IOException {
+        if (!(context instanceof JSONStreamWriterRootContext)) {
+            throw new IOException("Unexpected root context " + context);
+        }
+
+        context.endNode(codecs.getSchemaContext(), writer);
         writer.close();
     }
 
index d8bfb8d3f3110802cc1523b8b600050e36a45b09..fa2a7b9e8bd82bc82a77220216bc222eb2be646b 100644 (file)
@@ -10,6 +10,8 @@ package org.opendaylight.yangtools.yang.data.codec.gson;
 import static com.google.common.base.Preconditions.checkArgument;
 import static com.google.common.base.Preconditions.checkState;
 
+import com.google.common.base.MoreObjects;
+import com.google.common.base.MoreObjects.ToStringHelper;
 import com.google.gson.stream.JsonWriter;
 import java.io.IOException;
 import java.net.URI;
@@ -161,4 +163,13 @@ abstract class JSONStreamWriterContext {
         }
         return parent;
     }
+
+    @Override
+    public final String toString() {
+        return addToStringAttributes(MoreObjects.toStringHelper(this)).toString();
+    }
+
+    protected ToStringHelper addToStringAttributes(final ToStringHelper helper) {
+        return helper;
+    }
 }
index 4d064afc2f346f1c1e6ba6601e611a0a796e65de..eccb49478aa4b00a035a57789cbbdf88040937e6 100644 (file)
@@ -9,10 +9,23 @@ package org.opendaylight.yangtools.yang.data.codec.gson;
 
 import org.junit.AfterClass;
 import org.junit.BeforeClass;
+import org.opendaylight.yangtools.yang.common.Empty;
+import org.opendaylight.yangtools.yang.common.QName;
+import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeIdentifier;
+import org.opendaylight.yangtools.yang.data.api.schema.ContainerNode;
+import org.opendaylight.yangtools.yang.data.impl.schema.Builders;
+import org.opendaylight.yangtools.yang.data.impl.schema.ImmutableNodes;
 import org.opendaylight.yangtools.yang.model.api.SchemaContext;
 import org.opendaylight.yangtools.yang.test.util.YangParserTestUtils;
 
 public abstract class AbstractComplexJsonTest {
+    static final QName CONT_1 = QName.create("ns:complex:json", "2014-08-11", "cont1");
+    private static final QName EMPTY_LEAF = QName.create(CONT_1, "empty");
+
+    static final ContainerNode CONT1_WITH_EMPTYLEAF = Builders.containerBuilder()
+            .withNodeIdentifier(new NodeIdentifier(CONT_1))
+            .addChild(ImmutableNodes.leafNode(EMPTY_LEAF, Empty.getInstance()))
+            .build();
 
     static SchemaContext schemaContext;
     static JSONCodecFactory lhotkaCodecFactory;
index f7d3193a9679274755fcaf07de3444c17e94e166..b49b66497a4f6afb97fcad7220b82dbb39d7cf05 100644 (file)
@@ -44,7 +44,6 @@ import org.w3c.dom.Text;
 
 public class AnyXmlSupportTest extends AbstractComplexJsonTest {
 
-    private static final QName CONT_1 = QName.create("ns:complex:json", "2014-08-11", "cont1");
     private static final QName LF12_ANY = QName.create(CONT_1, "lf12-any");
     private static final QName LF13_ANY = QName.create(CONT_1, "lf13-any");
     private static final QName LF14_ANY = QName.create(CONT_1, "lf14-any");
index eb99d11069148b49f24468dc3e8f567c5cf1893a..9402f989f6639c52ebc04de2c9d5d18132eea845 100644 (file)
@@ -23,11 +23,9 @@ import java.io.IOException;
 import java.io.StringReader;
 import java.net.URISyntaxException;
 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.AugmentationIdentifier;
 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeIdentifier;
-import org.opendaylight.yangtools.yang.data.api.schema.ContainerNode;
 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.impl.schema.ImmutableNormalizedNodeStreamWriter;
@@ -38,10 +36,6 @@ import org.opendaylight.yangtools.yang.model.api.SchemaNode;
  * Each test tests whether json input is correctly transformed to normalized node structure.
  */
 public class JsonStreamToNormalizedNodeTest extends AbstractComplexJsonTest {
-
-    private static final QName CONT_1 = QName.create("ns:complex:json", "2014-08-11", "cont1");
-    private static final QName EMPTY_LEAF = QName.create(CONT_1,"empty");
-
     @Test
     public void leafNodeInContainer() throws IOException, URISyntaxException {
         final String inputJson = loadTextFile("/complexjson/leaf-node-in-container.json");
@@ -154,12 +148,7 @@ public class JsonStreamToNormalizedNodeTest extends AbstractComplexJsonTest {
     @Test
     public void emptyTypeTest() throws IOException, URISyntaxException {
         final String inputJson = loadTextFile("/complexjson/type-empty.json");
-        final ContainerNode awaitedStructure = containerBuilder()
-                .withNodeIdentifier(new NodeIdentifier(CONT_1))
-                .addChild(leafNode(EMPTY_LEAF, Empty.getInstance()))
-                .build();
-
-        verifyTransformationToNormalizedNode(inputJson, awaitedStructure);
+        verifyTransformationToNormalizedNode(inputJson, CONT1_WITH_EMPTYLEAF);
     }
 
     /**
index b718659756c0fe10bc396952765acf3ff0b6a7a7..06e9db25dbc7c52c75e2fc3612c16328e362d451 100644 (file)
@@ -29,14 +29,9 @@ import java.io.Writer;
 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.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;
-import org.opendaylight.yangtools.yang.data.impl.schema.Builders;
-import org.opendaylight.yangtools.yang.data.impl.schema.ImmutableNodes;
 import org.opendaylight.yangtools.yang.model.api.SchemaPath;
 
 /**
@@ -45,10 +40,6 @@ import org.opendaylight.yangtools.yang.model.api.SchemaPath;
  * via gson as structure of json elements which are walked and compared with awaited values.
  */
 public class NormalizedNodeToJsonStreamTest extends AbstractComplexJsonTest {
-
-    private static final QName CONT_1 = QName.create("ns:complex:json", "2014-08-11", "cont1");
-    private static final QName EMPTY_LEAF = QName.create(CONT_1, "empty");
-
     @Test
     public void leafNodeInContainer() throws IOException {
         final String jsonOutput = normalizedNodeToJsonStreamTransformation(
@@ -265,10 +256,7 @@ public class NormalizedNodeToJsonStreamTest extends AbstractComplexJsonTest {
 
     @Test
     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 String jsonOutput = normalizedNodeToJsonStreamTransformation(CONT1_WITH_EMPTYLEAF);
         final JsonObject cont1 = resolveCont1(jsonOutput);
         final JsonElement emptyObj = cont1.get("empty");
         assertNotNull(emptyObj);
diff --git a/yang/yang-data-codec-gson/src/test/java/org/opendaylight/yangtools/yang/data/codec/gson/YT1029Test.java b/yang/yang-data-codec-gson/src/test/java/org/opendaylight/yangtools/yang/data/codec/gson/YT1029Test.java
new file mode 100644 (file)
index 0000000..13cfd8f
--- /dev/null
@@ -0,0 +1,44 @@
+/*
+ * Copyright (c) 2019 PANTHEON.tech, s.r.o. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.yangtools.yang.data.codec.gson;
+
+import static org.junit.Assert.assertEquals;
+
+import java.io.IOException;
+import java.io.StringWriter;
+import java.io.Writer;
+import org.junit.Test;
+import org.opendaylight.yangtools.yang.data.api.schema.stream.NormalizedNodeStreamWriter;
+import org.opendaylight.yangtools.yang.data.api.schema.stream.NormalizedNodeWriter;
+import org.opendaylight.yangtools.yang.model.api.SchemaPath;
+
+public class YT1029Test extends AbstractComplexJsonTest {
+    @Test
+    public void testMultipleRootChildren() throws IOException {
+        final Writer writer = new StringWriter();
+        final NormalizedNodeStreamWriter jsonStream = JSONNormalizedNodeStreamWriter.createExclusiveWriter(
+            lhotkaCodecFactory, SchemaPath.ROOT, null, JsonWriterFactory.createJsonWriter(writer, 2));
+        try (NormalizedNodeWriter nodeWriter = NormalizedNodeWriter.forStreamWriter(jsonStream)) {
+            nodeWriter.write(CONT1_WITH_EMPTYLEAF);
+            nodeWriter.write(CONT1_WITH_EMPTYLEAF);
+        }
+
+        assertEquals("{\n"
+                + "  \"complexjson:cont1\": {\n"
+                + "    \"empty\": [\n"
+                + "      null\n"
+                + "    ]\n"
+                + "  },\n"
+                + "  \"complexjson:cont1\": {\n"
+                + "    \"empty\": [\n"
+                + "      null\n"
+                + "    ]\n"
+                + "  }\n"
+                + "}", writer.toString());
+    }
+}