Refactor EventFormatter interface 76/108876/3
authorRobert Varga <robert.varga@pantheon.tech>
Wed, 8 Nov 2023 00:52:48 +0000 (01:52 +0100)
committerRobert Varga <robert.varga@pantheon.tech>
Wed, 8 Nov 2023 10:14:17 +0000 (11:14 +0100)
We have some amount of method duplication and tangling. Move methods
around and clean them up.

JIRA: NETCONF-1102
Change-Id: Ica1af471d1c035142a77bfba14d94ebde624438a
Signed-off-by: Robert Varga <robert.varga@pantheon.tech>
restconf/restconf-nb/src/main/java/org/opendaylight/restconf/nb/rfc8040/streams/DataTreeCandidateFormatter.java
restconf/restconf-nb/src/main/java/org/opendaylight/restconf/nb/rfc8040/streams/EventFormatter.java
restconf/restconf-nb/src/main/java/org/opendaylight/restconf/nb/rfc8040/streams/JSONNotificationFormatter.java
restconf/restconf-nb/src/main/java/org/opendaylight/restconf/nb/rfc8040/streams/NotificationFormatter.java
restconf/restconf-nb/src/main/java/org/opendaylight/restconf/nb/rfc8040/streams/XMLNotificationFormatter.java

index 9ce5617601916d134f3d28b5c5eb9e661a205edc..ba85c107538d964fbe6b7ff9ba915ea8bf0243fa 100644 (file)
@@ -8,20 +8,17 @@
 package org.opendaylight.restconf.nb.rfc8040.streams;
 
 import java.io.IOException;
+import java.time.Instant;
 import java.util.List;
 import javax.xml.stream.XMLStreamException;
-import javax.xml.stream.XMLStreamWriter;
 import javax.xml.transform.dom.DOMResult;
 import javax.xml.xpath.XPathExpressionException;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.controller.md.sal.remote.rev140114.DataChangedNotification;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.controller.md.sal.remote.rev140114.data.changed.notification.DataChangeEvent;
-import org.opendaylight.yangtools.yang.data.api.schema.stream.NormalizedNodeStreamWriter;
-import org.opendaylight.yangtools.yang.data.api.schema.stream.NormalizedNodeWriter;
 import org.opendaylight.yangtools.yang.data.codec.xml.XMLStreamNormalizedNodeStreamWriter;
 import org.opendaylight.yangtools.yang.data.tree.api.DataTreeCandidate;
 import org.opendaylight.yangtools.yang.model.api.EffectiveModelContext;
 import org.w3c.dom.Document;
