Bug 2882: Fix off-by-one usage of cursor.
[yangtools.git] / yang / yang-data-api / src / main / java / org / opendaylight / yangtools / yang / data / api / schema / tree / DataTreeCandidates.java
index 1b242918ddd15799dec0b977040bf717bb860d5a..a75ec5984b7fa5f197e5656a28c67f5d7d701154 100644 (file)
@@ -10,6 +10,8 @@ package org.opendaylight.yangtools.yang.data.api.schema.tree;
 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;
@@ -39,9 +41,7 @@ public final class DataTreeCandidates {
 
     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;
         }
 
@@ -73,15 +73,32 @@ public final class DataTreeCandidates {
         }
     }
 
+    private static void applyToCursorAwareModification(final CursorAwareDataTreeModification modification,
+            final DataTreeCandidate candidate) {
+        final YangInstanceIdentifier candidatePath = candidate.getRootPath();
+        if (candidatePath.isEmpty()) {
+            try (DataTreeModificationCursor cursor =
+                    ((CursorAwareDataTreeModification) modification).createCursor(candidatePath)) {
+                DataTreeCandidateNodes.applyRootToCursor(cursor, candidate.getRootNode());
+            }
+        } else {
+            try (DataTreeModificationCursor cursor =
+                    ((CursorAwareDataTreeModification) modification).createCursor(candidatePath.getParent())) {
+                DataTreeCandidateNodes.applyToCursor(cursor, candidate.getRootNode());
+            }
+        }
+    }
+
     private static final class NodeIterator {
         private final Iterator<DataTreeCandidateNode> iterator;
         private final YangInstanceIdentifier path;
         private final NodeIterator parent;
 
-        public NodeIterator(final NodeIterator parent, final YangInstanceIdentifier path, final Iterator<DataTreeCandidateNode> iterator) {
+        public NodeIterator(@Nullable final NodeIterator parent, @Nonnull final YangInstanceIdentifier path,
+                @Nonnull final Iterator<DataTreeCandidateNode> iterator) {
             this.iterator = Preconditions.checkNotNull(iterator);
-            this.parent = Preconditions.checkNotNull(parent);
             this.path = Preconditions.checkNotNull(path);
+            this.parent = parent;
         }
 
         NodeIterator next(final DataTreeModification modification) {