Merge "Added tests for yang.model.util"
[yangtools.git] / yang / yang-data-codec-gson / src / main / java / org / opendaylight / yangtools / yang / data / codec / gson / JSONNormalizedNodeStreamWriter.java
index 16428cd477e1af4a03f26207f80ded9d0be1cd5e..c1a4c31d43f1c1b21146fd1dd87f84ff2ae556d9 100644 (file)
@@ -10,19 +10,23 @@ package org.opendaylight.yangtools.yang.data.codec.gson;
 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 java.util.ArrayDeque;
 import java.util.Deque;
-
+import org.opendaylight.yangtools.concepts.Codec;
 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.LeafListSchemaNode;
+import org.opendaylight.yangtools.yang.model.api.LeafSchemaNode;
 import org.opendaylight.yangtools.yang.model.api.Module;
 import org.opendaylight.yangtools.yang.model.api.SchemaContext;
+import org.opendaylight.yangtools.yang.model.api.SchemaPath;
 
 /**
  * This implementation will create JSON output as output stream.
@@ -68,6 +72,8 @@ public class JSONNormalizedNodeStreamWriter implements NormalizedNodeStreamWrite
 
     private final Deque<TypeInfo> stack = new ArrayDeque<>();
     private final SchemaContext schemaContext;
+    private final CodecFactory codecs;
+    private final SchemaTracker tracker;
     private final Writer writer;
     private final String indent;
 
@@ -80,12 +86,30 @@ public class JSONNormalizedNodeStreamWriter implements NormalizedNodeStreamWrite
         this.writer = Preconditions.checkNotNull(writer);
 
         Preconditions.checkArgument(indentSize >= 0, "Indent size must be non-negative");
+        if (indentSize != 0) {
+            indent = Strings.repeat(" ", indentSize);
+        } else {
+            indent = null;
+        }
+
+        this.codecs = CodecFactory.create(schemaContext);
+        this.tracker = SchemaTracker.create(schemaContext);
+    }
 
+    private JSONNormalizedNodeStreamWriter(final SchemaContext schemaContext, final SchemaPath path,
+            final Writer writer, final int indentSize) {
+        this.schemaContext = Preconditions.checkNotNull(schemaContext);
+        this.writer = Preconditions.checkNotNull(writer);
+
+        Preconditions.checkArgument(indentSize >= 0, "Indent size must be non-negative");
         if (indentSize != 0) {
             indent = Strings.repeat(" ", indentSize);
         } else {
             indent = null;
         }
+
+        this.codecs = CodecFactory.create(schemaContext);
+        this.tracker = SchemaTracker.create(schemaContext,path);
     }
 
     /**
@@ -99,6 +123,17 @@ public class JSONNormalizedNodeStreamWriter implements NormalizedNodeStreamWrite
         return new JSONNormalizedNodeStreamWriter(schemaContext, writer, 0);
     }
 
+    /**
+     * Create a new stream writer, which writes to the specified {@link Writer}.
+     *
+     * @param schemaContext Schema context
+     * @param writer Output writer
+     * @return A stream writer instance
+     */
+    public static NormalizedNodeStreamWriter create(final SchemaContext schemaContext, SchemaPath path,final Writer writer) {
+        return new JSONNormalizedNodeStreamWriter(schemaContext, path, writer, 0);
+    }
+
     /**
      * Create a new stream writer, which writes to the specified output stream.
      *
@@ -113,15 +148,20 @@ public class JSONNormalizedNodeStreamWriter implements NormalizedNodeStreamWrite
 
     @Override
     public void leafNode(final NodeIdentifier name, final Object value) throws IOException {
+        final LeafSchemaNode schema = tracker.leafNode(name);
+        final Codec<Object, Object> codec = codecs.codecFor(schema.getType());
+
         separateElementFromPreviousElement();
         writeJsonIdentifier(name);
         currentNamespace = stack.peek().getNamespace();
-        writeValue(value.toString());
+        writeValue(String.valueOf(codec.serialize(value)));
         separateNextSiblingsWithComma();
     }
 
     @Override
     public void startLeafSet(final NodeIdentifier name, final int childSizeHint) throws IOException {
+        tracker.startLeafSet(name);
+
         separateElementFromPreviousElement();
         stack.push(new TypeInfo(NodeType.LIST, name.getNodeType().getNamespace()));
         writeJsonIdentifier(name);
@@ -131,13 +171,18 @@ public class JSONNormalizedNodeStreamWriter implements NormalizedNodeStreamWrite
 
     @Override
     public void leafSetEntryNode(final Object value) throws IOException {
+        final LeafListSchemaNode schema = tracker.leafSetEntryNode();
+        final Codec<Object, Object> codec = codecs.codecFor(schema.getType());
+
         separateElementFromPreviousElement();
-        writeValue(value.toString());
+        writeValue(String.valueOf(codec.serialize(value)));
         separateNextSiblingsWithComma();
     }
 
     @Override
     public void startContainerNode(final NodeIdentifier name, final int childSizeHint) throws IOException {
+        tracker.startContainerNode(name);
+
         separateElementFromPreviousElement();
         stack.push(new TypeInfo(NodeType.OBJECT, name.getNodeType().getNamespace()));
         writeJsonIdentifier(name);
@@ -147,6 +192,8 @@ public class JSONNormalizedNodeStreamWriter implements NormalizedNodeStreamWrite
 
     @Override
     public void startUnkeyedList(final NodeIdentifier name, final int childSizeHint) throws IOException {
+        tracker.startList(name);
+
         separateElementFromPreviousElement();
         stack.push(new TypeInfo(NodeType.LIST, name.getNodeType().getNamespace()));
         writeJsonIdentifier(name);
@@ -156,6 +203,8 @@ public class JSONNormalizedNodeStreamWriter implements NormalizedNodeStreamWrite
 
     @Override
     public void startUnkeyedListItem(final NodeIdentifier name, final int childSizeHint) throws IOException {
+        tracker.startListItem(name);
+
         stack.push(new TypeInfo(NodeType.OBJECT, name.getNodeType().getNamespace()));
         separateElementFromPreviousElement();
         writeStartObject();
@@ -164,6 +213,8 @@ public class JSONNormalizedNodeStreamWriter implements NormalizedNodeStreamWrite
 
     @Override
     public void startMapNode(final NodeIdentifier name, final int childSizeHint) throws IOException {
+        tracker.startList(name);
+
         separateElementFromPreviousElement();
         stack.push(new TypeInfo(NodeType.LIST, name.getNodeType().getNamespace()));
         writeJsonIdentifier(name);
@@ -174,14 +225,19 @@ public class JSONNormalizedNodeStreamWriter implements NormalizedNodeStreamWrite
     @Override
     public void startMapEntryNode(final NodeIdentifierWithPredicates identifier, final int childSizeHint)
             throws IOException {
-        stack.push(new TypeInfo(NodeType.OBJECT, identifier.getNodeType().getNamespace()));
+        tracker.startListItem(identifier);
         separateElementFromPreviousElement();
+        stack.push(new TypeInfo(NodeType.OBJECT, identifier.getNodeType().getNamespace()));
+
+
         writeStartObject();
         indentRight();
     }
 
     @Override
     public void startOrderedMapNode(final NodeIdentifier name, final int childSizeHint) throws IOException {
+        tracker.startListItem(name);
+
         stack.push(new TypeInfo(NodeType.LIST, name.getNodeType().getNamespace()));
         separateElementFromPreviousElement();
         writeJsonIdentifier(name);
@@ -191,16 +247,21 @@ public class JSONNormalizedNodeStreamWriter implements NormalizedNodeStreamWrite
 
     @Override
     public void startChoiceNode(final NodeIdentifier name, final int childSizeHint) throws IllegalArgumentException {
+        tracker.startChoiceNode(name);
         handleInvisibleNode(name.getNodeType().getNamespace());
     }
 
     @Override
     public void startAugmentationNode(final AugmentationIdentifier identifier) throws IllegalArgumentException {
+        tracker.startAugmentationNode(identifier);
         handleInvisibleNode(currentNamespace);
     }
 
     @Override
     public void anyxmlNode(final NodeIdentifier name, final Object value) throws IOException {
+        final AnyXmlSchemaNode schema = tracker.anyxmlNode(name);
+        // FIXME: should have a codec based on this :)
+
         separateElementFromPreviousElement();
         writeJsonIdentifier(name);
         currentNamespace = stack.peek().getNamespace();
@@ -210,7 +271,10 @@ public class JSONNormalizedNodeStreamWriter implements NormalizedNodeStreamWrite
 
     @Override
     public void endNode() throws IOException {
-        switch (stack.peek().getType()) {
+        tracker.endNode();
+
+        final TypeInfo t = stack.pop();
+        switch (t.getType()) {
         case LIST:
             indentLeft();
             newLine();
@@ -224,7 +288,7 @@ public class JSONNormalizedNodeStreamWriter implements NormalizedNodeStreamWrite
         default:
             break;
         }
-        stack.pop();
+
         currentNamespace = stack.isEmpty() ? null : stack.peek().getNamespace();
         separateNextSiblingsWithComma();
     }