-import org.w3c.dom.Element;
 
 /**
  * Base formatter for DataTreeCandidates which only handles exporting to a document for filter checking purpose.
@@ -43,36 +40,28 @@ abstract class DataTreeCandidateFormatter extends EventFormatter<List<DataTreeCa
     @Override
     final void fillDocument(final Document doc, final EffectiveModelContext schemaContext,
             final List<DataTreeCandidate> input) throws IOException {
-        final Element notificationElement = NotificationFormatter.createNotificationElement(doc);
-        final Element notificationEventElement = doc.createElementNS(
-            DATA_CHANGED_NOTIFICATION_NS, DATA_CHANGED_NOTIFICATION_ELEMENT);
+        final var notificationElement = createNotificationElement(doc, Instant.now());
+        final var notificationEventElement = doc.createElementNS(DATA_CHANGED_NOTIFICATION_NS,
+            DATA_CHANGED_NOTIFICATION_ELEMENT);
 
-        for (DataTreeCandidate candidate : input) {
-            final Element dataChangedElement = doc.createElement(DATA_CHANGE_EVENT_ELEMENT);
+        for (var candidate : input) {
+            final var dataChangedElement = doc.createElement(DATA_CHANGE_EVENT_ELEMENT);
             try {
-                final Element dataElement = doc.createElement("data");
-                final DOMResult domResult = new DOMResult(dataElement);
-                final XMLStreamWriter writer = XML_OUTPUT_FACTORY.createXMLStreamWriter(domResult);
-
-                writeCandidate(XMLStreamNormalizedNodeStreamWriter.create(writer, schemaContext,
-                    candidate.getRootPath()), candidate);
-
+                final var dataElement = doc.createElement("data");
+                final var dataAfter = candidate.getRootNode().dataAfter();
+                if (dataAfter != null) {
+                    try (var writer = XMLStreamNormalizedNodeStreamWriter.create(
+                        XML_OUTPUT_FACTORY.createXMLStreamWriter(new DOMResult(dataElement)), schemaContext,
+                        candidate.getRootPath())) {
+                        writeBody(writer, dataAfter);
+                    }
+                }
                 dataChangedElement.appendChild(dataElement);
-            } catch (final XMLStreamException e) {
+            } catch (XMLStreamException e) {
                 throw new IOException("Failed to write notification content", e);
             }
             notificationElement.appendChild(notificationEventElement);
         }
         doc.appendChild(notificationElement);
     }
-
-    static void writeCandidate(final NormalizedNodeStreamWriter writer, final DataTreeCandidate candidate)
-            throws IOException {
-        final var dataAfter = candidate.getRootNode().dataAfter();
-        if (dataAfter != null) {
-            try (var nodeWriter = NormalizedNodeWriter.forStreamWriter(writer)) {
-                nodeWriter.write(dataAfter);
-            }
-        }
-    }
 }
index 95973653a6ce66815de5862beba833616ebda4c5..d5e2c5dfef955cfe69387c27759d1ac58e5832d8 100644 (file)
@@ -10,6 +10,7 @@ package org.opendaylight.restconf.nb.rfc8040.streams;
 import static java.util.Objects.requireNonNull;
 
 import java.io.IOException;
+import java.io.Writer;
 import java.time.Instant;
 import java.time.OffsetDateTime;
 import java.time.ZoneId;
@@ -18,6 +19,8 @@ import javax.xml.XMLConstants;
 import javax.xml.parsers.DocumentBuilderFactory;
 import javax.xml.parsers.ParserConfigurationException;
 import javax.xml.stream.XMLOutputFactory;
+import javax.xml.stream.XMLStreamException;
+import javax.xml.stream.XMLStreamWriter;
 import javax.xml.xpath.XPath;
 import javax.xml.xpath.XPathConstants;
 import javax.xml.xpath.XPathExpression;
@@ -25,9 +28,14 @@ import javax.xml.xpath.XPathExpressionException;
 import javax.xml.xpath.XPathFactory;
 import org.eclipse.jdt.annotation.NonNull;
 import org.eclipse.jdt.annotation.Nullable;
+import org.opendaylight.netconf.api.NamespaceURN;
 import org.opendaylight.yangtools.concepts.Immutable;
+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.api.schema.stream.NormalizedNodeWriter;
 import org.opendaylight.yangtools.yang.model.api.EffectiveModelContext;
 import org.w3c.dom.Document;
+import org.w3c.dom.Element;
 
 abstract class EventFormatter<T> implements Immutable {
     private static final XPathFactory XPF = XPathFactory.newInstance();
@@ -134,7 +142,35 @@ abstract class EventFormatter<T> implements Immutable {
      * @param now time stamp
      * @return Data specified by RFC3339.
      */
