From 597f63bfd537851033692a5cb8b79fa3fed509e9 Mon Sep 17 00:00:00 2001 From: Robert Varga Date: Mon, 7 Oct 2019 17:19:34 +0200 Subject: [PATCH] Close JSON root context when the writer is closed 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 (cherry picked from commit f8e3d9af24d8d5d1eeca6a714d29f9822537a773) --- .../gson/JSONNormalizedNodeStreamWriter.java | 9 ++-- .../codec/gson/JSONStreamWriterContext.java | 11 +++++ .../codec/gson/AbstractComplexJsonTest.java | 13 ++++++ .../data/codec/gson/AnyXmlSupportTest.java | 1 - .../gson/JsonStreamToNormalizedNodeTest.java | 13 +----- .../gson/NormalizedNodeToJsonStreamTest.java | 14 +----- .../yang/data/codec/gson/YT1029Test.java | 44 +++++++++++++++++++ 7 files changed, 75 insertions(+), 30 deletions(-) create mode 100644 yang/yang-data-codec-gson/src/test/java/org/opendaylight/yangtools/yang/data/codec/gson/YT1029Test.java diff --git a/yang/yang-data-codec-gson/src/main/java/org/opendaylight/yangtools/yang/data/codec/gson/JSONNormalizedNodeStreamWriter.java b/yang/yang-data-codec-gson/src/main/java/org/opendaylight/yangtools/yang/data/codec/gson/JSONNormalizedNodeStreamWriter.java index cb2ed769d3..38c873f46c 100644 --- a/yang/yang-data-codec-gson/src/main/java/org/opendaylight/yangtools/yang/data/codec/gson/JSONNormalizedNodeStreamWriter.java +++ b/yang/yang-data-codec-gson/src/main/java/org/opendaylight/yangtools/yang/data/codec/gson/JSONNormalizedNodeStreamWriter.java @@ -337,10 +337,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 @@ -349,6 +345,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(); } diff --git a/yang/yang-data-codec-gson/src/main/java/org/opendaylight/yangtools/yang/data/codec/gson/JSONStreamWriterContext.java b/yang/yang-data-codec-gson/src/main/java/org/opendaylight/yangtools/yang/data/codec/gson/JSONStreamWriterContext.java index d8bfb8d3f3..fa2a7b9e8b 100644 --- a/yang/yang-data-codec-gson/src/main/java/org/opendaylight/yangtools/yang/data/codec/gson/JSONStreamWriterContext.java +++ b/yang/yang-data-codec-gson/src/main/java/org/opendaylight/yangtools/yang/data/codec/gson/JSONStreamWriterContext.java @@ -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; + } } diff --git a/yang/yang-data-codec-gson/src/test/java/org/opendaylight/yangtools/yang/data/codec/gson/AbstractComplexJsonTest.java b/yang/yang-data-codec-gson/src/test/java/org/opendaylight/yangtools/yang/data/codec/gson/AbstractComplexJsonTest.java index 4d064afc2f..eccb49478a 100644 --- a/yang/yang-data-codec-gson/src/test/java/org/opendaylight/yangtools/yang/data/codec/gson/AbstractComplexJsonTest.java +++ b/yang/yang-data-codec-gson/src/test/java/org/opendaylight/yangtools/yang/data/codec/gson/AbstractComplexJsonTest.java @@ -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; diff --git a/yang/yang-data-codec-gson/src/test/java/org/opendaylight/yangtools/yang/data/codec/gson/AnyXmlSupportTest.java b/yang/yang-data-codec-gson/src/test/java/org/opendaylight/yangtools/yang/data/codec/gson/AnyXmlSupportTest.java index ce6b8a0cf3..a4e2bd9f6b 100644 --- a/yang/yang-data-codec-gson/src/test/java/org/opendaylight/yangtools/yang/data/codec/gson/AnyXmlSupportTest.java +++ b/yang/yang-data-codec-gson/src/test/java/org/opendaylight/yangtools/yang/data/codec/gson/AnyXmlSupportTest.java @@ -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"); diff --git a/yang/yang-data-codec-gson/src/test/java/org/opendaylight/yangtools/yang/data/codec/gson/JsonStreamToNormalizedNodeTest.java b/yang/yang-data-codec-gson/src/test/java/org/opendaylight/yangtools/yang/data/codec/gson/JsonStreamToNormalizedNodeTest.java index eb99d11069..9402f989f6 100644 --- a/yang/yang-data-codec-gson/src/test/java/org/opendaylight/yangtools/yang/data/codec/gson/JsonStreamToNormalizedNodeTest.java +++ b/yang/yang-data-codec-gson/src/test/java/org/opendaylight/yangtools/yang/data/codec/gson/JsonStreamToNormalizedNodeTest.java @@ -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); } /** diff --git a/yang/yang-data-codec-gson/src/test/java/org/opendaylight/yangtools/yang/data/codec/gson/NormalizedNodeToJsonStreamTest.java b/yang/yang-data-codec-gson/src/test/java/org/opendaylight/yangtools/yang/data/codec/gson/NormalizedNodeToJsonStreamTest.java index b718659756..06e9db25db 100644 --- a/yang/yang-data-codec-gson/src/test/java/org/opendaylight/yangtools/yang/data/codec/gson/NormalizedNodeToJsonStreamTest.java +++ b/yang/yang-data-codec-gson/src/test/java/org/opendaylight/yangtools/yang/data/codec/gson/NormalizedNodeToJsonStreamTest.java @@ -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 index 0000000000..13cfd8f90e --- /dev/null +++ b/yang/yang-data-codec-gson/src/test/java/org/opendaylight/yangtools/yang/data/codec/gson/YT1029Test.java @@ -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()); + } +} -- 2.36.6