Rename Any{Data,Xml}SchemaNode to Any{data,xml}SchemaNode
[yangtools.git] / yang / yang-data-codec-xml / src / main / java / org / opendaylight / yangtools / yang / data / codec / xml / DOMSourceAnydata.java
index 90bc6abcf431b780557ca4cf8bb665baff09a359..bb160fc596ae896be09ba8ba9540e1a359a36b74 100644 (file)
@@ -9,20 +9,33 @@ package org.opendaylight.yangtools.yang.data.codec.xml;
 
 import static java.util.Objects.requireNonNull;
 
+import com.google.common.annotations.VisibleForTesting;
 import com.google.common.base.MoreObjects.ToStringHelper;
 import java.io.IOException;
 import java.net.URISyntaxException;
 import javax.xml.stream.XMLStreamException;
+import javax.xml.stream.XMLStreamReader;
 import javax.xml.transform.dom.DOMSource;
 import org.eclipse.jdt.annotation.NonNullByDefault;
 import org.opendaylight.yangtools.yang.data.api.schema.stream.NormalizedNodeStreamWriter;
 import org.opendaylight.yangtools.yang.data.impl.schema.AbstractNormalizableAnydata;
-import org.opendaylight.yangtools.yang.data.util.DataSchemaContextNode;
-import org.opendaylight.yangtools.yang.data.util.DataSchemaContextTree;
 import org.opendaylight.yangtools.yang.model.api.DataSchemaNode;
 import org.opendaylight.yangtools.yang.model.api.SchemaContext;
 import org.xml.sax.SAXException;
 
+/**
+ * Internal parser representation of a parsed-out chunk of XML. This format is completely internal to the parser
+ * and can be changed at any time. Current implementation uses W3C DOM tree as the backing implementations, but others
+ * are possible as well.
+ *
+ * <p>
+ * Note that the DOMSource is expected to contain a top-level synthetic element, which acts as holder of namespace
+ * declarations coming from parsing context but is otherwise ignored. Parser-side of things is expected to reuse the
+ * {@code anydata} element name for this purpose. Writer-side of things is expected to skip this element except for
+ * its namespace declarations.
+ *
+ * @author Robert Varga
+ */
 @NonNullByDefault
 final class DOMSourceAnydata extends AbstractNormalizableAnydata {
     private final DOMSource source;
@@ -31,29 +44,25 @@ final class DOMSourceAnydata extends AbstractNormalizableAnydata {
         this.source = requireNonNull(source);
     }
 
-    DOMSource getSource() {
-        return source;
+    XMLStreamReader toStreamReader() throws XMLStreamException {
+        return new DOMSourceXMLStreamReader(source);
     }
 
     @Override
-    protected void writeTo(final NormalizedNodeStreamWriter streamWriter, final DataSchemaContextTree contextTree,
-            final DataSchemaContextNode<?> contextNode) throws IOException {
-        // TODO: this is rather ugly
-        final DataSchemaNode root = contextTree.getRoot().getDataSchemaNode();
-        if (!(root instanceof SchemaContext)) {
-            throw new IOException("Unexpected root context " + root);
-        }
-
+    protected void writeTo(final NormalizedNodeStreamWriter streamWriter, final SchemaContext schemaContext,
+            final DataSchemaNode contextNode) throws IOException {
         final XmlParserStream xmlParser;
         try {
-            xmlParser = XmlParserStream.create(streamWriter, (SchemaContext) root,
-                contextNode.getDataSchemaNode());
+            xmlParser = XmlParserStream.create(streamWriter, schemaContext, contextNode);
         } catch (IllegalArgumentException e) {
             throw new IOException("Failed to instantiate XML parser", e);
         }
 
         try {
-            xmlParser.traverse(source).close();
+            final XMLStreamReader reader = toStreamReader();
+            reader.nextTag();
+
+            xmlParser.parse(reader).flush();
         } catch (XMLStreamException | URISyntaxException | SAXException e) {
             throw new IOException("Failed to parse payload", e);
         }
@@ -63,4 +72,9 @@ final class DOMSourceAnydata extends AbstractNormalizableAnydata {
     protected ToStringHelper addToStringAttributes(final ToStringHelper helper) {
         return helper.add("source", source);
     }
+
+    @VisibleForTesting
+    DOMSource getSource() {
+        return source;
+    }
 }