-    static String toRFC3339(final Instant now) {
+    static final String toRFC3339(final Instant now) {
         return DateTimeFormatter.ISO_OFFSET_DATE_TIME.format(OffsetDateTime.ofInstant(now, ZoneId.systemDefault()));
     }
+
+    static final @NonNull Element createNotificationElement(final Document doc, final Instant now) {
+        final var notificationElement = doc.createElementNS(NamespaceURN.NOTIFICATION, "notification");
+        final var eventTimeElement = doc.createElement("eventTime");
+        eventTimeElement.setTextContent(toRFC3339(now));
+        notificationElement.appendChild(eventTimeElement);
+        return notificationElement;
+    }
+
+    static final @NonNull XMLStreamWriter createStreamWriterWithNotification(final Writer writer, final Instant now)
+            throws XMLStreamException {
+        final var xmlStreamWriter = XML_OUTPUT_FACTORY.createXMLStreamWriter(writer);
+        xmlStreamWriter.setDefaultNamespace(NamespaceURN.NOTIFICATION);
+
+        xmlStreamWriter.writeStartElement(NamespaceURN.NOTIFICATION, "notification");
+        xmlStreamWriter.writeDefaultNamespace(NamespaceURN.NOTIFICATION);
+
+        xmlStreamWriter.writeStartElement("eventTime");
+        xmlStreamWriter.writeCharacters(toRFC3339(now));
+        xmlStreamWriter.writeEndElement();
+        return xmlStreamWriter;
+    }
+
+    static final void writeBody(final NormalizedNodeStreamWriter writer, final NormalizedNode body) throws IOException {
+        try (var nodeWriter = NormalizedNodeWriter.forStreamWriter(writer)) {
+            nodeWriter.write(body);
+        }
+    }
 }
