Deprecate yang.binding.InstanceIdentifier
[yangtools.git] / data / yang-data-tree-ri / src / main / java / org / opendaylight / yangtools / yang / data / tree / impl / 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.tree.impl;
9
10 import static com.google.common.base.Preconditions.checkState;
11 import static java.util.Objects.requireNonNull;
12
13 import java.util.Iterator;
14 import org.opendaylight.yangtools.yang.data.tree.impl.node.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 = requireNonNull(children);
24         this.node = requireNonNull(node);
25         op = requireNonNull(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 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);
41
42             if (child.isEmpty()) {
43                 // The child is empty, seal it
44                 child.seal(childOp, version);
45                 if (child.getOperation() == LogicalOperation.NONE) {
46                     children.remove();
47                 }
48             } else {
49                 return new NestedReadyIterator(this, child, child.getChildren().iterator(), childOp);
50             }
51         }
52
53         // We are done with this node, seal it.
54         node.seal(op, version);
55
56         // Remove from parent if we have one and this is a no-op
57         if (node.getOperation() == LogicalOperation.NONE) {
58             removeFromParent();
59         }
60
61         // Sub-iteration complete, return back to parent
62         return getParent();
63     }
64
65     abstract AbstractReadyIterator getParent();
66
67     abstract void removeFromParent();
68
69     private static final class NestedReadyIterator extends AbstractReadyIterator {
70         private final AbstractReadyIterator parent;
71
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);
76         }
77
78         @Override
79         AbstractReadyIterator getParent() {
80             return parent;
81         }
82
83         @Override
84         void removeFromParent() {
85             parent.children.remove();
86         }
87     }
88
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);
93         }
94
95         @Override
96         AbstractReadyIterator getParent() {
97             return null;
98         }
99
100         @Override
101         void removeFromParent() {
102             // No-op, since root node cannot be removed
103         }
104     }
105 }