From e6c3a206a204de77c70df1c0940a088493401749 Mon Sep 17 00:00:00 2001 From: Jan Hajnar Date: Wed, 15 Oct 2014 14:54:37 +0200 Subject: [PATCH] Bug 2147 - JSON does not properly encode multiline string * added newline and return characters to escape list * updated tests Change-Id: I48cd418b1633de12e80bdab0b7c7bc91113dbf6d Signed-off-by: Jan Hajnar --- .../gson/JSONNormalizedNodeStreamWriter.java | 13 +++-- .../gson/NormalizedNodeToJsonStreamTest.java | 57 ++++++++++++++----- ...estingNormalizedNodeStructuresCreator.java | 24 +++++++- 3 files changed, 71 insertions(+), 23 deletions(-) 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 8fcc596ab4..e1bba78be0 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 @@ -11,9 +11,6 @@ import com.google.common.base.CharMatcher; import com.google.common.base.Preconditions; import com.google.common.base.Strings; import com.google.gson.stream.JsonWriter; -import java.io.IOException; -import java.io.Writer; -import java.net.URI; 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; @@ -26,6 +23,10 @@ import org.opendaylight.yangtools.yang.model.api.LeafSchemaNode; import org.opendaylight.yangtools.yang.model.api.SchemaContext; import org.opendaylight.yangtools.yang.model.api.SchemaPath; +import java.io.IOException; +import java.io.Writer; +import java.net.URI; + /** * This implementation will create JSON output as output stream. * @@ -43,7 +44,7 @@ public class JSONNormalizedNodeStreamWriter implements NormalizedNodeStreamWrite /** * Matcher used to check if a string needs to be escaped. */ - private static final CharMatcher QUOTES_OR_BACKSLASH = CharMatcher.anyOf("\\\""); + private static final CharMatcher JSON_ILLEGAL_STRING_CHARACTERS = CharMatcher.anyOf("\\\"\n\r"); private final SchemaTracker tracker; private final JSONCodecFactory codecs; @@ -228,14 +229,14 @@ public class JSONNormalizedNodeStreamWriter implements NormalizedNodeStreamWrite if (needQuotes) { writer.append('"'); - final int needEscape = QUOTES_OR_BACKSLASH.countIn(str); + final int needEscape = JSON_ILLEGAL_STRING_CHARACTERS.countIn(str); if (needEscape != 0) { final char[] escaped = new char[str.length() + needEscape]; int offset = 0; for (int i = 0; i < str.length(); i++) { final char c = str.charAt(i); - if (QUOTES_OR_BACKSLASH.matches(c)) { + if (JSON_ILLEGAL_STRING_CHARACTERS.matches(c)) { escaped[offset++] = '\\'; } escaped[offset++] = c; 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 62e7cf18cd..39a1f1bc7b 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 @@ -7,26 +7,11 @@ */ 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.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.loadModules; -import static org.opendaylight.yangtools.yang.data.codec.gson.TestUtils.resolveCont1; - import com.google.common.collect.Sets; import com.google.gson.JsonArray; import com.google.gson.JsonElement; import com.google.gson.JsonObject; 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.BeforeClass; import org.junit.Ignore; import org.junit.Test; @@ -35,6 +20,22 @@ import org.opendaylight.yangtools.yang.data.api.schema.stream.NormalizedNodeStre import org.opendaylight.yangtools.yang.data.api.schema.stream.NormalizedNodeWriter; import org.opendaylight.yangtools.yang.model.api.SchemaContext; +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 static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertNotNull; +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.loadModules; +import static org.opendaylight.yangtools.yang.data.codec.gson.TestUtils.resolveCont1; + /** * Each test tests whether json output obtained after transformation contains is corect. The transformation takes * normalized node data structure and transform it to json output. To make it easier validate json output it is loaded @@ -95,6 +96,32 @@ public class NormalizedNodeToJsonStreamTest { } + @Test + public void leafListNodeInContainerMultiline() throws IOException, URISyntaxException { + Writer writer = new StringWriter(); + NormalizedNode leafListNodeInContainer = TestingNormalizedNodeStructuresCreator.leafListNodeInContainerMultiline(); + String jsonOutput = normalizedNodeToJsonStreamTransformation(writer, leafListNodeInContainer); + new JsonValidator() { + + @Override + public void validate(String jsonOutput) { + JsonObject cont1 = resolveCont1(jsonOutput); + assertNotNull(cont1); + JsonArray lflst11 = childArray(cont1, "complexjson:lflst11", "lflst11"); + assertNotNull(lflst11); + + HashSet lflst11Values = Sets.newHashSet(); + for (JsonElement jsonElement : lflst11) { + assertTrue(jsonElement instanceof JsonPrimitive); + lflst11Values.add(((JsonPrimitive) jsonElement).getAsString()); + } + + assertEquals(Sets.newHashSet("lflst11 value2\r\nanother line 2", "lflst11 value1\nanother line 1"), lflst11Values); + } + }.validate(jsonOutput); + + } + @Test public void leafNodeViaAugmentationInContainer() throws IOException, URISyntaxException { Writer writer = new StringWriter(); diff --git a/yang/yang-data-codec-gson/src/test/java/org/opendaylight/yangtools/yang/data/codec/gson/TestingNormalizedNodeStructuresCreator.java b/yang/yang-data-codec-gson/src/test/java/org/opendaylight/yangtools/yang/data/codec/gson/TestingNormalizedNodeStructuresCreator.java index f1400854d9..1038ce883d 100644 --- a/yang/yang-data-codec-gson/src/test/java/org/opendaylight/yangtools/yang/data/codec/gson/TestingNormalizedNodeStructuresCreator.java +++ b/yang/yang-data-codec-gson/src/test/java/org/opendaylight/yangtools/yang/data/codec/gson/TestingNormalizedNodeStructuresCreator.java @@ -9,8 +9,6 @@ package org.opendaylight.yangtools.yang.data.codec.gson; import com.google.common.collect.Lists; import com.google.common.collect.Sets; -import java.util.HashMap; -import java.util.Map; import org.opendaylight.yangtools.yang.common.QName; import org.opendaylight.yangtools.yang.data.api.CompositeNode; import org.opendaylight.yangtools.yang.data.api.SimpleNode; @@ -40,6 +38,9 @@ import org.opendaylight.yangtools.yang.data.impl.schema.builder.api.DataContaine import org.opendaylight.yangtools.yang.data.impl.schema.builder.api.DataContainerNodeBuilder; import org.opendaylight.yangtools.yang.data.impl.schema.builder.api.ListNodeBuilder; +import java.util.HashMap; +import java.util.Map; + public class TestingNormalizedNodeStructuresCreator { static NormalizedNode cont1Node( @@ -236,6 +237,22 @@ public class TestingNormalizedNodeStructuresCreator { return lflst11.build(); } + private static DataContainerChild childLflst11Multiline() { + ListNodeBuilder> 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(); + } + private static CompositeNode prepareLf12Value() { SimpleNode anyxmlInData = NodeFactory.createImmutableSimpleNode( QName.create("ns:complex:json", "2014-08-11", "anyxml-in-data"), null, "foo"); @@ -260,6 +277,9 @@ public class TestingNormalizedNodeStructuresCreator { public static NormalizedNode leafListNodeInContainer() { return cont1Node(childLflst11()); } + public static NormalizedNode leafListNodeInContainerMultiline() { + return cont1Node(childLflst11Multiline()); + } public static NormalizedNode keyedListNodeInContainer() { return cont1Node(childLst11()); -- 2.36.6