Separate out RootModificationApplyOperation 46/80146/1
authorRobert Varga <robert.varga@pantheon.tech>
Thu, 31 Jan 2019 08:17:31 +0000 (09:17 +0100)
committerRobert Varga <robert.varga@pantheon.tech>
Tue, 5 Feb 2019 00:33:50 +0000 (01:33 +0100)
RootModificationApplyOperation is an operation holder, which has
particular lifecycle and can give access to the current
ModificationApplyOperation.

Rename it to RootApplyStrategy and have it *not* a subclass of
ModificationApplyOperation. This makes the flow more consistent
as well as making it obvious the three classes constituing its
associated logic cannot every come up in the context of traversing
a modification tree.

JIRA: YANGTOOLS-949
Change-Id: I01061db38c6d631f804eef1b241a93eaf11626e5
Signed-off-by: Robert Varga <robert.varga@pantheon.tech>
(cherry picked from commit ec6ea0775906ed2355553aec917bb77933764ecd)

yang/yang-data-impl/src/main/java/org/opendaylight/yangtools/yang/data/impl/schema/tree/AlwaysFailOperation.java
yang/yang-data-impl/src/main/java/org/opendaylight/yangtools/yang/data/impl/schema/tree/FullyDelegatedModificationApplyOperation.java [deleted file]
yang/yang-data-impl/src/main/java/org/opendaylight/yangtools/yang/data/impl/schema/tree/InMemoryDataTreeModification.java
yang/yang-data-impl/src/main/java/org/opendaylight/yangtools/yang/data/impl/schema/tree/InMemoryDataTreeSnapshot.java
yang/yang-data-impl/src/main/java/org/opendaylight/yangtools/yang/data/impl/schema/tree/LatestOperationHolder.java
yang/yang-data-impl/src/main/java/org/opendaylight/yangtools/yang/data/impl/schema/tree/NonApplyDelegatedModificationApplyOperation.java [new file with mode: 0644]
yang/yang-data-impl/src/main/java/org/opendaylight/yangtools/yang/data/impl/schema/tree/NotUpgradableRootApplyStrategy.java [moved from yang/yang-data-impl/src/main/java/org/opendaylight/yangtools/yang/data/impl/schema/tree/NotUpgradableModificationApplyOperation.java with 69% similarity]
yang/yang-data-impl/src/main/java/org/opendaylight/yangtools/yang/data/impl/schema/tree/RootApplyStrategy.java [moved from yang/yang-data-impl/src/main/java/org/opendaylight/yangtools/yang/data/impl/schema/tree/RootModificationApplyOperation.java with 81% similarity]
yang/yang-data-impl/src/main/java/org/opendaylight/yangtools/yang/data/impl/schema/tree/UpgradableRootApplyStrategy.java [moved from yang/yang-data-impl/src/main/java/org/opendaylight/yangtools/yang/data/impl/schema/tree/UpgradableModificationApplyOperation.java with 76% similarity]
yang/yang-data-impl/src/test/java/org/opendaylight/yangtools/yang/data/impl/schema/tree/ModificationMetadataTreeTest.java
yang/yang-data-impl/src/test/java/org/opendaylight/yangtools/yang/data/impl/schema/tree/StoreTreeNodesTest.java

index 41edf5d21ad0922a617a14a7a648221dcb5fde05..18dae27279527613666fc1799a52fd0d292faea0 100644 (file)
@@ -7,11 +7,16 @@
  */
 package org.opendaylight.yangtools.yang.data.impl.schema.tree;
 
+import java.util.Optional;
+import org.opendaylight.yangtools.yang.data.api.schema.tree.DataValidationFailedException;
+import org.opendaylight.yangtools.yang.data.api.schema.tree.spi.TreeNode;
+import org.opendaylight.yangtools.yang.data.api.schema.tree.spi.Version;
+
 /**
  * An implementation of apply operation which fails to do anything, consistently. An instance of this class is used by
  * the data tree if it does not have a SchemaContext attached and hence cannot perform anything meaningful.
  */
