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.impl.schema.tree;
10 import static com.google.common.base.Preconditions.checkState;
11 import static java.util.Objects.requireNonNull;
13 import java.util.Collection;
14 import java.util.Iterator;
15 import java.util.Optional;
16 import org.opendaylight.yangtools.yang.data.api.schema.tree.spi.Version;
18 abstract class AbstractReadyIterator {
19 final Iterator<ModifiedNode> children;
20 final ModifiedNode node;
21 final ModificationApplyOperation op;
23 private AbstractReadyIterator(final ModifiedNode node, final Iterator<ModifiedNode> children,
24 final ModificationApplyOperation operation) {
25 this.children = requireNonNull(children);
26 this.node = requireNonNull(node);
27 this.op = requireNonNull(operation);
30 static AbstractReadyIterator create(final ModifiedNode root, final ModificationApplyOperation operation) {
31 return new RootReadyIterator(root, root.getChildren().iterator(), operation);
34 final AbstractReadyIterator process(final Version version) {
35 // Walk all child nodes and remove any children which have not
36 // been modified. If a child has children, we need to iterate
37 // through it via re-entering this method on the child iterator.
38 while (children.hasNext()) {
39 final ModifiedNode child = children.next();
40 final Optional<ModificationApplyOperation> childOperation = op.getChild(child.getIdentifier());
41 checkState(childOperation.isPresent(), "Schema for child %s is not present.", child.getIdentifier());
42 final Collection<ModifiedNode> grandChildren = child.getChildren();
43 final ModificationApplyOperation childOp = childOperation.get();
45 if (grandChildren.isEmpty()) {
46 // The child is empty, seal it
47 child.seal(childOp, version);
48 if (child.getOperation() == LogicalOperation.NONE) {
52 return new NestedReadyIterator(this, child, grandChildren.iterator(), childOp);
56 // We are done with this node, seal it.
57 node.seal(op, version);
59 // Remove from parent if we have one and this is a no-op
60 if (node.getOperation() == LogicalOperation.NONE) {
64 // Sub-iteration complete, return back to parent
68 abstract AbstractReadyIterator getParent();
70 abstract void removeFromParent();
72 private static final class NestedReadyIterator extends AbstractReadyIterator {
73 private final AbstractReadyIterator parent;
75 private NestedReadyIterator(final AbstractReadyIterator parent, final ModifiedNode node,
76 final Iterator<ModifiedNode> children, final ModificationApplyOperation operation) {
77 super(node, children, operation);
78 this.parent = requireNonNull(parent);
82 AbstractReadyIterator getParent() {
87 void removeFromParent() {
88 parent.children.remove();
92 private static final class RootReadyIterator extends AbstractReadyIterator {
93 private RootReadyIterator(final ModifiedNode node, final Iterator<ModifiedNode> children,
94 final ModificationApplyOperation operation) {
95 super(node, children, operation);
99 AbstractReadyIterator getParent() {
104 void removeFromParent() {
105 // No-op, since root node cannot be removed