Split up prepareValueByType() 85/110985/4
authorRobert Varga <robert.varga@pantheon.tech>
Thu, 21 Mar 2024 13:49:47 +0000 (14:49 +0100)
committerRobert Varga <robert.varga@pantheon.tech>
Thu, 21 Mar 2024 14:30:57 +0000 (15:30 +0100)
This method does some heavy lifting in an atomic unit. Split out
DataSchemaNode type checking and clarify leafref resolution.

JIRA: NETCONF-1265
Change-Id: I7be50b5692ea7f33af5444688fc462edb2b591ec
Signed-off-by: Robert Varga <robert.varga@pantheon.tech>
restconf/restconf-nb/src/main/java/org/opendaylight/restconf/server/spi/ApiPathNormalizer.java

index 5da79c8bff19147ede4c26b4f6009e17c2af88d5..58f8e4982d7567a04272a3e27841847e841177ee 100644 (file)
@@ -11,6 +11,7 @@ import static com.google.common.base.Verify.verify;
 import static com.google.common.base.Verify.verifyNotNull;
 import static java.util.Objects.requireNonNull;
 
+import com.google.common.base.VerifyException;
 import com.google.common.collect.ImmutableMap;
 import java.text.ParseException;
 import java.util.ArrayList;
@@ -37,10 +38,9 @@ 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.EffectiveModelContext;
-import org.opendaylight.yangtools.yang.model.api.LeafListSchemaNode;
-import org.opendaylight.yangtools.yang.model.api.LeafSchemaNode;
 import org.opendaylight.yangtools.yang.model.api.ListSchemaNode;
 import org.opendaylight.yangtools.yang.model.api.TypeDefinition;
+import org.opendaylight.yangtools.yang.model.api.TypedDataSchemaNode;
 import org.opendaylight.yangtools.yang.model.api.stmt.ActionEffectiveStatement;
 import org.opendaylight.yangtools.yang.model.api.stmt.IdentityEffectiveStatement;
 import org.opendaylight.yangtools.yang.model.api.stmt.InputEffectiveStatement;
@@ -338,17 +338,23 @@ public final class ApiPathNormalizer implements PointNormalizer {
 
     private Object prepareValueByType(final SchemaInferenceStack stack, final DataSchemaNode schemaNode,
             final @NonNull String value) {
-
-        TypeDefinition<? extends TypeDefinition<?>> typedef;
-        if (schemaNode instanceof LeafListSchemaNode leafList) {
-            typedef = leafList.getType();
-        } else {
-            typedef = ((LeafSchemaNode) schemaNode).getType();
+        if (schemaNode instanceof TypedDataSchemaNode typedSchema) {
+            return prepareValueByType(stack, typedSchema, typedSchema.getType(), value);
         }
-        if (typedef instanceof LeafrefTypeDefinition leafref) {
+        throw new VerifyException("Unhandled schema " + schemaNode + " decoding '" + value + "'");
+    }
+
+    private Object prepareValueByType(final SchemaInferenceStack stack, final TypedDataSchemaNode schemaNode,
+            final TypeDefinition<?> unresolved, final @NonNull String value) {
+        // Resolve 'type leafref' before dispatching on type
+        final TypeDefinition<?> typedef;
+        if (unresolved instanceof LeafrefTypeDefinition leafref) {
             typedef = stack.resolveLeafref(leafref);
+        } else {
+            typedef = unresolved;
         }
 
+        // Complex types
         if (typedef instanceof IdentityrefTypeDefinition) {
             return toIdentityrefQName(value, schemaNode);
         }
@@ -356,9 +362,11 @@ public final class ApiPathNormalizer implements PointNormalizer {
             return toInstanceIdentifier(value, schemaNode);
         }
 
+        // Simple types
+        final var codec = verifyNotNull(TypeDefinitionAwareCodec.from(typedef), "Unhandled type %s decoding %s",
+            typedef, value);
         try {
-            return verifyNotNull(TypeDefinitionAwareCodec.from(typedef),
-                "Unhandled type %s decoding %s", typedef, value).deserialize(value);
+            return codec.deserialize(value);
         } catch (IllegalArgumentException e) {
             throw new RestconfDocumentedException("Invalid value '" + value + "' for " + schemaNode.getQName(),
                 ErrorType.PROTOCOL, ErrorTag.INVALID_VALUE, e);
@@ -373,7 +381,7 @@ public final class ApiPathNormalizer implements PointNormalizer {
             keyValues.get(0)));
     }
 
-    private YangInstanceIdentifier toInstanceIdentifier(final String value, final DataSchemaNode schemaNode) {
+    private YangInstanceIdentifier toInstanceIdentifier(final String value, final TypedDataSchemaNode schemaNode) {
         if (value.isEmpty() || !value.startsWith("/")) {
             throw new RestconfDocumentedException("Invalid value '" + value + "' for " + schemaNode.getQName(),
                 ErrorType.PROTOCOL, ErrorTag.INVALID_VALUE);
@@ -387,7 +395,7 @@ public final class ApiPathNormalizer implements PointNormalizer {
         }
     }
 
-    private QName toIdentityrefQName(final String value, final DataSchemaNode schemaNode) {
+    private QName toIdentityrefQName(final String value, final TypedDataSchemaNode schemaNode) {
         final QNameModule namespace;
         final String localName;
         final int firstColon = value.indexOf(':');