Refactor implementations to hide XMLStreamWriter
[yangtools.git] / yang / yang-data-codec-xml / src / main / java / org / opendaylight / yangtools / yang / data / codec / xml / XMLStreamNormalizedNodeStreamWriter.java
index 52925eaf1b65b37cc9e2f9dc729ff250e369a5ea..55e4e93b243bd439326b77b7bd459e2e308aa9b3 100644 (file)
@@ -18,8 +18,6 @@ import java.util.Map;
 import java.util.Map.Entry;
 import java.util.Set;
 import java.util.concurrent.ConcurrentHashMap;
-import javax.annotation.Nonnull;
-import javax.annotation.Nullable;
 import javax.xml.XMLConstants;
 import javax.xml.namespace.NamespaceContext;
 import javax.xml.stream.XMLStreamException;
@@ -32,6 +30,8 @@ import javax.xml.transform.TransformerFactoryConfigurationError;
 import javax.xml.transform.dom.DOMSource;
 import javax.xml.transform.stax.StAXResult;
 import javax.xml.transform.stream.StreamResult;
+import org.eclipse.jdt.annotation.NonNull;
+import org.eclipse.jdt.annotation.Nullable;
 import org.opendaylight.yangtools.yang.common.QName;
 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeIdentifier;
 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeIdentifierWithPredicates;
@@ -56,7 +56,7 @@ public abstract class XMLStreamNormalizedNodeStreamWriter<T> implements Normaliz
     private static final String COM_SUN_TRANSFORMER =
         "com.sun.org.apache.xalan.internal.xsltc.trax.TransformerFactoryImpl";
 
