Refactor checkTouchApplicable() 08/80308/2
authorRobert Varga <robert.varga@pantheon.tech>
Wed, 13 Feb 2019 11:52:14 +0000 (12:52 +0100)
committerRobert Varga <robert.varga@pantheon.tech>
Wed, 13 Feb 2019 13:48:59 +0000 (14:48 +0100)
We can remove direct overrides of checkTouchApplicable() by making
the method smarter in its checking of preconditions. Notably we
do not check TreeNode presence multiple times, but rather perform
a step-wise unpacking of state.

This has the benefit of having a clean place where we check if
automatic lifecycle is in effect and that happens only if the node
does not exist.

JIRA: YANGTOOLS-943
Change-Id: I72f4316c77d8f36efaf95209c36e898c9b4873cd
Signed-off-by: Robert Varga <robert.varga@pantheon.tech>
yang/yang-data-impl/src/main/java/org/opendaylight/yangtools/yang/data/impl/schema/tree/AbstractNodeContainerModificationStrategy.java
yang/yang-data-impl/src/main/java/org/opendaylight/yangtools/yang/data/impl/schema/tree/AugmentationModificationStrategy.java
yang/yang-data-impl/src/main/java/org/opendaylight/yangtools/yang/data/impl/schema/tree/ChoiceModificationStrategy.java
yang/yang-data-impl/src/main/java/org/opendaylight/yangtools/yang/data/impl/schema/tree/MapModificationStrategy.java
yang/yang-data-impl/src/main/java/org/opendaylight/yangtools/yang/data/impl/schema/tree/StructuralContainerModificationStrategy.java

index d8a651b03ff863d9999749189eb8e2dc0175e802..c4d8afbdc94f91fde1fe08e42cd417773494f925 100644 (file)
@@ -16,6 +16,7 @@ import com.google.common.base.Verify;
 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;
 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.PathArgument;
 import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
@@ -362,33 +363,41 @@ abstract class AbstractNodeContainerModificationStrategy<T extends WithStatus>
     }
 
     @Override
