X-Git-Url: https://git.opendaylight.org/gerrit/gitweb?a=blobdiff_plain;f=yang%2Fyang-data-impl%2Fsrc%2Fmain%2Fjava%2Forg%2Fopendaylight%2Fyangtools%2Fyang%2Fdata%2Fimpl%2Fschema%2Ftree%2FModifiedNode.java;h=735418ee59d617dadd21adbe2ad35574a9a25567;hb=970923b5f47f7507ec78021965fa5df1a878af48;hp=7360e988d23c08003e6ec71817dda1eea4bfadaf;hpb=6b5d20f6513bc3e6e5db4a2058ee81308edaa9c8;p=yangtools.git diff --git a/yang/yang-data-impl/src/main/java/org/opendaylight/yangtools/yang/data/impl/schema/tree/ModifiedNode.java b/yang/yang-data-impl/src/main/java/org/opendaylight/yangtools/yang/data/impl/schema/tree/ModifiedNode.java index 7360e988d2..735418ee59 100644 --- a/yang/yang-data-impl/src/main/java/org/opendaylight/yangtools/yang/data/impl/schema/tree/ModifiedNode.java +++ b/yang/yang-data-impl/src/main/java/org/opendaylight/yangtools/yang/data/impl/schema/tree/ModifiedNode.java @@ -7,17 +7,21 @@ */ 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.base.Predicate; +import static com.google.common.base.Verify.verifyNotNull; +import static java.util.Objects.requireNonNull; + +import com.google.common.base.MoreObjects; +import com.google.common.base.MoreObjects.ToStringHelper; +import edu.umd.cs.findbugs.annotations.SuppressFBWarnings; import java.util.Collection; import java.util.Map; -import javax.annotation.Nonnull; -import javax.annotation.Nullable; -import javax.annotation.concurrent.NotThreadSafe; +import java.util.Optional; +import java.util.function.Predicate; +import org.eclipse.jdt.annotation.NonNull; +import org.eclipse.jdt.annotation.Nullable; import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.PathArgument; +import org.opendaylight.yangtools.yang.data.api.schema.DistinctNodeContainer; import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode; -import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNodeContainer; import org.opendaylight.yangtools.yang.data.api.schema.tree.ModificationType; import org.opendaylight.yangtools.yang.data.api.schema.tree.StoreTreeNode; import org.opendaylight.yangtools.yang.data.api.schema.tree.spi.TreeNode; @@ -25,24 +29,23 @@ import org.opendaylight.yangtools.yang.data.api.schema.tree.spi.TreeNodeFactory; import org.opendaylight.yangtools.yang.data.api.schema.tree.spi.Version; /** - * Node Modification Node and Tree + * Node Modification Node and Tree. * + *

