2 * Copyright (c) 2015 Cisco Systems, Inc. and others. All rights reserved.
4 * This program and the accompanying materials are made available under the
5 * terms of the Eclipse Public License v1.0 which accompanies this distribution,
6 * and is available at http://www.eclipse.org/legal/epl-v10.html
8 package org.opendaylight.yangtools.yang.data.tree.impl;
10 import static com.google.common.base.Preconditions.checkState;
11 import static java.util.Objects.requireNonNull;
13 import java.util.Iterator;
14 import org.opendaylight.yangtools.yang.data.tree.impl.node.Version;
16 abstract class AbstractReadyIterator {
17 final Iterator<ModifiedNode> children;
18 final ModifiedNode node;
19 final ModificationApplyOperation op;
21 private AbstractReadyIterator(final ModifiedNode node, final Iterator<ModifiedNode> children,
22 final ModificationApplyOperation operation) {
23 this.children = requireNonNull(children);
24 this.node = requireNonNull(node);
25 op = requireNonNull(operation);
28 static AbstractReadyIterator create(final ModifiedNode root, final ModificationApplyOperation operation) {
29 return new RootReadyIterator(root, root.getChildren().iterator(), operation);
32 final AbstractReadyIterator process(final Version version) {
33 // Walk all child nodes and remove any children which have not
34 // been modified. If a child has children, we need to iterate
35 // through it via re-entering this method on the child iterator.
36 while (children.hasNext()) {
37 final var child = children.next();
38 final var childId = child.getIdentifier();
39 final var childOp = op.childByArg(childId);
40 checkState(childOp != null, "Schema for child %s is not present.", childId);
42 if (child.isEmpty()) {
43 // The child is empty, seal it
44 child.seal(childOp, version);
45 if (child.getOperation() == LogicalOperation.NONE) {
49 return new NestedReadyIterator(this, child, child.getChildren().iterator(), childOp);
53 // We are done with this node, seal it.
54 node.seal(op, version);
56 // Remove from parent if we have one and this is a no-op
57 if (node.getOperation() == LogicalOperation.NONE) {
61 // Sub-iteration complete, return back to parent
65 abstract AbstractReadyIterator getParent();
67 abstract void removeFromParent();
69 private static final class NestedReadyIterator extends AbstractReadyIterator {
70 private final AbstractReadyIterator parent;
72 private NestedReadyIterator(final AbstractReadyIterator parent, final ModifiedNode node,
73 final Iterator<ModifiedNode> children, final ModificationApplyOperation operation) {
74 super(node, children, operation);
75 this.parent = requireNonNull(parent);
79 AbstractReadyIterator getParent() {
84 void removeFromParent() {
85 parent.children.remove();
89 private static final class RootReadyIterator extends AbstractReadyIterator {
90 private RootReadyIterator(final ModifiedNode node, final Iterator<ModifiedNode> children,
91 final ModificationApplyOperation operation) {
92 super(node, children, operation);
96 AbstractReadyIterator getParent() {
101 void removeFromParent() {
102 // No-op, since root node cannot be removed