Eliminate SchemasStream.EntityType 84/110084/11
authorlubos-cicut <lubos.cicut@pantheon.tech>
Mon, 29 Jan 2024 18:48:29 +0000 (19:48 +0100)
committerIvan Hrasko <ivan.hrasko@pantheon.tech>
Tue, 27 Feb 2024 19:30:32 +0000 (19:30 +0000)
We were using SchemasStream.EntityType to distinguish if
SchemaEntity is node or RPC. Eliminated this enum and created
a class hierarchy structure, so we now have NodeSchemaEntity and
RpcSchemaEntity

JIRA: NETCONF-1226
Change-Id: I70a9f48de0528443831b95d16e83dd513a73bc13
Signed-off-by: lubos-cicut <lubos.cicut@pantheon.tech>
restconf/restconf-openapi/src/main/java/org/opendaylight/restconf/openapi/impl/SchemasStream.java
restconf/restconf-openapi/src/main/java/org/opendaylight/restconf/openapi/model/NodeSchemaEntity.java [new file with mode: 0644]
restconf/restconf-openapi/src/main/java/org/opendaylight/restconf/openapi/model/RpcSchemaEntity.java [new file with mode: 0644]
restconf/restconf-openapi/src/main/java/org/opendaylight/restconf/openapi/model/SchemaEntity.java

index 080348ef67247ac032f9ce4a81bee84fbd38b8b6..022668a3b8a30e3594087a18b1a04ffea2e76311 100644 (file)
@@ -25,6 +25,8 @@ import java.util.Deque;
 import java.util.Iterator;
 import java.util.List;
 import org.opendaylight.restconf.openapi.jaxrs.OpenApiBodyWriter;
+import org.opendaylight.restconf.openapi.model.NodeSchemaEntity;
+import org.opendaylight.restconf.openapi.model.RpcSchemaEntity;
 import org.opendaylight.restconf.openapi.model.SchemaEntity;
 import org.opendaylight.yangtools.yang.model.api.ActionNodeContainer;
 import org.opendaylight.yangtools.yang.model.api.ChoiceSchemaNode;
