Refactor ModificationApplyOperation 93/107693/18
authorRobert Varga <robert.varga@pantheon.tech>
Mon, 4 Sep 2023 18:50:25 +0000 (20:50 +0200)
committerRobert Varga <robert.varga@pantheon.tech>
Tue, 3 Oct 2023 09:09:57 +0000 (11:09 +0200)
Use currentMeta as a @Nullable TreeNode, replacing checks as
appropriate.

JIRA: YANGTOOLS-1538
Change-Id: I7dfeea43515fe0dd3099ed2dd48086fd8f297ea8
Signed-off-by: Robert Varga <robert.varga@pantheon.tech>
17 files changed:
data/yang-data-tree-ri/src/main/java/org/opendaylight/yangtools/yang/data/tree/impl/AbstractDataTreeTip.java
data/yang-data-tree-ri/src/main/java/org/opendaylight/yangtools/yang/data/tree/impl/AbstractNodeContainerModificationStrategy.java
data/yang-data-tree-ri/src/main/java/org/opendaylight/yangtools/yang/data/tree/impl/AbstractValidation.java
data/yang-data-tree-ri/src/main/java/org/opendaylight/yangtools/yang/data/tree/impl/AutomaticLifecycleMixin.java
data/yang-data-tree-ri/src/main/java/org/opendaylight/yangtools/yang/data/tree/impl/ChoiceModificationStrategy.java
data/yang-data-tree-ri/src/main/java/org/opendaylight/yangtools/yang/data/tree/impl/ContainerModificationStrategy.java
data/yang-data-tree-ri/src/main/java/org/opendaylight/yangtools/yang/data/tree/impl/InMemoryDataTreeCandidate.java
data/yang-data-tree-ri/src/main/java/org/opendaylight/yangtools/yang/data/tree/impl/InMemoryDataTreeModification.java
data/yang-data-tree-ri/src/main/java/org/opendaylight/yangtools/yang/data/tree/impl/InMemoryDataTreeSnapshot.java
data/yang-data-tree-ri/src/main/java/org/opendaylight/yangtools/yang/data/tree/impl/ListModificationStrategy.java
data/yang-data-tree-ri/src/main/java/org/opendaylight/yangtools/yang/data/tree/impl/MapEntryModificationStrategy.java
data/yang-data-tree-ri/src/main/java/org/opendaylight/yangtools/yang/data/tree/impl/MapModificationStrategy.java
data/yang-data-tree-ri/src/main/java/org/opendaylight/yangtools/yang/data/tree/impl/ModificationApplyOperation.java
data/yang-data-tree-ri/src/main/java/org/opendaylight/yangtools/yang/data/tree/impl/ModifiedNode.java
data/yang-data-tree-ri/src/main/java/org/opendaylight/yangtools/yang/data/tree/impl/OperationWithModification.java
data/yang-data-tree-ri/src/main/java/org/opendaylight/yangtools/yang/data/tree/impl/SchemaAwareApplyOperation.java
data/yang-data-tree-ri/src/main/java/org/opendaylight/yangtools/yang/data/tree/impl/ValueNodeModificationStrategy.java

index 494b5ba483dafd799f640e31c91bed1a9901558f..5d54527db44a4e84071179c226fabece31669b16 100644 (file)
@@ -7,7 +7,6 @@
  */
 package org.opendaylight.yangtools.yang.data.tree.impl;
 
-import java.util.Optional;
 import org.eclipse.jdt.annotation.NonNull;
 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
 import org.opendaylight.yangtools.yang.data.tree.api.DataTreeCandidateTip;
@@ -29,8 +28,8 @@ abstract class AbstractDataTreeTip implements DataTreeTip {
     @Override
     public final void validate(final DataTreeModification modification) throws DataValidationFailedException {
         final var m = accessMod(modification, "validate");
-        m.getStrategy().checkApplicable(new ModificationPath(getRootPath()), m.getRootModification(),
-            Optional.of(getTipRoot()), m.getVersion());
+        m.getStrategy().checkApplicable(new ModificationPath(getRootPath()), m.getRootModification(), getTipRoot(),
+            m.getVersion());
     }
 
     @Override
@@ -43,9 +42,9 @@ abstract class AbstractDataTreeTip implements DataTreeTip {
             return new NoopDataTreeCandidate(YangInstanceIdentifier.of(), root, currentRoot);
         }
 
-        final var newRoot = m.getStrategy().apply(m.getRootModification(), Optional.of(currentRoot), m.getVersion())
-            .orElseThrow(() -> new IllegalStateException("Apply strategy failed to produce root node for modification "
-                + modification));
+        final var newRoot = m.getStrategy().apply(m.getRootModification(), currentRoot, m.getVersion())
+            .orElseThrow(() -> new IllegalStateException(
+                "Apply strategy failed to produce root node for modification " + modification));
         return new InMemoryDataTreeCandidate(YangInstanceIdentifier.of(), root, currentRoot, newRoot);
     }
 
index 30240ce098cf2ea6aed5f9851aebe7de5061eb5e..b47df761f2aad766de955ced56393d781a66577d 100644 (file)
@@ -11,12 +11,11 @@ import static com.google.common.base.Preconditions.checkArgument;
 import static java.util.Objects.requireNonNull;
 
 import com.google.common.base.MoreObjects.ToStringHelper;
-import com.google.common.base.Verify;
+import com.google.common.base.VerifyException;
 import java.util.Collection;
 import java.util.Optional;
 import org.eclipse.jdt.annotation.NonNull;
 import org.eclipse.jdt.annotation.Nullable;
-import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.PathArgument;
 import org.opendaylight.yangtools.yang.data.api.schema.DistinctNodeContainer;
 import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
 import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNodeContainer;