-final class AlwaysFailOperation extends FullyDelegatedModificationApplyOperation {
+final class AlwaysFailOperation extends NonApplyDelegatedModificationApplyOperation {
     static final ModificationApplyOperation INSTANCE = new AlwaysFailOperation();
 
     private AlwaysFailOperation() {
@@ -20,6 +25,22 @@ final class AlwaysFailOperation extends FullyDelegatedModificationApplyOperation
 
     @Override
     ModificationApplyOperation delegate() {
-        throw new IllegalStateException("Schema Context is not available.");
+        throw ise();
+    }
+
+    @Override
+    Optional<TreeNode> apply(final ModifiedNode modification, final Optional<TreeNode> currentMeta,
+            final Version version) {
+        throw ise();
+    }
+
+    @Override
+    void checkApplicable(final ModificationPath path, final NodeModification modification,
+            final Optional<TreeNode> current, final Version version) throws DataValidationFailedException {
+        throw ise();
+    }
+
+    private static IllegalStateException ise() {
+        return new IllegalStateException("Schema Context is not available.");
     }
 }
diff --git a/yang/yang-data-impl/src/main/java/org/opendaylight/yangtools/yang/data/impl/schema/tree/FullyDelegatedModificationApplyOperation.java b/yang/yang-data-impl/src/main/java/org/opendaylight/yangtools/yang/data/impl/schema/tree/FullyDelegatedModificationApplyOperation.java
deleted file mode 100644 (file)
index dd37928..0000000
+++ /dev/null
@@ -1,36 +0,0 @@
-/*
- * Copyright (c) 2019 Pantheon Technologies, s.r.o. and others.  All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-package org.opendaylight.yangtools.yang.data.impl.schema.tree;
-
-import java.util.Optional;
-import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
-import org.opendaylight.yangtools.yang.data.api.schema.tree.DataValidationFailedException;
-import org.opendaylight.yangtools.yang.data.api.schema.tree.spi.TreeNode;
-import org.opendaylight.yangtools.yang.data.api.schema.tree.spi.Version;
-
-/**
- * A {@link ModificationApplyOperation} which delegates all invocations to a backing instance.
- */
-abstract class FullyDelegatedModificationApplyOperation extends DelegatingModificationApplyOperation {
-    @Override
-    final Optional<TreeNode> apply(final ModifiedNode modification, final Optional<TreeNode> currentMeta,
-            final Version version) {
-        return delegate().apply(modification, currentMeta, version);
-    }
-
-    @Override
-    final void checkApplicable(final ModificationPath path, final NodeModification modification,
-            final Optional<TreeNode> current, final Version version) throws DataValidationFailedException {
-        delegate().checkApplicable(path, modification, current, version);
-    }
-
-    @Override
-    final void verifyStructure(final NormalizedNode<?, ?> modification, final boolean verifyChildren) {
-        delegate().verifyStructure(modification, verifyChildren);
-    }
-}
index 54a3b5a587bb30a56f4fc162b6a69a840f565efb..f91873bd4848e4674dfddd133a98f215b015d9c5 100644 (file)
@@ -7,7 +7,10 @@
  */
 package org.opendaylight.yangtools.yang.data.impl.schema.tree;
 
-import com.google.common.base.Preconditions;
+import static com.google.common.base.Preconditions.checkArgument;
+import static com.google.common.base.Preconditions.checkState;
+import static java.util.Objects.requireNonNull;
+
 import java.util.Collection;
 import java.util.Map.Entry;
 import java.util.Optional;
@@ -33,7 +36,7 @@ final class InMemoryDataTreeModification extends AbstractCursorAware implements
             AtomicIntegerFieldUpdater.newUpdater(InMemoryDataTreeModification.class, "sealed");
     private static final Logger LOG = LoggerFactory.getLogger(InMemoryDataTreeModification.class);
 
-    private final RootModificationApplyOperation strategyTree;
+    private final RootApplyStrategy strategyTree;
     private final InMemoryDataTreeSnapshot snapshot;
     private final ModifiedNode rootNode;
     private final Version version;
@@ -41,10 +44,10 @@ final class InMemoryDataTreeModification extends AbstractCursorAware implements
     private volatile int sealed = 0;
 
     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());
+            final RootApplyStrategy resolver) {
+        this.snapshot = requireNonNull(snapshot);
+        this.strategyTree = requireNonNull(resolver).snapshot();
+        this.rootNode = ModifiedNode.createUnmodified(snapshot.getRootNode(), getStrategy().getChildPolicy());
 
         /*
          * We could allocate version beforehand, since Version contract
@@ -63,7 +66,7 @@ final class InMemoryDataTreeModification extends AbstractCursorAware implements
     }
 
     ModificationApplyOperation getStrategy() {
-        return strategyTree;
+        return strategyTree.delegate();
     }
 
     @Override
@@ -138,7 +141,7 @@ final class InMemoryDataTreeModification extends AbstractCursorAware implements
         LOG.trace("Resolving modification apply strategy for {}", path);
 
         upgradeIfPossible();
-        return StoreTreeNodes.findNodeChecked(strategyTree, path);
+        return StoreTreeNodes.findNodeChecked(getStrategy(), path);
     }
 
     private OperationWithModification resolveModificationFor(final YangInstanceIdentifier path) {
@@ -154,7 +157,7 @@ final class InMemoryDataTreeModification extends AbstractCursorAware implements
          * That is fine, as we will prune any empty TOUCH nodes in the last phase of the ready
          * process.
          */
-        ModificationApplyOperation operation = strategyTree;
+        ModificationApplyOperation operation = getStrategy();
         ModifiedNode modification = rootNode;
 
         int depth = 1;
@@ -174,7 +177,7 @@ final class InMemoryDataTreeModification extends AbstractCursorAware implements
     }
 
     private void checkSealed() {
-        Preconditions.checkState(sealed == 0, "Data Tree is sealed. No further modifications allowed.");
+        checkState(sealed == 0, "Data Tree is sealed. No further modifications allowed.");
     }
 
     @Override
