Bridge {Notification,Operation}Definition to ContainerLike 06/106106/3
authorRobert Varga <robert.varga@pantheon.tech>
Sun, 21 May 2023 14:41:05 +0000 (16:41 +0200)
committerRobert Varga <robert.varga@pantheon.tech>
Sun, 21 May 2023 15:45:44 +0000 (17:45 +0200)
We have overlapping interfaces dealing with the same thing --
{Notification,Operation}AsContainer and ContainerSchemaNodes. Hide the
former and unify the RPC operation provider.

Also increase visibility of these utilities by integrating them directly
into base interfaces.

Change-Id: Ib5c45785b2886a4c5f9c7b0393abe52259beefab
Signed-off-by: Robert Varga <robert.varga@pantheon.tech>
codec/yang-data-codec-gson/src/main/java/org/opendaylight/yangtools/yang/data/codec/gson/JsonParserStream.java
codec/yang-data-codec-xml/src/main/java/org/opendaylight/yangtools/yang/data/codec/xml/XmlParserStream.java
data/yang-data-util/src/main/java/org/opendaylight/yangtools/yang/data/util/ContainerSchemaNodes.java
data/yang-data-util/src/main/java/org/opendaylight/yangtools/yang/data/util/OperationAsContainer.java [deleted file]
model/yang-model-api/src/main/java/org/opendaylight/yangtools/yang/model/api/ContainerLikeCompat.java [moved from data/yang-data-util/src/main/java/org/opendaylight/yangtools/yang/data/util/AbstractAsContainer.java with 59% similarity]
model/yang-model-api/src/main/java/org/opendaylight/yangtools/yang/model/api/NotificationAsContainer.java [moved from data/yang-data-util/src/main/java/org/opendaylight/yangtools/yang/data/util/NotificationAsContainer.java with 52% similarity]
model/yang-model-api/src/main/java/org/opendaylight/yangtools/yang/model/api/NotificationDefinition.java
model/yang-model-api/src/main/java/org/opendaylight/yangtools/yang/model/api/OperationAsContainer.java [new file with mode: 0644]
model/yang-model-api/src/main/java/org/opendaylight/yangtools/yang/model/api/OperationDefinition.java

index d89244c3c447ecea00577f5f2780f5937c8ff3e1..ae48012c19df2f0f40764e16ecff9163080060d5 100644 (file)
@@ -42,8 +42,6 @@ import org.opendaylight.yangtools.yang.data.util.LeafListNodeDataWithSchema;
 import org.opendaylight.yangtools.yang.data.util.LeafNodeDataWithSchema;
 import org.opendaylight.yangtools.yang.data.util.ListNodeDataWithSchema;
 import org.opendaylight.yangtools.yang.data.util.MultipleEntryDataWithSchema;
-import org.opendaylight.yangtools.yang.data.util.NotificationAsContainer;
-import org.opendaylight.yangtools.yang.data.util.OperationAsContainer;
 import org.opendaylight.yangtools.yang.data.util.ParserStreamUtils;
 import org.opendaylight.yangtools.yang.data.util.SimpleNodeDataWithSchema;
 import org.opendaylight.yangtools.yang.model.api.CaseSchemaNode;
