Merge "Make sure LOOKUP is a proper constant"
[yangtools.git] / yang / yang-data-codec-gson / src / main / java / org / opendaylight / yangtools / yang / data / codec / gson / JSONNormalizedNodeStreamWriter.java
index 079b8e324aeba0638e2832596059b50c3f279f68..6b412d583d3c7675b81bc4ae89563b5d8809828d 100644 (file)
@@ -42,16 +42,19 @@ public class JSONNormalizedNodeStreamWriter implements NormalizedNodeStreamWrite
     private final JsonWriter writer;
     private JSONStreamWriterContext context;
 
-    private JSONNormalizedNodeStreamWriter(final JSONCodecFactory codecFactory, final SchemaPath path, final URI initialNs, JsonWriter JsonWriter) {
-        this.writer = JsonWriter;
+    private JSONNormalizedNodeStreamWriter(final JSONCodecFactory codecFactory, final SchemaPath path, JsonWriter JsonWriter, JSONStreamWriterRootContext rootContext) {
+        this.writer = Preconditions.checkNotNull(JsonWriter);
         this.codecs = Preconditions.checkNotNull(codecFactory);
         this.tracker = SchemaTracker.create(codecFactory.getSchemaContext(), path);
-        this.context = new JSONStreamWriterRootContext(initialNs);
+        this.context = Preconditions.checkNotNull(rootContext);
     }
 
     /**
      * Create a new stream writer, which writes to the specified {@link Writer}.
      *
+     * This instance of writer can be used only to emit one top level element,
+     * therwise it will produce incorrect JSON.
+     *
      * @param schemaContext Schema context
      * @param writer Output writer
      * @return A stream writer instance
@@ -63,6 +66,9 @@ public class JSONNormalizedNodeStreamWriter implements NormalizedNodeStreamWrite
     /**
      * Create a new stream writer, which writes to the specified {@link Writer}.
      *
+     * This instance of writer can be used only to emit one top level element,
+     * therwise it will produce incorrect JSON.
+     *
      * @param schemaContext Schema context
      * @param path Root schemapath
      * @param writer Output writer
@@ -75,6 +81,9 @@ public class JSONNormalizedNodeStreamWriter implements NormalizedNodeStreamWrite
     /**
      * Create a new stream writer, which writes to the specified {@link Writer}.
      *
+     * This instance of writer can be used only to emit one top level element,
+     * therwise it will produce incorrect JSON.
+     *
      * @param schemaContext Schema context
      * @param path Root schemapath
      * @param writer Output writer
@@ -83,37 +92,46 @@ public class JSONNormalizedNodeStreamWriter implements NormalizedNodeStreamWrite
      */
     public static NormalizedNodeStreamWriter create(final SchemaContext schemaContext, final SchemaPath path,
             final URI initialNs, final Writer writer) {
-        return create(JSONCodecFactory.create(schemaContext), path, initialNs, JsonWriterFactory.createJsonWriter(writer));
+        return createExclusiveWriter(JSONCodecFactory.create(schemaContext), path, initialNs, JsonWriterFactory.createJsonWriter(writer));
     }
 
     /**
      * Create a new stream writer, which writes to the specified output stream.
      *
+     * This instance of writer can be used only to emit one top level element,
+     * therwise it will produce incorrect JSON.
+     *
      * @param schemaContext Schema context
      * @param writer Output writer
      * @param indentSize indentation size
      * @return A stream writer instance
      */
     public static NormalizedNodeStreamWriter create(final SchemaContext schemaContext, final Writer writer, final int indentSize) {
-        return create(JSONCodecFactory.create(schemaContext), SchemaPath.ROOT, null,JsonWriterFactory.createJsonWriter(writer, indentSize));
+        return createExclusiveWriter(JSONCodecFactory.create(schemaContext), SchemaPath.ROOT, null,JsonWriterFactory.createJsonWriter(writer, indentSize));
     }
 
     /**
      * Create a new stream writer, which writes to the specified output stream. The codec factory
      * can be reused between multiple writers.
      *
+     * This instance of writer can be used only to emit one top level element,
+     * therwise it will produce incorrect JSON.
+     *
      * @param codecFactory JSON codec factory
      * @param writer Output writer
      * @param indentSize indentation size
      * @return A stream writer instance
      */
     public static NormalizedNodeStreamWriter create(final JSONCodecFactory codecFactory, final Writer writer, final int indentSize) {
-        return create(codecFactory, SchemaPath.ROOT, null, JsonWriterFactory.createJsonWriter(writer,indentSize));
+        return createExclusiveWriter(codecFactory, SchemaPath.ROOT, null, JsonWriterFactory.createJsonWriter(writer,indentSize));
     }
 
     /**
      * Create a new stream writer, which writes to the specified output stream.
      *
+     * This instance of writer can be used only to emit one top level element,
+     * therwise it will produce incorrect JSON.
+     *
      * @param schemaContext Schema context
      * @param path Schema Path
      * @param initialNs Initial namespace
@@ -122,12 +140,39 @@ public class JSONNormalizedNodeStreamWriter implements NormalizedNodeStreamWrite
      */
     public static NormalizedNodeStreamWriter create(SchemaContext schemaContext, SchemaPath path, URI initialNs,
             JsonWriter jsonWriter) {
-        return create(JSONCodecFactory.create(schemaContext), path, initialNs, jsonWriter);
+        return createExclusiveWriter(JSONCodecFactory.create(schemaContext), path, initialNs, jsonWriter);
     }
 
     /**
-     * Create a new stream writer, which writes to the specified output stream. The codec factory
-     * can be reused between multiple writers.
+     * Create a new stream writer, which writes to the specified output stream.
+     *
+     * The codec factory can be reused between multiple writers.
+     *
+     * Returned writer is exclusive user of JsonWriter, which means it will start
+     * top-level JSON element and ends it.
+     *
+     * This instance of writer can be used only to emit one top level element,
+     * therwise it will produce incorrect JSON.
+     *
+     * @param codecFactory JSON codec factory
+     * @param path Schema Path
+     * @param initialNs Initial namespace
+     * @param jsonWriter JsonWriter
+     * @return A stream writer instance
+     */
+    public static NormalizedNodeStreamWriter createExclusiveWriter(JSONCodecFactory codecFactory, SchemaPath path, URI initialNs, JsonWriter jsonWriter) {
+        return new JSONNormalizedNodeStreamWriter(codecFactory, path, jsonWriter, new JSONStreamWriterExclusiveRootContext(initialNs));
+    }
+
+    /**
+     * Create a new stream writer, which writes to the specified output stream.
+     *
+     * The codec factory can be reused between multiple writers.
+     *
+     * Returned writer can be used emit multiple top level element,
+     * but does not start / close parent JSON object, which must be done
+     * by user providing {@code jsonWriter} instance in order for
+     * JSON to be valid.
      *
      * @param codecFactory JSON codec factory
      * @param path Schema Path
@@ -135,18 +180,16 @@ public class JSONNormalizedNodeStreamWriter implements NormalizedNodeStreamWrite
      * @param jsonWriter JsonWriter
      * @return A stream writer instance
      */
-    public static NormalizedNodeStreamWriter create(JSONCodecFactory codecFactory, SchemaPath path, URI initialNs, JsonWriter jsonWriter) {
-        return new JSONNormalizedNodeStreamWriter(codecFactory, path, initialNs, jsonWriter);
+    public static NormalizedNodeStreamWriter createNestedWriter(JSONCodecFactory codecFactory, SchemaPath path, URI initialNs, JsonWriter jsonWriter) {
+        return new JSONNormalizedNodeStreamWriter(codecFactory, path, jsonWriter, new JSONStreamWriterSharedRootContext(initialNs));
     }
 
     @Override
     public void leafNode(final NodeIdentifier name, final Object value) throws IOException {
         final LeafSchemaNode schema = tracker.leafNode(name);
-        final JSONCodec<Object> codec = codecs.codecFor(schema.getType());
-
+        final JSONCodec<Object> codec = codecs.codecFor(schema);
         context.emittingChild(codecs.getSchemaContext(), writer);
         context.writeChildJsonIdentifier(codecs.getSchemaContext(), writer, name.getNodeType());
-
         writeValue(value, codec);
     }
 
@@ -159,10 +202,8 @@ public class JSONNormalizedNodeStreamWriter implements NormalizedNodeStreamWrite
     @Override
     public void leafSetEntryNode(final Object value) throws IOException {
         final LeafListSchemaNode schema = tracker.leafSetEntryNode();
-        final JSONCodec<Object> codec = codecs.codecFor(schema.getType());
-
+        final JSONCodec<Object> codec = codecs.codecFor(schema);
         context.emittingChild(codecs.getSchemaContext(), writer);
-
         writeValue(value, codec);
     }
 
@@ -231,6 +272,7 @@ public class JSONNormalizedNodeStreamWriter implements NormalizedNodeStreamWrite
 
         context.emittingChild(codecs.getSchemaContext(), writer);
         context.writeChildJsonIdentifier(codecs.getSchemaContext(), writer, name.getNodeType());
+        // FIXME this kind of serialization is incorrect since the value for AnyXml is now a DOMSource
         writer.value(String.valueOf(value));
     }
 
@@ -238,6 +280,7 @@ public class JSONNormalizedNodeStreamWriter implements NormalizedNodeStreamWrite
     public void endNode() throws IOException {
         tracker.endNode();
         context = context.endNode(codecs.getSchemaContext(), writer);
+
         if(context instanceof JSONStreamWriterRootContext) {
             context.emitEnd(writer);
         }