-    private static final TransformerFactory TRANSFORMER_FACTORY;
+    static final TransformerFactory TRANSFORMER_FACTORY;
 
     static {
         TransformerFactory fa = TransformerFactory.newInstance();
@@ -74,8 +74,8 @@ public abstract class XMLStreamNormalizedNodeStreamWriter<T> implements Normaliz
 
     private static final Set<String> BROKEN_NAMESPACES = ConcurrentHashMap.newKeySet();
 
+    private final @NonNull XMLStreamWriter writer;
     private final RandomPrefix prefixes;
-    final XMLStreamWriter writer;
 
     XMLStreamNormalizedNodeStreamWriter(final XMLStreamWriter writer) {
         this.writer = requireNonNull(writer);
@@ -102,9 +102,9 @@ public abstract class XMLStreamNormalizedNodeStreamWriter<T> implements Normaliz
      *
      * @return A new {@link NormalizedNodeStreamWriter}
      */
-    public static NormalizedNodeStreamWriter create(final XMLStreamWriter writer, final SchemaContext context,
+    public static @NonNull NormalizedNodeStreamWriter create(final XMLStreamWriter writer, final SchemaContext context,
             final SchemaPath path) {
-        return SchemaAwareXMLStreamNormalizedNodeStreamWriter.newInstance(writer, context, path);
+        return new SchemaAwareXMLStreamNormalizedNodeStreamWriter(writer, context, path);
     }
 
     /**
@@ -115,18 +115,18 @@ public abstract class XMLStreamNormalizedNodeStreamWriter<T> implements Normaliz
      *
      * @return A new {@link NormalizedNodeStreamWriter}
      */
-    public static NormalizedNodeStreamWriter createSchemaless(final XMLStreamWriter writer) {
-        return SchemalessXMLStreamNormalizedNodeStreamWriter.newInstance(writer);
+    public static @NonNull NormalizedNodeStreamWriter createSchemaless(final XMLStreamWriter writer) {
+        return new SchemalessXMLStreamNormalizedNodeStreamWriter(writer);
     }
 
-    abstract void writeValue(XMLStreamWriter xmlWriter, QName qname, @Nonnull Object value, T context)
+    abstract void writeValue(@NonNull XMLStreamWriter xmlWriter, QName qname, @NonNull Object value, T context)
             throws IOException, XMLStreamException;
 
     abstract void startList(NodeIdentifier name);
 
     abstract void startListItem(PathArgument name) throws IOException;
 
-    private void writeAttributes(@Nonnull final Map<QName, String> attributes) throws IOException {
+    private void writeAttributes(final @NonNull Map<QName, String> attributes) throws IOException {
         for (final Entry<QName, String> entry : attributes.entrySet()) {
             try {
                 final QName qname = entry.getKey();
@@ -161,22 +161,30 @@ public abstract class XMLStreamNormalizedNodeStreamWriter<T> implements Normaliz
     }
 
     private void writeStartElement(final QName qname) throws XMLStreamException {
-        String ns = qname.getNamespace().toString();
+        final String ns = qname.getNamespace().toString();
+        final NamespaceContext context = writer.getNamespaceContext();
+        final boolean needDefaultNs;
+        if (context != null) {
+            final String parentNs = context.getNamespaceURI(XMLConstants.DEFAULT_NS_PREFIX);
+            needDefaultNs = !ns.equals(parentNs);
+        } else {
+            needDefaultNs = false;
+        }
+
         writer.writeStartElement(XMLConstants.DEFAULT_NS_PREFIX, qname.getLocalName(), ns);
-        if (writer.getNamespaceContext() != null) {
-            String parentNs = writer.getNamespaceContext().getNamespaceURI(XMLConstants.DEFAULT_NS_PREFIX);
-            if (!ns.equals(parentNs)) {
-                writer.writeDefaultNamespace(ns);
-            }
+        if (needDefaultNs) {
+            writer.writeDefaultNamespace(ns);
         }
     }
 
-    void writeElement(final QName qname, final Object value, @Nullable final Map<QName, String> attributes,
+    final void writeElement(final QName qname, final Object value, final @Nullable Map<QName, String> attributes,
             final T context) throws IOException {
         try {
             writeStartElement(qname);
 
-            writeAttributes(attributes);
+            if (attributes != null) {
+                writeAttributes(attributes);
+            }
             if (value != null) {
                 writeValue(writer, qname, value, context);
             }
@@ -186,7 +194,7 @@ public abstract class XMLStreamNormalizedNodeStreamWriter<T> implements Normaliz
         }
     }
 
-    void startElement(final QName qname) throws IOException {
+    final void startElement(final QName qname) throws IOException {
         try {
             writeStartElement(qname);
         } catch (XMLStreamException e) {
@@ -194,7 +202,15 @@ public abstract class XMLStreamNormalizedNodeStreamWriter<T> implements Normaliz
         }
     }
 
-    void anyxmlNode(final QName qname, final Object value) throws IOException {
+    final void endElement() throws IOException {
+        try {
+            writer.writeEndElement();
+        } catch (XMLStreamException e) {
+            throw new IOException("Failed to end element", e);
+        }
+    }
+
+    final void anyxmlNode(final QName qname, final Object value) throws IOException {
         if (value != null) {
             checkArgument(value instanceof DOMSource, "AnyXML value must be DOMSource, not %s", value);
             final DOMSource domSource = (DOMSource) value;
@@ -270,7 +286,7 @@ public abstract class XMLStreamNormalizedNodeStreamWriter<T> implements Normaliz
 
     public static String toString(final Element xml) {
         try {
-            final Transformer transformer = TransformerFactory.newInstance().newTransformer();
+            final Transformer transformer = TRANSFORMER_FACTORY.newTransformer();
             transformer.setOutputProperty(OutputKeys.INDENT, "yes");
 
             final StreamResult result = new StreamResult(new StringWriter());
@@ -278,19 +294,8 @@ public abstract class XMLStreamNormalizedNodeStreamWriter<T> implements Normaliz
             transformer.transform(source, result);
 
             return result.getWriter().toString();
-        } catch (IllegalArgumentException | TransformerFactoryConfigurationError | TransformerException e) {
-            throw new RuntimeException("Unable to serialize xml element " + xml, e);
-        }
-    }
-
-    abstract void endNode(XMLStreamWriter xmlWriter) throws IOException, XMLStreamException;
-
-    @Override
-    public final void endNode() throws IOException {
-        try {
-            endNode(writer);
-        } catch (XMLStreamException e) {
-            throw new IOException("Failed to end element", e);
+        } catch (IllegalArgumentException | TransformerException e) {
+            throw new IllegalStateException("Unable to serialize xml element " + xml, e);
         }
     }