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,
32 * DataTreeCandidateNode) applyRootedNodeToCursor} method that works with rooted node candidates.
34 * @param cursor cursor from the modification we want to apply the {@code node} to
35 * @param node candidate tree to apply
37 public static void applyToCursor(final DataTreeModificationCursor cursor, final DataTreeCandidateNode node) {
38 switch (node.getModificationType()) {
40 cursor.delete(node.getIdentifier());
42 case SUBTREE_MODIFIED:
43 cursor.enter(node.getIdentifier());
44 AbstractNodeIterator iterator = new ExitingNodeIterator(null, node.getChildNodes().iterator());
46 iterator = iterator.next(cursor);
47 } while (iterator != null);
53 cursor.write(node.getIdentifier(), node.getDataAfter().get());
56 throw new IllegalArgumentException("Unsupported modification " + node.getModificationType());
61 * Applies the {@code node} that is rooted(doesn't have an identifier) in tree A to tree B's {@code cursor}
62 * at location specified by {@code rootPath}.
64 * @param cursor cursor from the modification we want to apply the {@code node} to
65 * @param rootPath path in the {@code cursor}'s tree we want to apply to candidate to
66 * @param node candidate tree to apply
68 public static void applyRootedNodeToCursor(final DataTreeModificationCursor cursor,
69 final YangInstanceIdentifier rootPath, final DataTreeCandidateNode node) {
70 switch (node.getModificationType()) {
72 cursor.delete(rootPath.getLastPathArgument());
74 case SUBTREE_MODIFIED:
75 cursor.enter(rootPath.getLastPathArgument());
76 AbstractNodeIterator iterator = new ExitingNodeIterator(null, node.getChildNodes().iterator());
78 iterator = iterator.next(cursor);
79 } while (iterator != null);
85 cursor.write(rootPath.getLastPathArgument(), node.getDataAfter().get());
88 throw new IllegalArgumentException("Unsupported modification " + node.getModificationType());
92 public static void applyRootToCursor(final DataTreeModificationCursor cursor, final DataTreeCandidateNode node) {
93 switch (node.getModificationType()) {
95 throw new IllegalArgumentException("Can not delete root.");
97 case SUBTREE_MODIFIED:
98 AbstractNodeIterator iterator = new RootNonExitingIterator(node.getChildNodes().iterator());
100 iterator = iterator.next(cursor);
101 } while (iterator != null);
107 throw new IllegalArgumentException("Unsupported modification " + node.getModificationType());
111 private abstract static class AbstractNodeIterator {
112 private final Iterator<DataTreeCandidateNode> iterator;
114 AbstractNodeIterator(final Iterator<DataTreeCandidateNode> iterator) {
115 this.iterator = Preconditions.checkNotNull(iterator);
118 AbstractNodeIterator next(final DataTreeModificationCursor cursor) {
119 while (iterator.hasNext()) {
120 final DataTreeCandidateNode node = iterator.next();
121 switch (node.getModificationType()) {
123 cursor.delete(node.getIdentifier());
127 case SUBTREE_MODIFIED:
128 final Collection<DataTreeCandidateNode> children = node.getChildNodes();
129 if (!children.isEmpty()) {
130 cursor.enter(node.getIdentifier());
131 return new ExitingNodeIterator(this, children.iterator());
138 cursor.write(node.getIdentifier(), node.getDataAfter().get());
141 throw new IllegalArgumentException("Unsupported modification " + node.getModificationType());
148 protected abstract @Nullable AbstractNodeIterator getParent();
150 protected abstract void exitNode(DataTreeModificationCursor cursor);
153 private static final class RootNonExitingIterator extends AbstractNodeIterator {
155 protected RootNonExitingIterator(@Nonnull final Iterator<DataTreeCandidateNode> iterator) {
160 protected void exitNode(final DataTreeModificationCursor cursor) {
165 protected AbstractNodeIterator getParent() {
170 private static final class ExitingNodeIterator extends AbstractNodeIterator {
172 private final AbstractNodeIterator parent;
174 ExitingNodeIterator(@Nullable final AbstractNodeIterator parent,
175 @Nonnull final Iterator<DataTreeCandidateNode> iterator) {
177 this.parent = parent;
181 protected AbstractNodeIterator getParent() {
186 protected void exitNode(final DataTreeModificationCursor cursor) {