@@ -139,8 +141,8 @@ public final class SchemasStream extends InputStream {
             final var rpcName = rpc.getQName().getLocalName();
             final var rpcInput = rpc.getInput();
             if (!rpcInput.getChildNodes().isEmpty()) {
-                final var input = new SchemaEntity(rpcInput, moduleName + "_" + rpcName + INPUT_SUFFIX, null,
-                    OBJECT_TYPE, stack, moduleName, false, definitionNames, EntityType.RPC);
+                final var input = new RpcSchemaEntity(rpcInput, moduleName + "_" + rpcName + INPUT_SUFFIX, null,
+                    OBJECT_TYPE, stack, moduleName, false, definitionNames);
                 result.add(input);
                 stack.enterSchemaTree(rpcInput.getQName());
                 for (final var child : rpcInput.getChildNodes()) {
@@ -154,8 +156,8 @@ public final class SchemasStream extends InputStream {
             }
             final var rpcOutput = rpc.getOutput();
             if (!rpcOutput.getChildNodes().isEmpty()) {
-                final var output = new SchemaEntity(rpcOutput, moduleName + "_" + rpcName + OUTPUT_SUFFIX, null,
-                    OBJECT_TYPE, stack, moduleName, false, definitionNames, EntityType.RPC);
+                final var output = new RpcSchemaEntity(rpcOutput, moduleName + "_" + rpcName + OUTPUT_SUFFIX, null,
+                    OBJECT_TYPE, stack, moduleName, false, definitionNames);
                 result.add(output);
                 stack.enterSchemaTree(rpcOutput.getQName());
                 for (final var child : rpcOutput.getChildNodes()) {
@@ -190,8 +192,8 @@ public final class SchemasStream extends InputStream {
             } else {
                 discriminator = definitionNames.getDiscriminator(node);
             }
-            final var child = new SchemaEntity(node, newTitle, discriminator, OBJECT_TYPE, stack, parentName,
-                isParentConfig, definitionNames, EntityType.NODE);
+            final var child = new NodeSchemaEntity(node, newTitle, discriminator, OBJECT_TYPE, stack, parentName,
+                isParentConfig, definitionNames);
             final var isConfig = node.isConfiguration() && isParentConfig;
             result.add(child);
             stack.enterSchemaTree(node.getQName());
@@ -222,22 +224,17 @@ public final class SchemasStream extends InputStream {
             final var actionName = actionDef.getQName().getLocalName();
             final var actionInput = actionDef.getInput();
             if (!actionInput.getChildNodes().isEmpty()) {
-                final var input = new SchemaEntity(actionInput, title + "_" + actionName + INPUT_SUFFIX, null,
-                    OBJECT_TYPE, stack, parentName, false, definitionNames, EntityType.RPC);
+                final var input = new RpcSchemaEntity(actionInput, title + "_" + actionName + INPUT_SUFFIX, null,
+                    OBJECT_TYPE, stack, parentName, false, definitionNames);
                 result.add(input);
             }
             final var actionOutput = actionDef.getOutput();
             if (!actionOutput.getChildNodes().isEmpty()) {
-                final var output = new SchemaEntity(actionOutput, title + "_" + actionName + OUTPUT_SUFFIX, null,
-                    OBJECT_TYPE, stack, parentName, false, definitionNames, EntityType.RPC);
+                final var output = new RpcSchemaEntity(actionOutput, title + "_" + actionName + OUTPUT_SUFFIX, null,
+                    OBJECT_TYPE, stack, parentName, false, definitionNames);
                 result.add(output);
             }
             stack.exit();
         }
     }
-
-    public enum EntityType {
-        NODE,
-        RPC
-    }
 }
diff --git a/restconf/restconf-openapi/src/main/java/org/opendaylight/restconf/openapi/model/NodeSchemaEntity.java b/restconf/restconf-openapi/src/main/java/org/opendaylight/restconf/openapi/model/NodeSchemaEntity.java
new file mode 100644 (file)
index 0000000..4a86524
--- /dev/null
@@ -0,0 +1,57 @@
+/*
+ * Copyright (c) 2024 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.openapi.model;
+
+import static org.opendaylight.restconf.openapi.model.PropertyEntity.isSchemaNodeMandatory;
+
+import com.fasterxml.jackson.core.JsonGenerator;
+import java.io.IOException;
+import java.util.HashMap;
+import java.util.List;
+import org.eclipse.jdt.annotation.NonNull;
+import org.eclipse.jdt.annotation.Nullable;
+import org.opendaylight.restconf.openapi.impl.DefinitionNames;
+import org.opendaylight.yangtools.yang.model.api.ContainerSchemaNode;
+import org.opendaylight.yangtools.yang.model.api.DataNodeContainer;
+import org.opendaylight.yangtools.yang.model.api.DataSchemaNode;
+import org.opendaylight.yangtools.yang.model.api.SchemaNode;
+import org.opendaylight.yangtools.yang.model.util.SchemaInferenceStack;
+
+public final class NodeSchemaEntity extends SchemaEntity {
+
+    public NodeSchemaEntity(final @NonNull SchemaNode value, final @NonNull String title,
+            final @Nullable String discriminator, final @NonNull String type,
+            final @NonNull SchemaInferenceStack context, final @NonNull String parentName, final boolean isParentConfig,
+            final @NonNull DefinitionNames definitionNames) {
+        super(value, title, discriminator, type, context, parentName, isParentConfig, definitionNames);
+    }
+
+    @Override
+    void generateProperties(final @NonNull JsonGenerator generator, final @NonNull List<String> required)
+            throws IOException {
+        final var childNodes = new HashMap<String, DataSchemaNode>();
+        for (final var childNode : ((DataNodeContainer) value()).getChildNodes()) {
+            childNodes.put(childNode.getQName().getLocalName(), childNode);
+        }
+        final boolean isValueConfig = ((DataSchemaNode) value()).isConfiguration();
+        for (final var childNode : childNodes.values()) {
+            if (shouldBeAddedAsProperty(childNode, isValueConfig)) {
+                new PropertyEntity(childNode, generator, stack(), required, parentName() + "_"
+                    + value().getQName().getLocalName(), isValueConfig, definitionNames());
+            }
+        }
+    }
+
+    private static boolean shouldBeAddedAsProperty(final DataSchemaNode childNode, final boolean isValueConfig) {
+        final boolean isChildNodeConfig = childNode.isConfiguration();
+        if (childNode instanceof ContainerSchemaNode) {
+            return isChildNodeConfig || isSchemaNodeMandatory(childNode) || !isValueConfig;
+        }
+        return isChildNodeConfig || !isValueConfig;
+    }
+}
diff --git a/restconf/restconf-openapi/src/main/java/org/opendaylight/restconf/openapi/model/RpcSchemaEntity.java b/restconf/restconf-openapi/src/main/java/org/opendaylight/restconf/openapi/model/RpcSchemaEntity.java
new file mode 100644 (file)
index 0000000..94379e1
--- /dev/null
@@ -0,0 +1,37 @@
+/*
+ * Copyright (c) 2024 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.openapi.model;
+
+import com.fasterxml.jackson.core.JsonGenerator;
+import java.io.IOException;
+import java.util.List;
+import org.eclipse.jdt.annotation.NonNull;
+import org.eclipse.jdt.annotation.Nullable;
+import org.opendaylight.restconf.openapi.impl.DefinitionNames;
+import org.opendaylight.yangtools.yang.model.api.ContainerLike;
+import org.opendaylight.yangtools.yang.model.api.SchemaNode;
+import org.opendaylight.yangtools.yang.model.util.SchemaInferenceStack;
+
+public final class RpcSchemaEntity extends SchemaEntity {
+
+    public RpcSchemaEntity(final @NonNull SchemaNode value, final @NonNull String title,
+            final @Nullable String discriminator, final @NonNull String type,
+            final @NonNull SchemaInferenceStack context, final @NonNull String parentName, final boolean isParentConfig,
+            final @NonNull DefinitionNames definitionNames) {
+        super(value, title, discriminator, type, context, parentName, isParentConfig, definitionNames);
+    }
+
+    @Override
+    void generateProperties(final @NonNull JsonGenerator generator, final @NonNull List<String> required)
+            throws IOException {
+        for (final var childNode : ((ContainerLike) value()).getChildNodes()) {
+            new PropertyEntity(childNode, generator, stack(), required, parentName(), isParentConfig(),
+                definitionNames());
+        }
+    }
+}
index 3ca5c39aff210cdd7de0e1052879330665102cc7..bb1c99cf62da3f3ac9136b9922ba06a6fe01812a 100644 (file)
@@ -9,50 +9,41 @@ package org.opendaylight.restconf.openapi.model;
 
 import static java.util.Objects.requireNonNull;
 import static java.util.Objects.requireNonNullElse;
-import static org.opendaylight.restconf.openapi.model.PropertyEntity.isSchemaNodeMandatory;
 
 import com.fasterxml.jackson.core.JsonGenerator;
 import java.io.IOException;
 import java.util.ArrayList;
-import java.util.HashMap;
 import java.util.List;
 import org.eclipse.jdt.annotation.NonNull;
 import org.eclipse.jdt.annotation.Nullable;
 import org.opendaylight.restconf.openapi.impl.DefinitionNames;
-import org.opendaylight.restconf.openapi.impl.SchemasStream;
-import org.opendaylight.yangtools.yang.model.api.ContainerLike;
-import org.opendaylight.yangtools.yang.model.api.ContainerSchemaNode;
-import org.opendaylight.yangtools.yang.model.api.DataNodeContainer;
-import org.opendaylight.yangtools.yang.model.api.DataSchemaNode;
 import org.opendaylight.yangtools.yang.model.api.SchemaNode;
 import org.opendaylight.yangtools.yang.model.util.SchemaInferenceStack;
 
 /**
  * Archetype for a Schema.
  */
-public final class SchemaEntity extends OpenApiEntity {
+public abstract sealed class SchemaEntity extends OpenApiEntity permits NodeSchemaEntity, RpcSchemaEntity {
     private final @NonNull SchemaNode value;
     private final @NonNull String title;
     private final @NonNull String discriminator;
     private final @NonNull String type;
     private final @NonNull SchemaInferenceStack stack;
     private final boolean isParentConfig;
-    private final SchemasStream.EntityType entityType;
     private final @NonNull String parentName;
     private final @NonNull DefinitionNames definitionNames;
 
-    public SchemaEntity(final @NonNull SchemaNode value, final @NonNull String title, final String discriminator,
-            @NonNull final String type, @NonNull final SchemaInferenceStack context, final String parentName,
-            final boolean isParentConfig, @NonNull final DefinitionNames definitionNames,
-            final SchemasStream.EntityType entityType) {
+    public SchemaEntity(final @NonNull SchemaNode value, final @NonNull String title,
+            final @Nullable String discriminator, final @NonNull String type,
+            final @NonNull SchemaInferenceStack context, final @NonNull String parentName, final boolean isParentConfig,
+            final @NonNull DefinitionNames definitionNames) {
         this.value = requireNonNull(value);
         this.title = requireNonNull(title);
         this.type = requireNonNull(type);
         this.stack = requireNonNull(context.copy());
         this.parentName = requireNonNull(parentName);
         this.isParentConfig = isParentConfig;
-        this.definitionNames = definitionNames;
-        this.entityType = entityType;
+        this.definitionNames = requireNonNull(definitionNames);
         this.discriminator = requireNonNullElse(discriminator, "");
     }
 
@@ -70,6 +61,26 @@ public final class SchemaEntity extends OpenApiEntity {
         generator.writeEndObject();
     }
 
+    protected @NonNull SchemaNode value() {
+        return value;
+    }
+
+    protected @NonNull SchemaInferenceStack stack() {
+        return stack;
+    }
+
+    protected @NonNull DefinitionNames definitionNames() {
+        return definitionNames;
+    }
+
+    protected boolean isParentConfig() {
+        return isParentConfig;
+    }
+
+    protected @NonNull String parentName() {
+        return parentName;
+    }
+
     private @NonNull String title() {
         return title;
     }
@@ -82,7 +93,7 @@ public final class SchemaEntity extends OpenApiEntity {
         return value.getDescription().orElse(null);
     }
 
-    private void generateRequired(final @NonNull JsonGenerator generator, final List<String> required)
+    protected void generateRequired(final @NonNull JsonGenerator generator, final List<String> required)
             throws IOException {
         if (!required.isEmpty()) {
             generator.writeArrayFieldStart("required");
@@ -93,42 +104,18 @@ public final class SchemaEntity extends OpenApiEntity {
         }
     }
 
-    private void generateProperties(final @NonNull JsonGenerator generator) throws IOException {
+    private void generateProperties(@NonNull JsonGenerator generator) throws IOException {
         final var required = new ArrayList<String>();
         generator.writeObjectFieldStart("properties");
-        stack.enterSchemaTree(value.getQName());
-        switch (entityType) {
-            case RPC:
-                for (final var childNode : ((ContainerLike) value).getChildNodes()) {
-                    new PropertyEntity(childNode, generator, stack, required, parentName, isParentConfig,
-                        definitionNames);
-                }
-                break;
-            default:
-                final var childNodes = new HashMap<String, DataSchemaNode>();
-                for (final var childNode : ((DataNodeContainer) value).getChildNodes()) {
-                    childNodes.put(childNode.getQName().getLocalName(), childNode);
-                }
-                for (final var childNode : childNodes.values()) {
-                    if (shouldBeAddedAsProperty(childNode)) {
-                        new PropertyEntity(childNode, generator, stack, required, parentName + "_"
-                            + value.getQName().getLocalName(), ((DataSchemaNode) value).isConfiguration(),
-                            definitionNames);
-                    }
-                }
-        }
-        stack.exit();
+        stack().enterSchemaTree(value().getQName());
+        generateProperties(generator, required);
+        stack().exit();
         generator.writeEndObject();
         generateRequired(generator, required);
     }
 
-    private boolean shouldBeAddedAsProperty(final DataSchemaNode childNode) {
-        if (childNode instanceof ContainerSchemaNode) {
-            return childNode.isConfiguration() || isSchemaNodeMandatory(childNode)
-                || !((DataSchemaNode) value).isConfiguration();
-        }
-        return childNode.isConfiguration() || !((DataSchemaNode) value).isConfiguration();
-    }
+    abstract void generateProperties(@NonNull JsonGenerator generator, @NonNull List<String> required)
+        throws IOException;
 
     private void generateXml(final @NonNull JsonGenerator generator) throws IOException {
         generator.writeObjectFieldStart("xml");