Refactor EventFormatter interface 36/107736/3
authorRobert Varga <robert.varga@pantheon.tech>
Wed, 6 Sep 2023 19:58:29 +0000 (21:58 +0200)
committerRobert Varga <robert.varga@pantheon.tech>
Wed, 6 Sep 2023 20:57:45 +0000 (22:57 +0200)
We are passing a ton of parameters around, where they are really state
captured in EventFormatter, but passed to AbstractWebsocketSerializer.

Split the four booleans we dance around into a separate TextParameters
record, which gets stored in each EventFormatter and passed to the
serializer as appropriate.

Change-Id: Ifa19e99f18a20c705e37ed0135982af9b50da755
Signed-off-by: Robert Varga <robert.varga@pantheon.tech>
17 files changed:
restconf/restconf-nb/src/main/java/org/opendaylight/restconf/nb/rfc8040/streams/listeners/AbstractCommonSubscriber.java
restconf/restconf-nb/src/main/java/org/opendaylight/restconf/nb/rfc8040/streams/listeners/AbstractNotificationListenerAdaptor.java
restconf/restconf-nb/src/main/java/org/opendaylight/restconf/nb/rfc8040/streams/listeners/AbstractWebsocketSerializer.java
restconf/restconf-nb/src/main/java/org/opendaylight/restconf/nb/rfc8040/streams/listeners/DataTreeCandidateFormatter.java
restconf/restconf-nb/src/main/java/org/opendaylight/restconf/nb/rfc8040/streams/listeners/DataTreeCandidateFormatterFactory.java
restconf/restconf-nb/src/main/java/org/opendaylight/restconf/nb/rfc8040/streams/listeners/EventFormatter.java
restconf/restconf-nb/src/main/java/org/opendaylight/restconf/nb/rfc8040/streams/listeners/EventFormatterFactory.java
restconf/restconf-nb/src/main/java/org/opendaylight/restconf/nb/rfc8040/streams/listeners/JSONDataTreeCandidateFormatter.java
restconf/restconf-nb/src/main/java/org/opendaylight/restconf/nb/rfc8040/streams/listeners/JSONNotificationFormatter.java
restconf/restconf-nb/src/main/java/org/opendaylight/restconf/nb/rfc8040/streams/listeners/ListenerAdapter.java
restconf/restconf-nb/src/main/java/org/opendaylight/restconf/nb/rfc8040/streams/listeners/NotificationFormatter.java
restconf/restconf-nb/src/main/java/org/opendaylight/restconf/nb/rfc8040/streams/listeners/NotificationFormatterFactory.java
restconf/restconf-nb/src/main/java/org/opendaylight/restconf/nb/rfc8040/streams/listeners/TextParameters.java [new file with mode: 0644]
restconf/restconf-nb/src/main/java/org/opendaylight/restconf/nb/rfc8040/streams/listeners/XMLDataTreeCandidateFormatter.java
restconf/restconf-nb/src/main/java/org/opendaylight/restconf/nb/rfc8040/streams/listeners/XMLNotificationFormatter.java
restconf/restconf-nb/src/test/java/org/opendaylight/restconf/nb/rfc8040/streams/listeners/JsonNotificationListenerTest.java
restconf/restconf-nb/src/test/java/org/opendaylight/restconf/nb/rfc8040/streams/listeners/XmlNotificationListenerTest.java

index 9cbae2d7ca77787ac198fb8cdf74b61e58c9ebd9..ccbd86c395bdcb9605013560970ce74600f6eca1 100644 (file)
@@ -61,13 +61,9 @@ abstract class AbstractCommonSubscriber<T> extends AbstractNotificationsData imp
     private Registration registration;
 
     // FIXME: these should be final
+    private @NonNull EventFormatter<T> formatter;
     private Instant start = null;
     private Instant stop = null;
-    private boolean leafNodesOnly = false;
-    private boolean skipNotificationData = false;
-    private boolean changedLeafNodesOnly = false;
-    private boolean childNodesOnly = false;
-    private EventFormatter<T> formatter;
 
     AbstractCommonSubscriber(final String streamName, final NotificationOutputType outputType,
             final EventFormatterFactory<T> formatterFactory) {
@@ -76,7 +72,7 @@ abstract class AbstractCommonSubscriber<T> extends AbstractNotificationsData imp
 
         this.outputType = requireNonNull(outputType);
         this.formatterFactory = requireNonNull(formatterFactory);
-        formatter = formatterFactory.getFormatter();
+        formatter = formatterFactory.emptyFormatter();
     }
 
     @Override