-    protected void checkTouchApplicable(final ModificationPath path, final NodeModification modification,
+    protected final void checkTouchApplicable(final ModificationPath path, final NodeModification modification,
             final Optional<TreeNode> current, final Version version) throws DataValidationFailedException {
-        if (!modification.getOriginal().isPresent() && !current.isPresent()) {
-            final YangInstanceIdentifier id = path.toInstanceIdentifier();
-            throw new ModifiedNodeDoesNotExistException(id,
-                String.format("Node %s does not exist. Cannot apply modification to its children.", id));
+        final TreeNode currentNode;
+        if (!current.isPresent()) {
+            currentNode = defaultTreeNode();
+            if (currentNode == null) {
+                if (!modification.getOriginal().isPresent()) {
+                    final YangInstanceIdentifier id = path.toInstanceIdentifier();
+                    throw new ModifiedNodeDoesNotExistException(id,
+                        String.format("Node %s does not exist. Cannot apply modification to its children.", id));
+                }
+
+                throw new ConflictingModificationAppliedException(path.toInstanceIdentifier(),
+                    "Node was deleted by other transaction.");
+            }
+        } else {
+            currentNode = current.get();
         }
 
-        checkConflicting(path, current.isPresent(), "Node was deleted by other transaction.");
-        checkChildPreconditions(path, modification, current.get(), version);
+        checkChildPreconditions(path, modification, currentNode, version);
     }
 
     /**
-     * Checks is supplied {@link NodeModification} is applicable for Subtree Modification. This variant is used by
-     * subclasses which support automatic lifecycle.
+     * Return the default tree node. Default implementation does nothing, but can be overridden to call
+     * {@link #defaultTreeNode(NormalizedNode)}.
      *
-     * @param path Path to current node
-     * @param modification Node modification which should be applied.
-     * @param current Current state of data tree
-     * @throws ConflictingModificationAppliedException If subtree was changed in conflicting way
-     * @throws org.opendaylight.yangtools.yang.data.api.schema.tree.IncorrectDataStructureException If subtree
-     *         modification is not applicable (e.g. leaf node).
+     * @return Default empty tree node, or null if no default is available
      */
-    final void checkTouchApplicable(final ModificationPath path, final NodeModification modification,
-            final Optional<TreeNode> current, final Version version, final NormalizedNode<?, ?> emptyNode)
-                    throws DataValidationFailedException {
-        checkChildPreconditions(path, modification, touchMeta(current, emptyNode), version);
+    @Nullable TreeNode defaultTreeNode() {
+        // Defaults to no recovery
+        return null;
+    }
+
+    static final TreeNode defaultTreeNode(final NormalizedNode<?, ?> emptyNode) {
+        return TreeNodeFactory.createTreeNode(emptyNode, FAKE_VERSION);
     }
 
     @Override
@@ -421,10 +430,6 @@ abstract class AbstractNodeContainerModificationStrategy<T extends WithStatus>
         }
     }
 
-    private static TreeNode touchMeta(final Optional<TreeNode> current, final NormalizedNode<?, ?> emptyNode) {
-        return current.isPresent() ? current.get() : TreeNodeFactory.createTreeNode(emptyNode, FAKE_VERSION);
-    }
-
     @Override
     public final String toString() {
         return addToStringAttributes(MoreObjects.toStringHelper(this)).toString();
index d24c544d74bd64339b3a448a9fe1f3b8021e5f9b..4e51ce3529540964b84ad83190cf922d34fe086b 100644 (file)
@@ -11,7 +11,6 @@ import java.util.Optional;
 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.AugmentationIdentifier;
 import org.opendaylight.yangtools.yang.data.api.schema.AugmentationNode;
 import org.opendaylight.yangtools.yang.data.api.schema.tree.DataTreeConfiguration;
-import org.opendaylight.yangtools.yang.data.api.schema.tree.DataValidationFailedException;
 import org.opendaylight.yangtools.yang.data.api.schema.tree.spi.TreeNode;
 import org.opendaylight.yangtools.yang.data.api.schema.tree.spi.Version;
 import org.opendaylight.yangtools.yang.data.impl.schema.Builders;
@@ -45,8 +44,7 @@ final class AugmentationModificationStrategy
     }
 
     @Override
-    protected void checkTouchApplicable(final ModificationPath path, final NodeModification modification,
-            final Optional<TreeNode> current, final Version version) throws DataValidationFailedException {
-        checkTouchApplicable(path, modification, current, version, emptyNode);
+    TreeNode defaultTreeNode() {
+        return defaultTreeNode(emptyNode);
     }
 }
index 66e6453f2d098aa03d3a8eed38da61fc26420b0f..428d2bb525a3129ade3b1e076bad6ad2ffc43f32 100644 (file)
@@ -28,7 +28,6 @@ import org.opendaylight.yangtools.yang.data.api.schema.DataContainerChild;
 import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
 import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNodes;
 import org.opendaylight.yangtools.yang.data.api.schema.tree.DataTreeConfiguration;
-import org.opendaylight.yangtools.yang.data.api.schema.tree.DataValidationFailedException;
 import org.opendaylight.yangtools.yang.data.api.schema.tree.spi.TreeNode;
 import org.opendaylight.yangtools.yang.data.api.schema.tree.spi.Version;
 import org.opendaylight.yangtools.yang.data.impl.schema.ImmutableNodes;
@@ -89,9 +88,8 @@ final class ChoiceModificationStrategy extends Visible<ChoiceSchemaNode> {
     }
 
     @Override
-    protected void checkTouchApplicable(final ModificationPath path, final NodeModification modification,
-            final Optional<TreeNode> current, final Version version) throws DataValidationFailedException {
-        checkTouchApplicable(path, modification, current, version, emptyNode);
+    TreeNode defaultTreeNode() {
+        return defaultTreeNode(emptyNode);
     }
 
     @Override
index ce189f8860c9acece6f9ef2506bd39a1e9293b02..de518e4628c1263505db7d894d27d76234574c9c 100644 (file)
@@ -17,7 +17,6 @@ import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeIdent
 import org.opendaylight.yangtools.yang.data.api.schema.MapNode;
 import org.opendaylight.yangtools.yang.data.api.schema.OrderedMapNode;
 import org.opendaylight.yangtools.yang.data.api.schema.tree.DataTreeConfiguration;
-import org.opendaylight.yangtools.yang.data.api.schema.tree.DataValidationFailedException;
 import org.opendaylight.yangtools.yang.data.api.schema.tree.spi.TreeNode;
 import org.opendaylight.yangtools.yang.data.api.schema.tree.spi.Version;
 import org.opendaylight.yangtools.yang.data.impl.schema.ImmutableNodes;
@@ -68,8 +67,7 @@ final class MapModificationStrategy extends Invisible<ListSchemaNode> {
     }
 
     @Override
-    protected void checkTouchApplicable(final ModificationPath path, final NodeModification modification,
-            final Optional<TreeNode> current, final Version version) throws DataValidationFailedException {
-        checkTouchApplicable(path, modification, current, version, emptyNode);
+    TreeNode defaultTreeNode() {
+        return defaultTreeNode(emptyNode);
     }
 }
index 20ab7523d9cc050c35b92cac0a65566730c2a43a..ff19a41c9c69267a29b52533b7753ecf2341f803 100644 (file)
@@ -10,7 +10,6 @@ package org.opendaylight.yangtools.yang.data.impl.schema.tree;
 import java.util.Optional;
 import org.opendaylight.yangtools.yang.data.api.schema.ContainerNode;
 import org.opendaylight.yangtools.yang.data.api.schema.tree.DataTreeConfiguration;
-import org.opendaylight.yangtools.yang.data.api.schema.tree.DataValidationFailedException;
 import org.opendaylight.yangtools.yang.data.api.schema.tree.spi.TreeNode;
 import org.opendaylight.yangtools.yang.data.api.schema.tree.spi.Version;
 import org.opendaylight.yangtools.yang.data.impl.schema.ImmutableNodes;
@@ -40,8 +39,7 @@ final class StructuralContainerModificationStrategy extends ContainerModificatio
     }
 
     @Override
-    protected void checkTouchApplicable(final ModificationPath path, final NodeModification modification,
-            final Optional<TreeNode> current, final Version version) throws DataValidationFailedException {
-        checkTouchApplicable(path, modification, current, version, emptyNode);
+    TreeNode defaultTreeNode() {
+        return defaultTreeNode(emptyNode);
     }
 }