Make JSON serializer always serialize empty containers
[yangtools.git] / yang / yang-data-codec-gson / src / main / java / org / opendaylight / yangtools / yang / data / codec / gson / JSONNormalizedNodeStreamWriter.java
index 643e9de9ad041f9b2c4c3c02bf6e3d3317061295..59ef1f1e501ffc53011230f5f2f8ba61271f530c 100644 (file)
@@ -11,21 +11,19 @@ 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;
 import org.opendaylight.yangtools.yang.data.api.schema.stream.NormalizedNodeStreamWriter;
 import org.opendaylight.yangtools.yang.data.impl.codec.SchemaTracker;
 import org.opendaylight.yangtools.yang.model.api.AnyXmlSchemaNode;
-import org.opendaylight.yangtools.yang.model.api.ContainerSchemaNode;
 import org.opendaylight.yangtools.yang.model.api.LeafListSchemaNode;
 import org.opendaylight.yangtools.yang.model.api.LeafSchemaNode;
 import org.opendaylight.yangtools.yang.model.api.SchemaContext;
+import org.opendaylight.yangtools.yang.model.api.SchemaNode;
 import org.opendaylight.yangtools.yang.model.api.SchemaPath;
 
 /**
@@ -45,7 +43,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;
@@ -121,7 +119,7 @@ public class JSONNormalizedNodeStreamWriter implements NormalizedNodeStreamWrite
      * Create a new stream writer, which writes to the specified output stream. The codec factory
      * can be reused between multiple writers.
      *
-     * @param codecFactor JSON codec factory
+     * @param codecFactory JSON codec factory
      * @param writer Output writer
      * @param indentSize indentation size
      * @return A stream writer instance
@@ -136,7 +134,7 @@ public class JSONNormalizedNodeStreamWriter implements NormalizedNodeStreamWrite
         final JSONCodec<Object> codec = codecs.codecFor(schema.getType());
 
         context.emittingChild(codecs.getSchemaContext(), writer, indent);
-        context.writeJsonIdentifier(codecs.getSchemaContext(), writer, name.getNodeType());
+        context.writeChildJsonIdentifier(codecs.getSchemaContext(), writer, name.getNodeType());
         writeValue(codec.serialize(value), codec.needQuotes());
     }
 
@@ -162,8 +160,11 @@ public class JSONNormalizedNodeStreamWriter implements NormalizedNodeStreamWrite
     @SuppressWarnings("unused")
     @Override
     public void startContainerNode(final NodeIdentifier name, final int childSizeHint) throws IOException {
-        final ContainerSchemaNode schema = tracker.startContainerNode(name);
-        context = new JSONStreamWriterNamedObjectContext(context, name, DEFAULT_EMIT_EMPTY_CONTAINERS || schema.isPresenceContainer());
+        final SchemaNode schema = tracker.startContainerNode(name);
+
+        // FIXME this code ignores presence for containers
+        // but datastore does as well and it needs be fixed first (2399)
+        context = new JSONStreamWriterNamedObjectContext(context, name, DEFAULT_EMIT_EMPTY_CONTAINERS);
     }
 
     @Override
@@ -211,11 +212,12 @@ public class JSONNormalizedNodeStreamWriter implements NormalizedNodeStreamWrite
 
     @Override
     public void anyxmlNode(final NodeIdentifier name, final Object value) throws IOException {
+        @SuppressWarnings("unused")
         final AnyXmlSchemaNode schema = tracker.anyxmlNode(name);
         // FIXME: should have a codec based on this :)
 
         context.emittingChild(codecs.getSchemaContext(), writer, indent);
-        context.writeJsonIdentifier(codecs.getSchemaContext(), writer, name.getNodeType());
+        context.writeChildJsonIdentifier(codecs.getSchemaContext(), writer, name.getNodeType());
         writeValue(String.valueOf(value), true);
     }
 
@@ -229,14 +231,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;