Merge "Bug 2157 - Race condition when adding a RPC implementation with an output"
[yangtools.git] / yang / yang-data-impl / src / main / java / org / opendaylight / yangtools / yang / data / impl / codec / xml / XMLStreamNormalizedNodeStreamWriter.java
index bec315491fc268c169ca5b41f6f1e6aaeb177778..7f2c3019d35af9356115f33ff3ecc3da77e7a20f 100644 (file)
@@ -7,13 +7,12 @@
  */
 package org.opendaylight.yangtools.yang.data.impl.codec.xml;
 
-import com.google.common.base.Preconditions;
+import static javax.xml.XMLConstants.DEFAULT_NS_PREFIX;
 
+import com.google.common.base.Preconditions;
 import java.io.IOException;
-
 import javax.xml.stream.XMLStreamException;
 import javax.xml.stream.XMLStreamWriter;
-
 import org.opendaylight.yangtools.yang.common.QName;
 import org.opendaylight.yangtools.yang.data.api.Node;
 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.AugmentationIdentifier;
@@ -37,14 +36,15 @@ import org.opendaylight.yangtools.yang.model.api.TypeDefinition;
  * {@link XMLStreamWriter}, resulting in a RFC 6020 XML encoding.
  */
 public final class XMLStreamNormalizedNodeStreamWriter implements NormalizedNodeStreamWriter {
-    private static final XmlStreamUtils UTILS = XmlStreamUtils.create(XmlUtils.DEFAULT_XML_CODEC_PROVIDER);
 
     private final XMLStreamWriter writer;
     private final SchemaTracker tracker;
+    private final XmlStreamUtils streamUtils;
 
     private XMLStreamNormalizedNodeStreamWriter(final XMLStreamWriter writer, final SchemaContext context, final SchemaPath path) {
         this.writer = Preconditions.checkNotNull(writer);
         this.tracker = SchemaTracker.create(context, path);
+        this.streamUtils = XmlStreamUtils.create(XmlUtils.DEFAULT_XML_CODEC_PROVIDER, context);
     }
 
     /**
@@ -70,17 +70,34 @@ public final class XMLStreamNormalizedNodeStreamWriter implements NormalizedNode
         return new XMLStreamNormalizedNodeStreamWriter(writer, context, path);
     }
 
+    private void writeStartElement( QName qname) throws XMLStreamException {
+        String ns = qname.getNamespace().toString();
+        String parentNs = writer.getNamespaceContext().getNamespaceURI(DEFAULT_NS_PREFIX);
+        writer.writeStartElement(DEFAULT_NS_PREFIX, qname.getLocalName(), ns);
+        if (!ns.equals(parentNs)) {
+            writer.writeDefaultNamespace(ns);
+        }
+    }
+
     private void writeElement(final QName qname, final TypeDefinition<?> type, final Object value) throws IOException {
-        final String ns = qname.getNamespace().toString();
+        try {
+            writeStartElement(qname);
+            if (value != null) {
+                streamUtils.writeValue(writer, type, value);
+            }
+            writer.writeEndElement();
+        } catch (XMLStreamException e) {
+            throw new IOException("Failed to emit element", e);
+        }
+    }
 
+    private void writeElement(final QName qname, final SchemaNode schemaNode, final Object value) throws IOException {
         try {
+            writeStartElement(qname);
             if (value != null) {
-                writer.writeStartElement(ns, qname.getLocalName());
-                UTILS.writeValue(writer, type, value);
-                writer.writeEndElement();
-            } else {
-                writer.writeEmptyElement(ns, qname.getLocalName());
+                streamUtils.writeValue(writer, schemaNode, value);
             }
+            writer.writeEndElement();
         } catch (XMLStreamException e) {
             throw new IOException("Failed to emit element", e);
         }
@@ -88,7 +105,7 @@ public final class XMLStreamNormalizedNodeStreamWriter implements NormalizedNode
 
     private void startElement(final QName qname) throws IOException {
         try {
-            writer.writeStartElement(qname.getNamespace().toString(), qname.getLocalName());
+            writeStartElement(qname);
         } catch (XMLStreamException e) {
             throw new IOException("Failed to start element", e);
         }
@@ -106,8 +123,7 @@ public final class XMLStreamNormalizedNodeStreamWriter implements NormalizedNode
     @Override
     public void leafNode(final NodeIdentifier name, final Object value) throws IOException {
         final LeafSchemaNode schema = tracker.leafNode(name);
-
-        writeElement(schema.getQName(), schema.getType(), value);
+        writeElement(schema.getQName(), schema, value);
     }
 
     @Override
@@ -118,7 +134,7 @@ public final class XMLStreamNormalizedNodeStreamWriter implements NormalizedNode
     @Override
     public void leafSetEntryNode(final Object value) throws IOException {
         final LeafListSchemaNode schema = tracker.leafSetEntryNode();
-        writeElement(schema.getQName(), schema.getType(), value);
+        writeElement(schema.getQName(), schema, value);
     }
 
     @Override
@@ -166,16 +182,12 @@ public final class XMLStreamNormalizedNodeStreamWriter implements NormalizedNode
     public void anyxmlNode(final NodeIdentifier name, final Object value) throws IOException {
         final AnyXmlSchemaNode schema = tracker.anyxmlNode(name);
         final QName qname = schema.getQName();
-        final String ns = qname.getNamespace().toString();
-
         try {
+            writeStartElement(qname);
             if (value != null) {
-                writer.writeStartElement(ns, qname.getLocalName());
-                UTILS.writeValue(writer, (Node<?>)value, schema);
-                writer.writeEndElement();
-            } else {
-                writer.writeEmptyElement(ns, qname.getLocalName());
+                streamUtils.writeValue(writer, (Node<?>)value, schema);
             }
+            writer.writeEndElement();
         } catch (XMLStreamException e) {
             throw new IOException("Failed to emit element", e);
         }