@@ -94,9 +92,9 @@ public final class JsonParserStream implements Closeable, Flushable {
             if (parent instanceof DataSchemaNode data) {
                 parentNode = data;
             } else if (parent instanceof OperationDefinition oper) {
-                parentNode = OperationAsContainer.of(oper);
+                parentNode = oper.toContainerLike();
             } else if (parent instanceof NotificationDefinition notif) {
-                parentNode = NotificationAsContainer.of(notif);
+                parentNode = notif.toContainerLike();
             } else {
                 throw new IllegalArgumentException("Illegal parent node " + parent);
             }
index 103088412189db45b8618883f062dca386b7a01c..fc3facb9f8df413f2fa8c2ecb825abc5ea573016 100644 (file)
@@ -68,8 +68,6 @@ import org.opendaylight.yangtools.yang.data.util.ListEntryNodeDataWithSchema;
 import org.opendaylight.yangtools.yang.data.util.ListNodeDataWithSchema;
 import org.opendaylight.yangtools.yang.data.util.MountPointData;
 import org.opendaylight.yangtools.yang.data.util.MultipleEntryDataWithSchema;
-import org.opendaylight.yangtools.yang.data.util.NotificationAsContainer;
-import org.opendaylight.yangtools.yang.data.util.OperationAsContainer;
 import org.opendaylight.yangtools.yang.data.util.ParserStreamUtils;
 import org.opendaylight.yangtools.yang.data.util.SimpleNodeDataWithSchema;
 import org.opendaylight.yangtools.yang.model.api.AnydataSchemaNode;
@@ -158,9 +156,9 @@ public final class XmlParserStream implements Closeable, Flushable {
             if (stmt instanceof DataSchemaNode data) {
                 parentNode = data;
             } else if (stmt instanceof OperationDefinition oper) {
-                parentNode = OperationAsContainer.of(oper);
+                parentNode = oper.toContainerLike();
             } else if (stmt instanceof NotificationDefinition notif) {
-                parentNode = NotificationAsContainer.of(notif);
+                parentNode = notif.toContainerLike();
             } else {
                 throw new IllegalArgumentException("Illegal parent node " + stmt);
             }
index 8021952c505e154ad217a8a43da621499e100595..70942dffdc91598703b46ec755520a64b2813005 100644 (file)
@@ -49,7 +49,7 @@ public final class ContainerSchemaNodes {
 
     @Beta
     public static @NonNull ContainerLike forRPC(final RpcDefinition rpc) {
-        return new RpcContainerSchemaNode(rpc);
+        return rpc.toContainerLike();
     }
 
     private abstract static class AbstractContainerSchemaNode<T extends SchemaNode> implements ContainerLike {
@@ -117,47 +117,6 @@ public final class ContainerSchemaNodes {
         }
     }
 
-    private static final class RpcContainerSchemaNode extends AbstractContainerSchemaNode<RpcDefinition> {
-        RpcContainerSchemaNode(final RpcDefinition rpcDefinition) {
-            super(rpcDefinition);
-        }
-
-        @Override
-        public Collection<? extends GroupingDefinition> getGroupings() {
-            return schemaNode.getGroupings();
-        }
-
-        @Override
-        public Collection<? extends TypeDefinition<?>> getTypeDefinitions() {
-            return schemaNode.getTypeDefinitions();
-        }
-
-        @Override
-        public Collection<? extends AugmentationSchemaNode> getAvailableAugmentations() {
-            return ImmutableSet.of();
-        }
-
-        @Override
-        public Collection<? extends DataSchemaNode> getChildNodes() {
-            return ImmutableList.of(schemaNode.getInput(), schemaNode.getOutput());
-        }
-
-        @Override
-        public DataSchemaNode dataChildByName(final QName name) {
-            // FIXME: also check namespace
-            return switch (name.getLocalName()) {
-                case "input" -> schemaNode.getInput();
-                case "output" -> schemaNode.getOutput();
-                default -> null;
-            };
-        }
-
-        @Override
-        public Collection<? extends NotificationDefinition> getNotifications() {
-            return ImmutableSet.of();
-        }
-    }
-
     private static final class NotificationContainerSchemaNode
             extends AbstractContainerSchemaNode<NotificationDefinition> {
         private final ImmutableMap<QName, ? extends DataSchemaNode> mapNodes;
diff --git a/data/yang-data-util/src/main/java/org/opendaylight/yangtools/yang/data/util/OperationAsContainer.java b/data/yang-data-util/src/main/java/org/opendaylight/yangtools/yang/data/util/OperationAsContainer.java
deleted file mode 100644 (file)
index 6df2385..0000000
+++ /dev/null
@@ -1,73 +0,0 @@
-/*
- * Copyright (c) 2016 Cisco Systems, Inc. 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.yangtools.yang.data.util;
-
-import static java.util.Objects.requireNonNull;
-
-import com.google.common.annotations.Beta;
-import com.google.common.collect.ImmutableList;
-import com.google.common.collect.ImmutableSet;
-import java.util.Collection;
-import org.eclipse.jdt.annotation.NonNull;
-import org.opendaylight.yangtools.yang.common.QName;
-import org.opendaylight.yangtools.yang.model.api.AugmentationSchemaNode;
-import org.opendaylight.yangtools.yang.model.api.DataSchemaNode;
-import org.opendaylight.yangtools.yang.model.api.GroupingDefinition;
-import org.opendaylight.yangtools.yang.model.api.OperationDefinition;
-import org.opendaylight.yangtools.yang.model.api.TypeDefinition;
-
-@Beta
-public class OperationAsContainer extends AbstractAsContainer {
-    private final @NonNull OperationDefinition delegate;
-
-    OperationAsContainer(final OperationDefinition parentNode) {
-        delegate = requireNonNull(parentNode);
-    }
-
-    public static @NonNull OperationAsContainer of(final OperationDefinition delegate) {
-        return new OperationAsContainer(delegate);
-    }
-
-    @Override
-    protected final @NonNull OperationDefinition delegate() {
-        return delegate;
-    }
-
-    @Override
-    public final Collection<? extends @NonNull TypeDefinition<?>> getTypeDefinitions() {
-        return delegate.getTypeDefinitions();
-    }
-
-    @Override
-    public final Collection<? extends @NonNull GroupingDefinition> getGroupings() {
-        return delegate.getGroupings();
-    }
-
-    @Override
-    public final DataSchemaNode dataChildByName(final QName name) {
-        final var input = delegate.getInput();
-        if (name.equals(input.getQName())) {
-            return input;
-        }
-        final var output = delegate.getOutput();
-        if (name.equals(output.getQName())) {
-            return output;
-        }
-        return null;
-    }
-
-    @Override
-    public final Collection<? extends AugmentationSchemaNode> getAvailableAugmentations() {
-        return ImmutableSet.of();
-    }
-
-    @Override
-    public final Collection<? extends DataSchemaNode> getChildNodes() {
-        return ImmutableList.of(delegate.getInput(), delegate.getOutput());
-    }
-}
similarity index 59%
rename from data/yang-data-util/src/main/java/org/opendaylight/yangtools/yang/data/util/AbstractAsContainer.java
rename to model/yang-model-api/src/main/java/org/opendaylight/yangtools/yang/model/api/ContainerLikeCompat.java
index 57e9b963bf26df4684614814f9957f7812b668a8..d3cc6407d30fb38537a2423014eab560c9d14561 100644 (file)
@@ -5,24 +5,26 @@
  * 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.yangtools.yang.data.util;
+package org.opendaylight.yangtools.yang.model.api;
 
 import com.google.common.collect.ForwardingObject;
-import com.google.common.collect.ImmutableSet;
-import java.util.Collection;
 import java.util.Optional;
+import java.util.Set;
 import org.eclipse.jdt.annotation.NonNull;
 import org.opendaylight.yangtools.yang.common.QName;
-import org.opendaylight.yangtools.yang.model.api.ActionDefinition;
-import org.opendaylight.yangtools.yang.model.api.ContainerLike;
-import org.opendaylight.yangtools.yang.model.api.MustDefinition;
-import org.opendaylight.yangtools.yang.model.api.NotificationDefinition;
-import org.opendaylight.yangtools.yang.model.api.SchemaNode;
-import org.opendaylight.yangtools.yang.model.api.Status;
-import org.opendaylight.yangtools.yang.model.api.UsesNode;
 import org.opendaylight.yangtools.yang.xpath.api.YangXPathExpression.QualifiedBound;
 
-abstract class AbstractAsContainer extends ForwardingObject implements ContainerLike {
+/**
+ * Base class supporting {@link OperationDefinition#toContainerLike()} and
+ * {@link NotificationDefinition#toContainerLike()}. This class is exposed only for the unlikely need users of those
+ * methods need to do tricks when encountering those containers.
+ */
+public abstract sealed class ContainerLikeCompat extends ForwardingObject implements ContainerLike
+        permits NotificationAsContainer, OperationAsContainer {
+    ContainerLikeCompat() {
+        // Hidden on purpose
+    }
+
     @Override
     protected abstract @NonNull SchemaNode delegate();
 
@@ -64,23 +66,23 @@ abstract class AbstractAsContainer extends ForwardingObject implements Container
     }
 
     @Override
-    public final Collection<? extends ActionDefinition> getActions() {
-        return ImmutableSet.of();
+    public final Set<ActionDefinition> getActions() {
+        return Set.of();
     }
 
     @Override
-    public final Collection<? extends NotificationDefinition> getNotifications() {
-        return ImmutableSet.of();
+    public final Set<NotificationDefinition> getNotifications() {
+        return Set.of();
     }
 
     @Override
-    public final Collection<? extends UsesNode> getUses() {
-        return ImmutableSet.of();
+    public final Set<UsesNode> getUses() {
+        return Set.of();
     }
 
     @Override
-    public final Collection<? extends @NonNull MustDefinition> getMustConstraints() {
-        return ImmutableSet.of();
+    public final Set<@NonNull MustDefinition> getMustConstraints() {
+        return Set.of();
     }
 
     @Override
similarity index 52%
rename from data/yang-data-util/src/main/java/org/opendaylight/yangtools/yang/data/util/NotificationAsContainer.java
rename to model/yang-model-api/src/main/java/org/opendaylight/yangtools/yang/model/api/NotificationAsContainer.java
index f2bcc52eb04530140ec82ebc5d39d86340c1d90d..4c201e04b9989fd05de711f04deb8e2efe3a2fb6 100644 (file)
@@ -5,35 +5,23 @@
  * 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.yangtools.yang.data.util;
+package org.opendaylight.yangtools.yang.model.api;
 
 import static java.util.Objects.requireNonNull;
 
-import com.google.common.annotations.Beta;
 import java.util.Collection;
 import org.eclipse.jdt.annotation.NonNull;
 import org.opendaylight.yangtools.yang.common.QName;
-import org.opendaylight.yangtools.yang.model.api.AugmentationSchemaNode;
-import org.opendaylight.yangtools.yang.model.api.DataSchemaNode;
-import org.opendaylight.yangtools.yang.model.api.GroupingDefinition;
-import org.opendaylight.yangtools.yang.model.api.NotificationDefinition;
-import org.opendaylight.yangtools.yang.model.api.TypeDefinition;
-import org.opendaylight.yangtools.yang.model.api.stmt.NotificationEffectiveStatement;
 
-@Beta
-public final class NotificationAsContainer extends AbstractAsContainer implements NotificationDefinition {
+final class NotificationAsContainer extends ContainerLikeCompat {
     private final @NonNull NotificationDefinition delegate;
 
     NotificationAsContainer(final NotificationDefinition delegate) {
         this.delegate = requireNonNull(delegate);
     }
 
-    public static @NonNull NotificationAsContainer of(final NotificationDefinition delegate) {
-        return new NotificationAsContainer(delegate);
-    }
-
     @Override
-    protected @NonNull NotificationDefinition delegate() {
+    protected NotificationDefinition delegate() {
         return delegate;
     }
 
@@ -53,17 +41,12 @@ public final class NotificationAsContainer extends AbstractAsContainer implement
     }
 
     @Override
-    public Collection<? extends @NonNull TypeDefinition<?>> getTypeDefinitions() {
+    public Collection<? extends TypeDefinition<?>> getTypeDefinitions() {
         return delegate.getTypeDefinitions();
     }
 
     @Override
-    public Collection<? extends @NonNull GroupingDefinition> getGroupings() {
+    public Collection<? extends GroupingDefinition> getGroupings() {
         return delegate.getGroupings();
     }
-
-    @Override
-    public NotificationEffectiveStatement asEffectiveStatement() {
-        return delegate.asEffectiveStatement();
-    }
 }
index ba054c16a16a5ee5d0da2787ee006bc8f9885532..72f09f3f92996eb091e65b6f61e7cbc5a65884bc 100644 (file)
@@ -7,13 +7,22 @@
  */
 package org.opendaylight.yangtools.yang.model.api;
 
+import org.eclipse.jdt.annotation.NonNull;
 import org.opendaylight.yangtools.yang.model.api.stmt.NotificationEffectiveStatement;
 
 /**
- * Interface describing YANG 'notification' statement. The notification
- * statement is used to define a NETCONF notification.
+ * Interface describing YANG 'notification' statement. The notification statement is used to define a NETCONF
+ * notification. Note that this interface is not a {@link DataSchemaNode}, which renders compatibility problematic. Use
+ * {@link #toContainerLike()} to get a {@link ContainerLike}, which can serve as a bridge.
  */
 public interface NotificationDefinition extends SchemaNode, DataNodeContainer, AugmentationTarget, CopyableNode,
         MustConstraintAware, EffectiveStatementEquivalent<NotificationEffectiveStatement> {
-
+    /**
+     * Return a {@link ContainerLike} backed by this definition's {@link #getChildNodes()}.
+     *
+     * @return A compatibility {@link ContainerLike}
+     */
+    default @NonNull ContainerLikeCompat toContainerLike() {
+        return new NotificationAsContainer(this);
+    }
 }
diff --git a/model/yang-model-api/src/main/java/org/opendaylight/yangtools/yang/model/api/OperationAsContainer.java b/model/yang-model-api/src/main/java/org/opendaylight/yangtools/yang/model/api/OperationAsContainer.java
new file mode 100644 (file)
index 0000000..d08cd53
--- /dev/null
@@ -0,0 +1,62 @@
+/*
+ * Copyright (c) 2016 Cisco Systems, Inc. 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.yangtools.yang.model.api;
+
+import static java.util.Objects.requireNonNull;
+
+import java.util.Collection;
+import java.util.List;
+import java.util.Set;
+import org.eclipse.jdt.annotation.NonNull;
+import org.opendaylight.yangtools.yang.common.QName;
+
+final class OperationAsContainer extends ContainerLikeCompat {
+    private final @NonNull OperationDefinition delegate;
+
+    OperationAsContainer(final OperationDefinition parentNode) {
+        delegate = requireNonNull(parentNode);
+    }
+
+    @Override
+    protected OperationDefinition delegate() {
+        return delegate;
+    }
+
+    @Override
+    public Collection<? extends TypeDefinition<?>> getTypeDefinitions() {
+        return delegate.getTypeDefinitions();
+    }
+
+    @Override
+    public Collection<? extends GroupingDefinition> getGroupings() {
+        return delegate.getGroupings();
+    }
+
+    @Override
+    public DataSchemaNode dataChildByName(final QName name) {
+        final var input = delegate.getInput();
+        if (name.equals(input.getQName())) {
+            return input;
+        }
+        final var output = delegate.getOutput();
+        if (name.equals(output.getQName())) {
+            return output;
+        }
+        return null;
+    }
+
+    @Override
+    public Set<AugmentationSchemaNode> getAvailableAugmentations() {
+        return Set.of();
+    }
+
+    @Override
+    public List<DataSchemaNode> getChildNodes() {
+        return List.of(delegate.getInput(), delegate.getOutput());
+    }
+}
index 30fdefa47c0556fd8d89dc008781041f07215c23..9e2ffd3258fc0d721284697c2f59de5756cdbee5 100644 (file)
@@ -11,7 +11,9 @@ import java.util.Collection;
 import org.eclipse.jdt.annotation.NonNullByDefault;
 
 /**
- * Common interface for an operation, such as an {@link RpcDefinition} or an {@link ActionDefinition}.
+ * Common interface for an operation, such as an {@link RpcDefinition} or an {@link ActionDefinition}. Note that this
+ * interface is not a {@link DataSchemaNode}, which renders compatibility problematic. Use {@link #toContainerLike()} to
+ * get a {@link ContainerLike}, which can serve as a bridge.
  */
 @NonNullByDefault
 public interface OperationDefinition extends SchemaNode {
@@ -44,4 +46,13 @@ public interface OperationDefinition extends SchemaNode {
      *         substatements of output define nodes under the operation's output node.
      */
     OutputSchemaNode getOutput();
+
+    /**
+     * Return a {@link ContainerLike} backed by this definition's {@link #getInput()} and {@link #getOutput()}.
+     *
+     * @return A compatibility {@link ContainerLike}
+     */
+    default ContainerLikeCompat toContainerLike() {
+        return new OperationAsContainer(this);
+    }
 }