Fix RFC8040 root access
[netconf.git] / restconf / restconf-nb-rfc8040 / src / main / java / org / opendaylight / restconf / nb / rfc8040 / jersey / providers / XmlNormalizedNodeBodyWriter.java
index 74ef222971e5da7264e0027fc96bca181d50ed6e..81a1c17b26bce444568d25e7bb7aee6fe8a4727d 100644 (file)
@@ -35,7 +35,6 @@ import org.opendaylight.yangtools.yang.common.QName;
 import org.opendaylight.yangtools.yang.data.api.schema.ContainerNode;
 import org.opendaylight.yangtools.yang.data.api.schema.MapEntryNode;
 import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
-import org.opendaylight.yangtools.yang.data.api.schema.stream.NormalizedNodeStreamWriter;
 import org.opendaylight.yangtools.yang.data.codec.xml.XMLStreamNormalizedNodeStreamWriter;
 import org.opendaylight.yangtools.yang.data.impl.schema.ImmutableNodes;
 import org.opendaylight.yangtools.yang.model.api.ActionDefinition;
@@ -74,7 +73,9 @@ public class XmlNormalizedNodeBodyWriter extends AbstractNormalizedNodeBodyWrite
         XMLStreamWriter xmlWriter;
         try {
             xmlWriter = XML_FACTORY.createXMLStreamWriter(entityStream, StandardCharsets.UTF_8.name());
-            if (context.getWriterParameters().prettyPrint()) {
+
+            final var prettyPrint = context.getWriterParameters().prettyPrint();
+            if (prettyPrint != null && prettyPrint.value()) {
                 xmlWriter = new IndentingXMLStreamWriter(xmlWriter);
             }
         } catch (final XMLStreamException | FactoryConfigurationError e) {
@@ -114,7 +115,8 @@ public class XmlNormalizedNodeBodyWriter extends AbstractNormalizedNodeBodyWrite
                 ((ActionDefinition) pathContext.getSchemaNode()).getOutput().getPath(), depth, fields);
             writeElements(xmlWriter, nnWriter, (ContainerNode) data);
         } else {
-            if (SchemaPath.ROOT.equals(path)) {
+            final boolean isRoot = SchemaPath.ROOT.equals(path);
+            if (isRoot) {
                 nnWriter = createNormalizedNodeWriter(xmlWriter, schemaCtx, path, depth, fields);
             } else {
                 nnWriter = createNormalizedNodeWriter(xmlWriter, schemaCtx, path.getParent(), depth, fields);
@@ -126,6 +128,12 @@ public class XmlNormalizedNodeBodyWriter extends AbstractNormalizedNodeBodyWrite
                 nnWriter.write(ImmutableNodes.mapNodeBuilder(data.getIdentifier().getNodeType())
                     .addChild((MapEntryNode) data)
                     .build());
+            } else if (isRoot) {
+                if (data instanceof ContainerNode && ((ContainerNode) data).isEmpty()) {
+                    writeEmptyDataNode(xmlWriter, data);
+                } else {
+                    writeAndWrapInDataNode(xmlWriter, nnWriter, data);
+                }
             } else {
                 nnWriter.write(data);
             }
@@ -137,18 +145,46 @@ public class XmlNormalizedNodeBodyWriter extends AbstractNormalizedNodeBodyWrite
     private static RestconfNormalizedNodeWriter createNormalizedNodeWriter(final XMLStreamWriter xmlWriter,
             final EffectiveModelContext schemaContext, final SchemaPath schemaPath, final DepthParam depth,
             final List<Set<QName>> fields) {
-        final NormalizedNodeStreamWriter xmlStreamWriter = XMLStreamNormalizedNodeStreamWriter
-                .create(xmlWriter, schemaContext, schemaPath);
-        return ParameterAwareNormalizedNodeWriter.forStreamWriter(xmlStreamWriter, depth, fields);
+        return ParameterAwareNormalizedNodeWriter.forStreamWriter(
+            XMLStreamNormalizedNodeStreamWriter.create(xmlWriter, schemaContext, schemaPath), depth, fields);
+    }
+
+    private static void writeAndWrapInDataNode(final XMLStreamWriter xmlWriter,
+            final RestconfNormalizedNodeWriter nnWriter, final NormalizedNode data) throws IOException {
+        final QName nodeType = data.getIdentifier().getNodeType();
+        final String namespace = nodeType.getNamespace().toString();
+        try {
+            xmlWriter.writeStartElement(XMLConstants.DEFAULT_NS_PREFIX, nodeType.getLocalName(), namespace);
+            xmlWriter.writeDefaultNamespace(namespace);
+            nnWriter.write(data);
+            xmlWriter.writeEndElement();
+            xmlWriter.flush();
+        } catch (XMLStreamException e) {
+            throw new IOException("Failed to write elements", e);
+        }
+    }
+
+    private static void writeEmptyDataNode(final XMLStreamWriter xmlWriter, final NormalizedNode data)
+            throws IOException {
+        final QName nodeType = data.getIdentifier().getNodeType();
+        final String namespace = nodeType.getNamespace().toString();
+        try {
+            xmlWriter.writeStartElement(XMLConstants.DEFAULT_NS_PREFIX, nodeType.getLocalName(), namespace);
+            xmlWriter.writeDefaultNamespace(namespace);
+            xmlWriter.writeEndElement();
+            xmlWriter.flush();
+        } catch (XMLStreamException e) {
+            throw new IOException("Failed to write elements", e);
+        }
     }
 
     private static void writeElements(final XMLStreamWriter xmlWriter, final RestconfNormalizedNodeWriter nnWriter,
             final ContainerNode data) throws IOException {
-        final QName name = data.getIdentifier().getNodeType();
+        final QName nodeType = data.getIdentifier().getNodeType();
+        final String namespace = nodeType.getNamespace().toString();
         try {
-            xmlWriter.writeStartElement(XMLConstants.DEFAULT_NS_PREFIX,
-                    name.getLocalName(), name.getNamespace().toString());
-            xmlWriter.writeDefaultNamespace(name.getNamespace().toString());
+            xmlWriter.writeStartElement(XMLConstants.DEFAULT_NS_PREFIX, nodeType.getLocalName(), namespace);
+            xmlWriter.writeDefaultNamespace(namespace);
             for (final NormalizedNode child : data.body()) {
                 nnWriter.write(child);
             }