Deprecate simple DataTreeFactory.create()
[yangtools.git] / data / yang-data-tree-ri / src / main / java / org / opendaylight / yangtools / yang / data / tree / impl / InMemoryDataTreeModification.java
index 5d1012f5c80de06356ec7cd24e66990545a2f187..c850d591bdca642b90e05a853a1b55f1e62f434d 100644 (file)
@@ -11,8 +11,10 @@ import static com.google.common.base.Preconditions.checkArgument;
 import static com.google.common.base.Preconditions.checkState;
 import static java.util.Objects.requireNonNull;
 
+import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
 import java.lang.invoke.MethodHandles;
 import java.lang.invoke.VarHandle;
+import java.util.Map.Entry;
 import java.util.Optional;
 import org.eclipse.jdt.annotation.Nullable;
 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
@@ -23,15 +25,14 @@ import org.opendaylight.yangtools.yang.data.api.schema.tree.StoreTreeNodes;
 import org.opendaylight.yangtools.yang.data.tree.api.CursorAwareDataTreeModification;
 import org.opendaylight.yangtools.yang.data.tree.api.DataTreeModificationCursor;
 import org.opendaylight.yangtools.yang.data.tree.api.SchemaValidationFailedException;
+import org.opendaylight.yangtools.yang.data.tree.api.VersionInfo;
 import org.opendaylight.yangtools.yang.data.tree.impl.node.TreeNode;
 import org.opendaylight.yangtools.yang.data.tree.impl.node.Version;
 import org.opendaylight.yangtools.yang.model.api.EffectiveModelContext;
-import org.opendaylight.yangtools.yang.model.api.EffectiveModelContextProvider;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
-final class InMemoryDataTreeModification extends AbstractCursorAware implements CursorAwareDataTreeModification,
-        EffectiveModelContextProvider {
+final class InMemoryDataTreeModification extends AbstractCursorAware implements CursorAwareDataTreeModification {
     private static final Logger LOG = LoggerFactory.getLogger(InMemoryDataTreeModification.class);
 
     private static final byte STATE_OPEN    = 0;
@@ -55,6 +56,7 @@ final class InMemoryDataTreeModification extends AbstractCursorAware implements
 
     // All access needs to go through STATE
     @SuppressWarnings("unused")
+    @SuppressFBWarnings(value = "UUF_UNUSED_FIELD", justification = "https://github.com/spotbugs/spotbugs/issues/2749")
     private volatile byte state;
 
     InMemoryDataTreeModification(final InMemoryDataTreeSnapshot snapshot,
@@ -72,7 +74,7 @@ final class InMemoryDataTreeModification extends AbstractCursorAware implements
          * node in modification and in data tree (if successfully
          * committed) will be same and will not change.
          */
-        version = snapshot.getRootNode().getSubtreeVersion().next();
+        version = snapshot.getRootNode().subtreeVersion().next();
     }
 
     ModifiedNode getRootModification() {
@@ -88,8 +90,8 @@ final class InMemoryDataTreeModification extends AbstractCursorAware implements
     }
 
     @Override
-    public EffectiveModelContext getEffectiveModelContext() {
-        return snapshot.getEffectiveModelContext();
+    public EffectiveModelContext modelContext() {
+        return snapshot.modelContext();
     }
 
     @Override
@@ -114,20 +116,34 @@ final class InMemoryDataTreeModification extends AbstractCursorAware implements
 
     @Override
     public Optional<NormalizedNode> readNode(final YangInstanceIdentifier path) {
+        final var terminal = resolveTerminal(path);
+        final var terminalPath = terminal.getKey();
+
+        final var result = resolveSnapshot(terminalPath, terminal.getValue());
+        return result == null ? Optional.empty() : NormalizedNodes.findNode(terminalPath, result.data(), path);
+    }
+
+    @Override
+    public Optional<VersionInfo> readVersionInfo(final YangInstanceIdentifier path) {
+        final var terminal = resolveTerminal(path);
+        final var terminalPath = terminal.getKey();
+
+        final var result = resolveSnapshot(terminalPath, terminal.getValue());
+        return result == null ? Optional.empty()
+            : StoreTreeNodes.findNode(result, path.relativeTo(terminalPath).orElseThrow())
+                .flatMap(treeNode -> Optional.ofNullable(treeNode.subtreeVersion().readInfo()));
+    }
+
+    private Entry<YangInstanceIdentifier, ModifiedNode> resolveTerminal(final YangInstanceIdentifier path) {
         /*
-         * Walk the tree from the top, looking for the first node between root and
-         * the requested path which has been modified. If no such node exists,
-         * we use the node itself.
+         * Walk the tree from the top, looking for the first node between root and the requested path which has been
+         * modified. If no such node exists, we use the node itself.
          */
-        final var terminal = StoreTreeNodes.findClosestsOrFirstMatch(rootNode, path,
+        return StoreTreeNodes.findClosestsOrFirstMatch(rootNode, path,
             input -> switch (input.getOperation()) {
                 case DELETE, MERGE, WRITE -> true;
                 case TOUCH, NONE -> false;
             });
-        final var terminalPath = terminal.getKey();
-
-        final var result = resolveSnapshot(terminalPath, terminal.getValue());
-        return result == null ? Optional.empty() : NormalizedNodes.findNode(terminalPath, result.getData(), path);
     }
 
     @SuppressWarnings("checkstyle:illegalCatch")
@@ -212,8 +228,7 @@ final class InMemoryDataTreeModification extends AbstractCursorAware implements
         if (newRoot == null) {
             throw new IllegalStateException("Data tree root is not present, possibly removed by previous modification");
         }
-        return new InMemoryDataTreeSnapshot(snapshot.getEffectiveModelContext(), newRoot, strategyTree)
-            .newModification();
+        return new InMemoryDataTreeSnapshot(snapshot.modelContext(), newRoot, strategyTree).newModification();
     }
 
     Version getVersion() {