Cleanup checkstyle warnings and turn enforcement on in yang-data-impl
[yangtools.git] / yang / yang-data-impl / src / main / java / org / opendaylight / yangtools / yang / data / impl / schema / tree / InMemoryDataTreeModification.java
index 9bf2d3fdfc9072afa4cbadc43b2abca95e37d393..02e062add73f39af6cf382f873443fb3b9e6aa4c 100644 (file)
@@ -9,22 +9,19 @@ 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.common.QName;
+import javax.annotation.Nonnull;
 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.PathArgument;
 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.CursorAwareDataTreeModification;
-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;
-import org.opendaylight.yangtools.yang.model.api.SchemaContext;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -40,7 +37,8 @@ final class InMemoryDataTreeModification extends AbstractCursorAware implements
 
     private volatile int sealed = 0;
 
-    InMemoryDataTreeModification(final InMemoryDataTreeSnapshot snapshot, final RootModificationApplyOperation resolver) {
+    InMemoryDataTreeModification(final InMemoryDataTreeSnapshot snapshot,
+            final RootModificationApplyOperation resolver) {
         this.snapshot = Preconditions.checkNotNull(snapshot);
         this.strategyTree = Preconditions.checkNotNull(resolver).snapshot();
         this.rootNode = ModifiedNode.createUnmodified(snapshot.getRootNode(), strategyTree.getChildPolicy());
@@ -76,7 +74,7 @@ final class InMemoryDataTreeModification extends AbstractCursorAware implements
     public void merge(final YangInstanceIdentifier path, final NormalizedNode<?, ?> data) {
         checkSealed();
         checkIdentifierReferencesData(path, data);
-        resolveModificationFor(path).merge(data);
+        resolveModificationFor(path).merge(data, version);
     }
 
     @Override
@@ -93,7 +91,8 @@ final class InMemoryDataTreeModification extends AbstractCursorAware implements
          * the requested path which has been modified. If no such node exists,
          * we use the node itself.
          */
-        final Entry<YangInstanceIdentifier, ModifiedNode> entry = StoreTreeNodes.findClosestsOrFirstMatch(rootNode, path, ModifiedNode.IS_TERMINAL_PREDICATE);
+        final Entry<YangInstanceIdentifier, ModifiedNode> entry = StoreTreeNodes.findClosestsOrFirstMatch(rootNode,
+            path, ModifiedNode.IS_TERMINAL_PREDICATE);
         final YangInstanceIdentifier key = entry.getKey();
         final ModifiedNode mod = entry.getValue();
 
@@ -101,11 +100,12 @@ final class InMemoryDataTreeModification extends AbstractCursorAware implements
         if (result.isPresent()) {
             final NormalizedNode<?, ?> data = result.get().getData();
             return NormalizedNodes.findNode(key, data, path);
-        } else {
-            return Optional.absent();
         }
+
+        return Optional.absent();
     }
 
+    @SuppressWarnings("checkstyle:illegalCatch")
     private Optional<TreeNode> resolveSnapshot(final YangInstanceIdentifier path, final ModifiedNode modification) {
         final Optional<TreeNode> potentialSnapshot = modification.getSnapshot();
         if (potentialSnapshot != null) {
@@ -113,8 +113,7 @@ final class InMemoryDataTreeModification extends AbstractCursorAware implements
         }
 
         try {
-            return resolveModificationStrategy(path).apply(modification, modification.getOriginal(),
-                    version);
+            return resolveModificationStrategy(path).apply(modification, modification.getOriginal(), version);
         } catch (final Exception e) {
             LOG.error("Could not create snapshot for {}:{}", path, modification, e);
             throw e;
@@ -131,7 +130,7 @@ final class InMemoryDataTreeModification extends AbstractCursorAware implements
         LOG.trace("Resolving modification apply strategy for {}", path);
 
         upgradeIfPossible();
-        return StoreTreeNodes.<ModificationApplyOperation>findNodeChecked(strategyTree, path);
+        return StoreTreeNodes.findNodeChecked(strategyTree, path);
     }
 
     private OperationWithModification resolveModificationFor(final YangInstanceIdentifier path) {
@@ -150,17 +149,17 @@ final class InMemoryDataTreeModification extends AbstractCursorAware implements
         ModificationApplyOperation operation = strategyTree;
         ModifiedNode modification = rootNode;
 
-        int i = 1;
-        for(final PathArgument pathArg : path.getPathArguments()) {
+        int depth = 1;
+        for (final PathArgument pathArg : path.getPathArguments()) {
             final Optional<ModificationApplyOperation> potential = operation.getChild(pathArg);
             if (!potential.isPresent()) {
                 throw new SchemaValidationFailedException(String.format("Child %s is not present in schema tree.",
-                        Iterables.toString(Iterables.limit(path.getPathArguments(), i))));
+                        path.getAncestor(depth)));
             }
             operation = potential.get();
-            ++i;
+            ++depth;
 
-            modification = modification.modifyChild(pathArg, operation.getChildPolicy());
+            modification = modification.modifyChild(pathArg, operation, version);
         }
 
         return OperationWithModification.from(operation, modification);
@@ -176,7 +175,7 @@ final class InMemoryDataTreeModification extends AbstractCursorAware implements
     }
 
     @Override
-    public DataTreeModification newModification() {
+    public InMemoryDataTreeModification newModification() {
         Preconditions.checkState(sealed == 1, "Attempted to chain on an unsealed modification");
 
         if (rootNode.getOperation() == LogicalOperation.NONE) {
@@ -190,9 +189,11 @@ final class InMemoryDataTreeModification extends AbstractCursorAware implements
          */
         final TreeNode originalSnapshotRoot = snapshot.getRootNode();
         final Optional<TreeNode> tempRoot = strategyTree.apply(rootNode, Optional.of(originalSnapshotRoot), version);
-        Preconditions.checkState(tempRoot.isPresent(), "Data tree root is not present, possibly removed by previous modification");
+        Preconditions.checkState(tempRoot.isPresent(),
+            "Data tree root is not present, possibly removed by previous modification");
 
-        final InMemoryDataTreeSnapshot tempTree = new InMemoryDataTreeSnapshot(snapshot.getSchemaContext(), tempRoot.get(), strategyTree);
+        final InMemoryDataTreeSnapshot tempTree = new InMemoryDataTreeSnapshot(snapshot.getSchemaContext(),
+            tempRoot.get(), strategyTree);
         return tempTree.newModification();
     }
 
@@ -217,33 +218,33 @@ final class InMemoryDataTreeModification extends AbstractCursorAware implements
 
     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());
+            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) {
+    public void applyToCursor(@Nonnull final DataTreeModificationCursor cursor) {
         for (final ModifiedNode child : rootNode.getChildren()) {
             applyNode(cursor, child);
         }
@@ -254,30 +255,34 @@ final class InMemoryDataTreeModification extends AbstractCursorAware implements
             "Instance identifier references %s but data identifier is %s", arg, data.getIdentifier());
     }
 
-    private static void checkIdentifierReferencesData(final YangInstanceIdentifier path, final NormalizedNode<?, ?> data) {
+    private void checkIdentifierReferencesData(final YangInstanceIdentifier path,
+            final NormalizedNode<?, ?> data) {
+        final PathArgument arg;
+
         if (!path.isEmpty()) {
-            final PathArgument lastArg = path.getLastPathArgument();
-            Preconditions.checkArgument(lastArg != null, "Instance identifier %s has invalid null path argument", path);
-            checkIdentifierReferencesData(lastArg, data);
+            arg = path.getLastPathArgument();
+            Preconditions.checkArgument(arg != null, "Instance identifier %s has invalid null path argument", path);
         } else {
-            final QName type = data.getNodeType();
-            Preconditions.checkArgument(SchemaContext.NAME.equals(type), "Incorrect name %s of root node", type);
+            arg = rootNode.getIdentifier();
         }
+
+        checkIdentifierReferencesData(arg, data);
     }
 
     @Override
-    public DataTreeModificationCursor createCursor(final YangInstanceIdentifier path) {
+    public DataTreeModificationCursor createCursor(@Nonnull final YangInstanceIdentifier path) {
         final OperationWithModification op = resolveModificationFor(path);
         return openCursor(new InMemoryDataTreeModificationCursor(this, path, op));
     }
 
+    @Override
     public void ready() {
         final boolean wasRunning = SEALED_UPDATER.compareAndSet(this, 0, 1);
         Preconditions.checkState(wasRunning, "Attempted to seal an already-sealed Data Tree.");
 
         AbstractReadyIterator current = AbstractReadyIterator.create(rootNode, strategyTree);
         do {
-            current = current.process();
+            current = current.process(version);
         } while (current != null);
     }
 }