Switch XML value encoding 64/81364/2
authorRobert Varga <robert.varga@pantheon.tech>
Thu, 4 Apr 2019 00:46:01 +0000 (02:46 +0200)
committerRobert Varga <robert.varga@pantheon.tech>
Thu, 4 Apr 2019 05:19:27 +0000 (07:19 +0200)
Rather than directly emitting the value, this reworks the patch
to return it encoded. This will be important when we are writing
out annotations.

JIRA: YANGTOOLS-961
Change-Id: I81c970d3b215514059b3d12ffa9c5a9ad5ba986b
Signed-off-by: Robert Varga <robert.varga@pantheon.tech>
yang/yang-data-codec-xml/src/main/java/org/opendaylight/yangtools/yang/data/codec/xml/SchemaAwareXMLStreamNormalizedNodeStreamWriter.java
yang/yang-data-codec-xml/src/main/java/org/opendaylight/yangtools/yang/data/codec/xml/SchemaAwareXMLStreamWriterUtils.java
yang/yang-data-codec-xml/src/main/java/org/opendaylight/yangtools/yang/data/codec/xml/SchemalessXMLStreamNormalizedNodeStreamWriter.java
yang/yang-data-codec-xml/src/main/java/org/opendaylight/yangtools/yang/data/codec/xml/SchemalessXMLStreamWriterUtils.java
yang/yang-data-codec-xml/src/main/java/org/opendaylight/yangtools/yang/data/codec/xml/StreamWriterFacade.java
yang/yang-data-codec-xml/src/main/java/org/opendaylight/yangtools/yang/data/codec/xml/ValueWriter.java
yang/yang-data-codec-xml/src/main/java/org/opendaylight/yangtools/yang/data/codec/xml/XMLStreamNormalizedNodeStreamWriter.java
yang/yang-data-codec-xml/src/main/java/org/opendaylight/yangtools/yang/data/codec/xml/XMLStreamWriterUtils.java
yang/yang-data-codec-xml/src/test/java/org/opendaylight/yangtools/yang/data/codec/xml/XmlStreamUtilsTest.java

index 71c86321808d62fac3675f497c6f21463edcbb7b..a13a1646e6e18c4a4c2b62799520bb04c64d5762 100644 (file)
@@ -42,9 +42,9 @@ final class SchemaAwareXMLStreamNormalizedNodeStreamWriter extends XMLStreamNorm
     }
 
     @Override
-    void writeValue(final ValueWriter xmlWriter, final Object value, final SchemaNode schemaNode)
+    String encodeValue(final ValueWriter xmlWriter, final Object value, final SchemaNode schemaNode)
             throws XMLStreamException {
-        streamUtils.writeValue(xmlWriter, schemaNode, value, schemaNode.getQName().getModule());
+        return streamUtils.encodeValue(xmlWriter, schemaNode, value, schemaNode.getQName().getModule());
     }
 
     @Override
index 50b17342e3eb979fbfb809448d39694adc9d2d4e..fe7168ad06b00edaa8fedc38670fd131c7e7cfd5 100644 (file)
@@ -36,7 +36,7 @@ final class SchemaAwareXMLStreamWriterUtils extends XMLStreamWriterUtils impleme
     }
 
     @Override
-    void writeInstanceIdentifier(final ValueWriter writer, final YangInstanceIdentifier value)
+    String encodeInstanceIdentifier(final ValueWriter writer, final YangInstanceIdentifier value)
             throws XMLStreamException {
         RandomPrefixInstanceIdentifierSerializer iiCodec = new RandomPrefixInstanceIdentifierSerializer(schemaContext,
             writer.getNamespaceContext());
@@ -46,7 +46,7 @@ final class SchemaAwareXMLStreamWriterUtils extends XMLStreamWriterUtils impleme
             writer.writeNamespace(e.getValue(), e.getKey().toString());
         }
 
-        writer.writeCharacters(serializedValue);
+        return serializedValue;
     }
 
     @Override
index 8668bfe677b89646f7be956848c2cbb4c8ac7f96..99186071ef231cc667b9f0556a4860aa06792dd6 100644 (file)
@@ -12,7 +12,6 @@ import static com.google.common.base.Preconditions.checkState;
 import java.io.IOException;
 import java.util.ArrayDeque;
 import java.util.Deque;
-import javax.xml.stream.XMLStreamException;
 import javax.xml.stream.XMLStreamWriter;
 import javax.xml.transform.dom.DOMSource;
 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.AugmentationIdentifier;
@@ -90,8 +89,8 @@ final class SchemalessXMLStreamNormalizedNodeStreamWriter extends XMLStreamNorma
     }
 
     @Override