@@ -166,7 +165,7 @@ abstract sealed class AbstractNodeContainerModificationStrategy<T extends DataSc
 
     @Override
     protected TreeNode applyWrite(final ModifiedNode modification, final NormalizedNode newValue,
-            final Optional<? extends TreeNode> currentMeta, final Version version) {
+            final TreeNode currentMeta, final Version version) {
         final var newValueMeta = TreeNode.of(newValue, version);
         if (modification.isEmpty()) {
             return newValueMeta;
@@ -211,14 +210,11 @@ abstract sealed class AbstractNodeContainerModificationStrategy<T extends DataSc
     @SuppressWarnings({ "rawtypes", "unchecked" })
     private TreeNode mutateChildren(final MutableTreeNode meta, final NormalizedNodeContainerBuilder data,
             final Version nodeVersion, final Iterable<ModifiedNode> modifications) {
-
-        for (final ModifiedNode mod : modifications) {
-            final PathArgument id = mod.getIdentifier();
-            final Optional<? extends TreeNode> cm = meta.findChildByArg(id);
-
-            final Optional<? extends TreeNode> result = resolveChildOperation(id).apply(mod, cm, nodeVersion);
+        for (var mod : modifications) {
+            final var id = mod.getIdentifier();
+            final var result = resolveChildOperation(id).apply(mod, meta.childByArg(id), nodeVersion);
             if (result.isPresent()) {
-                final TreeNode tn = result.orElseThrow();
+                final var tn = result.orElseThrow();
                 meta.putChild(tn);
                 data.addChild(tn.getData());
             } else {
@@ -238,10 +234,12 @@ abstract sealed class AbstractNodeContainerModificationStrategy<T extends DataSc
          * we do that, ModifiedNode children will look like this node were a TOUCH and we will let applyTouch() do the
          * heavy lifting of applying the children recursively (either through here or through applyWrite().
          */
-        final NormalizedNode value = modification.getWrittenValue();
+        final var value = modification.getWrittenValue();
+        if (!(value instanceof DistinctNodeContainer<?, ?> containerValue)) {
+            throw new VerifyException("Attempted to merge non-container " + value);
+        }
 
-        Verify.verify(value instanceof DistinctNodeContainer, "Attempted to merge non-container %s", value);
-        for (var c : ((DistinctNodeContainer<?, ?>) value).body()) {
+        for (var c : containerValue.body()) {
             final var id = c.name();
             modification.modifyChild(id, resolveChildOperation(id), version);
         }
@@ -289,7 +287,7 @@ abstract sealed class AbstractNodeContainerModificationStrategy<T extends DataSc
                 // and then append any child entries.
                 if (!modification.isEmpty()) {
                     // Version does not matter here as we'll throw it out
-                    final var current = apply(modification, modification.getOriginal(), Version.initial());
+                    final var current = apply(modification, modification.original(), Version.initial());
                     if (current.isPresent()) {
                         modification.updateValue(LogicalOperation.WRITE, current.orElseThrow().getData());
                         mergeChildrenIntoModification(modification, valueChildren, version);
@@ -351,9 +349,9 @@ abstract sealed class AbstractNodeContainerModificationStrategy<T extends DataSc
 
     @Override
     protected final void checkTouchApplicable(final ModificationPath path, final NodeModification modification,
-            final Optional<? extends TreeNode> current, final Version version) throws DataValidationFailedException {
+            final TreeNode currentMeta, final Version version) throws DataValidationFailedException {
         final TreeNode currentNode;
-        if (current.isEmpty()) {
+        if (currentMeta == null) {
             currentNode = defaultTreeNode();
             if (currentNode == null) {
                 if (modification.original() == null) {
@@ -366,7 +364,7 @@ abstract sealed class AbstractNodeContainerModificationStrategy<T extends DataSc
                     "Node was deleted by other transaction.");
             }
         } else {
-            currentNode = current.orElseThrow();
+            currentNode = currentMeta;
         }
 
         checkChildPreconditions(path, modification, currentNode, version);
@@ -389,9 +387,9 @@ abstract sealed class AbstractNodeContainerModificationStrategy<T extends DataSc
 
     @Override
     protected final void checkMergeApplicable(final ModificationPath path, final NodeModification modification,
-            final Optional<? extends TreeNode> current, final Version version) throws DataValidationFailedException {
-        if (current.isPresent()) {
-            checkChildPreconditions(path, modification, current.orElseThrow(), version);
+            final TreeNode currentMeta, final Version version) throws DataValidationFailedException {
+        if (currentMeta != null) {
+            checkChildPreconditions(path, modification, currentMeta, version);
         }
     }
 
@@ -400,13 +398,13 @@ abstract sealed class AbstractNodeContainerModificationStrategy<T extends DataSc
      *
      * @param path current node path
      * @param modification current modification
-     * @param current Current data tree node.
+     * @param currentMeta Current data tree node.
      */
     private void checkChildPreconditions(final ModificationPath path, final NodeModification modification,
-            final TreeNode current, final Version version) throws DataValidationFailedException {
-        for (final NodeModification childMod : modification.getChildren()) {
-            final PathArgument childId = childMod.getIdentifier();
-            final Optional<? extends TreeNode> childMeta = current.findChildByArg(childId);
+            final @NonNull TreeNode currentMeta, final Version version) throws DataValidationFailedException {
+        for (var childMod : modification.getChildren()) {
+            final var childId = childMod.getIdentifier();
+            final var childMeta = currentMeta.childByArg(childId);
 
             path.push(childId);
             try {
index 38907df628e74f583565ad9a65e83ad1883605df..e69b959a7d324bf1be8391e7aea6ebdc4bf17cc0 100644 (file)
@@ -61,31 +61,31 @@ abstract sealed class AbstractValidation extends ModificationApplyOperation
     }
 
     @Override
-    final Optional<? extends TreeNode> apply(final ModifiedNode modification,
-            final Optional<? extends TreeNode> storeMeta, final Version version) {
-        var validated = modification.validatedNode(this, storeMeta);
+    final Optional<? extends TreeNode> apply(final ModifiedNode modification, final TreeNode currentMeta,
+            final Version version) {
+        var validated = modification.validatedNode(this, currentMeta);
         if (validated != null) {
             return validated.toOptional();
         }
 
         // This might also mean the delegate is maintaining validation
         if (delegate instanceof AbstractValidation) {
-            validated = modification.validatedNode(delegate, storeMeta);
+            validated = modification.validatedNode(delegate, currentMeta);
             if (validated != null) {
                 return validated.toOptional();
             }
         }
 
         // Deal with the result moving on us
-        final var ret = delegate.apply(modification, storeMeta, version);
+        final var ret = delegate.apply(modification, currentMeta, version);
         ret.ifPresent(meta -> enforceOnData(meta.getData()));
         return ret;
     }
 
     @Override
     final void checkApplicable(final ModificationPath path, final NodeModification modification,
-            final Optional<? extends TreeNode> current, final Version version) throws DataValidationFailedException {
-        delegate.checkApplicable(path, modification, current, version);
+            final TreeNode currentMeta, final Version version) throws DataValidationFailedException {
+        delegate.checkApplicable(path, modification, currentMeta, version);
         if (!(modification instanceof ModifiedNode modified)) {
             // FIXME: 7.0.0: turn this into a verify?
             LOG.debug("Could not validate {}, does not implement expected class {}", modification, ModifiedNode.class);
@@ -93,13 +93,13 @@ abstract sealed class AbstractValidation extends ModificationApplyOperation
         }
 
         if (delegate instanceof AbstractValidation) {
-            checkApplicable(path, verifyNotNull(modified.validatedNode(delegate, current)).toOptional());
+            checkApplicable(path, verifyNotNull(modified.validatedNode(delegate, currentMeta)).toOptional());
             return;
         }
 
         // We need to actually perform the operation to deal with merge in a sane manner. We know the modification
         // is immutable, so the result of validation will probably not change. Note we should not be checking number
-        final Optional<? extends TreeNode> applied = delegate.apply(modified, current, version);
+        final var applied = delegate.apply(modified, currentMeta, version);
         checkApplicable(path, applied);
 
         // Everything passed. We now have a snapshot of the result node, it would be too bad if we just threw it out.
@@ -108,7 +108,7 @@ abstract sealed class AbstractValidation extends ModificationApplyOperation
         // - the effective model context (therefore, the fact this object is associated with the modification)
         //
         // So let's stash the result. We will pick it up during apply operation.
-        modified.setValidatedNode(this, current, applied);
+        modified.setValidatedNode(this, currentMeta, applied);
     }
 
     private void checkApplicable(final ModificationPath path, final Optional<? extends TreeNode> applied)
index 89467acdbb69ae6e5ff9fe5f83994f9749584912..fa16bbd8e9d8da1aa474ebc12f9959134d568ac6 100644 (file)
@@ -10,6 +10,8 @@ package org.opendaylight.yangtools.yang.data.tree.impl;
 import static com.google.common.base.Preconditions.checkState;
 
 import java.util.Optional;
+import org.eclipse.jdt.annotation.NonNull;
+import org.eclipse.jdt.annotation.Nullable;
 import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
 import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNodeContainer;
 import org.opendaylight.yangtools.yang.data.tree.api.ModificationType;
@@ -22,52 +24,51 @@ import org.opendaylight.yangtools.yang.data.tree.impl.node.Version;
  */
 final class AutomaticLifecycleMixin {
     /**
-     * This is a capture of {@link ModificationApplyOperation#apply(ModifiedNode, Optional, Version)}.
+     * This is a capture of {@link ModificationApplyOperation#apply(ModifiedNode, TreeNode, Version)}.
      */
     @FunctionalInterface
     interface Apply {
-        Optional<? extends TreeNode> apply(ModifiedNode modification, Optional<? extends TreeNode> storeMeta,
-                Version version);
+        Optional<? extends TreeNode> apply(ModifiedNode modification, @Nullable TreeNode currentMeta, Version version);
     }
 
     /**
      * This is a capture of
-     * {@link SchemaAwareApplyOperation#applyWrite(ModifiedNode, NormalizedNode, Optional, Version)}.
+     * {@link SchemaAwareApplyOperation#applyWrite(ModifiedNode, NormalizedNode, TreeNode, Version)}.
      */
     @FunctionalInterface
     interface ApplyWrite {
-        TreeNode applyWrite(ModifiedNode modification, NormalizedNode newValue,
-                Optional<? extends TreeNode> storeMeta, Version version);
+        TreeNode applyWrite(ModifiedNode modification, NormalizedNode newValue, @Nullable TreeNode currentMeta,
+            Version version);
     }
 
     private AutomaticLifecycleMixin() {
-
+        // Hidden on purpose
     }
 
     static Optional<? extends TreeNode> apply(final Apply delegate, final ApplyWrite writeDelegate,
-            final NormalizedNode emptyNode, final ModifiedNode modification,
-            final Optional<? extends TreeNode> storeMeta, final Version version) {
+            final NormalizedNode emptyNode, final ModifiedNode modification, final @Nullable TreeNode currentMeta,
+            final Version version) {
         final Optional<? extends TreeNode> ret;
         if (modification.getOperation() == LogicalOperation.DELETE) {
             if (modification.isEmpty()) {
-                return delegate.apply(modification, storeMeta, version);
+                return delegate.apply(modification, currentMeta, version);
             }
             // Delete with children, implies it really is an empty write
-            ret = Optional.of(writeDelegate.applyWrite(modification, emptyNode, storeMeta, version));
-        } else if (modification.getOperation() == LogicalOperation.TOUCH && storeMeta.isEmpty()) {
-            ret = applyTouch(delegate, emptyNode, modification, storeMeta, version);
+            ret = Optional.of(writeDelegate.applyWrite(modification, emptyNode, currentMeta, version));
+        } else if (modification.getOperation() == LogicalOperation.TOUCH && currentMeta == null) {
+            ret = applyTouch(delegate, emptyNode, modification, null, version);
         } else {
             // No special handling required here, run normal apply operation
-            ret = delegate.apply(modification, storeMeta, version);
+            ret = delegate.apply(modification, currentMeta, version);
         }
 
-        return ret.isPresent() ? disappearResult(modification, ret.orElseThrow(), storeMeta) : ret;
+        return ret.isPresent() ? disappearResult(modification, ret.orElseThrow(), currentMeta) : ret;
     }
 
     private static Optional<? extends TreeNode> applyTouch(final Apply delegate, final NormalizedNode emptyNode,
-            final ModifiedNode modification, final Optional<? extends TreeNode> storeMeta, final Version version) {
+            final ModifiedNode modification, final @Nullable TreeNode currentMeta, final Version version) {
         // Container is not present, let's take care of the 'magically appear' part of our job
-        final Optional<? extends TreeNode> ret = delegate.apply(modification, fakeMeta(emptyNode, version), version);
+        final var ret = delegate.apply(modification, fakeMeta(emptyNode, version), version);
 
         // If the delegate indicated SUBTREE_MODIFIED, account for the fake and report APPEARED
         if (modification.getModificationType() == ModificationType.SUBTREE_MODIFIED) {
@@ -77,7 +78,7 @@ final class AutomaticLifecycleMixin {
     }
 
     private static Optional<? extends TreeNode> disappearResult(final ModifiedNode modification, final TreeNode result,
-            final Optional<? extends TreeNode> storeMeta) {
+            final @Nullable TreeNode currentMeta) {
         // Check if the result is in fact empty before pulling any tricks
         if (!isEmpty(result)) {
             return Optional.of(result);
@@ -85,7 +86,7 @@ final class AutomaticLifecycleMixin {
 
         // We are pulling the 'disappear' trick, but what we report can be three different things
         final ModificationType finalType;
-        if (storeMeta.isEmpty()) {
+        if (currentMeta == null) {
             // ... there was nothing in the datastore, no change
             finalType = ModificationType.UNMODIFIED;
         } else if (modification.getModificationType() == ModificationType.WRITE) {
@@ -99,8 +100,8 @@ final class AutomaticLifecycleMixin {
         return Optional.empty();
     }
 
-    private static Optional<TreeNode> fakeMeta(final NormalizedNode emptyNode, final Version version) {
-        return Optional.of(TreeNode.of(emptyNode, version));
+    private static @NonNull TreeNode fakeMeta(final NormalizedNode emptyNode, final Version version) {
+        return TreeNode.of(emptyNode, version);
     }
 
     private static boolean isEmpty(final TreeNode treeNode) {
index 8d842c66e0535462028cea64c0470740369c3066..9420a6527011026a0cfb0011ad365920271b1e8a 100644 (file)
@@ -76,9 +76,9 @@ final class ChoiceModificationStrategy extends Visible<ChoiceSchemaNode> {
     }
 
     @Override
-    Optional<? extends TreeNode> apply(final ModifiedNode modification, final Optional<? extends TreeNode> storeMeta,
+    Optional<? extends TreeNode> apply(final ModifiedNode modification, final TreeNode currentMeta,
             final Version version) {
-        return AutomaticLifecycleMixin.apply(super::apply, this::applyWrite, emptyNode, modification, storeMeta,
+        return AutomaticLifecycleMixin.apply(super::apply, this::applyWrite, emptyNode, modification, currentMeta,
             version);
     }
 
@@ -127,22 +127,22 @@ final class ChoiceModificationStrategy extends Visible<ChoiceSchemaNode> {
 
     @Override
     protected TreeNode applyMerge(final ModifiedNode modification, final TreeNode currentMeta, final Version version) {
-        final TreeNode ret = super.applyMerge(modification, currentMeta, version);
+        final var ret = super.applyMerge(modification, currentMeta, version);
         enforceCases(ret);
         return ret;
     }
 
     @Override
     protected TreeNode applyWrite(final ModifiedNode modification, final NormalizedNode newValue,
-            final Optional<? extends TreeNode> currentMeta, final Version version) {
-        final TreeNode ret = super.applyWrite(modification, newValue, currentMeta, version);
+            final TreeNode currentMeta, final Version version) {
+        final var ret = super.applyWrite(modification, newValue, currentMeta, version);
         enforceCases(ret);
         return ret;
     }
 
     @Override
     protected TreeNode applyTouch(final ModifiedNode modification, final TreeNode currentMeta, final Version version) {
-        final TreeNode ret = super.applyTouch(modification, currentMeta, version);
+        final var ret = super.applyTouch(modification, currentMeta, version);
         enforceCases(ret);
         return ret;
     }
index 906b9eed5b148464a73cf23a3813e9ea1db36f7c..b6bc51b70bb63a2a904b878cfe7234b2d627806c 100644 (file)
@@ -45,15 +45,15 @@ sealed class ContainerModificationStrategy extends DataNodeContainerModification
         @Override
         protected TreeNode applyMerge(final ModifiedNode modification, final TreeNode currentMeta,
                 final Version version) {
-            final TreeNode ret = super.applyMerge(modification, currentMeta, version);
+            final var ret = super.applyMerge(modification, currentMeta, version);
             enforcer.enforceOnTreeNode(ret);
             return ret;
         }
 
         @Override
         protected TreeNode applyWrite(final ModifiedNode modification, final NormalizedNode newValue,
-                final Optional<? extends TreeNode> currentMeta, final Version version) {
-            final TreeNode ret = super.applyWrite(modification, newValue, currentMeta, version);
+                final TreeNode currentMeta, final Version version) {
+            final var ret = super.applyWrite(modification, newValue, currentMeta, version);
             enforcer.enforceOnTreeNode(ret);
             return ret;
         }
@@ -61,7 +61,7 @@ sealed class ContainerModificationStrategy extends DataNodeContainerModification
         @Override
         protected TreeNode applyTouch(final ModifiedNode modification, final TreeNode currentMeta,
                 final Version version) {
-            final TreeNode ret = super.applyTouch(modification, currentMeta, version);
+            final var ret = super.applyTouch(modification, currentMeta, version);
             enforcer.enforceOnTreeNode(ret);
             return ret;
         }
@@ -84,9 +84,9 @@ sealed class ContainerModificationStrategy extends DataNodeContainerModification
         }
 
         @Override
-        Optional<? extends TreeNode> apply(final ModifiedNode modification,
-                final Optional<? extends TreeNode> storeMeta, final Version version) {
-            return AutomaticLifecycleMixin.apply(super::apply, this::applyWrite, emptyNode, modification, storeMeta,
+        Optional<? extends TreeNode> apply(final ModifiedNode modification, final TreeNode currentMeta,
+                final Version version) {
+            return AutomaticLifecycleMixin.apply(super::apply, this::applyWrite, emptyNode, modification, currentMeta,
                 version);
         }
 
index c0ff4518c89673fc39977eb4bfd66da4de9ef660..02961a8ad869df8289a2fe8d39d3d147c01d0542 100644 (file)
@@ -7,7 +7,10 @@
  */
 package org.opendaylight.yangtools.yang.data.tree.impl;
 
+import static java.util.Objects.requireNonNull;
+
 import com.google.common.base.MoreObjects;
+import org.eclipse.jdt.annotation.NonNull;
 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.PathArgument;
 import org.opendaylight.yangtools.yang.data.tree.api.DataTreeCandidateNode;
@@ -25,12 +28,12 @@ final class InMemoryDataTreeCandidate extends AbstractDataTreeCandidate {
         }
     }
 
-    private final RootNode root;
+    private final @NonNull RootNode root;
 
     InMemoryDataTreeCandidate(final YangInstanceIdentifier rootPath, final ModifiedNode modificationRoot,
             final TreeNode beforeRoot, final TreeNode afterRoot) {
         super(rootPath);
-        root = new RootNode(modificationRoot, beforeRoot, afterRoot);
+        root = new RootNode(modificationRoot, requireNonNull(beforeRoot), requireNonNull(afterRoot));
     }
 
     @Override
@@ -49,7 +52,7 @@ final class InMemoryDataTreeCandidate extends AbstractDataTreeCandidate {
 
     @Override
     public String toString() {
-        return MoreObjects.toStringHelper(this).add("rootPath", getRootPath())
-                .add("rootNode", getRootNode()).toString();
+        return MoreObjects.toStringHelper(this).add("rootPath", getRootPath()).add("rootNode", getRootNode())
+            .toString();
     }
 }
index df3da508a0a894e24ba5e6d8aef808ed0b55ce07..56f426fd4a92dbd07ce2a476aeda90ca330769ec 100644 (file)
@@ -143,7 +143,7 @@ final class InMemoryDataTreeModification extends AbstractCursorAware implements
         }
 
         try {
-            return resolveModificationStrategy(path).apply(modification, modification.getOriginal(), version);
+            return resolveModificationStrategy(path).apply(modification, modification.original(), version);
         } catch (Exception e) {
             LOG.error("Could not create snapshot for {}:{}", path, modification, e);
             throw e;
@@ -213,12 +213,11 @@ final class InMemoryDataTreeModification extends AbstractCursorAware implements
          * have same version each time this method is called.
          */
         final var originalSnapshotRoot = snapshot.getRootNode();
-        final var tempRoot = getStrategy().apply(rootNode, Optional.of(originalSnapshotRoot), version);
-        checkState(tempRoot.isPresent(), "Data tree root is not present, possibly removed by previous modification");
-
-        final var tempTree = new InMemoryDataTreeSnapshot(snapshot.getEffectiveModelContext(), tempRoot.orElseThrow(),
-            strategyTree);
-        return tempTree.newModification();
+        return new InMemoryDataTreeSnapshot(snapshot.getEffectiveModelContext(),
+            getStrategy().apply(rootNode, originalSnapshotRoot, version)
+                .orElseThrow(() -> new IllegalStateException(
+                    "Data tree root is not present, possibly removed by previous modification")), strategyTree)
+            .newModification();
     }
 
     Version getVersion() {
index 1d3d643c809a019f253c99c7ab334d14d2730e08..f058d6317d92ee0f4106008ad35dbfa1f5784213 100644 (file)
@@ -35,7 +35,7 @@ final class InMemoryDataTreeSnapshot extends AbstractCursorAware implements Curs
         this.applyOper = requireNonNull(applyOper);
     }
 
-    TreeNode getRootNode() {
+    @NonNull TreeNode getRootNode() {
         return rootNode;
     }
 
index 51b04fbdc8d3ffcbbd58baa9cd4144b102b91775..8b3563e116d256b08fb1a64f3e2e655c06a39a47 100644 (file)
@@ -44,9 +44,9 @@ final class ListModificationStrategy extends SchemaAwareApplyOperation<ListSchem
     }
 
     @Override
-    Optional<? extends TreeNode> apply(final ModifiedNode modification, final Optional<? extends TreeNode> storeMeta,
+    Optional<? extends TreeNode> apply(final ModifiedNode modification, final TreeNode currentMeta,
             final Version version) {
-        return AutomaticLifecycleMixin.apply(super::apply, this::applyWrite, emptyNode, modification, storeMeta,
+        return AutomaticLifecycleMixin.apply(super::apply, this::applyWrite, emptyNode, modification, currentMeta,
             version);
     }
 
@@ -68,7 +68,7 @@ final class ListModificationStrategy extends SchemaAwareApplyOperation<ListSchem
 
     @Override
     protected TreeNode applyWrite(final ModifiedNode modification, final NormalizedNode newValue,
-            final Optional<? extends TreeNode> currentMeta, final Version version) {
+            final TreeNode currentMeta, final Version version) {
         final var newValueMeta = TreeNode.of(newValue, version);
         if (modification.isEmpty()) {
             return newValueMeta;
@@ -103,12 +103,11 @@ final class ListModificationStrategy extends SchemaAwareApplyOperation<ListSchem
     @SuppressWarnings({ "rawtypes", "unchecked" })
     private TreeNode mutateChildren(final MutableTreeNode meta, final NormalizedNodeContainerBuilder data,
             final Version nodeVersion, final Iterable<ModifiedNode> modifications) {
+        for (var mod : modifications) {
+            final var id = mod.getIdentifier();
+            final var cm = meta.childByArg(id);
 
-        for (final ModifiedNode mod : modifications) {
-            final PathArgument id = mod.getIdentifier();
-            final Optional<? extends TreeNode> cm = meta.findChildByArg(id);
-
-            final Optional<? extends TreeNode> result = resolveChildOperation(id).apply(mod, cm, nodeVersion);
+            final var result = resolveChildOperation(id).apply(mod, cm, nodeVersion);
             if (result.isPresent()) {
                 final TreeNode tn = result.orElseThrow();
                 meta.putChild(tn);
@@ -140,7 +139,7 @@ final class ListModificationStrategy extends SchemaAwareApplyOperation<ListSchem
 
     @Override
     protected void checkTouchApplicable(final ModificationPath path, final NodeModification modification,
-            final Optional<? extends TreeNode> current, final Version version) throws IncorrectDataStructureException {
+            final TreeNode currentMeta, final Version version) throws IncorrectDataStructureException {
         throw new IncorrectDataStructureException(path.toInstanceIdentifier(), "Subtree modification is not allowed.");
     }
 
index 0a35aeec9151fb3825edbd8fa03dfbb6be62c5e4..4e0fa476afc53876243ec092ab2a03bfda401a95 100644 (file)
@@ -9,7 +9,6 @@ package org.opendaylight.yangtools.yang.data.tree.impl;
 
 import static java.util.Objects.requireNonNull;
 
-import java.util.Optional;
 import org.eclipse.jdt.annotation.NonNull;
 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeIdentifierWithPredicates;
 import org.opendaylight.yangtools.yang.data.api.schema.DistinctNodeContainer;
@@ -39,15 +38,15 @@ sealed class MapEntryModificationStrategy extends DataNodeContainerModificationS
         @Override
         protected TreeNode applyMerge(final ModifiedNode modification, final TreeNode currentMeta,
                 final Version version) {
-            final TreeNode ret = super.applyMerge(modification, currentMeta, version);
+            final var ret = super.applyMerge(modification, currentMeta, version);
             enforcer.enforceOnTreeNode(ret);
             return ret;
         }
 
         @Override
         protected TreeNode applyWrite(final ModifiedNode modification, final NormalizedNode newValue,
-                final Optional<? extends TreeNode> currentMeta, final Version version) {
-            final TreeNode ret = super.applyWrite(modification, newValue, currentMeta, version);
+                final TreeNode currentMeta, final Version version) {
+            final var ret = super.applyWrite(modification, newValue, currentMeta, version);
             enforcer.enforceOnTreeNode(ret);
             return ret;
         }
@@ -55,7 +54,7 @@ sealed class MapEntryModificationStrategy extends DataNodeContainerModificationS
         @Override
         protected TreeNode applyTouch(final ModifiedNode modification, final TreeNode currentMeta,
                 final Version version) {
-            final TreeNode ret = super.applyTouch(modification, currentMeta, version);
+            final var ret = super.applyTouch(modification, currentMeta, version);
             enforcer.enforceOnTreeNode(ret);
             return ret;
         }
index bb02d258a7b715d4f0521bcb6ecde5977193705a..c894bd2814bb6707bc1fcd9d4b51e64a069ade28 100644 (file)
@@ -61,9 +61,9 @@ final class MapModificationStrategy extends Invisible<ListSchemaNode> {
     }
 
     @Override
-    Optional<? extends TreeNode> apply(final ModifiedNode modification, final Optional<? extends TreeNode> storeMeta,
+    Optional<? extends TreeNode> apply(final ModifiedNode modification, final TreeNode currentMeta,
             final Version version) {
-        return AutomaticLifecycleMixin.apply(super::apply, this::applyWrite, emptyNode, modification, storeMeta,
+        return AutomaticLifecycleMixin.apply(super::apply, this::applyWrite, emptyNode, modification, currentMeta,
             version);
     }
 
index 1688d66f78893f1da50ca3da2b8a7bbeafe61fc4..3fcdccd1ae8bfc2c730bc4c54d7cebc0e5f99fd8 100644 (file)
@@ -10,6 +10,7 @@ package org.opendaylight.yangtools.yang.data.tree.impl;
 import com.google.common.base.MoreObjects;
 import com.google.common.base.MoreObjects.ToStringHelper;
 import java.util.Optional;
+import org.eclipse.jdt.annotation.Nullable;
 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.PathArgument;
 import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
 import org.opendaylight.yangtools.yang.data.api.schema.tree.StoreTreeNode;
@@ -26,8 +27,8 @@ import org.opendaylight.yangtools.yang.data.tree.impl.node.Version;
  * <b>Implementation notes</b>
  * <ul>
  *   <li>Implementations MUST expose all nested suboperations which operates on child nodes expose via
- *       {@link #findChildByArg(PathArgument)} method.</li>
- *   <li>Same suboperations SHOULD be used when invoked via {@link #apply(ModifiedNode, Optional, Version)},
+ *       {@link #childByArg(PathArgument)} method.</li>
+ *   <li>Same suboperations SHOULD be used when invoked via {@link #apply(ModifiedNode, TreeNode, Version)},
  *       if applicable.</li>
  *   <li>There are exactly two base implementations:
  *     <ul>
@@ -47,20 +48,14 @@ abstract sealed class ModificationApplyOperation implements StoreTreeNode<Modifi
     /**
      * Implementation of this operation must be stateless and must not change state of this object.
      *
-     * @param modification
-     *            NodeModification to be applied
-     * @param storeMeta
-     *            Store Metadata Node on which NodeModification should be
-     *            applied
+     * @param modification NodeModification to be applied
+     * @param currentMeta Store Metadata Node on which NodeModification should be applied
      * @param version New subtree version of parent node
-     * @return new {@link TreeNode} if operation resulted in updating
-     *         node, {@link Optional#absent()} if {@link ModifiedNode}
-     *         resulted in deletion of this node.
-     * @throws IllegalArgumentException
-     *             If it is not possible to apply Operation on provided Metadata
-     *             node
+     * @return new {@link TreeNode} if operation resulted in updating node, {@link Optional#empty()} if
+     *         {@link ModifiedNode} resulted in deletion of this node.
+     * @throws IllegalArgumentException If it is not possible to apply Operation on provided Metadata node
      */
-    abstract Optional<? extends TreeNode> apply(ModifiedNode modification, Optional<? extends TreeNode> storeMeta,
+    abstract Optional<? extends TreeNode> apply(ModifiedNode modification, @Nullable TreeNode currentMeta,
             Version version);
 
     /**
@@ -68,12 +63,12 @@ abstract sealed class ModificationApplyOperation implements StoreTreeNode<Modifi
      *
      * @param path Path to modification
      * @param modification Modification
-     * @param current Metadata Node to which modification should be applied
+     * @param currentMeta Metadata Node to which modification should be applied
      * @param version Metadata version
      * @throws DataValidationFailedException if the modification is not applicable
      */
     abstract void checkApplicable(ModificationPath path, NodeModification modification,
-            Optional<? extends TreeNode> current, Version version) throws DataValidationFailedException;
+        @Nullable TreeNode currentMeta, Version version) throws DataValidationFailedException;
 
     /**
      * Performs a quick structural verification of NodeModification, such as written values / types uses right
@@ -105,7 +100,7 @@ abstract sealed class ModificationApplyOperation implements StoreTreeNode<Modifi
 
     /**
      * Stage a merge operation into a {@link ModifiedNode} such that it will be processed correctly by
-     * {@link #apply(ModifiedNode, Optional, Version)}. This method is the context which is introducing this operation,
+     * {@link #apply(ModifiedNode, TreeNode, Version)}. This method is the context which is introducing this operation,
      * and so any overheads are charged to whoever is in control of the access pattern.
      *
      * @param modification Original modification node
index 73b25bd693003042fb3222b7691bb5b3add30da4..bad329943b6dc6d6322561826c7bb5847f2bac67 100644 (file)
@@ -14,6 +14,7 @@ import com.google.common.base.MoreObjects;
 import com.google.common.base.MoreObjects.ToStringHelper;
 import java.util.Collection;
 import java.util.Map;
+import java.util.Objects;
 import java.util.Optional;
 import org.eclipse.jdt.annotation.NonNull;
 import org.eclipse.jdt.annotation.Nullable;
@@ -54,7 +55,7 @@ final class ModifiedNode extends NodeModification implements StoreTreeNode<Modif
 
     // Internal cache for TreeNodes created as part of validation
     private ModificationApplyOperation validatedOp;
-    private Optional<? extends TreeNode> validatedCurrent;
+    private @Nullable TreeNode validatedCurrent;
     private ValidatedTreeNode validatedNode;
 
     private ModifiedNode(final PathArgument identifier, final @Nullable TreeNode original,
@@ -250,7 +251,7 @@ final class ModifiedNode extends NodeModification implements StoreTreeNode<Modif
             case WRITE -> {
                 // A WRITE can collapse all of its children
                 if (!children.isEmpty()) {
-                    value = schema.apply(this, getOriginal(), version).map(TreeNode::getData).orElse(null);
+                    value = schema.apply(this, original(), version).map(TreeNode::getData).orElse(null);
                     children.clear();
                 }
 
@@ -330,10 +331,10 @@ final class ModifiedNode extends NodeModification implements StoreTreeNode<Modif
         return new ModifiedNode(metadataTree.getIdentifier(), requireNonNull(metadataTree), childPolicy);
     }
 
-    void setValidatedNode(final ModificationApplyOperation op, final Optional<? extends TreeNode> current,
+    void setValidatedNode(final ModificationApplyOperation op, final @Nullable TreeNode currentMeta,
             final Optional<? extends TreeNode> node) {
         validatedOp = requireNonNull(op);
-        validatedCurrent = requireNonNull(current);
+        validatedCurrent = currentMeta;
         validatedNode = new ValidatedTreeNode(node);
     }
 
@@ -342,12 +343,11 @@ final class ModifiedNode extends NodeModification implements StoreTreeNode<Modif
      * {@link #setValidatedNode(ModificationApplyOperation, Optional, Optional)}.
      *
      * @param op Currently-executing operation
-     * @param current Currently-used tree node
+     * @param storeMeta Currently-used tree node
      * @return {@code null} if there is a mismatch with previously-validated node (if present) or the result of previous
      *         validation.
      */
-    @Nullable ValidatedTreeNode validatedNode(final ModificationApplyOperation op,
-            final Optional<? extends TreeNode> current) {
-        return op.equals(validatedOp) && current.equals(validatedCurrent) ? validatedNode : null;
+    @Nullable ValidatedTreeNode validatedNode(final ModificationApplyOperation op, final @Nullable TreeNode storeMeta) {
+        return op.equals(validatedOp) && Objects.equals(storeMeta, validatedCurrent) ? validatedNode : null;
     }
 }
index 52a8072b2daa54ad8ebce4603ab12fd40cf520a1..64b2a891d806cfa77d59eea9f7fa8007a5b049be 100644 (file)
@@ -10,6 +10,7 @@ package org.opendaylight.yangtools.yang.data.tree.impl;
 import static java.util.Objects.requireNonNull;
 
 import java.util.Optional;
+import org.eclipse.jdt.annotation.Nullable;
 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.PathArgument;
 import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
 import org.opendaylight.yangtools.yang.data.tree.impl.node.TreeNode;
@@ -61,7 +62,7 @@ final class OperationWithModification {
             Optional<? extends TreeNode> snapshot = childNode.getSnapshot();
             if (snapshot == null) {
                 // Snapshot is not present, force instantiation
-                snapshot = applyOperation.getChildByArg(child).apply(childNode, childNode.getOriginal(), version);
+                snapshot = applyOperation.getChildByArg(child).apply(childNode, childNode.original(), version);
             }
 
             return snapshot.map(TreeNode::getData);
@@ -69,7 +70,7 @@ final class OperationWithModification {
 
         Optional<? extends TreeNode> snapshot = modification.getSnapshot();
         if (snapshot == null) {
-            snapshot = apply(modification.getOriginal(), version);
+            snapshot = apply(modification.original(), version);
         }
 
         if (snapshot.isPresent()) {
@@ -87,7 +88,7 @@ final class OperationWithModification {
         return applyOperation;
     }
 
-    public Optional<? extends TreeNode> apply(final Optional<? extends TreeNode> data, final Version version) {
+    public Optional<? extends TreeNode> apply(final @Nullable TreeNode data, final Version version) {
         return applyOperation.apply(modification, data, version);
     }
 
index 8cd04e29ab320b7825ca90bee2a8a630076f5980..79ae7310882a39a79f976882f77d8735db5b78bc 100644 (file)
@@ -13,6 +13,7 @@ import static com.google.common.base.Verify.verifyNotNull;
 import java.util.List;
 import java.util.Optional;
 import org.eclipse.jdt.annotation.NonNull;
+import org.eclipse.jdt.annotation.Nullable;
 import org.opendaylight.yangtools.yang.common.QName;
 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.PathArgument;
 import org.opendaylight.yangtools.yang.data.api.schema.AnydataNode;
@@ -88,8 +89,8 @@ abstract sealed class SchemaAwareApplyOperation<T extends DataSchemaNode> extend
         return UniqueValidation.of(schemaNode, treeConfig, MinMaxElementsValidation.from(op));
     }
 
-    protected static void checkNotConflicting(final ModificationPath path, final TreeNode original,
-            final TreeNode current) throws ConflictingModificationAppliedException {
+    protected static final void checkNotConflicting(final ModificationPath path, final @NonNull TreeNode original,
+            final @NonNull TreeNode current) throws ConflictingModificationAppliedException {
         checkConflicting(path, original.getVersion().equals(current.getVersion()),
                 "Node was replaced by other transaction.");
         checkConflicting(path, original.getSubtreeVersion().equals(current.getSubtreeVersion()),
@@ -104,12 +105,12 @@ abstract sealed class SchemaAwareApplyOperation<T extends DataSchemaNode> extend
 
     @Override
     final void checkApplicable(final ModificationPath path, final NodeModification modification,
-            final Optional<? extends TreeNode> current, final Version version) throws DataValidationFailedException {
+            final TreeNode currentMeta, final Version version) throws DataValidationFailedException {
         switch (modification.getOperation()) {
-            case DELETE -> checkDeleteApplicable(modification, current);
-            case TOUCH -> checkTouchApplicable(path, modification, current, version);
-            case WRITE -> checkWriteApplicable(path, modification, current, version);
-            case MERGE -> checkMergeApplicable(path, modification, current, version);
+            case DELETE -> checkDeleteApplicable(modification, currentMeta);
+            case TOUCH -> checkTouchApplicable(path, modification, currentMeta, version);
+            case WRITE -> checkWriteApplicable(path, modification, currentMeta, version);
+            case MERGE -> checkMergeApplicable(path, modification, currentMeta, version);
             case NONE -> {
                 // No-op
             }
@@ -147,17 +148,16 @@ abstract sealed class SchemaAwareApplyOperation<T extends DataSchemaNode> extend
     }
 
     protected void checkMergeApplicable(final ModificationPath path, final NodeModification modification,
-            final Optional<? extends TreeNode> current, final Version version) throws DataValidationFailedException {
+            final TreeNode currentMeta, final Version version) throws DataValidationFailedException {
         final var orig = modification.original();
-        if (orig != null && current.isPresent()) {
+        if (orig != null && currentMeta != null) {
             /*
              * We need to do conflict detection only and only if the value of leaf changed before two transactions. If
              * value of leaf is unchanged between two transactions it should not cause transaction to fail, since result
              * of this merge leads to same data.
              */
-            final var cur = current.orElseThrow();
-            if (!orig.getData().equals(cur.getData())) {
-                checkNotConflicting(path, orig, cur);
+            if (!orig.getData().equals(currentMeta.getData())) {
+                checkNotConflicting(path, orig, currentMeta);
             }
         }
     }
@@ -169,55 +169,56 @@ abstract sealed class SchemaAwareApplyOperation<T extends DataSchemaNode> extend
      *
      * @param path Path from current node in TreeNode
      * @param modification modification to apply
-     * @param current current node in TreeNode for modification to apply
+     * @param currentMeta current node in TreeNode for modification to apply
      * @throws DataValidationFailedException when a data dependency conflict is detected
      */
     private static void checkWriteApplicable(final ModificationPath path, final NodeModification modification,
-            final Optional<? extends TreeNode> current, final Version version) throws DataValidationFailedException {
+            final TreeNode currentMeta, final Version version) throws DataValidationFailedException {
         final var original = modification.original();
-        if (original != null && current.isPresent()) {
-            checkNotConflicting(path, original, current.orElseThrow());
+        if (original != null && currentMeta != null) {
+            checkNotConflicting(path, original, currentMeta);
         } else {
             checkConflicting(path, original == null, "Node was deleted by other transaction.");
-            checkConflicting(path, current.isEmpty(), "Node was created by other transaction.");
+            checkConflicting(path, currentMeta == null, "Node was created by other transaction.");
         }
     }
 
     private static void checkDeleteApplicable(final NodeModification modification,
-            final Optional<? extends TreeNode> current) {
+            final @Nullable TreeNode currentMeta) {
         // Delete is always applicable, we do not expose it to subclasses
-        if (current.isEmpty()) {
+        if (currentMeta == null) {
             LOG.trace("Delete operation turned to no-op on missing node {}", modification);
         }
     }
 
     @Override
-    Optional<? extends TreeNode> apply(final ModifiedNode modification, final Optional<? extends TreeNode> currentMeta,
+    Optional<? extends TreeNode> apply(final ModifiedNode modification, final TreeNode currentMeta,
             final Version version) {
         return switch (modification.getOperation()) {
             case DELETE -> {
                 // Deletion of a non-existing node is a no-op, report it as such
-                modification.resolveModificationType(currentMeta.isPresent() ? ModificationType.DELETE
+                modification.resolveModificationType(currentMeta != null ? ModificationType.DELETE
                         : ModificationType.UNMODIFIED);
                 yield modification.setSnapshot(Optional.empty());
             }
             case TOUCH -> {
-                checkArgument(currentMeta.isPresent(), "Metadata not available for modification %s", modification);
-                yield modification.setSnapshot(Optional.of(applyTouch(modification, currentMeta.orElseThrow(),
-                    version)));
+                if (currentMeta == null) {
+                    throw new IllegalArgumentException("Metadata not available for modification " + modification);
+                }
+                yield modification.setSnapshot(Optional.of(applyTouch(modification, currentMeta, version)));
             }
             case MERGE -> {
                 final TreeNode result;
 
-                if (currentMeta.isEmpty()) {
+                if (currentMeta == null) {
                     // This is a slight optimization: a merge on a non-existing node equals to a write. Written data
                     // structure is usually verified when the transaction is sealed. To preserve correctness, we have
                     // to run that validation here.
                     modification.resolveModificationType(ModificationType.WRITE);
-                    result = applyWrite(modification, modification.getWrittenValue(), currentMeta, version);
+                    result = applyWrite(modification, modification.getWrittenValue(), null, version);
                     fullVerifyStructure(result.getData());
                 } else {
-                    result = applyMerge(modification, currentMeta.orElseThrow(), version);
+                    result = applyMerge(modification, currentMeta, version);
                 }
 
                 yield modification.setSnapshot(Optional.of(result));
@@ -229,7 +230,7 @@ abstract sealed class SchemaAwareApplyOperation<T extends DataSchemaNode> extend
             }
             case NONE -> {
                 modification.resolveModificationType(ModificationType.UNMODIFIED);
-                yield currentMeta;
+                yield Optional.ofNullable(currentMeta);
             }
         };
     }
@@ -244,10 +245,11 @@ abstract sealed class SchemaAwareApplyOperation<T extends DataSchemaNode> extend
      * @param version New subtree version of parent node
      * @return A sealed TreeNode representing applied operation.
      */
-    protected abstract TreeNode applyMerge(ModifiedNode modification, TreeNode currentMeta, Version version);
+    protected abstract @NonNull TreeNode applyMerge(ModifiedNode modification, @NonNull TreeNode currentMeta,
+        Version version);
 
-    protected abstract TreeNode applyWrite(ModifiedNode modification, NormalizedNode newValue,
-            Optional<? extends TreeNode> currentMeta, Version version);
+    protected abstract @NonNull TreeNode applyWrite(ModifiedNode modification, NormalizedNode newValue,
+        @Nullable TreeNode currentMeta, Version version);
 
     /**
      * Apply a nested operation. Since there may not actually be a nested operation
@@ -259,20 +261,21 @@ abstract sealed class SchemaAwareApplyOperation<T extends DataSchemaNode> extend
      * @param version New subtree version of parent node
      * @return A sealed TreeNode representing applied operation.
      */
-    protected abstract TreeNode applyTouch(ModifiedNode modification, TreeNode currentMeta, Version version);
+    protected abstract @NonNull TreeNode applyTouch(ModifiedNode modification, @NonNull TreeNode currentMeta,
+        Version version);
 
     /**
      * Checks is supplied {@link NodeModification} is applicable for Subtree Modification.
      *
      * @param path Path to current node
      * @param modification Node modification which should be applied.
-     * @param current Current state of data tree
+     * @param currentMeta Current state of data tree
      * @throws ConflictingModificationAppliedException If subtree was changed in conflicting way
      * @throws org.opendaylight.yangtools.yang.data.tree.api.IncorrectDataStructureException If subtree
      *         modification is not applicable (e.g. leaf node).
      */
     protected abstract void checkTouchApplicable(ModificationPath path, NodeModification modification,
-            Optional<? extends TreeNode> current, Version version) throws DataValidationFailedException;
+        @Nullable TreeNode currentMeta, Version version) throws DataValidationFailedException;
 
     /**
      * Return the {@link DataSchemaNode}-subclass schema associated with this operation.
index 7ec50eb0844b6ef5fe11ae67d9dcd7825f5be860..93ccfc10b60d444edd30b4f47f0bf6ed1950a986 100644 (file)
@@ -11,7 +11,6 @@ import static com.google.common.base.Preconditions.checkArgument;
 import static java.util.Objects.requireNonNull;
 
 import com.google.common.base.MoreObjects.ToStringHelper;
-import java.util.Optional;
 import org.eclipse.jdt.annotation.NonNull;
 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.PathArgument;
 import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
@@ -65,13 +64,13 @@ final class ValueNodeModificationStrategy<T extends DataSchemaNode, V extends No
 
     @Override
     protected TreeNode applyWrite(final ModifiedNode modification, final NormalizedNode newValue,
-            final Optional<? extends TreeNode> currentMeta, final Version version) {
+            final TreeNode currentMeta, final Version version) {
         return TreeNode.of(newValue, version);
     }
 
     @Override
     protected void checkTouchApplicable(final ModificationPath path, final NodeModification modification,
-            final Optional<? extends TreeNode> current, final Version version) throws IncorrectDataStructureException {
+            final TreeNode currentMeta, final Version version) throws IncorrectDataStructureException {
         throw new IncorrectDataStructureException(path.toInstanceIdentifier(), "Subtree modification is not allowed.");
     }