Clean up TreeNode API
[yangtools.git] / data / yang-data-tree-ri / src / main / java / org / opendaylight / yangtools / yang / data / tree / impl / AutomaticLifecycleMixin.java
index 7a9f30e24ff1d440095e223c1d4748ae02d22eb2..ec70e8164c3c9bf12ee2b46eb7758481255c1e8c 100644 (file)
@@ -7,14 +7,14 @@
  */
 package org.opendaylight.yangtools.yang.data.tree.impl;
 
-import static com.google.common.base.Preconditions.checkState;
+import static com.google.common.base.Verify.verifyNotNull;
 
-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;
 import org.opendaylight.yangtools.yang.data.tree.impl.node.TreeNode;
-import org.opendaylight.yangtools.yang.data.tree.impl.node.TreeNodeFactory;
 import org.opendaylight.yangtools.yang.data.tree.impl.node.Version;
 
 /**
@@ -23,52 +23,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);
+        @Nullable 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 Optional<? extends TreeNode> ret;
+    static @Nullable TreeNode apply(final Apply delegate, final ApplyWrite writeDelegate,
+            final NormalizedNode emptyNode, final ModifiedNode modification, final @Nullable TreeNode currentMeta,
+            final Version version) {
+        final @Nullable TreeNode ret;
         if (modification.getOperation() == LogicalOperation.DELETE) {
-            if (modification.getChildren().isEmpty()) {
-                return delegate.apply(modification, storeMeta, version);
+            if (modification.isEmpty()) {
+                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.isPresent()) {
-            ret = applyTouch(delegate, emptyNode, modification, storeMeta, version);
+            ret = verifyNotNull(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.get(), storeMeta) : ret;
+        return ret == null ? null : disappearResult(modification, ret, currentMeta);
     }
 
-    private static Optional<? extends TreeNode> applyTouch(final Apply delegate, final NormalizedNode emptyNode,
-            final ModifiedNode modification, final Optional<? extends TreeNode> storeMeta, final Version version) {
+    private static @Nullable TreeNode applyTouch(final Apply delegate, final NormalizedNode emptyNode,
+            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,16 +76,20 @@ final class AutomaticLifecycleMixin {
         return ret;
     }
 
-    private static Optional<? extends TreeNode> disappearResult(final ModifiedNode modification, final TreeNode result,
-            final Optional<? extends TreeNode> storeMeta) {
+    private static @Nullable TreeNode disappearResult(final ModifiedNode modification, final @NonNull TreeNode result,
+            final @Nullable TreeNode currentMeta) {
         // Check if the result is in fact empty before pulling any tricks
-        if (!isEmpty(result)) {
-            return Optional.of(result);
+        final var data = result.data();
+        if (!(data instanceof NormalizedNodeContainer<?> container)) {
+            throw new IllegalStateException("Unhandled data " + data);
+        }
+        if (!container.isEmpty()) {
+            return result;
         }
 
         // We are pulling the 'disappear' trick, but what we report can be three different things
         final ModificationType finalType;
-        if (!storeMeta.isPresent()) {
+        if (currentMeta == null) {
             // ... there was nothing in the datastore, no change
             finalType = ModificationType.UNMODIFIED;
         } else if (modification.getModificationType() == ModificationType.WRITE) {
@@ -97,16 +100,10 @@ final class AutomaticLifecycleMixin {
             finalType = ModificationType.DISAPPEARED;
         }
         modification.resolveModificationType(finalType);
-        return Optional.empty();
-    }
-
-    private static Optional<TreeNode> fakeMeta(final NormalizedNode emptyNode, final Version version) {
-        return Optional.of(TreeNodeFactory.createTreeNode(emptyNode, version));
+        return null;
     }
 
-    private static boolean isEmpty(final TreeNode treeNode) {
-        final NormalizedNode data = treeNode.getData();
-        checkState(data instanceof NormalizedNodeContainer, "Unhandled data %s", data);
-        return ((NormalizedNodeContainer<?>) data).size() == 0;
+    private static @NonNull TreeNode fakeMeta(final NormalizedNode emptyNode, final Version version) {
+        return TreeNode.of(emptyNode, version);
     }
 }