-    void writeValue(final ValueWriter xmlWriter, final Object value, final Object context) throws XMLStreamException {
-        xmlWriter.writeToStringCharacters(value);
+    String encodeValue(final ValueWriter xmlWriter, final Object value, final Object context) {
+        return value.toString();
     }
 
     @Override
index af93de8427790747238e10cb99b67d52da34fb38..75633278121b06768de88c19194ee849b09166d0 100644 (file)
@@ -25,7 +25,7 @@ final class SchemalessXMLStreamWriterUtils extends XMLStreamWriterUtils {
     }
 
     @Override
-    void writeInstanceIdentifier(final ValueWriter writer, final YangInstanceIdentifier value) {
+    String encodeInstanceIdentifier(final ValueWriter writer, final YangInstanceIdentifier value) {
         throw new UnsupportedOperationException("Schema context not present in " + this + ", cannot serialize "
             + value);
     }
index f0660fc4f23f940a165f060337ad55ff7cb7d2b1..a7f27eb69979ca9a9e2beb318e8097d49ad4d0e4 100644 (file)
@@ -44,7 +44,6 @@ final class StreamWriterFacade extends ValueWriter {
         prefixes = new RandomPrefix(writer.getNamespaceContext());
     }
 
-    @Override
     void writeCharacters(final String text) throws XMLStreamException {
         if (!Strings.isNullOrEmpty(text)) {
             flushElement();
index ed25e7dcedf5c86168c8d9faf2c0490bd08a9cc6..592f3a370f145895ca905f01e91d1fccf5ae08cd 100644 (file)
@@ -10,7 +10,6 @@ package org.opendaylight.yangtools.yang.data.codec.xml;
 import javax.xml.namespace.NamespaceContext;
 import javax.xml.stream.XMLStreamException;
 import javax.xml.stream.XMLStreamWriter;
-import org.eclipse.jdt.annotation.NonNull;
 
 /**
  * A minimal facade for exposing just enough information from {@link XMLStreamWriter} for the purposes of encoding
@@ -21,9 +20,6 @@ import org.eclipse.jdt.annotation.NonNull;
  * See XMLStreamWriter for description of methods.
  */
 abstract class ValueWriter {
-    // Additionally ignores null/empty
-    abstract void writeCharacters(String text) throws XMLStreamException;
-
     abstract void writeNamespace(String prefix, String namespaceURI) throws XMLStreamException;
 
     abstract void writeAttribute(String localName, String value) throws XMLStreamException;
@@ -33,9 +29,4 @@ abstract class ValueWriter {
 
     // Note: lookup results may change if there is other interaction
     abstract NamespaceContext getNamespaceContext();
-
-    // Utility shortcut
-    final void writeToStringCharacters(final @NonNull Object obj) throws XMLStreamException {
-        writeCharacters(obj.toString());
-    }
 }
index 6d0302c70e07deb4b618127b28aad9f5a2621c0a..a6c5ffd57b9fd55b715b7fb1069920f7e36407c8 100644 (file)
@@ -95,12 +95,12 @@ public abstract class XMLStreamNormalizedNodeStreamWriter<T> implements Normaliz
 
     abstract void startListItem(PathArgument name) throws IOException;
 
-    abstract void writeValue(@NonNull ValueWriter xmlWriter, @NonNull Object value, T context)
+    abstract String encodeValue(@NonNull ValueWriter xmlWriter, @NonNull Object value, T context)
             throws XMLStreamException;
 
     final void writeValue(final @NonNull Object value, final T context) throws IOException {
         try {
-            writeValue(facade, value, context);
+            facade.writeCharacters(encodeValue(facade, value, context));
         } catch (XMLStreamException e) {
             throw new IOException("Failed to write value", e);
         }
index ff86e2e7987281c55803ecda471dd29daf012dd4..8e3ce1aff7839d6cbdd86b82d35d6ec0b12e3f64 100644 (file)
@@ -40,9 +40,10 @@ abstract class XMLStreamWriterUtils {
      * @param schemaNode Schema node that describes the value
      * @param value data value
      * @param parent module QName owning the leaf definition
+     * @return String characters to be written
      * @throws XMLStreamException if an encoding problem occurs
      */
-    void writeValue(final @NonNull ValueWriter writer, final @NonNull SchemaNode schemaNode,
+    String encodeValue(final @NonNull ValueWriter writer, final @NonNull SchemaNode schemaNode,
             final @NonNull Object value, final QNameModule parent) throws XMLStreamException {
         checkArgument(schemaNode instanceof TypedDataSchemaNode,
             "Unable to write value for node %s, only nodes of type: leaf and leaf-list can be written at this point",
@@ -53,7 +54,7 @@ abstract class XMLStreamWriterUtils {
             type = getBaseTypeForLeafRef(schemaNode, (LeafrefTypeDefinition) type);
         }
 
-        writeValue(writer, type, value, parent);
+        return encodeValue(writer, type, value, parent);
     }
 
     /**
@@ -64,16 +65,17 @@ abstract class XMLStreamWriterUtils {
      * @param type data type. In case of leaf ref this should be the type of leaf being referenced
      * @param value data value
      * @param parent optional parameter of a module QName owning the leaf definition
+     * @return String characters to be written
      * @throws XMLStreamException if an encoding problem occurs
      */
-    private void writeValue(final @NonNull ValueWriter writer, final @NonNull TypeDefinition<?> type,
+    private String encodeValue(final @NonNull ValueWriter writer, final @NonNull TypeDefinition<?> type,
             final @NonNull Object value, final QNameModule parent) throws XMLStreamException {
         if (type instanceof IdentityrefTypeDefinition) {
-            write(writer, (IdentityrefTypeDefinition) type, value, parent);
+            return encode(writer, (IdentityrefTypeDefinition) type, value, parent);
         } else if (type instanceof InstanceIdentifierTypeDefinition) {
-            write(writer, (InstanceIdentifierTypeDefinition) type, value);
+            return encode(writer, (InstanceIdentifierTypeDefinition) type, value);
         } else {
-            writer.writeCharacters(serialize(type, value));
+            return serialize(type, value);
         }
     }
 
@@ -94,43 +96,42 @@ abstract class XMLStreamWriterUtils {
     }
 
     @VisibleForTesting
-    static void write(final @NonNull ValueWriter writer, final @NonNull IdentityrefTypeDefinition type,
+    static String encode(final @NonNull ValueWriter writer, final @NonNull IdentityrefTypeDefinition type,
             final @NonNull Object value, final QNameModule parent) throws XMLStreamException {
         if (value instanceof QName) {
             final QName qname = (QName) value;
 
             //in case parent is present and same as element namespace write value without namespace
             if (qname.getNamespace().equals(parent.getNamespace())) {
-                writer.writeCharacters(qname.getLocalName());
-            } else {
-                final String ns = qname.getNamespace().toString();
-                final String prefix = "x";
-                writer.writeNamespace(prefix, ns);
-                writer.writeCharacters(prefix + ':' + qname.getLocalName());
+                return qname.getLocalName();
             }
-        } else {
-            final QName qname = type.getQName();
-            LOG.debug("Value of {}:{} is not a QName but {}", qname.getNamespace(), qname.getLocalName(),
-                value.getClass());
-            writer.writeToStringCharacters(value);
+
+            final String ns = qname.getNamespace().toString();
+            final String prefix = "x";
+            writer.writeNamespace(prefix, ns);
+            return prefix + ':' + qname.getLocalName();
         }
+
+        final QName qname = type.getQName();
+        LOG.debug("Value of {}:{} is not a QName but {}", qname.getNamespace(), qname.getLocalName(), value.getClass());
+        return value.toString();
     }
 
-    private void write(final @NonNull ValueWriter writer, final @NonNull InstanceIdentifierTypeDefinition type,
+    private String encode(final @NonNull ValueWriter writer, final @NonNull InstanceIdentifierTypeDefinition type,
             final @NonNull Object value) throws XMLStreamException {
         if (value instanceof YangInstanceIdentifier) {
-            writeInstanceIdentifier(writer, (YangInstanceIdentifier)value);
-        } else {
-            final QName qname = type.getQName();
-            LOG.warn("Value of {}:{} is not an InstanceIdentifier but {}", qname.getNamespace(), qname.getLocalName(),
-                value.getClass());
-            writer.writeToStringCharacters(value);
+            return encodeInstanceIdentifier(writer, (YangInstanceIdentifier)value);
         }
+
+        final QName qname = type.getQName();
+        LOG.warn("Value of {}:{} is not an InstanceIdentifier but {}", qname.getNamespace(), qname.getLocalName(),
+            value.getClass());
+        return value.toString();
     }
 
     abstract @NonNull TypeDefinition<?> getBaseTypeForLeafRef(SchemaNode schemaNode,
             @NonNull LeafrefTypeDefinition type);
 
-    abstract void writeInstanceIdentifier(@NonNull ValueWriter writer, YangInstanceIdentifier value)
+    abstract String encodeInstanceIdentifier(@NonNull ValueWriter writer, YangInstanceIdentifier value)
             throws XMLStreamException;
 }
index 22fdf1daf6e46419b4a1f9fc2eb221cc4d5662d3..569a0438f480c1a306c259b790138b2bbccf2565 100644 (file)
@@ -73,7 +73,7 @@ public class XmlStreamUtilsTest {
         String xmlAsString = createXml(writer -> {
             writer.writeStartElement("element");
             final StreamWriterFacade facade = new StreamWriterFacade(writer);
-            XMLStreamWriterUtils.write(facade, null, QName.create(parent, "identity"), parent);
+            facade.writeCharacters(XMLStreamWriterUtils.encode(facade, null, QName.create(parent, "identity"), parent));
             facade.flush();
             writer.writeEndElement();
         });
@@ -83,7 +83,8 @@ public class XmlStreamUtilsTest {
         xmlAsString = createXml(writer -> {
             writer.writeStartElement("elementDifferent");
             final StreamWriterFacade facade = new StreamWriterFacade(writer);
-            XMLStreamWriterUtils.write(facade, null, QName.create("different:namespace", "identity"), parent);
+            facade.writeCharacters(XMLStreamWriterUtils.encode(facade, null, QName.create("different:namespace",
+                "identity"), parent));
             facade.flush();
             writer.writeEndElement();
         });