Optimize DataTreeCandidate.applyToModification()
[yangtools.git] / yang / yang-data-api / src / main / java / org / opendaylight / yangtools / yang / data / api / schema / tree / DataTreeCandidateNodes.java
index 44f24c2a70f8548327f49e3c6c797bea6efe6ce9..e1636ae77e8707baccc837e5f721ad78cbc30a55 100644 (file)
@@ -8,6 +8,9 @@
 package org.opendaylight.yangtools.yang.data.api.schema.tree;
 
 import com.google.common.annotations.Beta;
+import com.google.common.base.Preconditions;
+import java.util.Collection;
+import java.util.Iterator;
 import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
 
 @Beta
@@ -19,4 +22,66 @@ public final class DataTreeCandidateNodes {
     public static DataTreeCandidateNode fromNormalizedNode(final NormalizedNode<?, ?> node) {
         return new NormalizedNodeDataTreeCandidateNode(node);
     }
+
+    public static void applyToCursor(final DataTreeModificationCursor cursor, final DataTreeCandidateNode node) {
+        switch (node.getModificationType()) {
+        case DELETE:
+            cursor.delete(node.getIdentifier());
+            break;
+        case SUBTREE_MODIFIED:
+            cursor.enter(node.getIdentifier());
+            NodeIterator iterator = new NodeIterator(null, node.getChildNodes().iterator());
+            do {
+                iterator = iterator.next(cursor);
+            } while (iterator != null);
+            break;
+        case UNMODIFIED:
+            // No-op
+            break;
+        case WRITE:
+            cursor.write(node.getIdentifier(), node.getDataAfter().get());
+            break;
+        default:
+            throw new IllegalArgumentException("Unsupported modification " + node.getModificationType());
+        }
+    }
+
+    private static final class NodeIterator {
+        private final Iterator<DataTreeCandidateNode> iterator;
+        private final NodeIterator parent;
+
+        NodeIterator(final NodeIterator parent, final Iterator<DataTreeCandidateNode> iterator) {
+            this.parent = Preconditions.checkNotNull(parent);
+            this.iterator = Preconditions.checkNotNull(iterator);
+        }
+
+        NodeIterator next(final DataTreeModificationCursor cursor) {
+            while (iterator.hasNext()) {
+                final DataTreeCandidateNode node = iterator.next();
+                switch (node.getModificationType()) {
+                case DELETE:
+                    cursor.delete(node.getIdentifier());
+                    break;
+                case SUBTREE_MODIFIED:
+                    final Collection<DataTreeCandidateNode> children = node.getChildNodes();
+                    if (!children.isEmpty()) {
+                        cursor.enter(node.getIdentifier());
+                        return new NodeIterator(this, children.iterator());
+                    }
+                    break;
+                case UNMODIFIED:
+                    // No-op
+                    break;
+                case WRITE:
+                    cursor.write(node.getIdentifier(), node.getDataAfter().get());
+                    break;
+                default:
+                    throw new IllegalArgumentException("Unsupported modification " + node.getModificationType());
+                }
+            }
+
+            cursor.exit();
+            return parent;
+        }
+    }
 }