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.
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;
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);
}
/**
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.
*
@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);
@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);
@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);
@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();
@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);
@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);
@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();
@Override
public void endNode() throws IOException {
- switch (stack.peek().getType()) {
+ tracker.endNode();
+
+ final TypeInfo t = stack.pop();
+ switch (t.getType()) {
case LIST:
indentLeft();
newLine();
default:
break;
}
- stack.pop();
+
currentNamespace = stack.isEmpty() ? null : stack.peek().getNamespace();
separateNextSiblingsWithComma();
}