Move patch target resolution
[netconf.git] / restconf / restconf-nb / src / main / java / org / opendaylight / restconf / server / spi / ApiPathNormalizer.java
index 6beae7ce94ada97dfc5e1dab578c9df41d88db48..b54c081d96324a9514c1dd335759cb7ad7cbad04 100644 (file)
@@ -15,6 +15,7 @@ import com.google.common.base.VerifyException;
 import com.google.common.collect.ImmutableList;
 import com.google.common.collect.ImmutableMap;
 import java.io.IOException;
+import java.text.ParseException;
 import java.util.ArrayList;
 import java.util.List;
 import org.eclipse.jdt.annotation.NonNull;
@@ -52,7 +53,6 @@ import org.opendaylight.yangtools.yang.model.api.TypedDataSchemaNode;
 import org.opendaylight.yangtools.yang.model.api.stmt.RpcEffectiveStatement;
 import org.opendaylight.yangtools.yang.model.api.stmt.SchemaTreeEffectiveStatement;
 import org.opendaylight.yangtools.yang.model.util.SchemaInferenceStack;
-import org.opendaylight.yangtools.yang.model.util.SchemaInferenceStack.Inference;
 
 /**
  * Utility for normalizing {@link ApiPath}s. An {@link ApiPath} can represent a number of different constructs, as
@@ -73,8 +73,7 @@ public final class ApiPathNormalizer implements PointNormalizer {
     public @NonNull DatabindPath normalizePath(final ApiPath apiPath) {
         final var it = apiPath.steps().iterator();
         if (!it.hasNext()) {
-            return new Data(databind, Inference.ofDataTreePath(databind.modelContext()), YangInstanceIdentifier.of(),
-                databind.schemaTree().getRoot());
+            return new Data(databind);
         }
 
         // First step is somewhat special:
@@ -212,6 +211,29 @@ public final class ApiPathNormalizer implements PointNormalizer {
             ErrorType.PROTOCOL, ErrorTag.DATA_MISSING);
     }
 
+    public static @NonNull Data normalizeSubResource(final Data resource, final ApiPath subResource) {
+        // If subResource is empty just return the resource
+        final var urlPath = resource.instance();
+        if (subResource.steps().isEmpty()) {
+            return resource;
+        }
+        final var normalizer = new ApiPathNormalizer(resource.databind());
+        if (urlPath.isEmpty()) {
+            // URL indicates the datastore resource, let's just normalize targetPath
+            return normalizer.normalizeDataPath(subResource);
+        }
+
+        // FIXME: We are re-parsing the concatenation. We should provide enough context for the bottom half of
+        //        normalizePath() logic instead
+        final String targetUrl = normalizer.canonicalize(urlPath).toString() + "/" + subResource.toString();
+        try {
+            return normalizer.normalizeDataPath(ApiPath.parse(targetUrl));
+        } catch (ParseException e) {
+            throw new RestconfDocumentedException("Failed to parse target " + targetUrl,
+                ErrorType.PROTOCOL, ErrorTag.MALFORMED_MESSAGE, e);
+        }
+    }
+
     @Override
     public PathArgument normalizePoint(final ApiPath value) {
         final var path = normalizePath(value);