X-Git-Url: https://git.opendaylight.org/gerrit/gitweb?a=blobdiff_plain;f=netconf%2Fnetconf-util%2Fsrc%2Fmain%2Fjava%2Forg%2Fopendaylight%2Fnetconf%2Futil%2FNetconfUtil.java;h=2bf085609283c0ec2d058c8eb2b176a0f374a28c;hb=197acb99bed8c585e26091eafb761481533718a0;hp=3bf93f8d01068dc142c9de68ff7efdef9a45caba;hpb=e8de1c930945535751e3ad0b8569d70ec91a6245;p=netconf.git diff --git a/netconf/netconf-util/src/main/java/org/opendaylight/netconf/util/NetconfUtil.java b/netconf/netconf-util/src/main/java/org/opendaylight/netconf/util/NetconfUtil.java index 3bf93f8d01..2bf0856092 100644 --- a/netconf/netconf-util/src/main/java/org/opendaylight/netconf/util/NetconfUtil.java +++ b/netconf/netconf-util/src/main/java/org/opendaylight/netconf/util/NetconfUtil.java @@ -9,6 +9,7 @@ package org.opendaylight.netconf.util; import static com.google.common.base.Preconditions.checkState; +import com.google.common.collect.ImmutableMap; import java.io.IOException; import java.net.URISyntaxException; import java.util.Iterator; @@ -49,6 +50,45 @@ import org.w3c.dom.Document; import org.xml.sax.SAXException; public final class NetconfUtil { + /** + * Shim interface to handle differences around namespace handling between various XMLStreamWriter implementations. + * Specifically: + * + * + *

+ * Due to this we perform a quick test for behavior and decide the appropriate strategy. + */ + @FunctionalInterface + private interface NamespaceSetter { + void initializeNamespace(XMLStreamWriter writer) throws XMLStreamException; + + static NamespaceSetter forFactory(final XMLOutputFactory xmlFactory) { + final String netconfNamespace = NETCONF_QNAME.getNamespace().toString(); + final AnyXmlNamespaceContext namespaceContext = new AnyXmlNamespaceContext(ImmutableMap.of( + "op", netconfNamespace)); + + try { + final XMLStreamWriter testWriter = xmlFactory.createXMLStreamWriter(new DOMResult( + XmlUtil.newDocument())); + testWriter.setNamespaceContext(namespaceContext); + } catch (final UnsupportedOperationException e) { + // This happens with JDK's DOM writer, which we may be using + LOG.warn("Unable to set namespace context, falling back to setPrefix()", e); + return writer -> writer.setPrefix("op", netconfNamespace); + } catch (XMLStreamException e) { + throw new ExceptionInInitializerError(e); + } + + // Success, we can use setNamespaceContext() + return writer -> writer.setNamespaceContext(namespaceContext); + } + } + private static final Logger LOG = LoggerFactory.getLogger(NetconfUtil.class); // FIXME: document what exactly this QName means, as it is not referring to a tangible node nor the ietf-module. @@ -60,6 +100,7 @@ public final class NetconfUtil { Revision.of("2011-06-01")), "netconf").intern(); // FIXME: is this the device-bound revision? public static final QName NETCONF_DATA_QNAME = QName.create(NETCONF_QNAME, "data").intern(); + public static final XMLOutputFactory XML_FACTORY; static { @@ -69,6 +110,8 @@ public final class NetconfUtil { XML_FACTORY = f; } + private static final NamespaceSetter XML_NAMESPACE_SETTER = NamespaceSetter.forFactory(XML_FACTORY); + private NetconfUtil() { // No-op } @@ -123,6 +166,7 @@ public final class NetconfUtil { } final XMLStreamWriter writer = XML_FACTORY.createXMLStreamWriter(result); + XML_NAMESPACE_SETTER.initializeNamespace(writer); try ( NormalizedNodeStreamWriter normalizedNodeStreamWriter = XMLStreamNormalizedNodeStreamWriter.create(writer, context, schemaPath);