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.api.schema.tree;
10 import com.google.common.annotations.Beta;
11 import com.google.common.base.Preconditions;
12 import java.util.Collection;
13 import java.util.Iterator;
14 import javax.annotation.Nonnull;
15 import javax.annotation.Nullable;
16 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
17 import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
20 public final class DataTreeCandidateNodes {
21 private DataTreeCandidateNodes() {
22 throw new UnsupportedOperationException();
25 public static DataTreeCandidateNode fromNormalizedNode(final NormalizedNode<?, ?> node) {
26 return new NormalizedNodeDataTreeCandidateNode(node);
30 * Applies the {@code node} to the {@code cursor}, note that if the top node of (@code node} is RootNode
31 * you need to use {@link #applyRootedNodeToCursor(DataTreeModificationCursor, YangInstanceIdentifier, DataTreeCandidateNode) applyRootedNodeToCursor}
32 * method that works with rooted node candidates
33 * @param cursor cursor from the modification we want to apply the {@code node} to
34 * @param node candidate tree to apply
36 public static void applyToCursor(final DataTreeModificationCursor cursor, final DataTreeCandidateNode node) {
37 switch (node.getModificationType()) {
39 cursor.delete(node.getIdentifier());
41 case SUBTREE_MODIFIED:
42 cursor.enter(node.getIdentifier());
43 AbstractNodeIterator iterator = new ExitingNodeIterator(null, node.getChildNodes().iterator());
45 iterator = iterator.next(cursor);
46 } while (iterator != null);
52 cursor.write(node.getIdentifier(), node.getDataAfter().get());
55 throw new IllegalArgumentException("Unsupported modification " + node.getModificationType());
60 * Applies the {@code node} that is rooted(doesn't have an identifier) in tree A to tree B's {@code cursor}
61 * at location specified by {@code rootPath}
62 * @param cursor cursor from the modification we want to apply the {@code node} to
63 * @param rootPath path in the {@code cursor}'s tree we want to apply to candidate to
64 * @param node candidate tree to apply
66 public static void applyRootedNodeToCursor(final DataTreeModificationCursor cursor, final YangInstanceIdentifier rootPath, final DataTreeCandidateNode node) {
67 switch (node.getModificationType()) {
69 cursor.delete(rootPath.getLastPathArgument());
71 case SUBTREE_MODIFIED:
72 cursor.enter(rootPath.getLastPathArgument());
73 AbstractNodeIterator iterator = new ExitingNodeIterator(null, node.getChildNodes().iterator());
75 iterator = iterator.next(cursor);
76 } while (iterator != null);
82 cursor.write(rootPath.getLastPathArgument(), node.getDataAfter().get());
85 throw new IllegalArgumentException("Unsupported modification " + node.getModificationType());
89 public static void applyRootToCursor(final DataTreeModificationCursor cursor, final DataTreeCandidateNode node) {
90 switch (node.getModificationType()) {
92 throw new IllegalArgumentException("Can not delete root.");
94 case SUBTREE_MODIFIED:
95 AbstractNodeIterator iterator = new RootNonExitingIterator(node.getChildNodes().iterator());
97 iterator = iterator.next(cursor);
98 } while (iterator != null);
104 throw new IllegalArgumentException("Unsupported modification " + node.getModificationType());
108 private abstract static class AbstractNodeIterator {
109 private final Iterator<DataTreeCandidateNode> iterator;
111 AbstractNodeIterator(final Iterator<DataTreeCandidateNode> iterator) {
112 this.iterator = Preconditions.checkNotNull(iterator);
115 AbstractNodeIterator next(final DataTreeModificationCursor cursor) {
116 while (iterator.hasNext()) {
117 final DataTreeCandidateNode node = iterator.next();
118 switch (node.getModificationType()) {
120 cursor.delete(node.getIdentifier());
124 case SUBTREE_MODIFIED:
125 final Collection<DataTreeCandidateNode> children = node.getChildNodes();
126 if (!children.isEmpty()) {
127 cursor.enter(node.getIdentifier());
128 return new ExitingNodeIterator(this, children.iterator());
135 cursor.write(node.getIdentifier(), node.getDataAfter().get());
138 throw new IllegalArgumentException("Unsupported modification " + node.getModificationType());
145 protected abstract @Nullable AbstractNodeIterator getParent();
147 protected abstract void exitNode(DataTreeModificationCursor cursor);
150 private static final class RootNonExitingIterator extends AbstractNodeIterator {
152 protected RootNonExitingIterator(@Nonnull final Iterator<DataTreeCandidateNode> iterator) {
157 protected void exitNode(final DataTreeModificationCursor cursor) {
162 protected AbstractNodeIterator getParent() {
167 private static final class ExitingNodeIterator extends AbstractNodeIterator {
169 private final AbstractNodeIterator parent;
171 public ExitingNodeIterator(@Nullable final AbstractNodeIterator parent,
172 @Nonnull final Iterator<DataTreeCandidateNode> iterator) {
174 this.parent = parent;
178 protected AbstractNodeIterator getParent() {
183 protected void exitNode(final DataTreeModificationCursor cursor) {