Add a bit of documentation in AbstractReadyIterator
[yangtools.git] / yang / yang-data-impl / src / main / java / org / opendaylight / yangtools / yang / data / impl / schema / tree / AbstractReadyIterator.java
1 /*
2  * Copyright (c) 2015 Cisco Systems, Inc. and others.  All rights reserved.
3  *
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
7  */
8 package org.opendaylight.yangtools.yang.data.impl.schema.tree;
9
10 import com.google.common.base.Optional;
11 import com.google.common.base.Preconditions;
12 import java.util.Collection;
13 import java.util.Iterator;
14 import org.opendaylight.yangtools.yang.data.api.schema.tree.spi.Version;
15
16 abstract class AbstractReadyIterator {
17     final Iterator<ModifiedNode> children;
18     final ModifiedNode node;
19     final ModificationApplyOperation op;
20
21     private AbstractReadyIterator(final ModifiedNode node, final Iterator<ModifiedNode> children,
22             final ModificationApplyOperation operation) {
23         this.children = Preconditions.checkNotNull(children);
24         this.node = Preconditions.checkNotNull(node);
25         this.op = Preconditions.checkNotNull(operation);
26     }
27
28     static AbstractReadyIterator create(final ModifiedNode root, final ModificationApplyOperation operation) {
29         return new RootReadyIterator(root, root.getChildren().iterator(), operation);
30     }
31
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 ModifiedNode child = children.next();
38             final Optional<ModificationApplyOperation> childOperation = op.getChild(child.getIdentifier());
39             Preconditions.checkState(childOperation.isPresent(), "Schema for child %s is not present.",
40                     child.getIdentifier());
41             final Collection<ModifiedNode> grandChildren = child.getChildren();
42             final ModificationApplyOperation childOp = childOperation.get();
43
44             if (grandChildren.isEmpty()) {
45                 // The child is empty, seal it
46                 child.seal(childOp, version);
47                 if (child.getOperation() == LogicalOperation.NONE) {
48                     children.remove();
49                 }
50             } else {
51                 return new NestedReadyIterator(this, child, grandChildren.iterator(), childOp);
52             }
53         }
54
55         // We are done with this node, seal it.
56         node.seal(op, version);
57
58         // Remove from parent if we have one and this is a no-op
59         if (node.getOperation() == LogicalOperation.NONE) {
60             removeFromParent();
61         }
62
63         // Sub-iteration complete, return back to parent
64         return getParent();
65     }
66
67     abstract AbstractReadyIterator getParent();
68     abstract void removeFromParent();
69
70     private static final class NestedReadyIterator extends AbstractReadyIterator {
71         private final AbstractReadyIterator parent;
72
73         private NestedReadyIterator(final AbstractReadyIterator parent, final ModifiedNode node,
74                 final Iterator<ModifiedNode> children, final ModificationApplyOperation operation) {
75             super(node, children, operation);
76             this.parent = Preconditions.checkNotNull(parent);
77         }
78
79         @Override
80         AbstractReadyIterator getParent() {
81             return parent;
82         }
83
84         @Override
85         void removeFromParent() {
86             parent.children.remove();
87         }
88     }
89
90     private static final class RootReadyIterator extends AbstractReadyIterator {
91         private RootReadyIterator(final ModifiedNode node, final Iterator<ModifiedNode> children,
92                 final ModificationApplyOperation operation) {
93             super(node, children, operation);
94         }
95
96         @Override
97         AbstractReadyIterator getParent() {
98             return null;
99         }
100
101         @Override
102         void removeFromParent() {
103             // No-op, since root node cannot be removed
104         }
105     }
106
107 }