BUG-509: limit visibility of updateModificationType()
[controller.git] / opendaylight / md-sal / sal-dom-broker / src / main / java / org / opendaylight / controller / md / sal / dom / store / impl / tree / NodeModification.java
index 764afcb3e185f3d48d09b192660c3cc882c36537..04fb3b7c6c50499ad0b96b220c2685b597bdcb9d 100644 (file)
@@ -12,11 +12,15 @@ import static com.google.common.base.Preconditions.checkState;
 import java.util.LinkedHashMap;
 import java.util.Map;
 
+import javax.annotation.concurrent.GuardedBy;
+
 import org.opendaylight.yangtools.concepts.Identifiable;
 import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier.PathArgument;
 import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
 
 import com.google.common.base.Optional;
+import com.google.common.base.Predicate;
+import com.google.common.primitives.UnsignedLong;
 
 /**
  * Node Modification Node and Tree
@@ -30,6 +34,12 @@ import com.google.common.base.Optional;
  */
 public class NodeModification implements StoreTreeNode<NodeModification>, Identifiable<PathArgument> {
 
+    public static final Predicate<NodeModification> IS_TERMINAL_PREDICATE = new Predicate<NodeModification>() {
+        @Override
+        public boolean apply(final NodeModification input) {
+            return input.getModificationType() == ModificationType.WRITE || input.getModificationType() == ModificationType.DELETE;
+        }
+    };
     private final PathArgument identifier;
     private ModificationType modificationType = ModificationType.UNMODIFIED;
 
@@ -38,10 +48,12 @@ public class NodeModification implements StoreTreeNode<NodeModification>, Identi
 
     private NormalizedNode<?, ?> value;
 
-    private StoreMetadataNode snapshotCache;
+    private UnsignedLong subtreeVersion;
+    private Optional<StoreMetadataNode> snapshotCache;
 
     private final Map<PathArgument, NodeModification> childModification;
 
+    @GuardedBy("this")
     private boolean sealed = false;
 
     protected NodeModification(final PathArgument identifier, final Optional<StoreMetadataNode> original) {
@@ -109,6 +121,7 @@ public class NodeModification implements StoreTreeNode<NodeModification>, Identi
      */
     public synchronized NodeModification modifyChild(final PathArgument child) {
         checkSealed();
+        clearSnapshot();
         if(modificationType == ModificationType.UNMODIFIED) {
             updateModificationType(ModificationType.SUBTREE_MODIFIED);
         }
@@ -143,6 +156,7 @@ public class NodeModification implements StoreTreeNode<NodeModification>, Identi
      */
     public synchronized void delete() {
         checkSealed();
+        clearSnapshot();
         updateModificationType(ModificationType.DELETE);
         childModification.clear();
         this.value = null;
@@ -156,17 +170,20 @@ public class NodeModification implements StoreTreeNode<NodeModification>, Identi
      */
     public synchronized void write(final NormalizedNode<?, ?> value) {
         checkSealed();
+        clearSnapshot();
         updateModificationType(ModificationType.WRITE);
         childModification.clear();
         this.value = value;
     }
 
+    @GuardedBy("this")
     private void checkSealed() {
         checkState(!sealed, "Node Modification is sealed. No further changes allowed.");
     }
 
     public synchronized void seal() {
         sealed = true;
+        clearSnapshot();
         for(NodeModification child : childModification.values()) {
             child.seal();
         }
@@ -176,11 +193,21 @@ public class NodeModification implements StoreTreeNode<NodeModification>, Identi
         snapshotCache = null;
     }
 
+    public Optional<StoreMetadataNode> storeSnapshot(final Optional<StoreMetadataNode> snapshot) {
+        snapshotCache = snapshot;
+        return snapshot;
+    }
+
+    public Optional<Optional<StoreMetadataNode>> getSnapshotCache() {
+        return Optional.fromNullable(snapshotCache);
+    }
+
     public boolean hasAdditionalModifications() {
         return !childModification.isEmpty();
     }
 
-    public void updateModificationType(final ModificationType type) {
+    @GuardedBy("this")
+    private void updateModificationType(final ModificationType type) {
         modificationType = type;
         clearSnapshot();
     }
@@ -188,7 +215,7 @@ public class NodeModification implements StoreTreeNode<NodeModification>, Identi
     @Override
     public String toString() {
         return "NodeModification [identifier=" + identifier + ", modificationType="
-                + modificationType + ", value=" + value + ", childModification=" + childModification + "]";
+                + modificationType + ", childModification=" + childModification + "]";
     }
 
     public static NodeModification createUnmodified(final StoreMetadataNode metadataTree) {