Merge "BUG-1275: teach NormalizedNode builders about size hints"
[yangtools.git] / yang / yang-data-impl / src / main / java / org / opendaylight / yangtools / yang / data / impl / schema / tree / RootModificationApplyOperation.java
index fd3b73473aa01eb34804be16fc18b76f5a55d236..5cddb0d6343c7bd21b9ca7ab89b0aee6d8449f1f 100644 (file)
@@ -7,15 +7,59 @@
  */
 package org.opendaylight.yangtools.yang.data.impl.schema.tree;
 
-import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier;
-import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier.PathArgument;
+import com.google.common.base.Optional;
+
+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.tree.DataValidationFailedException;
 import org.opendaylight.yangtools.yang.data.api.schema.tree.spi.TreeNode;
 import org.opendaylight.yangtools.yang.data.api.schema.tree.spi.Version;
 
-import com.google.common.base.Optional;
-
-public abstract class RootModificationApplyOperation implements ModificationApplyOperation {
+/**
+ * Represents a {@link ModificationApplyOperation} which is rooted at conceptual
+ * top of data tree.
+ *
+ * <p>
+ * 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
+ * be affected by upgrade of original one.
+ *
+ * <p>
+ * There are two variations of this {@link ModificationApplyOperation}:
+ * <ul>
+ * <li>
+ * <b>Upgradable</b> - operation may be upgraded to different backing
+ * implementation by invoking {@link #upgradeIfPossible()}.</li>
+ * <li><b>Not Upgradable</b> - operation is immutable, invocation of
+ * {@link #upgradeIfPossible()} is no-op and method {@link #snapshot()} returns
+ * pointer on same object.
+ *
+ * <h3>Upgradable Root Modification Operation</h3>
+ *
+ * Upgradable Root Modification Operation may be created using:
+ * <ul>
+ * <li> {@link #from(ModificationApplyOperation)} with other upgradable root
+ * modification as an argument
+ * <li>using factory {@link LatestOperationHolder} which instantiates Upgradable
+ * Root Modification Operations and provides an option to set latest
+ * implementation.
+ * </ul>
+ * <p>
+ * Upgradable root operation is never upgraded to latest operation
+ * automatically, but client code must explicitly invoke
+ * {@link #upgradeIfPossible()} to get latest implementation.
+ *
+ * Note: This is helpful for implementing
+ * {@link org.opendaylight.yangtools.yang.data.api.schema.tree.DataTreeModification}
+ * which may be derived from
+ * {@link org.opendaylight.yangtools.yang.data.api.schema.tree.DataTree} before
+ * update of schema and user actually writes data after schema update. During
+ * update user did not invoked any operation.
+ *
+ */
+abstract class RootModificationApplyOperation implements ModificationApplyOperation {
 
     @Override
     public Optional<ModificationApplyOperation> getChild(final PathArgument child) {
@@ -23,13 +67,14 @@ public abstract class RootModificationApplyOperation implements ModificationAppl
     }
 
     @Override
-    public final void checkApplicable(final InstanceIdentifier path, final NodeModification modification, final Optional<TreeNode> current)
+    public final void checkApplicable(final YangInstanceIdentifier path, final NodeModification modification, final Optional<TreeNode> current)
             throws DataValidationFailedException {
         getDelegate().checkApplicable(path, modification, current);
     }
 
     @Override
-    public final Optional<TreeNode> apply(final ModifiedNode modification, final Optional<TreeNode> currentMeta, final Version version) {
+    public final Optional<TreeNode> apply(final ModifiedNode modification, final Optional<TreeNode> currentMeta,
+            final Version version) {
         return getDelegate().apply(modification, currentMeta, version);
     }
 
@@ -53,27 +98,58 @@ public abstract class RootModificationApplyOperation implements ModificationAppl
         getDelegate().verifyStructure(modification);
     }
 
+    /**
+     * Return the underlying delegate.
+     *
+     * @return Underlying delegate.
+     */
     abstract ModificationApplyOperation getDelegate();
 
+    /**
+     * Creates a snapshot from this modification, which may have separate
+     * upgrade lifecycle and is not affected by upgrades
+     * <p>
+     * Newly created snapshot uses backing implementation of this modi
+     *
+     * @return Derived {@link RootModificationApplyOperation} with separate
+     *         upgrade lifecycle.
+     */
     public abstract RootModificationApplyOperation snapshot();
 
+    /**
+     * Upgrades backing implementation to latest available, if possible.
+     * <p>
+     * Latest implementation of {@link RootModificationApplyOperation} is
+     * managed by {@link LatestOperationHolder} which was used to construct this
+     * operation and latest operation is updated by
+     * {@link LatestOperationHolder#setCurrent(ModificationApplyOperation)}.
+     */
     public abstract void upgradeIfPossible();
 
-
-
     public static RootModificationApplyOperation from(final ModificationApplyOperation resolver) {
-        if(resolver instanceof RootModificationApplyOperation) {
+        if (resolver instanceof RootModificationApplyOperation) {
             return ((RootModificationApplyOperation) resolver).snapshot();
         }
         return new NotUpgradable(resolver);
     }
 
+    /**
+     * Implementation of Upgradable {@link RootModificationApplyOperation}
+     *
+     * This implementation is associated with {@link LatestOperationHolder}
+     * which holds latest available implementation, which may be used for
+     * upgrade.
+     *
+     * Upgrading {@link LatestOperationHolder} will not affect any instance,
+     * unless client invoked {@link #upgradeIfPossible()} which will result in
+     * changing delegate to the latest one.
+     *
+     */
     private static final class Upgradable extends RootModificationApplyOperation {
 
         private final LatestOperationHolder holder;
         private ModificationApplyOperation delegate;
 
-
         public Upgradable(final LatestOperationHolder holder, final ModificationApplyOperation delegate) {
             this.holder = holder;
             this.delegate = delegate;
@@ -83,8 +159,9 @@ public abstract class RootModificationApplyOperation implements ModificationAppl
         @Override
         public void upgradeIfPossible() {
             ModificationApplyOperation holderCurrent = holder.getCurrent();
-            if(holderCurrent != delegate) {
-                // FIXME: Allow update only if there is addition of models, not removals.
+            if (holderCurrent != delegate) {
+                // FIXME: Allow update only if there is addition of models, not
+                // removals.
                 delegate = holderCurrent;
             }
 
@@ -97,7 +174,7 @@ public abstract class RootModificationApplyOperation implements ModificationAppl
 
         @Override
         public RootModificationApplyOperation snapshot() {
-            return new Upgradable(holder,getDelegate());
+            return new Upgradable(holder, getDelegate());
         }
 
     }
@@ -126,20 +203,55 @@ public abstract class RootModificationApplyOperation implements ModificationAppl
         }
     }
 
-    public static class LatestOperationHolder {
+    /**
+     * Holder and factory for upgradable root modifications
+     *
+     * This class is factory for upgradable root modifications and provides an
+     * access to set latest backing implementation.
+     *
+     */
+    static class LatestOperationHolder {
 
         private ModificationApplyOperation current = new AlwaysFailOperation();
 
+        /**
+         * Return latest backing implemenation
+         *
+         * @return
+         */
         public ModificationApplyOperation getCurrent() {
             return current;
         }
 
+        /**
+         * Sets latest backing implementation of associated
+         * {@link RootModificationApplyOperation}.
+         * <p>
+         * Note: This does not result in upgrading implementation of already
+         * existing {@link RootModificationApplyOperation}. Users, which
+         * 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 implementation.
+         *
+         * @param newApplyOper
+         *            New backing implementation
+         */
         public void setCurrent(final ModificationApplyOperation newApplyOper) {
             current = newApplyOper;
         }
 
+        /**
+         *
+         * Creates new upgradable {@link RootModificationApplyOperation}
+         * associated with holder.
+         *
+         * @return New upgradable {@link RootModificationApplyOperation} with
+         *         {@link #getCurrent()} used as backing implementation.
+         */
         public RootModificationApplyOperation newSnapshot() {
-            return new Upgradable(this,current);
+            return new Upgradable(this, current);
         }
 
     }