Rework Anydata model
[yangtools.git] / yang / yang-data-codec-xml / src / main / java / org / opendaylight / yangtools / yang / data / codec / xml / SchemalessXMLStreamNormalizedNodeStreamWriter.java
index 8cbe0d2d664121c4e324fa62abb2140771069e55..fc13c52b0ec0ff0d1e118523101e62efa865a6fa 100644 (file)
  */
 package org.opendaylight.yangtools.yang.data.codec.xml;
 
+import static com.google.common.base.Preconditions.checkState;
+import static com.google.common.base.Verify.verify;
+
 import java.io.IOException;
 import java.util.ArrayDeque;
-import java.util.Collections;
 import java.util.Deque;
-import java.util.Map;
-import javax.xml.stream.XMLStreamException;
 import javax.xml.stream.XMLStreamWriter;
+import javax.xml.transform.dom.DOMSource;
 import org.opendaylight.yangtools.yang.common.QName;
 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.NodeWithValue;
 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.PathArgument;
 
 final class SchemalessXMLStreamNormalizedNodeStreamWriter extends XMLStreamNormalizedNodeStreamWriter<Object> {
-    private enum ContainerType {
+    private enum NodeType {
         CONTAINER,
         LEAF_SET,
         LIST,
         LIST_ITEM,
-        ANY_XML,
+        YANG_MODELED_ANY_XML,
         CHOICE,
-        AUGMENTATION
+        AUGMENTATION,
+        SCALAR,
+        ANY_XML,
+        ANYDATA,
     }
 
-    private final Deque<ContainerType> containerTypeStack = new ArrayDeque<>();
+    private final Deque<NodeType> nodeTypeStack = new ArrayDeque<>();
 
     SchemalessXMLStreamNormalizedNodeStreamWriter(final XMLStreamWriter writer) {
         super(writer);
     }
 
     @Override
-    public void leafNode(final NodeIdentifier name, final Object value, final Map<QName, String> attributes)
-            throws IOException {
-        writeElement(name.getNodeType(), value, attributes, null);
-    }
-
-    @Override
-    public void leafNode(final NodeIdentifier name, final Object value) throws IOException {
-        writeElement(name.getNodeType(), value, Collections.emptyMap(), null);
-    }
-
-    @Override
-    public void leafSetEntryNode(final QName name, final Object value, final Map<QName, String> attributes)
-            throws IOException {
-        writeElement(name, value, attributes, null);
+    public void startLeafNode(final NodeIdentifier name) throws IOException {
+        nodeTypeStack.push(NodeType.SCALAR);
+        startElement(name.getNodeType());
     }
 
     @Override
-    public void leafSetEntryNode(final QName name, final Object value) throws IOException {
-        writeElement(name, value, Collections.emptyMap(), null);
+    public void startLeafSetEntryNode(final NodeWithValue<?> name) throws IOException {
+        nodeTypeStack.push(NodeType.SCALAR);
+        startElement(name.getNodeType());
     }
 
     @Override
     public void startLeafSet(final NodeIdentifier name, final int childSizeHint) throws IOException {
-        containerTypeStack.push(ContainerType.LEAF_SET);
+        nodeTypeStack.push(NodeType.LEAF_SET);
     }
 
     @Override
     public void startOrderedLeafSet(final NodeIdentifier name, final int childSizeHint) throws IOException {
-        containerTypeStack.push(ContainerType.LEAF_SET);
+        nodeTypeStack.push(NodeType.LEAF_SET);
     }
 
     @Override
     public void startContainerNode(final NodeIdentifier name, final int childSizeHint) throws IOException {
-        containerTypeStack.push(ContainerType.CONTAINER);
+        nodeTypeStack.push(NodeType.CONTAINER);
         startElement(name.getNodeType());
     }
 
     @Override
     public void startChoiceNode(final NodeIdentifier name, final int childSizeHint) throws IOException {
-        containerTypeStack.push(ContainerType.CHOICE);
+        nodeTypeStack.push(NodeType.CHOICE);
     }
 
     @Override
     public void startAugmentationNode(final AugmentationIdentifier identifier) throws IOException {
-        containerTypeStack.push(ContainerType.AUGMENTATION);
+        nodeTypeStack.push(NodeType.AUGMENTATION);
     }
 
     @Override
-    public void anyxmlNode(final NodeIdentifier name, final Object value) throws IOException {
-        anyxmlNode(name.getNodeType(), value);
+    public void startAnyxmlNode(final NodeIdentifier name) throws IOException {
+        nodeTypeStack.push(NodeType.ANY_XML);
+        startElement(name.getNodeType());
     }
 
     @Override
     public void startYangModeledAnyXmlNode(final NodeIdentifier name, final int childSizeHint) throws IOException {
-        containerTypeStack.push(ContainerType.ANY_XML);
+        nodeTypeStack.push(NodeType.YANG_MODELED_ANY_XML);
         startElement(name.getNodeType());
     }
 
     @Override
-    void writeValue(final XMLStreamWriter xmlWriter, final QName qname, final Object value, final Object context)
-            throws XMLStreamException {
-        xmlWriter.writeCharacters(value.toString());
+    String encodeValue(final ValueWriter xmlWriter, final Object value, final Object context) {
+        return value.toString();
+    }
+
+    @Override
+    String encodeAnnotationValue(final ValueWriter xmlWriter, final QName qname, final Object value) {
+        return value.toString();
     }
 
     @Override
     void startList(final NodeIdentifier name) {
-        containerTypeStack.push(ContainerType.LIST);
+        nodeTypeStack.push(NodeType.LIST);
     }
 
     @Override
     void startListItem(final PathArgument name) throws IOException {
-        containerTypeStack.push(ContainerType.LIST_ITEM);
+        nodeTypeStack.push(NodeType.LIST_ITEM);
         startElement(name.getNodeType());
     }
 
+    @Override
+    public void scalarValue(final Object value) throws IOException {
+        final NodeType type = nodeTypeStack.peek();
+        if (type == NodeType.SCALAR) {
+            writeValue(value, null);
+        } else if (type == NodeType.ANYDATA) {
+            verify(value instanceof DOMSource, "Unexpected anydata value %s", value);
+            anydataValue((DOMSource) value);
+        } else {
+            throw new IllegalStateException("Unexpected scalar " + value + " in type " + type);
+        }
+    }
+
+    @Override
+    public void domSourceValue(final DOMSource value) throws IOException {
+        final NodeType type = nodeTypeStack.peek();
+        checkState(type == NodeType.ANY_XML, "Unexpected DOMSource %s in %s", value, type);
+        anyxmlValue(value);
+    }
+
     @Override
     public void endNode() throws IOException {
-        ContainerType type = containerTypeStack.pop();
+        NodeType type = nodeTypeStack.pop();
         switch (type) {
             case CONTAINER:
             case LIST_ITEM:
+            case SCALAR:
             case ANY_XML:
+            case ANYDATA:
                 endElement();
                 break;
             default:
                 break;
         }
     }
+
+    @Override
+    void startAnydata(final NodeIdentifier name) {
+        nodeTypeStack.push(NodeType.ANYDATA);
+    }
 }