import com.google.common.base.Preconditions;
import java.util.Collection;
import java.util.Iterator;
+import javax.annotation.Nonnull;
+import javax.annotation.Nullable;
import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
@Beta
cursor.delete(node.getIdentifier());
break;
case SUBTREE_MODIFIED:
- cursor.enter(node.getIdentifier());
- NodeIterator iterator = new NodeIterator(null, node.getChildNodes().iterator());
+ cursor.enter(node.getIdentifier());
+ AbstractNodeIterator iterator = new ExitingNodeIterator(null, node.getChildNodes().iterator());
do {
iterator = iterator.next(cursor);
} while (iterator != null);
}
}
- private static final class NodeIterator {
+ public static void applyRootToCursor(final DataTreeModificationCursor cursor, final DataTreeCandidateNode node) {
+ switch (node.getModificationType()) {
+ case DELETE:
+ throw new IllegalArgumentException("Can not delete root.");
+ case WRITE:
+ case SUBTREE_MODIFIED:
+ AbstractNodeIterator iterator = new RootNonExitingIterator(node.getChildNodes().iterator());
+ do {
+ iterator = iterator.next(cursor);
+ } while (iterator != null);
+ break;
+ case UNMODIFIED:
+ // No-op
+ break;
+ default:
+ throw new IllegalArgumentException("Unsupported modification " + node.getModificationType());
+ }
+ }
+
+ private static abstract class AbstractNodeIterator {
private final Iterator<DataTreeCandidateNode> iterator;
- private final NodeIterator parent;
- NodeIterator(final NodeIterator parent, final Iterator<DataTreeCandidateNode> iterator) {
- this.parent = Preconditions.checkNotNull(parent);
+ AbstractNodeIterator(final Iterator<DataTreeCandidateNode> iterator) {
this.iterator = Preconditions.checkNotNull(iterator);
}
- NodeIterator next(final DataTreeModificationCursor cursor) {
+ AbstractNodeIterator next(final DataTreeModificationCursor cursor) {
while (iterator.hasNext()) {
final DataTreeCandidateNode node = iterator.next();
switch (node.getModificationType()) {
final Collection<DataTreeCandidateNode> children = node.getChildNodes();
if (!children.isEmpty()) {
cursor.enter(node.getIdentifier());
- return new NodeIterator(this, children.iterator());
+ return new ExitingNodeIterator(this, children.iterator());
}
break;
case UNMODIFIED:
throw new IllegalArgumentException("Unsupported modification " + node.getModificationType());
}
}
+ exitNode(cursor);
+ return getParent();
+ }
- cursor.exit();
+ protected abstract @Nullable AbstractNodeIterator getParent();
+
+ protected abstract void exitNode(DataTreeModificationCursor cursor);
+ }
+
+ private static final class RootNonExitingIterator extends AbstractNodeIterator {
+
+ protected RootNonExitingIterator(@Nonnull final Iterator<DataTreeCandidateNode> iterator) {
+ super(iterator);
+ }
+
+ @Override
+ protected void exitNode(final DataTreeModificationCursor cursor) {
+ // Intentional noop.
+ }
+
+ @Override
+ protected AbstractNodeIterator getParent() {
+ return null;
+ }
+
+ }
+
+ private static final class ExitingNodeIterator extends AbstractNodeIterator {
+
+ private final AbstractNodeIterator parent;
+
+ public ExitingNodeIterator(@Nullable final AbstractNodeIterator parent,
+ @Nonnull final Iterator<DataTreeCandidateNode> iterator) {
+ super(iterator);
+ this.parent = parent;
+ }
+
+ @Override
+ protected AbstractNodeIterator getParent() {
return parent;
}
+
+ @Override
+ protected final void exitNode(final DataTreeModificationCursor cursor) {
+ cursor.exit();
+ }
+
}
}
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;
}
}
}
+ 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;