Fix missing location in error reports
[yangtools.git] / yang / yang-data-codec-xml / src / main / java / org / opendaylight / yangtools / yang / data / codec / xml / SchemalessXMLStreamNormalizedNodeStreamWriter.java
index 9450c7a14b56ba333c6805a57eed5e55015f7b5a..ff21106cd3d5f946a6a67e3389ddca791dab1163 100644 (file)
  */
 package org.opendaylight.yangtools.yang.data.codec.xml;
 
+import static com.google.common.base.Preconditions.checkState;
+
 import java.io.IOException;
 import java.util.ArrayDeque;
-import java.util.Collections;
 import java.util.Deque;
-import java.util.Map;
-import javax.annotation.Nonnull;
-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;
-import org.opendaylight.yangtools.yang.data.api.schema.stream.NormalizedNodeStreamWriter;
 
-class SchemalessXMLStreamNormalizedNodeStreamWriter extends XMLStreamNormalizedNodeStreamWriter<Object> {
-    private enum ContainerType {
+final class SchemalessXMLStreamNormalizedNodeStreamWriter extends XMLStreamNormalizedNodeStreamWriter<Object> {
+    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<>();
 
-    private SchemalessXMLStreamNormalizedNodeStreamWriter(final XMLStreamWriter writer) {
+    SchemalessXMLStreamNormalizedNodeStreamWriter(final XMLStreamWriter writer) {
         super(writer);
     }
 
-    static NormalizedNodeStreamWriter newInstance(final XMLStreamWriter writer) {
-        return new SchemalessXMLStreamNormalizedNodeStreamWriter(writer);
+    @Override
+    public void startLeafNode(final NodeIdentifier name) throws IOException {
+        nodeTypeStack.push(NodeType.SCALAR);
+        startElement(name.getNodeType());
     }
 
     @Override
-    public void leafNode(final NodeIdentifier name, final Object value, final Map<QName, String> attributes) throws IOException {
-        writeElement(name.getNodeType(), value, attributes, null);
+    public void startLeafSetEntryNode(final NodeWithValue<?> name) throws IOException {
+        nodeTypeStack.push(NodeType.SCALAR);
+        startElement(name.getNodeType());
     }
 
     @Override
-    public void leafSetEntryNode(final QName name, final Object value, final Map<QName, String> attributes) throws IOException {
-        writeElement(name, value, attributes, null);
+    public void startLeafSet(final NodeIdentifier name, final int childSizeHint) throws IOException {
+        nodeTypeStack.push(NodeType.LEAF_SET);
     }
 
     @Override
-    public void leafNode(final NodeIdentifier name, final Object value) throws IOException {
-        writeElement(name.getNodeType(), value, Collections.emptyMap(), null);
+    public void startOrderedLeafSet(final NodeIdentifier name, final int childSizeHint) throws IOException {
+        nodeTypeStack.push(NodeType.LEAF_SET);
     }
 
     @Override
-    public void leafSetEntryNode(final QName name, final Object value) throws IOException {
-        writeElement(name, value, Collections.emptyMap(), null);
+    public void startContainerNode(final NodeIdentifier name, final int childSizeHint) throws IOException {
+        nodeTypeStack.push(NodeType.CONTAINER);
+        startElement(name.getNodeType());
     }
 
     @Override
-    public void startLeafSet(final NodeIdentifier name, final int childSizeHint) throws IOException {
-        containerTypeStack.push(ContainerType.LEAF_SET);
+    public void startChoiceNode(final NodeIdentifier name, final int childSizeHint) throws IOException {
+        nodeTypeStack.push(NodeType.CHOICE);
     }
 
     @Override
-    public void startOrderedLeafSet(final NodeIdentifier name, final int childSizeHint)
-            throws IOException, IllegalArgumentException {
-        containerTypeStack.push(ContainerType.LEAF_SET);
+    public void startAugmentationNode(final AugmentationIdentifier identifier) throws IOException {
+        nodeTypeStack.push(NodeType.AUGMENTATION);
     }
 
     @Override
-    public void startContainerNode(final NodeIdentifier name, final int childSizeHint) throws IOException {
-        containerTypeStack.push(ContainerType.CONTAINER);
-        startElement(name.getNodeType());
+    public boolean startAnyxmlNode(final NodeIdentifier name, final Class<?> objectModel) throws IOException {
+        if (DOMSource.class.isAssignableFrom(objectModel)) {
+            nodeTypeStack.push(NodeType.ANY_XML);
+            startElement(name.getNodeType());
+            return true;
+        }
+        return false;
     }
 
     @Override
-    public void startChoiceNode(final NodeIdentifier name, final int childSizeHint) throws IOException {
-        containerTypeStack.push(ContainerType.CHOICE);
+    String encodeValue(final ValueWriter xmlWriter, final Object value, final Object context) {
+        return value.toString();
     }
 
     @Override
-    public void startAugmentationNode(final AugmentationIdentifier identifier) throws IOException {
-        containerTypeStack.push(ContainerType.AUGMENTATION);
+    String encodeAnnotationValue(final ValueWriter xmlWriter, final QName qname, final Object value) {
+        return value.toString();
     }
 
     @Override
-    public void anyxmlNode(final NodeIdentifier name, final Object value) throws IOException {
-        anyxmlNode(name.getNodeType(), value);
+    void startList(final NodeIdentifier name) {
+        nodeTypeStack.push(NodeType.LIST);
     }
 
     @Override
-    public void startYangModeledAnyXmlNode(final NodeIdentifier name, final int childSizeHint) throws IOException {
-        containerTypeStack.push(ContainerType.ANY_XML);
+    void startListItem(final PathArgument name) throws IOException {
+        nodeTypeStack.push(NodeType.LIST_ITEM);
         startElement(name.getNodeType());
     }
 
     @Override
-    protected void writeValue(final XMLStreamWriter xmlWriter, final QName qname, @Nonnull final Object value, final Object context)
-            throws XMLStreamException {
-        xmlWriter.writeCharacters(value.toString());
+    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) {
+            anydataValue(value);
+        } else {
+            throw new IllegalStateException("Unexpected scalar " + value + " in type " + type);
+        }
     }
 
     @Override
-    protected void startList(final NodeIdentifier name) {
-        containerTypeStack.push(ContainerType.LIST);
+    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
-    protected void startListItem(final PathArgument name) throws IOException {
-        containerTypeStack.push(ContainerType.LIST_ITEM);
-        startElement(name.getNodeType());
+    public void endNode() throws IOException {
+        NodeType type = nodeTypeStack.pop();
+        switch (type) {
+            case CONTAINER:
+            case LIST_ITEM:
+            case SCALAR:
+            case ANY_XML:
+            case ANYDATA:
+                endElement();
+                break;
+            default:
+                break;
+        }
     }
 
     @Override
-    protected void endNode(final XMLStreamWriter xmlWriter) throws IOException, XMLStreamException {
-        ContainerType type = containerTypeStack.pop();
-        switch (type) {
-        case CONTAINER:
-        case LIST_ITEM:
-        case ANY_XML:
-            xmlWriter.writeEndElement();
-            break;
-        default:
-            break;
-        }
+    void startAnydata(final NodeIdentifier name) {
+        nodeTypeStack.push(NodeType.ANYDATA);
     }
 }