Fix a few sonar warnings
[yangtools.git] / yang / yang-data-api / src / main / java / org / opendaylight / yangtools / yang / data / api / schema / tree / DataTreeCandidateNodes.java
index 44f24c2a70f8548327f49e3c6c797bea6efe6ce9..8145bfe711884fbe1a72fba28ee7c19eb8ef1469 100644 (file)
@@ -8,6 +8,11 @@
 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 javax.annotation.Nonnull;
+import javax.annotation.Nullable;
 import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
 
 @Beta
@@ -19,4 +24,124 @@ 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());
+                AbstractNodeIterator iterator = new ExitingNodeIterator(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());
+        }
+    }
+
+    public static void applyRootToCursor(final DataTreeModificationCursor cursor, final DataTreeCandidateNode node) {
+        switch (node.getModificationType()) {
+            case DELETE:
+                throw new IllegalArgumentException("Can not delete root.");
+            case WRITE:
+            case SUBTREE_MODIFIED:
+                AbstractNodeIterator iterator = new RootNonExitingIterator(node.getChildNodes().iterator());
+                do {
+                    iterator = iterator.next(cursor);
+                } while (iterator != null);
+                break;
+            case UNMODIFIED:
+                // No-op
+                break;
+            default:
+                throw new IllegalArgumentException("Unsupported modification " + node.getModificationType());
+        }
+    }
+
+    private abstract static class AbstractNodeIterator {
+        private final Iterator<DataTreeCandidateNode> iterator;
+
+        AbstractNodeIterator(final Iterator<DataTreeCandidateNode> iterator) {
+            this.iterator = Preconditions.checkNotNull(iterator);
+        }
+
+        AbstractNodeIterator 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 ExitingNodeIterator(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());
+                }
+            }
+            exitNode(cursor);
+            return getParent();
+        }
+
+        protected abstract @Nullable AbstractNodeIterator getParent();
+
+        protected abstract void exitNode(DataTreeModificationCursor cursor);
+    }
+
+    private static final class RootNonExitingIterator extends AbstractNodeIterator {
+
+        protected RootNonExitingIterator(@Nonnull final Iterator<DataTreeCandidateNode> iterator) {
+            super(iterator);
+        }
+
+        @Override
+        protected void exitNode(final DataTreeModificationCursor cursor) {
+            // Intentional noop.
+        }
+
+        @Override
+        protected AbstractNodeIterator getParent() {
+            return null;
+        }
+    }
+
+    private static final class ExitingNodeIterator extends AbstractNodeIterator {
+
+        private final AbstractNodeIterator parent;
+
+        public ExitingNodeIterator(@Nullable final AbstractNodeIterator parent,
+                @Nonnull final Iterator<DataTreeCandidateNode> iterator) {
+            super(iterator);
+            this.parent = parent;
+        }
+
+        @Override
+        protected AbstractNodeIterator getParent() {
+            return parent;
+        }
+
+        @Override
+        protected void exitNode(final DataTreeModificationCursor cursor) {
+            cursor.exit();
+        }
+    }
 }