Fix possible null pointer in NormalizedNode XML stream writer
[yangtools.git] / yang / yang-data-impl / src / main / java / org / opendaylight / yangtools / yang / data / impl / codec / xml / XMLStreamNormalizedNodeStreamWriter.java
index 02b93a44f21a724086c9dedf7371a66dd565cb41..ddc8076d612cd2b4af752920655b9fed58729a4c 100644 (file)
@@ -10,12 +10,9 @@ package org.opendaylight.yangtools.yang.data.impl.codec.xml;
 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;
@@ -39,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);
     }
 
     /**
@@ -72,17 +70,36 @@ public final class XMLStreamNormalizedNodeStreamWriter implements NormalizedNode
         return new XMLStreamNormalizedNodeStreamWriter(writer, context, path);
     }
 
+    private void writeStartElement( QName qname) throws XMLStreamException {
+        String ns = qname.getNamespace().toString();
+        writer.writeStartElement(DEFAULT_NS_PREFIX, qname.getLocalName(), ns);
+        if(writer.getNamespaceContext() != null) {
+            String parentNs = writer.getNamespaceContext().getNamespaceURI(DEFAULT_NS_PREFIX);
+            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(DEFAULT_NS_PREFIX, qname.getLocalName(), ns);
-                UTILS.writeValue(writer, type, value);
-                writer.writeEndElement();
-            } else {
-                writer.writeEmptyElement(DEFAULT_NS_PREFIX, qname.getLocalName(), ns);
+                streamUtils.writeValue(writer, schemaNode, value);
             }
+            writer.writeEndElement();
         } catch (XMLStreamException e) {
             throw new IOException("Failed to emit element", e);
         }
@@ -90,7 +107,7 @@ public final class XMLStreamNormalizedNodeStreamWriter implements NormalizedNode
 
     private void startElement(final QName qname) throws IOException {
         try {
-            writer.writeStartElement(DEFAULT_NS_PREFIX, qname.getLocalName(), qname.getNamespace().toString());
+            writeStartElement(qname);
         } catch (XMLStreamException e) {
             throw new IOException("Failed to start element", e);
         }
@@ -108,8 +125,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
@@ -120,7 +136,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
@@ -168,16 +184,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);
         }