Turn ApiPath into a record
[netconf.git] / restconf / restconf-nb / src / main / java / org / opendaylight / restconf / server / spi / ApiPathNormalizer.java
index 0f92c20b3b7cf985b5daafae7c01f924dd4c8d5c..d2841c43430f770fba5a4ceeb85a3786cdc8b593 100644 (file)
@@ -22,6 +22,7 @@ import org.opendaylight.restconf.api.ApiPath.ListInstance;
 import org.opendaylight.restconf.common.errors.RestconfDocumentedException;
 import org.opendaylight.restconf.nb.rfc8040.Insert.PointNormalizer;
 import org.opendaylight.restconf.server.api.DatabindContext;
+import org.opendaylight.restconf.server.spi.ApiPathNormalizer.Path.Action;
 import org.opendaylight.restconf.server.spi.ApiPathNormalizer.Path.Data;
 import org.opendaylight.restconf.server.spi.ApiPathNormalizer.Path.Rpc;
 import org.opendaylight.yangtools.yang.common.ErrorTag;
@@ -37,6 +38,7 @@ import org.opendaylight.yangtools.yang.data.util.DataSchemaContext.PathMixin;
 import org.opendaylight.yangtools.yang.model.api.ActionNodeContainer;
 import org.opendaylight.yangtools.yang.model.api.DataSchemaNode;
 import org.opendaylight.yangtools.yang.model.api.EffectiveStatementInference;
+import org.opendaylight.yangtools.yang.model.api.LeafListSchemaNode;
 import org.opendaylight.yangtools.yang.model.api.ListSchemaNode;
 import org.opendaylight.yangtools.yang.model.api.TypedDataSchemaNode;
 import org.opendaylight.yangtools.yang.model.api.stmt.ActionEffectiveStatement;
@@ -231,7 +233,7 @@ public final class ApiPathNormalizer implements PointNormalizer {
             final var stack = SchemaInferenceStack.of(modelContext);
             final var stmt = stack.enterSchemaTree(rpc.argument());
             verify(rpc.equals(stmt), "Expecting %s, inferred %s", rpc, stmt);
-            return new OperationPath.Rpc(stack.toInference(), rpc);
+            return new Rpc(stack.toInference(), rpc);
         }
 
         final var stack = SchemaInferenceStack.of(modelContext);
@@ -258,7 +260,7 @@ public final class ApiPathNormalizer implements PointNormalizer {
                     final var actionStmt = action.asEffectiveStatement();
                     verify(actionStmt.equals(stmt), "Expecting %s, inferred %s", actionStmt, stmt);
 
-                    return new OperationPath.Action(stack.toInference(), YangInstanceIdentifier.of(path), actionStmt);
+                    return new Action(stack.toInference(), YangInstanceIdentifier.of(path), actionStmt);
                 }
             }
 
@@ -282,10 +284,19 @@ public final class ApiPathNormalizer implements PointNormalizer {
             if (step instanceof ListInstance listStep) {
                 final var values = listStep.keyValues();
                 final var schema = childNode.dataSchemaNode();
-                pathArg = schema instanceof ListSchemaNode listSchema
-                    ? prepareNodeWithPredicates(stack, qname, listSchema, values)
-                        // FIXME: recognize only leaf-list here, which has only a single item
-                        : prepareNodeWithValue(stack, qname, schema, values);
+                if (schema instanceof ListSchemaNode listSchema) {
+                    pathArg = prepareNodeWithPredicates(stack, qname, listSchema, values);
+                } else if (schema instanceof LeafListSchemaNode leafListSchema) {
+                    if (values.size() != 1) {
+                        throw new RestconfDocumentedException("Entry '" + qname + "' requires one value predicate.",
+                            ErrorType.PROTOCOL, ErrorTag.BAD_ATTRIBUTE);
+                    }
+                    pathArg = new NodeWithValue<>(qname, parserJsonValue(stack, leafListSchema, values.get(0)));
+                } else {
+                    throw new RestconfDocumentedException(
+                        "Entry '" + qname + "' does not take a key or value predicate.",
+                        ErrorType.PROTOCOL, ErrorTag.MISSING_ATTRIBUTE);
+                }
             } else {
                 if (childNode.dataSchemaNode() instanceof ListSchemaNode list && !list.getKeyDefinition().isEmpty()) {
                     throw new RestconfDocumentedException(
@@ -376,7 +387,7 @@ public final class ApiPathNormalizer implements PointNormalizer {
         if (path instanceof Data dataPath) {
             return dataPath;
         }
-        if (path instanceof OperationPath.Action actionPath) {
+        if (path instanceof Action actionPath) {
             return actionPath;
         }
         throw new RestconfDocumentedException("Unexpected path " + path, ErrorType.PROTOCOL, ErrorTag.DATA_MISSING);
@@ -431,14 +442,6 @@ public final class ApiPathNormalizer implements PointNormalizer {
         }
     }
 
-    private NodeWithValue<?> prepareNodeWithValue(final SchemaInferenceStack stack, final QName qname,
-            final DataSchemaNode schema, final List<String> keyValues) {
-        // TODO: qname should be always equal to schema.getQName(), right?
-        return new NodeWithValue<>(qname, prepareValueByType(stack, schema,
-            // FIXME: ahem: we probably want to do something differently here
-            keyValues.get(0)));
-    }
-
     private @NonNull QNameModule resolveNamespace(final String moduleName) {
         final var it = databind.modelContext().findModuleStatements(moduleName).iterator();
         if (it.hasNext()) {