@@ -143,67 +139,35 @@ abstract class AbstractCommonSubscriber<T> extends AbstractNotificationsData imp
         stop = stopTime == null ? null : parseDateAndTime(stopTime.value());
 
         final var leafNodes = params.leafNodesOnly();
-        leafNodesOnly = leafNodes != null && leafNodes.value();
-
         final var skipData = params.skipNotificationData();
-        skipNotificationData = skipData != null && skipData.value();
-
         final var changedLeafNodes = params.changedLeafNodesOnly();
-        changedLeafNodesOnly = changedLeafNodes != null && changedLeafNodes.value();
-
         final var childNodes = params.childNodesOnly();
-        childNodesOnly = childNodes != null && childNodes.value();
+
+        final var textParams = new TextParameters(
+            leafNodes != null && leafNodes.value(),
+            skipData != null && skipData.value(),
+            changedLeafNodes != null && changedLeafNodes.value(),
+            childNodes != null && childNodes.value());
 
         final var filter = params.filter();
-        final String filterValue = filter == null ? null : filter.paramValue();
+        final var filterValue = filter == null ? null : filter.paramValue();
+
+        final EventFormatter<T> newFormatter;
         if (filterValue != null && !filterValue.isEmpty()) {
             try {
-                formatter = formatterFactory.getFormatter(filterValue);
+                newFormatter = formatterFactory.getFormatter(textParams, filterValue);
             } catch (XPathExpressionException e) {
                 throw new IllegalArgumentException("Failed to get filter", e);
             }
         } else {
-            formatter = formatterFactory.getFormatter();
+            newFormatter = formatterFactory.getFormatter(textParams);
         }
-    }
-
-    /**
-     * Check whether this query should only notify about leaf node changes.
-     *
-     * @return true if this query should only notify about leaf node changes
-     */
-    final boolean getLeafNodesOnly() {
-        return leafNodesOnly;
-    }
-
-    /**
-     * Check whether this query should only notify about leaf node changes and report only changed nodes.
-     *
-     * @return true if this query should only notify about leaf node changes and report only changed nodes
-     */
-    final boolean getChangedLeafNodesOnly() {
-        return changedLeafNodesOnly;
-    }
-
-    /**
-     * Check whether this query should notify changes without data.
-     *
-     * @return true if this query should notify about changes with  data
-     */
-    final boolean isSkipNotificationData() {
-        return skipNotificationData;
-    }
 
-    /**
-     * Check whether this query should only notify about child node changes.
-     *
-     * @return true if this query should only notify about child node changes
-     */
-    final boolean getChildNodesOnly() {
-        return childNodesOnly;
+        // Single assign
+        formatter = newFormatter;
     }
 