index c61b12d8256abace217e6543e3c3841af838b229..6d215defab88c88734a5c14ebafe831b12ffef45 100644 (file)
@@ -56,7 +56,7 @@ final class JSONNotificationFormatter extends NotificationFormatter {
                 jsonWriter.beginObject()
                     .name(NOTIFICATION_NAME).beginObject()
                         .name("event-time").value(toRFC3339(now));
-                writeNotificationBody(JSONNormalizedNodeStreamWriter.createNestedWriter(
+                writeBody(JSONNormalizedNodeStreamWriter.createNestedWriter(
                     JSONCodecFactorySupplier.RFC7951.getShared(schemaContext), input.getType(), null, jsonWriter),
                     input.getBody());
                 jsonWriter.endObject().endObject();
index b774d93b3a56ca689f9ca66f19daf3fc5b96bde9..c009fd7f39677ae87a6d97ac5eeb0e73c93a8256 100644 (file)
@@ -8,27 +8,18 @@
 package org.opendaylight.restconf.nb.rfc8040.streams;
 
 import java.io.IOException;
-import java.io.Writer;
 import java.time.Instant;
 import javax.xml.stream.XMLStreamException;
-import javax.xml.stream.XMLStreamWriter;
 import javax.xml.transform.dom.DOMResult;
 import javax.xml.xpath.XPathExpressionException;
-import org.eclipse.jdt.annotation.NonNull;
 import org.opendaylight.mdsal.dom.api.DOMEvent;
 import org.opendaylight.mdsal.dom.api.DOMNotification;
-import org.opendaylight.netconf.api.NamespaceURN;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.controller.md.sal.remote.rev140114.CreateNotificationStream;
-import org.opendaylight.yangtools.yang.data.api.schema.ContainerNode;
-import org.opendaylight.yangtools.yang.data.api.schema.stream.NormalizedNodeStreamWriter;
-import org.opendaylight.yangtools.yang.data.api.schema.stream.NormalizedNodeWriter;
 import org.opendaylight.yangtools.yang.data.codec.xml.XMLStreamNormalizedNodeStreamWriter;
 import org.opendaylight.yangtools.yang.model.api.EffectiveModelContext;
 import org.w3c.dom.Document;
-import org.w3c.dom.Element;
 
 abstract class NotificationFormatter extends EventFormatter<DOMNotification> {
-    private static final String NOTIFICATION_ELEMENT = "notification";
     private static final String CREATE_NOTIFICATION_STREAM_ELEMENT = CreateNotificationStream.QNAME.getLocalName();
     private static final String CREATE_NOTIFICATION_STREAM_NS =
         CreateNotificationStream.QNAME.getNamespace().toString();
@@ -46,15 +37,15 @@ abstract class NotificationFormatter extends EventFormatter<DOMNotification> {
             throws IOException {
         final var notificationElement = createNotificationElement(doc,
             input instanceof DOMEvent domEvent ? domEvent.getEventInstant() : Instant.now());
+        // FIXME: what is this really?!
         final var notificationEventElement = doc.createElementNS(CREATE_NOTIFICATION_STREAM_NS,
             CREATE_NOTIFICATION_STREAM_ELEMENT);
-        final var dataElement = doc.createElement(NOTIFICATION_ELEMENT);
-        final DOMResult result = new DOMResult(dataElement);
+        final var dataElement = doc.createElement("notification");
         try {
-            final XMLStreamWriter writer = XML_OUTPUT_FACTORY.createXMLStreamWriter(result);
+            final var writer = XML_OUTPUT_FACTORY.createXMLStreamWriter(new DOMResult(dataElement));
             try {
-                writeNotificationBody(XMLStreamNormalizedNodeStreamWriter.create(writer, schemaContext,
-                        input.getType()), input.getBody());
+                writeBody(XMLStreamNormalizedNodeStreamWriter.create(writer, schemaContext, input.getType()),
+                    input.getBody());
             } finally {
                 writer.close();
             }
@@ -64,43 +55,4 @@ abstract class NotificationFormatter extends EventFormatter<DOMNotification> {
         notificationElement.appendChild(notificationEventElement);
         doc.appendChild(notificationElement);
     }
-
-    static void writeNotificationBody(final NormalizedNodeStreamWriter writer, final ContainerNode body)
-            throws IOException {
-        try (NormalizedNodeWriter nodeWriter = NormalizedNodeWriter.forStreamWriter(writer)) {
-            nodeWriter.write(body);
-        }
-    }
-
-    /**
-     * Generating base element of every notification.
-     *
-     * @param doc base {@link Document}
-     * @return element of {@link Document}
-     */
-    static @NonNull Element createNotificationElement(final Document doc) {
-        return createNotificationElement(doc, Instant.now());
-    }
-
-    static @NonNull Element createNotificationElement(final Document doc, final Instant now) {
-        final var notificationElement = doc.createElementNS(NamespaceURN.NOTIFICATION, NOTIFICATION_ELEMENT);
-        final Element eventTimeElement = doc.createElement("eventTime");
-        eventTimeElement.setTextContent(toRFC3339(now));
-        notificationElement.appendChild(eventTimeElement);
-        return notificationElement;
-    }
-
-    static @NonNull XMLStreamWriter createStreamWriterWithNotification(final Writer writer, final Instant now)
-            throws XMLStreamException {
-        final var xmlStreamWriter = XML_OUTPUT_FACTORY.createXMLStreamWriter(writer);
-        xmlStreamWriter.setDefaultNamespace(NamespaceURN.NOTIFICATION);
-
-        xmlStreamWriter.writeStartElement(NamespaceURN.NOTIFICATION, NOTIFICATION_ELEMENT);
-        xmlStreamWriter.writeDefaultNamespace(NamespaceURN.NOTIFICATION);
-
-        xmlStreamWriter.writeStartElement("eventTime");
-        xmlStreamWriter.writeCharacters(toRFC3339(now));
-        xmlStreamWriter.writeEndElement();
-        return xmlStreamWriter;
-    }
 }
index 30ca670ddbcaccde611e3cb5a8c5574bc469cf29..43e518b8012718d0bfdb8b0f4ad72ef8965e52f9 100644 (file)
@@ -50,10 +50,8 @@ final class XMLNotificationFormatter extends NotificationFormatter {
 
         try {
             final var xmlStreamWriter = NotificationFormatter.createStreamWriterWithNotification(writer, now);
-            final var nnStreamWriter = XMLStreamNormalizedNodeStreamWriter.create(xmlStreamWriter, schemaContext,
-                input.getType());
-
-            try (var nnWriter = NormalizedNodeWriter.forStreamWriter(nnStreamWriter)) {
+            try (var nnWriter = NormalizedNodeWriter.forStreamWriter(XMLStreamNormalizedNodeStreamWriter.create(
+                    xmlStreamWriter, schemaContext, input.getType()))) {
                 nnWriter.write(input.getBody());
                 nnWriter.flush();