Merge "Fix sonar issues in AnyXmlEffectiveStatementImpl"
[yangtools.git] / yang / yang-data-impl / src / main / java / org / opendaylight / yangtools / yang / data / impl / schema / tree / InMemoryDataTreeModification.java
index e0e136545803a902dc643fce86284ffa88c8c2a9..f86c71249bc53b20f2b3a5586cc16b49302c58cb 100644 (file)
@@ -10,6 +10,7 @@ package org.opendaylight.yangtools.yang.data.impl.schema.tree;
 import com.google.common.base.Optional;
 import com.google.common.base.Preconditions;
 import com.google.common.collect.Iterables;
+import java.util.Collection;
 import java.util.Map.Entry;
 import java.util.concurrent.atomic.AtomicIntegerFieldUpdater;
 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
@@ -17,6 +18,7 @@ import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.PathArgum
 import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
 import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNodes;
 import org.opendaylight.yangtools.yang.data.api.schema.tree.DataTreeModification;
+import org.opendaylight.yangtools.yang.data.api.schema.tree.DataTreeModificationCursor;
 import org.opendaylight.yangtools.yang.data.api.schema.tree.StoreTreeNodes;
 import org.opendaylight.yangtools.yang.data.api.schema.tree.spi.TreeNode;
 import org.opendaylight.yangtools.yang.data.api.schema.tree.spi.Version;
@@ -146,7 +148,7 @@ final class InMemoryDataTreeModification implements DataTreeModification {
         ModifiedNode modification = rootNode;
 
         int i = 1;
-        for(PathArgument pathArg : path.getPathArguments()) {
+        for (PathArgument pathArg : path.getPathArguments()) {
             Optional<ModificationApplyOperation> potential = operation.getChild(pathArg);
             if (!potential.isPresent()) {
                 throw new IllegalArgumentException(String.format("Child %s is not present in schema tree.",
@@ -161,14 +163,6 @@ final class InMemoryDataTreeModification implements DataTreeModification {
         return OperationWithModification.from(operation, modification);
     }
 
-    @Override
-    public void ready() {
-        final boolean wasRunning = UPDATER.compareAndSet(this, 0, 1);
-        Preconditions.checkState(wasRunning, "Attempted to seal an already-sealed Data Tree.");
-
-        rootNode.seal();
-    }
-
     private void checkSealed() {
         Preconditions.checkState(sealed == 0, "Data Tree is sealed. No further modifications allowed.");
     }
@@ -201,4 +195,61 @@ final class InMemoryDataTreeModification implements DataTreeModification {
     Version getVersion() {
         return version;
     }
+
+    private static void applyChildren(final DataTreeModificationCursor cursor, final ModifiedNode node) {
+        final Collection<ModifiedNode> children = node.getChildren();
+        if (!children.isEmpty()) {
+            cursor.enter(node.getIdentifier());
+            for (ModifiedNode child : children) {
+                applyNode(cursor, child);
+            }
+            cursor.exit();
+        }
+    }
+
+    private static void applyNode(final DataTreeModificationCursor cursor, final ModifiedNode node) {
+        switch (node.getOperation()) {
+        case NONE:
+            break;
+        case DELETE:
+            cursor.delete(node.getIdentifier());
+            break;
+        case MERGE:
+            cursor.merge(node.getIdentifier(), node.getWrittenValue());
+            applyChildren(cursor, node);
+            break;
+        case TOUCH:
+            // TODO: we could improve efficiency of cursor use if we could understand
+            //       nested TOUCH operations. One way of achieving that would be a proxy
+            //       cursor, which would keep track of consecutive enter and exit calls
+            //       and coalesce them.
+            applyChildren(cursor, node);
+            break;
+        case WRITE:
+            cursor.write(node.getIdentifier(), node.getWrittenValue());
+            applyChildren(cursor, node);
+            break;
+        default:
+            throw new IllegalArgumentException("Unhandled node operation " + node.getOperation());
+        }
+    }
+
+    @Override
+    public void applyToCursor(final DataTreeModificationCursor cursor) {
+        for (ModifiedNode child : rootNode.getChildren()) {
+            applyNode(cursor, child);
+        }
+    }
+
+    @Override
+    public void ready() {
+        final boolean wasRunning = UPDATER.compareAndSet(this, 0, 1);
+        Preconditions.checkState(wasRunning, "Attempted to seal an already-sealed Data Tree.");
+
+        AbstractReadyIterator current = AbstractReadyIterator.create(rootNode);
+        do {
+            current = current.process();
+        } while (current != null);
+    }
+
 }