Update CursorAwareDataTree{Modification,Snapshot} API
[yangtools.git] / yang / yang-data-api / src / main / java / org / opendaylight / yangtools / yang / data / api / schema / tree / DataTreeCandidates.java
index 1b242918ddd15799dec0b977040bf717bb860d5a..b933ce1e3e248d5e213c0f2cd891ca89024ba1ef 100644 (file)
@@ -7,9 +7,12 @@
  */
 package org.opendaylight.yangtools.yang.data.api.schema.tree;
 
+import static java.util.Objects.requireNonNull;
+
 import com.google.common.annotations.Beta;
-import com.google.common.base.Preconditions;
 import java.util.Iterator;
+import javax.annotation.Nonnull;
+import javax.annotation.Nullable;
 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
 import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
 import org.slf4j.Logger;
@@ -21,15 +24,18 @@ import org.slf4j.LoggerFactory;
 @Beta
 public final class DataTreeCandidates {
     private static final Logger LOG = LoggerFactory.getLogger(DataTreeCandidates.class);
+
     private DataTreeCandidates() {
         throw new UnsupportedOperationException();
     }
 
-    public static DataTreeCandidate newDataTreeCandidate(final YangInstanceIdentifier rootPath, final DataTreeCandidateNode rootNode) {
+    public static DataTreeCandidate newDataTreeCandidate(final YangInstanceIdentifier rootPath,
+            final DataTreeCandidateNode rootNode) {
         return new DefaultDataTreeCandidate(rootPath, rootNode);
     }
 
-    public static DataTreeCandidate fromNormalizedNode(final YangInstanceIdentifier rootPath, final NormalizedNode<?, ?> node) {
+    public static DataTreeCandidate fromNormalizedNode(final YangInstanceIdentifier rootPath,
+            final NormalizedNode<?, ?> node) {
         return new DefaultDataTreeCandidate(rootPath, new NormalizedNodeDataTreeCandidateNode(node));
     }
 
@@ -37,39 +43,52 @@ public final class DataTreeCandidates {
         DataTreeCandidateNodes.applyToCursor(cursor, candidate.getRootNode());
     }
 
-    public static void applyToModification(final DataTreeModification modification, final DataTreeCandidate candidate) {
+    public static void applyToModification(final DataTreeModification modification,
+            final DataTreeCandidate candidate) {
         if (modification instanceof CursorAwareDataTreeModification) {
-            try (DataTreeModificationCursor cursor = ((CursorAwareDataTreeModification) modification).createCursor(candidate.getRootPath())) {
-                applyToCursor(cursor, candidate);
-            }
+            applyToCursorAwareModification((CursorAwareDataTreeModification) modification, candidate);
             return;
         }
 
         final DataTreeCandidateNode node = candidate.getRootNode();
         final YangInstanceIdentifier path = candidate.getRootPath();
         switch (node.getModificationType()) {
-        case DELETE:
-            modification.delete(path);
-            LOG.debug("Modification {} deleted path {}", modification, path);
-            break;
-        case SUBTREE_MODIFIED:
-            LOG.debug("Modification {} modified path {}", modification, path);
-
-            NodeIterator iterator = new NodeIterator(null, path, node.getChildNodes().iterator());
-            do {
-                iterator = iterator.next(modification);
-            } while (iterator != null);
-            break;
-        case UNMODIFIED:
-            LOG.debug("Modification {} unmodified path {}", modification, path);
-            // No-op
-            break;
-        case WRITE:
-            modification.write(path, node.getDataAfter().get());
-            LOG.debug("Modification {} written path {}", modification, path);
-            break;
-        default:
-            throw new IllegalArgumentException("Unsupported modification " + node.getModificationType());
+            case DELETE:
+                modification.delete(path);
+                LOG.debug("Modification {} deleted path {}", modification, path);
+                break;
+            case SUBTREE_MODIFIED:
+                LOG.debug("Modification {} modified path {}", modification, path);
+
+                NodeIterator iterator = new NodeIterator(null, path, node.getChildNodes().iterator());
+                do {
+                    iterator = iterator.next(modification);
+                } while (iterator != null);
+                break;
+            case UNMODIFIED:
+                LOG.debug("Modification {} unmodified path {}", modification, path);
+                // No-op
+                break;
+            case WRITE:
+                modification.write(path, node.getDataAfter().get());
+                LOG.debug("Modification {} written path {}", modification, path);
+                break;
+            default:
+                throw new IllegalArgumentException("Unsupported modification " + node.getModificationType());
+        }
+    }
+
+    private static void applyToCursorAwareModification(final CursorAwareDataTreeModification modification,
+            final DataTreeCandidate candidate) {
+        final YangInstanceIdentifier candidatePath = candidate.getRootPath();
+        if (candidatePath.isEmpty()) {
+            try (DataTreeModificationCursor cursor = modification.openCursor()) {
+                DataTreeCandidateNodes.applyRootToCursor(cursor, candidate.getRootNode());
+            }
+        } else {
+            try (DataTreeModificationCursor cursor = modification.openCursor(candidatePath.getParent()).get()) {
+                DataTreeCandidateNodes.applyRootedNodeToCursor(cursor, candidatePath, candidate.getRootNode());
+            }
         }
     }
 
@@ -78,10 +97,11 @@ public final class DataTreeCandidates {
         private final YangInstanceIdentifier path;
         private final NodeIterator parent;
 
-        public NodeIterator(final NodeIterator parent, final YangInstanceIdentifier path, final Iterator<DataTreeCandidateNode> iterator) {
-            this.iterator = Preconditions.checkNotNull(iterator);
-            this.parent = Preconditions.checkNotNull(parent);
-            this.path = Preconditions.checkNotNull(path);
+        NodeIterator(@Nullable final NodeIterator parent, @Nonnull final YangInstanceIdentifier path,
+                @Nonnull final Iterator<DataTreeCandidateNode> iterator) {
+            this.iterator = requireNonNull(iterator);
+            this.path = requireNonNull(path);
+            this.parent = parent;
         }
 
         NodeIterator next(final DataTreeModification modification) {
@@ -90,23 +110,25 @@ public final class DataTreeCandidates {
                 final YangInstanceIdentifier child = path.node(node.getIdentifier());
 
                 switch (node.getModificationType()) {
-                case DELETE:
-                    modification.delete(child);
-                    LOG.debug("Modification {} deleted path {}", modification, child);
-                    break;
-                case SUBTREE_MODIFIED:
-                    LOG.debug("Modification {} modified path {}", modification, child);
-                    return new NodeIterator(this, child, node.getChildNodes().iterator());
-                case UNMODIFIED:
-                    LOG.debug("Modification {} unmodified path {}", modification, child);
-                    // No-op
-                    break;
-                case WRITE:
-                    modification.write(child, node.getDataAfter().get());
-                    LOG.debug("Modification {} written path {}", modification, child);
-                    break;
-                default:
-                    throw new IllegalArgumentException("Unsupported modification " + node.getModificationType());
+                    case DELETE:
+                        modification.delete(child);
+                        LOG.debug("Modification {} deleted path {}", modification, child);
+                        break;
+                    case APPEARED:
+                    case DISAPPEARED:
+                    case SUBTREE_MODIFIED:
+                        LOG.debug("Modification {} modified path {}", modification, child);
+                        return new NodeIterator(this, child, node.getChildNodes().iterator());
+                    case UNMODIFIED:
+                        LOG.debug("Modification {} unmodified path {}", modification, child);
+                        // No-op
+                        break;
+                    case WRITE:
+                        modification.write(child, node.getDataAfter().get());
+                        LOG.debug("Modification {} written path {}", modification, child);
+                        break;
+                    default:
+                        throw new IllegalArgumentException("Unsupported modification " + node.getModificationType());
                 }
             }