@@ -184,7 +187,7 @@ final class InMemoryDataTreeModification extends AbstractCursorAware implements
 
     @Override
     public InMemoryDataTreeModification newModification() {
-        Preconditions.checkState(sealed == 1, "Attempted to chain on an unsealed modification");
+        checkState(sealed == 1, "Attempted to chain on an unsealed modification");
 
         if (rootNode.getOperation() == LogicalOperation.NONE) {
             // Simple fast case: just use the underlying modification
@@ -196,9 +199,8 @@ final class InMemoryDataTreeModification extends AbstractCursorAware implements
          * have same version each time this method is called.
          */
         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");
+        final Optional<TreeNode> tempRoot = getStrategy().apply(rootNode, Optional.of(originalSnapshotRoot), version);
+        checkState(tempRoot.isPresent(), "Data tree root is not present, possibly removed by previous modification");
 
         final InMemoryDataTreeSnapshot tempTree = new InMemoryDataTreeSnapshot(snapshot.getSchemaContext(),
             tempRoot.get(), strategyTree);
@@ -259,7 +261,7 @@ final class InMemoryDataTreeModification extends AbstractCursorAware implements
     }
 
     static void checkIdentifierReferencesData(final PathArgument arg, final NormalizedNode<?, ?> data) {
-        Preconditions.checkArgument(arg.equals(data.getIdentifier()),
+        checkArgument(arg.equals(data.getIdentifier()),
             "Instance identifier references %s but data identifier is %s", arg, data.getIdentifier());
     }
 
@@ -269,7 +271,7 @@ final class InMemoryDataTreeModification extends AbstractCursorAware implements
 
         if (!path.isEmpty()) {
             arg = path.getLastPathArgument();
-            Preconditions.checkArgument(arg != null, "Instance identifier %s has invalid null path argument", path);
+            checkArgument(arg != null, "Instance identifier %s has invalid null path argument", path);
         } else {
             arg = rootNode.getIdentifier();
         }
@@ -286,9 +288,9 @@ final class InMemoryDataTreeModification extends AbstractCursorAware implements
     @Override
     public void ready() {
         final boolean wasRunning = SEALED_UPDATER.compareAndSet(this, 0, 1);
-        Preconditions.checkState(wasRunning, "Attempted to seal an already-sealed Data Tree.");
+        checkState(wasRunning, "Attempted to seal an already-sealed Data Tree.");
 
-        AbstractReadyIterator current = AbstractReadyIterator.create(rootNode, strategyTree);
+        AbstractReadyIterator current = AbstractReadyIterator.create(rootNode, getStrategy());
         do {
             current = current.process(version);
         } while (current != null);
index ac68e4eda8425ea8b78c9c5f6e3b64a88e1257a0..4dbfe37dd7a5ed5bfb289f9cb8eca7a2a1a693d3 100644 (file)
@@ -25,12 +25,12 @@ import org.opendaylight.yangtools.yang.model.api.SchemaContextProvider;
 
 final class InMemoryDataTreeSnapshot extends AbstractCursorAware implements CursorAwareDataTreeSnapshot,
         SchemaContextProvider {
-    private final @NonNull RootModificationApplyOperation applyOper;
+    private final @NonNull RootApplyStrategy applyOper;
     private final @NonNull SchemaContext schemaContext;
     private final @NonNull TreeNode rootNode;
 
     InMemoryDataTreeSnapshot(final SchemaContext schemaContext, final TreeNode rootNode,
-            final RootModificationApplyOperation applyOper) {
+            final RootApplyStrategy applyOper) {
         this.schemaContext = requireNonNull(schemaContext);
         this.rootNode = requireNonNull(rootNode);
         this.applyOper = requireNonNull(applyOper);
index 33fc91a08b160dc443ecfe6dc0de9bc071611e90..8a31f092c6365e3992a5b82c73ec39f63114316b 100644 (file)
@@ -27,13 +27,13 @@ final class LatestOperationHolder {
     }
 
     /**
-     * Sets latest backing implementation of associated {@link RootModificationApplyOperation}.
+     * Sets latest backing implementation of associated {@link RootApplyStrategy}.
      *
      * <p>
      * Note: This does not result in upgrading implementation of already existing
-     * {@link RootModificationApplyOperation}. Users, who obtained instances using {@link #newSnapshot()}, deriving
-     * {@link RootModificationApplyOperation} from this modification must explicitly invoke
-     * {@link RootModificationApplyOperation#upgradeIfPossible()} on their instance to be updated to latest backing
+     * {@link RootApplyStrategy}. Users, who obtained instances using {@link #newSnapshot()}, deriving
+     * {@link RootApplyStrategy} from this modification must explicitly invoke
+     * {@link RootApplyStrategy#upgradeIfPossible()} on their instance to be updated to latest backing
      * implementation.
      *
      * @param newApplyOper New backing implementation
@@ -43,13 +43,13 @@ final class LatestOperationHolder {
     }
 
     /**
-     * Creates new upgradable {@link RootModificationApplyOperation} associated with holder.
+     * Creates new upgradable {@link RootApplyStrategy} associated with holder.
      *
-     * @return New upgradable {@link RootModificationApplyOperation} with {@link #getCurrent()} used
+     * @return New upgradable {@link RootApplyStrategy} with {@link #getCurrent()} used
      *         as the backing implementation.
      */
-    RootModificationApplyOperation newSnapshot() {
-        return new UpgradableModificationApplyOperation(this, current);
+    RootApplyStrategy newSnapshot() {
+        return new UpgradableRootApplyStrategy(this, current);
     }
 
 }
\ No newline at end of file
diff --git a/yang/yang-data-impl/src/main/java/org/opendaylight/yangtools/yang/data/impl/schema/tree/NonApplyDelegatedModificationApplyOperation.java b/yang/yang-data-impl/src/main/java/org/opendaylight/yangtools/yang/data/impl/schema/tree/NonApplyDelegatedModificationApplyOperation.java
new file mode 100644 (file)
index 0000000..e1db42e
--- /dev/null
@@ -0,0 +1,21 @@
+/*
+ * Copyright (c) 2019 Pantheon Technologies, s.r.o. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.yangtools.yang.data.impl.schema.tree;
+
+import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
+
+/**
+ * A {@link ModificationApplyOperation} which delegates all invocations except checkApplicable()/apply() to a delegate
+ * instance.
+ */
+abstract class NonApplyDelegatedModificationApplyOperation extends DelegatingModificationApplyOperation {
+    @Override
+    final void verifyStructure(final NormalizedNode<?, ?> modification, final boolean verifyChildren) {
+        delegate().verifyStructure(modification, verifyChildren);
+    }
+}
@@ -7,15 +7,15 @@
  */
 package org.opendaylight.yangtools.yang.data.impl.schema.tree;
 
-final class NotUpgradableModificationApplyOperation extends RootModificationApplyOperation {
+final class NotUpgradableRootApplyStrategy extends RootApplyStrategy {
     private final ModificationApplyOperation delegate;
 
-    NotUpgradableModificationApplyOperation(final ModificationApplyOperation delegate) {
+    NotUpgradableRootApplyStrategy(final ModificationApplyOperation delegate) {
         this.delegate = delegate;
     }
 
     @Override
-    ModificationApplyOperation delegate() {
+    protected ModificationApplyOperation delegate() {
         return delegate;
     }
 
@@ -25,7 +25,7 @@ final class NotUpgradableModificationApplyOperation extends RootModificationAppl
     }
 
     @Override
-    RootModificationApplyOperation snapshot() {
+    RootApplyStrategy snapshot() {
         return this;
     }
 }
@@ -7,6 +7,8 @@
  */
 package org.opendaylight.yangtools.yang.data.impl.schema.tree;
 
+import com.google.common.collect.ForwardingObject;
+
 /**
  * Represents a {@link ModificationApplyOperation} which is rooted at conceptual
  * top of data tree.
@@ -15,7 +17,7 @@ package org.opendaylight.yangtools.yang.data.impl.schema.tree;
  * This implementation differs from other implementations in this package that
  * is not immutable, but may be upgraded to newer state if available by
  * explicitly invoking {@link #upgradeIfPossible()} and also serves as factory
- * for deriving snapshot {@link RootModificationApplyOperation} which will not
+ * for deriving snapshot {@link RootApplyStrategy} which will not
  * be affected by upgrade of original one.
  *
  * <p>
@@ -51,15 +53,15 @@ package org.opendaylight.yangtools.yang.data.impl.schema.tree;
  * update of schema and user actually writes data after schema update. During
  * update user did not invoked any operation.
  */
-abstract class RootModificationApplyOperation extends FullyDelegatedModificationApplyOperation {
+abstract class RootApplyStrategy extends ForwardingObject {
 
-    static RootModificationApplyOperation from(final ModificationApplyOperation resolver) {
-        if (resolver instanceof RootModificationApplyOperation) {
-            return ((RootModificationApplyOperation) resolver).snapshot();
-        }
-        return new NotUpgradableModificationApplyOperation(resolver);
+    static RootApplyStrategy from(final ModificationApplyOperation resolver) {
+        return new NotUpgradableRootApplyStrategy(resolver);
     }
 
+    @Override
+    protected abstract ModificationApplyOperation delegate();
+
     @Override
     public final boolean equals(final Object obj) {
         return delegate().equals(obj);
@@ -82,16 +84,16 @@ abstract class RootModificationApplyOperation extends FullyDelegatedModification
      * <p>
      * Newly created snapshot uses backing implementation of this modification.
      *
-     * @return Derived {@link RootModificationApplyOperation} with separate
+     * @return Derived {@link RootApplyStrategy} with separate
      *         upgrade lifecycle.
      */
-    abstract RootModificationApplyOperation snapshot();
+    abstract RootApplyStrategy snapshot();
 
     /**
      * Upgrades backing implementation to latest available, if possible.
      *
      * <p>
-     * Latest implementation of {@link RootModificationApplyOperation} is
+     * Latest implementation of {@link RootApplyStrategy} is
      * managed by {@link LatestOperationHolder} which was used to construct this
      * operation and latest operation is updated by
      * {@link LatestOperationHolder#setCurrent(ModificationApplyOperation)}.
@@ -8,7 +8,7 @@
 package org.opendaylight.yangtools.yang.data.impl.schema.tree;
 
 /**
- * Implementation of Upgradable {@link RootModificationApplyOperation}
+ * Implementation of Upgradable {@link RootApplyStrategy}
  *
  * <p>
  * This implementation is associated with {@link LatestOperationHolder}
@@ -20,11 +20,11 @@ package org.opendaylight.yangtools.yang.data.impl.schema.tree;
  * unless client invoked {@link #upgradeIfPossible()} which will result in
  * changing delegate to the latest one.
  */
-final class UpgradableModificationApplyOperation extends RootModificationApplyOperation {
+final class UpgradableRootApplyStrategy extends RootApplyStrategy {
     private final LatestOperationHolder holder;
     private ModificationApplyOperation delegate;
 
-    UpgradableModificationApplyOperation(final LatestOperationHolder holder,
+    UpgradableRootApplyStrategy(final LatestOperationHolder holder,
         final ModificationApplyOperation delegate) {
         this.holder = holder;
         this.delegate = delegate;
@@ -41,12 +41,12 @@ final class UpgradableModificationApplyOperation extends RootModificationApplyOp
     }
 
     @Override
-    ModificationApplyOperation delegate() {
+    protected ModificationApplyOperation delegate() {
         return delegate;
     }
 
     @Override
-    RootModificationApplyOperation snapshot() {
-        return new UpgradableModificationApplyOperation(holder, delegate);
+    RootApplyStrategy snapshot() {
+        return new UpgradableRootApplyStrategy(holder, delegate);
     }
 }
\ No newline at end of file
index 18aa79987419f3af19c9f2da030172442455cf77..84d8997e99a8d77533e5156b7b2605faff692bcd 100644 (file)
@@ -89,11 +89,11 @@ public class ModificationMetadataTreeTest extends AbstractTestModelTest {
                     .build())
                     .build();
 
-    private RootModificationApplyOperation rootOper;
+    private RootApplyStrategy rootOper;
 
     @Before
     public void prepare() {
-        rootOper = RootModificationApplyOperation.from(SchemaAwareApplyOperation.from(SCHEMA_CONTEXT,
+        rootOper = RootApplyStrategy.from(SchemaAwareApplyOperation.from(SCHEMA_CONTEXT,
             DataTreeConfiguration.DEFAULT_OPERATIONAL));
     }
 
index 323eadef24860e526100ac6368f4311722609f7c..8b8b2d0b527952028423f2f68f142e51bc65bdfa 100644 (file)
@@ -63,11 +63,11 @@ public class StoreTreeNodesTest extends AbstractTestModelTest {
                     .build())
                     .build();
 
-    private RootModificationApplyOperation rootOper;
+    private RootApplyStrategy rootOper;
 
     @Before
     public void prepare() {
-        rootOper = RootModificationApplyOperation.from(SchemaAwareApplyOperation.from(SCHEMA_CONTEXT,
+        rootOper = RootApplyStrategy.from(SchemaAwareApplyOperation.from(SCHEMA_CONTEXT,
             DataTreeConfiguration.DEFAULT_OPERATIONAL));
     }