* 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)} and {@link TreeNode} which represents original
- * state as tracked by {@link #getOriginal()}.
+ * 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
*/
@NotThreadSafe
final class ModifiedNode extends NodeModification implements StoreTreeNode<ModifiedNode> {
- static final Predicate<ModifiedNode> IS_TERMINAL_PREDICATE = new Predicate<ModifiedNode>() {
- @Override
- public boolean apply(@Nonnull final ModifiedNode input) {
- Preconditions.checkNotNull(input);
- switch (input.getOperation()) {
+ static final Predicate<ModifiedNode> IS_TERMINAL_PREDICATE = input -> {
+ Preconditions.checkNotNull(input);
+ switch (input.getOperation()) {
case DELETE:
case MERGE:
case WRITE:
case TOUCH:
case NONE:
return false;
- }
-
- throw new IllegalArgumentException(String.format("Unhandled modification type %s", input.getOperation()));
}
+
+ throw new IllegalArgumentException(String.format("Unhandled modification type %s", input.getOperation()));
};
private final Map<PathArgument, ModifiedNode> children;
// 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<TreeNode> validatedCurrent;
+ private TreeNode validatedNode;
+
private ModifiedNode(final PathArgument identifier, final Optional<TreeNode> original, final ChildTrackingPolicy childPolicy) {
this.identifier = identifier;
this.original = original;
*/
@Override
public Optional<ModifiedNode> getChild(final PathArgument child) {
- return Optional.<ModifiedNode> fromNullable(children.get(child));
+ return Optional.fromNullable(children.get(child));
}
private Optional<TreeNode> metadataFromSnapshot(@Nonnull final PathArgument child) {
- return original.isPresent() ? original.get().getChild(child) : Optional.<TreeNode>absent();
+ return original.isPresent() ? original.get().getChild(child) : Optional.absent();
}
private Optional<TreeNode> metadataFromData(@Nonnull final PathArgument child, final Version modVersion) {
* changes modification type to {@link ModificationType#SUBTREE_MODIFIED}
*
* @param child child identifier, may not be null
- * @param childPolicy child tracking policy for the node we are looking for
+ * @param childOper Child operation
* @param modVersion Version allocated by the calling {@link InMemoryDataTreeModification}
* @return {@link ModifiedNode} for specified child, with {@link #getOriginal()}
* containing child metadata if child was present in original data.
*/
- ModifiedNode modifyChild(@Nonnull final PathArgument child, @Nonnull final ChildTrackingPolicy childPolicy,
+ ModifiedNode modifyChild(@Nonnull final PathArgument child, @Nonnull final ModificationApplyOperation childOper,
@Nonnull final Version modVersion) {
clearSnapshot();
if (operation == LogicalOperation.NONE) {
final Optional<TreeNode> currentMetadata = findOriginalMetadata(child, modVersion);
- final ModifiedNode newlyCreated = new ModifiedNode(child, currentMetadata, childPolicy);
+ final ModifiedNode newlyCreated = new ModifiedNode(child, currentMetadata, childOper.getChildPolicy());
if (operation == LogicalOperation.MERGE && value != null) {
/*
* We are attempting to modify a previously-unmodified part of a MERGE node. If the
@SuppressWarnings({ "rawtypes", "unchecked" })
final Optional<NormalizedNode<?, ?>> childData = ((NormalizedNodeContainer)value).getChild(child);
if (childData.isPresent()) {
- newlyCreated.updateValue(LogicalOperation.MERGE, childData.get());
+ childOper.mergeIntoModifiedNode(newlyCreated, childData.get(), modVersion);
}
}
public static ModifiedNode createUnmodified(final TreeNode metadataTree, final ChildTrackingPolicy childPolicy) {
return new ModifiedNode(metadataTree.getIdentifier(), Optional.of(metadataTree), childPolicy);
}
+
+ void setValidatedNode(final SchemaAwareApplyOperation op, final Optional<TreeNode> current, final TreeNode node) {
+ this.validatedOp = Preconditions.checkNotNull(op);
+ this.validatedCurrent = Preconditions.checkNotNull(current);
+ this.validatedNode = Preconditions.checkNotNull(node);
+ }
+
+ TreeNode getValidatedNode(final SchemaAwareApplyOperation op, final Optional<TreeNode> current) {
+ return op.equals(validatedOp) && current.equals(validatedCurrent) ? validatedNode : null;
+ }
}