* Tree which structurally resembles data tree and captures client modifications to the data store tree. This tree is * lazily created and populated via {@link #modifyChild(PathArgument, ModificationApplyOperation, Version)} and * {@link TreeNode} which represents original state as tracked by {@link #getOriginal()}. * + *

* The contract is that the state information exposed here preserves the temporal ordering of whatever modifications * were executed. A child's effects pertain to data node as modified by its ancestors. This means that in order to * reconstruct the effective data node presentation, it is sufficient to perform a depth-first pre-order traversal of * the tree. */ -@NotThreadSafe final class ModifiedNode extends NodeModification implements StoreTreeNode { - static final Predicate IS_TERMINAL_PREDICATE = new Predicate() { - @Override - public boolean apply(@Nullable final ModifiedNode input) { - Preconditions.checkNotNull(input); - switch (input.getOperation()) { + static final Predicate IS_TERMINAL_PREDICATE = input -> { + requireNonNull(input); + switch (input.getOperation()) { case DELETE: case MERGE: case WRITE: @@ -50,29 +53,29 @@ final class ModifiedNode extends NodeModification implements StoreTreeNode children; - private final Optional original; + private final Optional original; private final PathArgument identifier; private LogicalOperation operation = LogicalOperation.NONE; private Optional snapshotCache; - private NormalizedNode value; + private NormalizedNode value; private ModificationType modType; // Alternative history introduced in WRITE nodes. Instantiated when we touch any child underneath such a node. private TreeNode writtenOriginal; // Internal cache for TreeNodes created as part of validation - private SchemaAwareApplyOperation validatedOp; - private Optional validatedCurrent; - private TreeNode validatedNode; + private ModificationApplyOperation validatedOp; + private Optional validatedCurrent; + private Optional validatedNode; - private ModifiedNode(final PathArgument identifier, final Optional original, final ChildTrackingPolicy childPolicy) { + private ModifiedNode(final PathArgument identifier, final Optional original, + final ChildTrackingPolicy childPolicy) { this.identifier = identifier; this.original = original; this.children = childPolicy.createMap(); @@ -89,7 +92,7 @@ final class ModifiedNode extends NodeModification implements StoreTreeNode getOriginal() { + Optional getOriginal() { return original; } @@ -101,28 +104,25 @@ final class ModifiedNode extends NodeModification implements StoreTreeNode getWrittenValue() { - return value; + @NonNull NormalizedNode getWrittenValue() { + return verifyNotNull(value); } /** + * Returns child modification if child was modified. * - * Returns child modification if child was modified - * - * @return Child modification if direct child or it's subtree - * was modified. - * + * @return Child modification if direct child or it's subtree was modified. */ @Override - public Optional getChild(final PathArgument child) { - return Optional.fromNullable(children.get(child)); + public ModifiedNode childByArg(final PathArgument arg) { + return children.get(arg); } - private Optional metadataFromSnapshot(@Nonnull final PathArgument child) { - return original.isPresent() ? original.get().getChild(child) : Optional.absent(); + private Optional metadataFromSnapshot(final @NonNull PathArgument child) { + return original.isPresent() ? original.get().findChildByArg(child) : Optional.empty(); } - private Optional metadataFromData(@Nonnull final PathArgument child, final Version modVersion) { + private Optional metadataFromData(final @NonNull PathArgument child, final Version modVersion) { if (writtenOriginal == null) { // Lazy instantiation, as we do not want do this for all writes. We are using the modification's version // here, as that version is what the SchemaAwareApplyOperation will see when dealing with the resulting @@ -130,7 +130,7 @@ final class ModifiedNode extends NodeModification implements StoreTreeNode findOriginalMetadata(@Nonnull final PathArgument child, final Version modVersion) { + private Optional findOriginalMetadata(final @NonNull PathArgument child, + final Version modVersion) { switch (operation) { - case DELETE: - // DELETE implies non-presence - return Optional.absent(); - case NONE: - case TOUCH: - case MERGE: - return metadataFromSnapshot(child); - case WRITE: - // WRITE implies presence based on written data - return metadataFromData(child, modVersion); + case DELETE: + // DELETE implies non-presence + return Optional.empty(); + case NONE: + case TOUCH: + case MERGE: + return metadataFromSnapshot(child); + case WRITE: + // WRITE implies presence based on written data + return metadataFromData(child, modVersion); + default: + throw new IllegalStateException("Unhandled node operation " + operation); } - - throw new IllegalStateException("Unhandled node operation " + operation); } /** - * * Returns child modification if child was modified, creates {@link ModifiedNode} - * for child otherwise. - * - * If this node's {@link ModificationType} is {@link ModificationType#UNMODIFIED} - * changes modification type to {@link ModificationType#SUBTREE_MODIFIED} + * for child otherwise. If this node's {@link ModificationType} is {@link ModificationType#UNMODIFIED} + * changes modification type to {@link ModificationType#SUBTREE_MODIFIED}. * * @param child child identifier, may not be null * @param childOper Child operation @@ -173,8 +171,8 @@ final class ModifiedNode extends NodeModification implements StoreTreeNode currentMetadata = findOriginalMetadata(child, modVersion); - - + final Optional currentMetadata = findOriginalMetadata(child, modVersion); final ModifiedNode newlyCreated = new ModifiedNode(child, currentMetadata, childOper.getChildPolicy()); if (operation == LogicalOperation.MERGE && value != null) { /* @@ -194,9 +190,9 @@ final class ModifiedNode extends NodeModification implements StoreTreeNode> childData = ((NormalizedNodeContainer)value).getChild(child); - if (childData.isPresent()) { - childOper.mergeIntoModifiedNode(newlyCreated, childData.get(), modVersion); + final NormalizedNode childData = ((DistinctNodeContainer)value).childByArg(child); + if (childData != null) { + childOper.mergeIntoModifiedNode(newlyCreated, childData, modVersion); } } @@ -205,7 +201,7 @@ final class ModifiedNode extends NodeModification implements StoreTreeNode value) { - updateValue(LogicalOperation.WRITE, value); + void write(final NormalizedNode newValue) { + updateValue(LogicalOperation.WRITE, newValue); children.clear(); } /** * Seal the modification node and prune any children which has not been modified. * - * @param schema + * @param schema associated apply operation + * @param version target version */ void seal(final ModificationApplyOperation schema, final Version version) { clearSnapshot(); @@ -283,11 +278,16 @@ final class ModifiedNode extends NodeModification implements StoreTreeNode setSnapshot(final Optional snapshot) { - snapshotCache = Preconditions.checkNotNull(snapshot); + snapshotCache = requireNonNull(snapshot); return snapshot; } @@ -318,11 +318,15 @@ final class ModifiedNode extends NodeModification implements StoreTreeNode value) { - this.value = Preconditions.checkNotNull(value); + void updateValue(final LogicalOperation type, final NormalizedNode newValue) { + this.value = requireNonNull(newValue); updateOperationType(type); } @@ -353,13 +357,26 @@ final class ModifiedNode extends NodeModification implements StoreTreeNode current, final TreeNode node) { - this.validatedOp = Preconditions.checkNotNull(op); - this.validatedCurrent = Preconditions.checkNotNull(current); - this.validatedNode = Preconditions.checkNotNull(node); + void setValidatedNode(final ModificationApplyOperation op, final Optional current, + final Optional node) { + this.validatedOp = requireNonNull(op); + this.validatedCurrent = requireNonNull(current); + this.validatedNode = requireNonNull(node); } - TreeNode getValidatedNode(final SchemaAwareApplyOperation op, final Optional current) { + /** + * Acquire pre-validated node assuming a previous operation and node. This is a counterpart to + * {@link #setValidatedNode(ModificationApplyOperation, Optional, Optional)}. + * + * @param op Currently-executing operation + * @param current Currently-used tree node + * @return {@code null} if there is a mismatch with previously-validated node (if present) or the result of previous + * validation. + */ + @SuppressFBWarnings(value = "NP_OPTIONAL_RETURN_NULL", + justification = "The contract is package-internal and well documented, we do not need a separate wrapper") + @Nullable Optional getValidatedNode(final ModificationApplyOperation op, + final Optional current) { return op.equals(validatedOp) && current.equals(validatedCurrent) ? validatedNode : null; } }