X-Git-Url: https://git.opendaylight.org/gerrit/gitweb?a=blobdiff_plain;f=yang%2Fyang-data-codec-gson%2Fsrc%2Fmain%2Fjava%2Forg%2Fopendaylight%2Fyangtools%2Fyang%2Fdata%2Fcodec%2Fgson%2FJSONNormalizedNodeStreamWriter.java;h=6d3ba419fab3aa4e9f6c4ccafce21df979d8d5e2;hb=02d5aa352315929d3c2511b37c049fea89d0a2a7;hp=57204c838aba86eee96f3f675090c8b9bb03d5bd;hpb=37af625ff667533daeee98aec9240ed85c3fb7f5;p=yangtools.git 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 57204c838a..6d3ba419fa 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 @@ -7,152 +7,176 @@ */ package org.opendaylight.yangtools.yang.data.codec.gson; -import com.google.common.base.Preconditions; +import static com.google.common.base.Preconditions.checkState; +import static java.util.Objects.requireNonNull; +import static org.w3c.dom.Node.ELEMENT_NODE; +import static org.w3c.dom.Node.TEXT_NODE; + +import com.google.common.collect.ClassToInstanceMap; import com.google.gson.stream.JsonWriter; import java.io.IOException; -import java.io.Writer; import java.net.URI; +import java.util.regex.Pattern; +import javax.xml.transform.dom.DOMSource; +import org.checkerframework.checker.regex.qual.Regex; +import org.opendaylight.yangtools.concepts.ObjectExtensions; +import org.opendaylight.yangtools.rfc8528.data.api.MountPointContext; +import org.opendaylight.yangtools.rfc8528.data.api.MountPointIdentifier; +import org.opendaylight.yangtools.rfc8528.data.api.MountPointStreamWriter; 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.YangInstanceIdentifier.NodeWithValue; +import org.opendaylight.yangtools.yang.data.api.schema.NormalizedAnydata; +import org.opendaylight.yangtools.yang.data.api.schema.stream.AnydataExtension; import org.opendaylight.yangtools.yang.data.api.schema.stream.NormalizedNodeStreamWriter; +import org.opendaylight.yangtools.yang.data.api.schema.stream.NormalizedNodeStreamWriterExtension; import org.opendaylight.yangtools.yang.data.impl.codec.SchemaTracker; -import org.opendaylight.yangtools.yang.model.api.AnyXmlSchemaNode; -import org.opendaylight.yangtools.yang.model.api.LeafListSchemaNode; -import org.opendaylight.yangtools.yang.model.api.LeafSchemaNode; +import org.opendaylight.yangtools.yang.data.util.SingleChildDataNodeContainer; +import org.opendaylight.yangtools.yang.model.api.AnydataSchemaNode; +import org.opendaylight.yangtools.yang.model.api.AnyxmlSchemaNode; +import org.opendaylight.yangtools.yang.model.api.ContainerSchemaNode; +import org.opendaylight.yangtools.yang.model.api.DataNodeContainer; import org.opendaylight.yangtools.yang.model.api.SchemaContext; import org.opendaylight.yangtools.yang.model.api.SchemaNode; import org.opendaylight.yangtools.yang.model.api.SchemaPath; +import org.opendaylight.yangtools.yang.model.api.TypedDataSchemaNode; +import org.w3c.dom.Element; +import org.w3c.dom.Node; +import org.w3c.dom.NodeList; +import org.w3c.dom.Text; /** * This implementation will create JSON output as output stream. * + *
* Values of leaf and leaf-list are NOT translated according to codecs.
- *
*/
-public class JSONNormalizedNodeStreamWriter implements NormalizedNodeStreamWriter {
+public abstract class JSONNormalizedNodeStreamWriter implements NormalizedNodeStreamWriter, AnydataExtension,
+ MountPointStreamWriter {
+ private static final class Exclusive extends JSONNormalizedNodeStreamWriter {
+ Exclusive(final JSONCodecFactory codecFactory, final SchemaTracker tracker, final JsonWriter writer,
+ final JSONStreamWriterRootContext rootContext) {
+ super(codecFactory, tracker, writer, rootContext);
+ }
+
+ @Override
+ public void close() throws IOException {
+ flush();
+ closeWriter();
+ }
+ }
+
+ private static final class Nested extends JSONNormalizedNodeStreamWriter {
+ Nested(final JSONCodecFactory codecFactory, final SchemaTracker tracker, final JsonWriter writer,
+ final JSONStreamWriterRootContext rootContext) {
+ super(codecFactory, tracker, writer, rootContext);
+ }
+
+ @Override
+ public void close() throws IOException {
+ flush();
+ // The caller "owns" the writer, let them close it
+ }
+ }
+
/**
* RFC6020 deviation: we are not required to emit empty containers unless they
* are marked as 'presence'.
*/
private static final boolean DEFAULT_EMIT_EMPTY_CONTAINERS = true;
+ static final ObjectExtensions.Factory
+ * The codec factory can be reused between multiple writers.
*
- * @param schemaContext Schema context
- * @param path Root schemapath
- * @param writer Output writer
- * @return A stream writer instance
- */
- public static NormalizedNodeStreamWriter create(final SchemaContext schemaContext, final SchemaPath path, final Writer writer) {
- return create(schemaContext, path, null, writer);
- }
-
- /**
- * Create a new stream writer, which writes to the specified {@link Writer}.
+ *
+ * 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.
+ * otherwise it will produce incorrect JSON. Closing this instance will close
+ * the writer too.
*
- * @param schemaContext Schema context
- * @param path Root schemapath
- * @param writer Output writer
+ * @param codecFactory JSON codec factory
+ * @param path Schema Path
* @param initialNs Initial namespace
+ * @param jsonWriter JsonWriter
* @return A stream writer instance
*/
- public static NormalizedNodeStreamWriter create(final SchemaContext schemaContext, final SchemaPath path,
- final URI initialNs, final Writer writer) {
- return createExclusiveWriter(JSONCodecFactory.create(schemaContext), path, initialNs, JsonWriterFactory.createJsonWriter(writer));
+ public static NormalizedNodeStreamWriter createExclusiveWriter(final JSONCodecFactory codecFactory,
+ final SchemaPath path, final URI initialNs, final JsonWriter jsonWriter) {
+ return new Exclusive(codecFactory, SchemaTracker.create(codecFactory.getSchemaContext(), path), jsonWriter,
+ new JSONStreamWriterExclusiveRootContext(initialNs));
}
/**
* 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.
+ *
+ * The codec factory can be reused between multiple writers.
*
- * @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 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.
+ *
+ * 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.
+ * otherwise it will produce incorrect JSON. Closing this instance will close
+ * the writer too.
*
* @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 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 rootNode Root node
* @param initialNs Initial namespace
* @param jsonWriter JsonWriter
* @return A stream writer instance
*/
- public static NormalizedNodeStreamWriter create(SchemaContext schemaContext, SchemaPath path, URI initialNs,
- JsonWriter jsonWriter) {
- return createExclusiveWriter(JSONCodecFactory.create(schemaContext), path, initialNs, jsonWriter);
+ public static NormalizedNodeStreamWriter createExclusiveWriter(final JSONCodecFactory codecFactory,
+ final DataNodeContainer rootNode, final URI initialNs, final JsonWriter jsonWriter) {
+ return new Exclusive(codecFactory, SchemaTracker.create(rootNode), 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 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.
+ *
+ * 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. Closing this instance will not
+ * close the wrapped writer; the caller must take care of that.
*
* @param codecFactory JSON codec factory
* @param path Schema Path
@@ -160,152 +184,338 @@ public class JSONNormalizedNodeStreamWriter implements NormalizedNodeStreamWrite
* @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));
+ public static NormalizedNodeStreamWriter createNestedWriter(final JSONCodecFactory codecFactory,
+ final SchemaPath path, final URI initialNs, final JsonWriter jsonWriter) {
+ return new Nested(codecFactory, SchemaTracker.create(codecFactory.getSchemaContext(), path), jsonWriter,
+ new JSONStreamWriterSharedRootContext(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.
+ * JSON to be valid. Closing this instance will not
+ * close the wrapped writer; the caller must take care of that.
*
* @param codecFactory JSON codec factory
- * @param path Schema Path
+ * @param rootNode Root node
* @param initialNs Initial namespace
* @param jsonWriter JsonWriter
* @return A stream writer instance
*/
- public static NormalizedNodeStreamWriter createNestedWriter(JSONCodecFactory codecFactory, SchemaPath path, URI initialNs, JsonWriter jsonWriter) {
- return new JSONNormalizedNodeStreamWriter(codecFactory, path, jsonWriter, new JSONStreamWriterSharedRootContext(initialNs));
+ public static NormalizedNodeStreamWriter createNestedWriter(final JSONCodecFactory codecFactory,
+ final DataNodeContainer rootNode, final URI initialNs, final JsonWriter jsonWriter) {
+ return new Nested(codecFactory, SchemaTracker.create(rootNode), jsonWriter,
+ new JSONStreamWriterSharedRootContext(initialNs));
}
@Override
- public void leafNode(final NodeIdentifier name, final Object value) throws IOException {
- final LeafSchemaNode schema = tracker.leafNode(name);
- final JSONCodec