-    final EventFormatter<T> formatter() {
+    final @NonNull EventFormatter<T> formatter() {
         return formatter;
     }
 
index 35371d4f9a4e2936f5f9a5913d1245d1e70db7bf..0ca8f4233401f407828249f2265f1c021911d951 100644 (file)
@@ -50,8 +50,7 @@ abstract class AbstractNotificationListenerAdaptor extends AbstractCommonSubscri
 
         final Optional<String> maybeOutput;
         try {
-            maybeOutput = formatter().eventData(effectiveModel(), notification, eventInstant, getLeafNodesOnly(),
-                isSkipNotificationData(), getChangedLeafNodesOnly(), getChildNodesOnly());
+            maybeOutput = formatter().eventData(effectiveModel(), notification, eventInstant);
         } catch (Exception e) {
             LOG.error("Failed to process notification {}", notification, e);
             return;
index ba2e3ebee7b855bfc4156cfaff62302a500b6be6..575a5a219cd42e9f10db1db54db523d8b7811896 100644 (file)
@@ -44,13 +44,14 @@ abstract class AbstractWebsocketSerializer<T extends Exception> {
         this.context = requireNonNull(context);
     }
 
-    public final boolean serialize(final DataTreeCandidate candidate, final boolean leafNodesOnly,
-            final boolean skipData, final boolean changedLeafNodesOnly, final boolean childNodesOnly) throws T {
-        if (leafNodesOnly || changedLeafNodesOnly) {
+    public final boolean serialize(final DataTreeCandidate candidate, final TextParameters params) throws T {
+        final var skipData = params.skipData();
+        final var changedLeafNodesOnly = params.changedLeafNodesOnly();
+        if (changedLeafNodesOnly || params.leafNodesOnly()) {
             return serializeLeafNodesOnly(mutableRootPath(candidate), candidate.getRootNode(), skipData,
                 changedLeafNodesOnly);
         }
-        if (childNodesOnly) {
+        if (params.childNodesOnly()) {
             serializeChildNodesOnly(mutableRootPath(candidate), candidate.getRootNode(), skipData);
             return true;
         }
index a3c6b99d4cd4bc9ce5b9bed90865a4fde188ae37..dbd7a455fbb714387c6d92d17b691f5dcb93389c 100644 (file)
@@ -30,12 +30,13 @@ import org.w3c.dom.Element;
  * Base formatter for DataTreeCandidates which only handles exporting to a document for filter checking purpose.
  */
 abstract class DataTreeCandidateFormatter extends EventFormatter<Collection<DataTreeCandidate>> {
-    DataTreeCandidateFormatter() {
-
+    DataTreeCandidateFormatter(final TextParameters textParams) {
+        super(textParams);
     }
 
-    DataTreeCandidateFormatter(final String xpathFilter) throws XPathExpressionException {
-        super(xpathFilter);
+    DataTreeCandidateFormatter(final TextParameters textParams, final String xpathFilter)
+            throws XPathExpressionException {
+        super(textParams, xpathFilter);
     }
 
     @Override
index e9372c9fe4276c8ec6ac060c49c9558b3fdaf774..783927326a3dfc1a5155c7fbab76e51fe1bfd8ef 100644 (file)
@@ -8,14 +8,10 @@
 package org.opendaylight.restconf.nb.rfc8040.streams.listeners;
 
 import java.util.Collection;
-import javax.xml.xpath.XPathExpressionException;
 import org.opendaylight.yangtools.yang.data.tree.api.DataTreeCandidate;
 
-interface DataTreeCandidateFormatterFactory extends EventFormatterFactory<Collection<DataTreeCandidate>> {
-
-    @Override
-    DataTreeCandidateFormatter getFormatter();
-
-    @Override
-    DataTreeCandidateFormatter getFormatter(String xpathFilter) throws XPathExpressionException;
+abstract class DataTreeCandidateFormatterFactory extends EventFormatterFactory<Collection<DataTreeCandidate>> {
+    DataTreeCandidateFormatterFactory(final DataTreeCandidateFormatter emptyFormatter) {
+        super(emptyFormatter);
+    }
 }
index 89584ef818f020e65d88ca41bca028bdb3390fa3..eeb6489461ec0adad12a9bc3d43a888f38546de6 100644 (file)
@@ -7,6 +7,8 @@
  */
 package org.opendaylight.restconf.nb.rfc8040.streams.listeners;
 
+import static java.util.Objects.requireNonNull;
+
 import java.io.IOException;
 import java.time.Instant;
 import java.time.OffsetDateTime;
@@ -52,13 +54,17 @@ abstract class EventFormatter<T> implements Immutable {
         DBF = f;
     }
 
+    private final TextParameters textParams;
     private final XPathExpression filter;
 
-    EventFormatter()  {
+    EventFormatter(final TextParameters textParams)  {
+        this.textParams = requireNonNull(textParams);
         filter = null;
     }
 
-    EventFormatter(final String xpathFilter)  throws XPathExpressionException {
+    EventFormatter(final TextParameters params, final String xpathFilter) throws XPathExpressionException {
+        textParams = requireNonNull(params);
+
         final XPath xpath;
         synchronized (XPF) {
             xpath = XPF.newXPath();
@@ -67,14 +73,12 @@ abstract class EventFormatter<T> implements Immutable {
         filter = xpath.compile(xpathFilter);
     }
 
-    final Optional<String> eventData(final EffectiveModelContext schemaContext, final T input, final Instant now,
-            final boolean leafNodesOnly, final boolean skipData, final boolean changedLeafNodesOnly,
-            final boolean childNodeOnly) throws Exception {
+    final Optional<String> eventData(final EffectiveModelContext schemaContext, final T input, final Instant now)
+            throws Exception {
         if (!filterMatches(schemaContext, input, now)) {
             return Optional.empty();
         }
-        return Optional.ofNullable(
-                createText(schemaContext, input, now, leafNodesOnly, skipData, changedLeafNodesOnly, childNodeOnly));
+        return Optional.ofNullable(createText(textParams, schemaContext, input, now));
     }
 
     /**
@@ -90,18 +94,15 @@ abstract class EventFormatter<T> implements Immutable {
     /**
      * Format the input data into string representation of the data provided.
      *
+     * @param params output text parameters
      * @param schemaContext context to use for the export
      * @param input input data
      * @param now time the event happened
-     * @param leafNodesOnly option to include only leaves in the result
-     * @param skipData option to skip data in the result, only paths would be included
-     * @param changedLeafNodesOnly  option to include only changed leaves in the result
-     * @param childNodesOnly option to include only children in the result
      * @return String representation of the formatted data
      * @throws Exception if the underlying formatters fail to export the data to the requested format
      */
-    abstract String createText(EffectiveModelContext schemaContext, T input, Instant now, boolean leafNodesOnly,
-        boolean skipData, boolean changedLeafNodesOnly, boolean childNodeOnly) throws Exception;
+    abstract String createText(TextParameters params, EffectiveModelContext schemaContext, T input, Instant now)
+        throws Exception;
 
     private boolean filterMatches(final EffectiveModelContext schemaContext, final T input, final Instant now)
             throws IOException {
index 1710628402e105e640bd1b92171bbe5f00b04961..9b46147e6026835184cf9a3eff97a339ca451274 100644 (file)
@@ -7,11 +7,30 @@
  */
 package org.opendaylight.restconf.nb.rfc8040.streams.listeners;
 
+import static java.util.Objects.requireNonNull;
+
 import javax.xml.xpath.XPathExpressionException;
+import org.eclipse.jdt.annotation.NonNull;
+
+abstract class EventFormatterFactory<T> {
+    private final @NonNull EventFormatter<T> emptyFormatter;
+
+    EventFormatterFactory(final EventFormatter<T> emptyFormatter) {
+        this.emptyFormatter = requireNonNull(emptyFormatter);
+    }
+
+    final @NonNull EventFormatter<T> emptyFormatter() {
+        return emptyFormatter;
+    }
+
+    final @NonNull EventFormatter<T> getFormatter(final @NonNull TextParameters textParamaters) {
+        return textParamaters.equals(TextParameters.EMPTY) ? emptyFormatter : newFormatter(textParamaters);
+    }
+
+    abstract @NonNull EventFormatter<T> getFormatter(@NonNull TextParameters textParamaters, String xpathFilter)
+        throws XPathExpressionException;
 
-interface EventFormatterFactory<T> {
+    abstract @NonNull EventFormatter<T> newFormatter(@NonNull TextParameters textParamaters);
 
-    EventFormatter<T> getFormatter();
 
-    EventFormatter<T> getFormatter(String xpathFilter) throws XPathExpressionException;
 }
index 226db6a7a4a36c8d8580506727154063f04fa2eb..00bfe2282643a56172d3fced271868d51f11093e 100644 (file)
@@ -25,37 +25,38 @@ public final class JSONDataTreeCandidateFormatter extends DataTreeCandidateForma
     public static final String NETCONF_NOTIFICATION_NAMESPACE = "urn-ietf-params-xml-ns-netconf-notification-1.0";
     private final JSONCodecFactorySupplier codecSupplier;
 
-    private JSONDataTreeCandidateFormatter(final JSONCodecFactorySupplier codecSupplier) {
+    private JSONDataTreeCandidateFormatter(final TextParameters textParams,
+            final JSONCodecFactorySupplier codecSupplier) {
+        super(textParams);
         this.codecSupplier = requireNonNull(codecSupplier);
     }
 
-    private JSONDataTreeCandidateFormatter(final String xpathFilter, final JSONCodecFactorySupplier codecSupplier)
-            throws XPathExpressionException {
-        super(xpathFilter);
+    private JSONDataTreeCandidateFormatter(final TextParameters textParams, final String xpathFilter,
+            final JSONCodecFactorySupplier codecSupplier) throws XPathExpressionException {
+        super(textParams, xpathFilter);
         this.codecSupplier = requireNonNull(codecSupplier);
     }
 
     public static DataTreeCandidateFormatterFactory createFactory(
             final JSONCodecFactorySupplier codecSupplier) {
-        requireNonNull(codecSupplier);
-        return new DataTreeCandidateFormatterFactory() {
+        final var empty = new JSONDataTreeCandidateFormatter(TextParameters.EMPTY, codecSupplier);
+        return new DataTreeCandidateFormatterFactory(empty) {
             @Override
-            public DataTreeCandidateFormatter getFormatter(final String xpathFilter)
-                    throws XPathExpressionException {
-                return new JSONDataTreeCandidateFormatter(xpathFilter, codecSupplier);
+            DataTreeCandidateFormatter newFormatter(final TextParameters textParams) {
+                return new JSONDataTreeCandidateFormatter(textParams, codecSupplier);
             }
 
             @Override
-            public DataTreeCandidateFormatter getFormatter() {
-                return new JSONDataTreeCandidateFormatter(codecSupplier);
+            DataTreeCandidateFormatter getFormatter(final TextParameters textParams, final String xpathFilter)
+                    throws XPathExpressionException {
+                return new JSONDataTreeCandidateFormatter(textParams, xpathFilter, codecSupplier);
             }
         };
     }
 
     @Override
-    String createText(final EffectiveModelContext schemaContext, final Collection<DataTreeCandidate> input,
-            final Instant now, final boolean leafNodesOnly, final boolean skipData, final boolean changedLeafNodesOnly,
-            final boolean childNodesOnly) throws IOException {
+    String createText(final TextParameters params, final EffectiveModelContext schemaContext,
+            final Collection<DataTreeCandidate> input, final Instant now) throws IOException {
         final Writer writer = new StringWriter();
         final JsonWriter jsonWriter = new JsonWriter(writer).beginObject();
 
@@ -66,7 +67,7 @@ public final class JSONDataTreeCandidateFormatter extends DataTreeCandidateForma
         final var serializer = new JsonDataTreeCandidateSerializer(schemaContext, codecSupplier, jsonWriter);
         boolean nonEmpty = false;
         for (var candidate : input) {
-            nonEmpty |= serializer.serialize(candidate, leafNodesOnly, skipData, changedLeafNodesOnly, childNodesOnly);
+            nonEmpty |= serializer.serialize(candidate, params);
         }
 
         // data-change-event
index 9f49866218c7cdf789aff65d43589d878e56ce98..b917f43d991427bcb3ecbcd046750f27d6d05d38 100644 (file)
@@ -23,36 +23,36 @@ import org.opendaylight.yangtools.yang.model.api.EffectiveModelContext;
 final class JSONNotificationFormatter extends NotificationFormatter {
     private final JSONCodecFactorySupplier codecSupplier;
 
-    private JSONNotificationFormatter(final JSONCodecFactorySupplier codecSupplier) {
+    private JSONNotificationFormatter(final TextParameters textParams, final JSONCodecFactorySupplier codecSupplier) {
+        super(textParams);
         this.codecSupplier = requireNonNull(codecSupplier);
     }
 
-    private JSONNotificationFormatter(final String xpathFilter, final JSONCodecFactorySupplier codecSupplier)
-            throws XPathExpressionException {
-        super(xpathFilter);
+    private JSONNotificationFormatter(final TextParameters textParams, final String xpathFilter,
+            final JSONCodecFactorySupplier codecSupplier) throws XPathExpressionException {
+        super(textParams, xpathFilter);
         this.codecSupplier = requireNonNull(codecSupplier);
     }
 
     static NotificationFormatterFactory createFactory(final JSONCodecFactorySupplier codecSupplier) {
-        requireNonNull(codecSupplier);
-        return new NotificationFormatterFactory() {
+        final var empty = new JSONNotificationFormatter(TextParameters.EMPTY, codecSupplier);
+        return new NotificationFormatterFactory(empty) {
             @Override
-            public JSONNotificationFormatter getFormatter(final String xpathFilter)
+            JSONNotificationFormatter getFormatter(final TextParameters textParams, final String xpathFilter)
                     throws XPathExpressionException {
-                return new JSONNotificationFormatter(xpathFilter, codecSupplier);
+                return new JSONNotificationFormatter(textParams, xpathFilter, codecSupplier);
             }
 
             @Override
-            public JSONNotificationFormatter getFormatter() {
-                return new JSONNotificationFormatter(codecSupplier);
+            JSONNotificationFormatter newFormatter(final TextParameters textParams) {
+                return new JSONNotificationFormatter(textParams, codecSupplier);
             }
         };
     }
 
     @Override
-    String createText(final EffectiveModelContext schemaContext, final DOMNotification input, final Instant now,
-            final boolean leafNodesOnly, final boolean skipData, final boolean changedLeafNodesOnly,
-            final boolean childNodesOnly) throws IOException {
+    String createText(final TextParameters params, final EffectiveModelContext schemaContext,
+            final DOMNotification input, final Instant now) throws IOException {
         final Writer writer = new StringWriter();
         final JsonWriter jsonWriter = new JsonWriter(writer).beginObject();
         jsonWriter.name("ietf-restconf:notification").beginObject();
index 38f767d10165f9591fa4e5c72f7844901be17476..6fee17d65f5bd9561c03677de80b01ae52ef0ba5 100644 (file)
@@ -75,8 +75,8 @@ public class ListenerAdapter extends AbstractCommonSubscriber<Collection<DataTre
 
         final Optional<String> maybeData;
         try {
-            maybeData = formatter().eventData(databindProvider.currentContext().modelContext(), dataTreeCandidates, now,
-                getLeafNodesOnly(), isSkipNotificationData(), getChangedLeafNodesOnly(), getChildNodesOnly());
+            maybeData = formatter().eventData(databindProvider.currentContext().modelContext(), dataTreeCandidates,
+                now);
         } catch (final Exception e) {
             LOG.error("Failed to process notification {}",
                     dataTreeCandidates.stream().map(Object::toString).collect(Collectors.joining(",")), e);
index b864c109a5c9e3267172f7820cdf51941fd6a1b1..913038316d0cb80c44773c5b9f5be225f32c3d38 100644 (file)
@@ -43,12 +43,12 @@ abstract class NotificationFormatter extends EventFormatter<DOMNotification> {
         XML_OUTPUT_FACTORY.setProperty(XMLOutputFactory.IS_REPAIRING_NAMESPACES, true);
     }
 
-    NotificationFormatter() {
-
+    NotificationFormatter(final TextParameters textParams) {
+        super(textParams);
     }
 
-    NotificationFormatter(final String xpathFilter) throws XPathExpressionException {
-        super(xpathFilter);
+    NotificationFormatter(final TextParameters textParams, final String xpathFilter) throws XPathExpressionException {
+        super(textParams, xpathFilter);
     }
 
     @Override
index 254a032dd9a0d8a5180f4c88c43fcd9949f0db95..b80f34f289311fd2d512c0644c782c4531562031 100644 (file)
@@ -7,13 +7,10 @@
  */
 package org.opendaylight.restconf.nb.rfc8040.streams.listeners;
 
-import javax.xml.xpath.XPathExpressionException;
 import org.opendaylight.mdsal.dom.api.DOMNotification;
 
-interface NotificationFormatterFactory extends EventFormatterFactory<DOMNotification> {
-    @Override
-    NotificationFormatter getFormatter();
-
-    @Override
-    NotificationFormatter getFormatter(String xpathFilter) throws XPathExpressionException;
+abstract class NotificationFormatterFactory extends EventFormatterFactory<DOMNotification> {
+    NotificationFormatterFactory(final EventFormatter<DOMNotification> emptyFormatter) {
+        super(emptyFormatter);
+    }
 }
diff --git a/restconf/restconf-nb/src/main/java/org/opendaylight/restconf/nb/rfc8040/streams/listeners/TextParameters.java b/restconf/restconf-nb/src/main/java/org/opendaylight/restconf/nb/rfc8040/streams/listeners/TextParameters.java
new file mode 100644 (file)
index 0000000..aceb84a
--- /dev/null
@@ -0,0 +1,24 @@
+/*
+ * Copyright (c) 2023 PANTHEON.tech, s.r.o. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.restconf.nb.rfc8040.streams.listeners;
+
+import org.eclipse.jdt.annotation.NonNullByDefault;
+
+/**
+ * Text formatting parameters.
+ *
+ * @param leafNodesOnly {@code true} if this query should only notify about leaf node changes
+ * @param skipData {@code true} if this query should notify about changes with data
+ * @param changedLeafNodesOnly {@code true} if this query should only notify about leaf node changes and report only
+ *                             changed nodes
+ * @param childNodesOnly {@code true} if this query should only notify about child node changes
+ */
+@NonNullByDefault
+record TextParameters(boolean leafNodesOnly, boolean skipData, boolean changedLeafNodesOnly, boolean childNodesOnly) {
+    static final TextParameters EMPTY = new TextParameters(false, false, false, false);
+}
\ No newline at end of file
index 1d16ce3d72f96e8ae6ffb1f25e970887a16a7c5e..bf0e219653914441b454654157e30cec4a7636f9 100644 (file)
@@ -20,34 +20,33 @@ import org.opendaylight.yangtools.yang.data.tree.api.DataTreeCandidate;
 import org.opendaylight.yangtools.yang.model.api.EffectiveModelContext;
 
 public final class XMLDataTreeCandidateFormatter extends DataTreeCandidateFormatter {
-    private static final XMLDataTreeCandidateFormatter INSTANCE = new XMLDataTreeCandidateFormatter();
+    private static final XMLDataTreeCandidateFormatter EMPTY = new XMLDataTreeCandidateFormatter(TextParameters.EMPTY);
 
-    static final DataTreeCandidateFormatterFactory FACTORY =
-        new DataTreeCandidateFormatterFactory() {
-            @Override
-            public XMLDataTreeCandidateFormatter getFormatter(final String xpathFilter)
-                    throws XPathExpressionException {
-                return new XMLDataTreeCandidateFormatter(xpathFilter);
-            }
-
-            @Override
-            public XMLDataTreeCandidateFormatter getFormatter() {
-                return INSTANCE;
-            }
-        };
+    static final DataTreeCandidateFormatterFactory FACTORY = new DataTreeCandidateFormatterFactory(EMPTY) {
+        @Override
+        XMLDataTreeCandidateFormatter getFormatter(final TextParameters textParams, final String xpathFilter)
+                throws XPathExpressionException {
+            return new XMLDataTreeCandidateFormatter(textParams, xpathFilter);
+        }
 
-    private XMLDataTreeCandidateFormatter() {
+        @Override
+        XMLDataTreeCandidateFormatter newFormatter(final TextParameters textParams) {
+            return new XMLDataTreeCandidateFormatter(textParams);
+        }
+    };
 
+    private XMLDataTreeCandidateFormatter(final TextParameters textParams) {
+        super(textParams);
     }
 
-    private XMLDataTreeCandidateFormatter(final String xpathFilter) throws XPathExpressionException {
-        super(xpathFilter);
+    private XMLDataTreeCandidateFormatter(final TextParameters textParams, final String xpathFilter)
+            throws XPathExpressionException {
+        super(textParams, xpathFilter);
     }
 
     @Override
-    String createText(final EffectiveModelContext schemaContext, final Collection<DataTreeCandidate> input,
-            final Instant now, final boolean leafNodesOnly, final boolean skipData, final boolean changedLeafNodesOnly,
-            final boolean childNodeOnly) throws Exception {
+    String createText(final TextParameters params, final EffectiveModelContext schemaContext,
+            final Collection<DataTreeCandidate> input, final Instant now) throws Exception {
         final var writer = new StringWriter();
         boolean nonEmpty = false;
         try {
@@ -58,8 +57,7 @@ public final class XMLDataTreeCandidateFormatter extends DataTreeCandidateFormat
 
             final var serializer = new XmlDataTreeCandidateSerializer(schemaContext, xmlStreamWriter);
             for (var candidate : input) {
-                nonEmpty |= serializer.serialize(candidate, leafNodesOnly, skipData, changedLeafNodesOnly,
-                    childNodeOnly);
+                nonEmpty |= serializer.serialize(candidate, params);
             }
 
             // data-changed-notification
index ca00050c7cf3c2cb4108c4a779e8b58899b4b5e9..e2a2d6cdcc2955f8098f8c79a6e6359764f6587f 100644 (file)
@@ -18,32 +18,33 @@ import org.opendaylight.yangtools.yang.data.codec.xml.XMLStreamNormalizedNodeStr
 import org.opendaylight.yangtools.yang.model.api.EffectiveModelContext;
 
 final class XMLNotificationFormatter extends NotificationFormatter {
-    private static final XMLNotificationFormatter INSTANCE = new XMLNotificationFormatter();
+    private static final XMLNotificationFormatter EMPTY = new XMLNotificationFormatter(TextParameters.EMPTY);
 
-    static final NotificationFormatterFactory FACTORY = new NotificationFormatterFactory() {
+    static final NotificationFormatterFactory FACTORY = new NotificationFormatterFactory(EMPTY) {
         @Override
-        public XMLNotificationFormatter getFormatter(final String xpathFilter) throws XPathExpressionException {
-            return new XMLNotificationFormatter(xpathFilter);
+        XMLNotificationFormatter newFormatter(final TextParameters textParams) {
+            return new XMLNotificationFormatter(textParams);
         }
 
         @Override
-        public XMLNotificationFormatter getFormatter() {
-            return INSTANCE;
+        XMLNotificationFormatter getFormatter(final TextParameters textParams, final String xpathFilter)
+                throws XPathExpressionException {
+            return new XMLNotificationFormatter(textParams, xpathFilter);
         }
     };
 
-    XMLNotificationFormatter() {
-
+    XMLNotificationFormatter(final TextParameters textParams) {
+        super(textParams);
     }
 
-    XMLNotificationFormatter(final String xpathFilter) throws XPathExpressionException {
-        super(xpathFilter);
+    XMLNotificationFormatter(final TextParameters textParams, final String xpathFilter)
+            throws XPathExpressionException {
+        super(textParams, xpathFilter);
     }
 
     @Override
-    String createText(final EffectiveModelContext schemaContext, final DOMNotification input, final Instant now,
-            final boolean leafNodesOnly, final boolean skipData, final boolean changedLeafNodesOnly,
-            final boolean childNodesOnly) throws IOException {
+    String createText(final TextParameters params, final EffectiveModelContext schemaContext,
+            final DOMNotification input, final Instant now) throws IOException {
         final var writer = new StringWriter();
 
         try {
index 0744abdfd34f93a0032f406448eea2dbd2ef11db..7d35822df3dfababae58e41cb379f90c97ffb8e1 100644 (file)
@@ -161,9 +161,8 @@ public class JsonNotificationListenerTest extends AbstractNotificationListenerTe
 
     private static String prepareJson(final DOMNotification notificationData, final Absolute schemaPathNotifi)
             throws Exception {
-        final NotificationListenerAdapter notifiAdapter = ListenersBroker.getInstance().registerNotificationListener(
+        final var notifiAdapter = ListenersBroker.getInstance().registerNotificationListener(
                 schemaPathNotifi, "json-stream", NotificationOutputType.JSON);
-        return notifiAdapter.formatter()
-                .eventData(SCHEMA_CONTEXT, notificationData, Instant.now(), false, false, false, false).orElseThrow();
+        return notifiAdapter.formatter().eventData(SCHEMA_CONTEXT, notificationData, Instant.now()).orElseThrow();
     }
 }
index 2928898b7218cee2bf1b04328b0317461008dad7..1400b783440afe3e217743973bdffe5788d4262a 100644 (file)
@@ -15,7 +15,7 @@ import org.junit.Test;
 import org.junit.runner.RunWith;
 import org.mockito.junit.MockitoJUnitRunner;
 import org.opendaylight.mdsal.dom.api.DOMNotification;
-import org.opendaylight.yang.gen.v1.urn.sal.restconf.event.subscription.rev140708.NotificationOutputTypeGrouping;
+import org.opendaylight.yang.gen.v1.urn.sal.restconf.event.subscription.rev140708.NotificationOutputTypeGrouping.NotificationOutputType;
 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;
@@ -168,9 +168,8 @@ public class XmlNotificationListenerTest extends AbstractNotificationListenerTes
 
     private static String prepareXmlResult(final DOMNotification notificationData, final Absolute schemaPathNotifi)
             throws Exception {
-        final NotificationListenerAdapter notifiAdapter = ListenersBroker.getInstance().registerNotificationListener(
-                schemaPathNotifi, "xml-stream", NotificationOutputTypeGrouping.NotificationOutputType.XML);
-        return notifiAdapter.formatter().eventData(SCHEMA_CONTEXT, notificationData, Instant.now(), false,
-                false, false, false).orElseThrow();
+        final var notifiAdapter = ListenersBroker.getInstance().registerNotificationListener(
+                schemaPathNotifi, "xml-stream", NotificationOutputType.XML);
+        return notifiAdapter.formatter().eventData(SCHEMA_CONTEXT, notificationData, Instant.now()).orElseThrow();
     }
 }