*/
final class ModifiedNode extends NodeModification implements StoreTreeNode<ModifiedNode> {
private final Map<PathArgument, ModifiedNode> children;
- private final Optional<? extends TreeNode> original;
+ private final @Nullable TreeNode original;
private final @NonNull PathArgument identifier;
private LogicalOperation operation = LogicalOperation.NONE;
private Optional<? extends TreeNode> validatedCurrent;
private ValidatedTreeNode validatedNode;
- private ModifiedNode(final PathArgument identifier, final Optional<? extends TreeNode> original,
+ private ModifiedNode(final PathArgument identifier, final @Nullable TreeNode original,
final ChildTrackingPolicy childPolicy) {
this.identifier = requireNonNull(identifier);
this.original = original;
}
@Override
- Optional<? extends TreeNode> getOriginal() {
+ TreeNode original() {
return original;
}
return children.get(arg);
}
- private Optional<? extends TreeNode> metadataFromSnapshot(final @NonNull PathArgument child) {
- return original.isPresent() ? original.orElseThrow().findChildByArg(child) : Optional.empty();
+ private @Nullable TreeNode metadataFromSnapshot(final @NonNull PathArgument child) {
+ final var local = original;
+ return local != null ? local.childByArg(child) : null;
}
- private Optional<? extends TreeNode> metadataFromData(final @NonNull PathArgument child, final Version modVersion) {
+ private @Nullable TreeNode 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
writtenOriginal = TreeNode.of(value, modVersion);
}
- return writtenOriginal.findChildByArg(child);
+ return writtenOriginal.childByArg(child);
}
/**
* @param modVersion Version allocated by the calling {@link InMemoryDataTreeModification}
* @return Before-image tree node as observed by that child.
*/
- private Optional<? extends TreeNode> findOriginalMetadata(final @NonNull PathArgument child,
- final Version modVersion) {
+ private @Nullable TreeNode originalMetadata(final @NonNull PathArgument child, final Version modVersion) {
return switch (operation) {
case DELETE ->
// DELETE implies non-presence
- Optional.empty();
+ null;
case NONE, TOUCH, MERGE -> metadataFromSnapshot(child);
case WRITE ->
// WRITE implies presence based on written data
if (operation == LogicalOperation.NONE) {
updateOperationType(LogicalOperation.TOUCH);
}
- final ModifiedNode potential = children.get(child);
+ final var potential = children.get(child);
if (potential != null) {
return potential;
}
- final Optional<? extends TreeNode> currentMetadata = findOriginalMetadata(child, modVersion);
- final ModifiedNode newlyCreated = new ModifiedNode(child, currentMetadata, childOper.getChildPolicy());
+ final var newlyCreated = new ModifiedNode(child, originalMetadata(child, modVersion),
+ childOper.getChildPolicy());
if (operation == LogicalOperation.MERGE && value != null) {
/*
* We are attempting to modify a previously-unmodified part of a MERGE node. If the
* value contains this component, we need to materialize it as a MERGE modification.
*/
@SuppressWarnings({ "rawtypes", "unchecked" })
- final NormalizedNode childData = ((DistinctNodeContainer)value).childByArg(child);
+ final var childData = ((DistinctNodeContainer) value).childByArg(child);
if (childData != null) {
childOper.mergeIntoModifiedNode(newlyCreated, childData, modVersion);
}
//
// As documented in BUG-2470, a delete of data introduced in this transaction needs to be turned into
// a no-op.
- original.isPresent() ? LogicalOperation.DELETE : LogicalOperation.NONE;
+ original != null ? LogicalOperation.DELETE : LogicalOperation.NONE;
};
clearSnapshot();
}
public static ModifiedNode createUnmodified(final TreeNode metadataTree, final ChildTrackingPolicy childPolicy) {
- return new ModifiedNode(metadataTree.getIdentifier(), Optional.of(metadataTree), childPolicy);
+ return new ModifiedNode(metadataTree.getIdentifier(), requireNonNull(metadataTree), childPolicy);
}
void setValidatedNode(final ModificationApplyOperation op, final Optional<? extends TreeNode> current,
import java.util.Collection;
import java.util.Optional;
+import org.eclipse.jdt.annotation.Nullable;
import org.opendaylight.yangtools.concepts.Identifiable;
import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.PathArgument;
import org.opendaylight.yangtools.yang.data.tree.impl.node.TreeNode;
/**
* Get the original tree node to which the modification is to be applied.
*
- * @return The original node, or {@link Optional#absent()} if the node is
- * a new node.
+ * @return The original node, or {@link Optional#absent()} if the node is a new node.
*/
- abstract Optional<? extends TreeNode> getOriginal();
+ // FIXME: we should not need this method
+ final Optional<? extends TreeNode> getOriginal() {
+ return Optional.ofNullable(original());
+ }
+
+ /**
+ * Get the original tree node to which the modification is to be applied.
+ *
+ * @return The original node, or {@code null} if the node is a new node.
+ */
+ abstract @Nullable TreeNode original();
/**
* Get a read-only view of children nodes.
protected void checkMergeApplicable(final ModificationPath path, final NodeModification modification,
final Optional<? extends TreeNode> current, final Version version) throws DataValidationFailedException {
- final Optional<? extends TreeNode> original = modification.getOriginal();
- if (original.isPresent() && current.isPresent()) {
+ final var orig = modification.original();
+ if (orig != null && current.isPresent()) {
/*
- * We need to do conflict detection only and only if the value of leaf changed
- * before two transactions. If value of leaf is unchanged between two transactions
- * it should not cause transaction to fail, since result of this merge
- * leads to same data.
+ * We need to do conflict detection only and only if the value of leaf changed before two transactions. If
+ * value of leaf is unchanged between two transactions it should not cause transaction to fail, since result
+ * of this merge leads to same data.
*/
- final TreeNode orig = original.orElseThrow();
- final TreeNode cur = current.orElseThrow();
+ final var cur = current.orElseThrow();
if (!orig.getData().equals(cur.getData())) {
checkNotConflicting(path, orig, cur);
}
*/
private static void checkWriteApplicable(final ModificationPath path, final NodeModification modification,
final Optional<? extends TreeNode> current, final Version version) throws DataValidationFailedException {
- final var original = modification.getOriginal();
- if (original.isPresent() && current.isPresent()) {
- checkNotConflicting(path, original.orElseThrow(), current.orElseThrow());
+ final var original = modification.original();
+ if (original != null && current.isPresent()) {
+ checkNotConflicting(path, original, current.orElseThrow());
} else {
- checkConflicting(path, original.isEmpty(), "Node was deleted by other transaction.");
+ checkConflicting(path, original == null, "Node was deleted by other transaction.");
checkConflicting(path, current.isEmpty(), "Node was created by other transaction.");
}
}