* contents, it has been merged. This means that any incoming nodes which
* were present in the tree have been replaced, but their child nodes have
* been retained.
+ *
+ * @deprecated This value is never reported. Whenever it would be reported, based
+ * on the actual effects, either {@link #WRITE} or {@link #SUBTREE_MODIFIED}
+ * is reported.
*/
+ @Deprecated
MERGE,
}
import org.opendaylight.yangtools.yang.data.api.schema.tree.DataTreeCandidate;
import org.opendaylight.yangtools.yang.data.api.schema.tree.DataTreeModification;
import org.opendaylight.yangtools.yang.data.api.schema.tree.DataValidationFailedException;
-import org.opendaylight.yangtools.yang.data.api.schema.tree.ModificationType;
import org.opendaylight.yangtools.yang.data.api.schema.tree.spi.TreeNode;
import org.opendaylight.yangtools.yang.model.api.SchemaContext;
import org.slf4j.Logger;
final InMemoryDataTreeModification m = (InMemoryDataTreeModification)modification;
final ModifiedNode root = m.getRootModification();
- if (root.getType() == ModificationType.UNMODIFIED) {
+ if (root.getOperation() == LogicalOperation.NONE) {
return new NoopDataTreeCandidate(PUBLIC_ROOT_PATH, root);
}
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.NormalizedNode;
+import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNodeContainer;
+import org.opendaylight.yangtools.yang.data.api.schema.OrderedLeafSetNode;
+import org.opendaylight.yangtools.yang.data.api.schema.OrderedMapNode;
+import org.opendaylight.yangtools.yang.data.api.schema.UnkeyedListNode;
import org.opendaylight.yangtools.yang.data.api.schema.tree.DataTreeCandidateNode;
import org.opendaylight.yangtools.yang.data.api.schema.tree.ModificationType;
import org.opendaylight.yangtools.yang.data.api.schema.tree.spi.TreeNode;
@Override
public ModificationType getModificationType() {
- return mod.getType();
+ switch (mod.getOperation()) {
+ case DELETE:
+ return ModificationType.DELETE;
+ case MERGE:
+ // Merge into non-existing data is a write
+ if (oldMeta == null) {
+ return ModificationType.WRITE;
+ }
+
+ // Data-based checks to narrow down types
+ final NormalizedNode<?, ?> data = newMeta.getData();
+
+ // leaf or anyxml are always written
+ if (!(data instanceof NormalizedNodeContainer)) {
+ return ModificationType.WRITE;
+ }
+
+ // Unkeyed collections are always written
+ if (data instanceof UnkeyedListNode || data instanceof OrderedMapNode || data instanceof OrderedLeafSetNode) {
+ return ModificationType.WRITE;
+ }
+
+ // Everything else is subtree modified
+ return ModificationType.SUBTREE_MODIFIED;
+ case TOUCH:
+ return ModificationType.SUBTREE_MODIFIED;
+ case NONE:
+ return ModificationType.UNMODIFIED;
+ case WRITE:
+ return ModificationType.WRITE;
+ }
+
+ throw new IllegalStateException("Unhandled internal operation " + mod.getOperation());
}
private Optional<NormalizedNode<?, ?>> optionalData(final TreeNode meta) {
import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNodes;
import org.opendaylight.yangtools.yang.data.api.schema.tree.DataTreeModification;
-import org.opendaylight.yangtools.yang.data.api.schema.tree.ModificationType;
import org.opendaylight.yangtools.yang.data.api.schema.tree.StoreTreeNodes;
import org.opendaylight.yangtools.yang.data.api.schema.tree.spi.TreeNode;
import org.opendaylight.yangtools.yang.data.api.schema.tree.spi.Version;
private ModificationApplyOperation resolveModificationStrategy(final YangInstanceIdentifier path) {
LOG.trace("Resolving modification apply strategy for {}", path);
- if (rootNode.getType() == ModificationType.UNMODIFIED) {
+ if (rootNode.getOperation() == LogicalOperation.NONE) {
strategyTree.upgradeIfPossible();
}
public DataTreeModification newModification() {
Preconditions.checkState(sealed == 1, "Attempted to chain on an unsealed modification");
- if (rootNode.getType() == ModificationType.UNMODIFIED) {
+ if (rootNode.getOperation() == LogicalOperation.NONE) {
// Simple fast case: just use the underlying modification
return snapshot.newModification();
}
--- /dev/null
+/*
+ * Copyright (c) 2014 Cisco Systems, Inc. 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.tree.ModificationType;
+
+/**
+ * Enumeration of all possible node modification states. These are used in
+ * data tree modification context to quickly assess what sort of modification
+ * the node is undergoing. This is a superset of {@link ModificationType}:
+ * where this type represents a logical operation, {@link ModificationType}
+ * represents a physical operation.
+ */
+enum LogicalOperation {
+ /**
+ * Node is currently unmodified.
+ */
+ NONE,
+
+ /**
+ * A child node, either direct or indirect, has been modified. This means
+ * that the data representation of this node has potentially changed.
+ */
+ TOUCH,
+
+ /**
+ * This node has been placed into the tree, potentially completely replacing
+ * pre-existing contents.
+ */
+ WRITE,
+
+ /**
+ * This node has been deleted along with any of its child nodes.
+ */
+ DELETE,
+
+ /**
+ * Node has been written into the tree, but instead of replacing pre-existing
+ * contents, it has been merged. This means that any incoming nodes which
+ * were present in the tree have been replaced, but their child nodes have
+ * been retained.
+ */
+ MERGE,
+}
@Override
public boolean apply(final @Nonnull ModifiedNode input) {
Preconditions.checkNotNull(input);
- switch (input.getType()) {
+ switch (input.getOperation()) {
case DELETE:
case MERGE:
case WRITE:
return true;
- case SUBTREE_MODIFIED:
- case UNMODIFIED:
+ case TOUCH:
+ case NONE:
return false;
}
- throw new IllegalArgumentException(String.format("Unhandled modification type %s", input.getType()));
+ throw new IllegalArgumentException(String.format("Unhandled modification type %s", input.getOperation()));
}
};
private final Map<PathArgument, ModifiedNode> children;
private final Optional<TreeNode> original;
private final PathArgument identifier;
- private ModificationType modificationType = ModificationType.UNMODIFIED;
+ private LogicalOperation operation = LogicalOperation.NONE;
private Optional<TreeNode> snapshotCache;
private NormalizedNode<?, ?> value;
return identifier;
}
- /**
- *
- * Returns original store metadata
- * @return original store metadata
- */
@Override
Optional<TreeNode> getOriginal() {
return original;
}
- /**
- * Returns modification type
- *
- * @return modification type
- */
+
@Override
- ModificationType getType() {
- return modificationType;
+ LogicalOperation getOperation() {
+ return operation;
}
/**
*/
ModifiedNode modifyChild(final PathArgument child, final boolean isOrdered) {
clearSnapshot();
- if (modificationType == ModificationType.UNMODIFIED) {
- updateModificationType(ModificationType.SUBTREE_MODIFIED);
+ if (operation == LogicalOperation.NONE) {
+ updateModificationType(LogicalOperation.TOUCH);
}
final ModifiedNode potential = children.get(child);
if (potential != null) {
* Records a delete for associated node.
*/
void delete() {
- final ModificationType newType;
+ final LogicalOperation newType;
- switch (modificationType) {
+ switch (operation) {
case DELETE:
- case UNMODIFIED:
+ case NONE:
// We need to record this delete.
- newType = ModificationType.DELETE;
+ newType = LogicalOperation.DELETE;
break;
case MERGE:
- case SUBTREE_MODIFIED:
+ case TOUCH:
case WRITE:
/*
* We are canceling a previous modification. This is a bit tricky,
* As documented in BUG-2470, a delete of data introduced in this
* transaction needs to be turned into a no-op.
*/
- newType = original.isPresent() ? ModificationType.DELETE : ModificationType.UNMODIFIED;
+ newType = original.isPresent() ? LogicalOperation.DELETE : LogicalOperation.NONE;
break;
default:
- throw new IllegalStateException("Unhandled deletion of node with " + modificationType);
+ throw new IllegalStateException("Unhandled deletion of node with " + operation);
}
clearSnapshot();
*/
void write(final NormalizedNode<?, ?> value) {
clearSnapshot();
- updateModificationType(ModificationType.WRITE);
+ updateModificationType(LogicalOperation.WRITE);
children.clear();
this.value = value;
}
void merge(final NormalizedNode<?, ?> value) {
clearSnapshot();
- updateModificationType(ModificationType.MERGE);
+ updateModificationType(LogicalOperation.MERGE);
/*
* Blind overwrite of any previous data is okay, no matter whether the node
final ModifiedNode child = it.next();
child.seal();
- if (child.modificationType == ModificationType.UNMODIFIED) {
+ if (child.operation == LogicalOperation.NONE) {
it.remove();
}
}
- // A SUBTREE_MODIFIED node without any children is a no-op
- if (modificationType == ModificationType.SUBTREE_MODIFIED && children.isEmpty()) {
- updateModificationType(ModificationType.UNMODIFIED);
+ // A TOUCH node without any children is a no-op
+ if (operation == LogicalOperation.TOUCH && children.isEmpty()) {
+ updateModificationType(LogicalOperation.NONE);
}
}
return snapshot;
}
- private void updateModificationType(final ModificationType type) {
- modificationType = type;
+ private void updateModificationType(final LogicalOperation type) {
+ operation = type;
clearSnapshot();
}
@Override
public String toString() {
return "NodeModification [identifier=" + identifier + ", modificationType="
- + modificationType + ", childModification=" + children + "]";
+ + operation + ", childModification=" + children + "]";
}
/**
*/
package org.opendaylight.yangtools.yang.data.impl.schema.tree;
-
import com.google.common.base.Optional;
import java.util.Collection;
import org.opendaylight.yangtools.concepts.Identifiable;
import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.PathArgument;
-import org.opendaylight.yangtools.yang.data.api.schema.tree.ModificationType;
import org.opendaylight.yangtools.yang.data.api.schema.tree.spi.TreeNode;
/**
/**
* Get the type of modification.
*
- * @return Modification type.
+ * @return Operation type.
*/
- abstract ModificationType getType();
+ abstract LogicalOperation getOperation();
/**
* Get the original tree node to which the modification is to be applied.
protected NoopDataTreeCandidate(final YangInstanceIdentifier rootPath, final ModifiedNode modificationRoot) {
super(rootPath);
- Preconditions.checkArgument(modificationRoot.getType() == ModificationType.UNMODIFIED);
+ Preconditions.checkArgument(modificationRoot.getOperation() == LogicalOperation.NONE);
}
@Override
import org.opendaylight.yangtools.yang.data.api.schema.tree.ConflictingModificationAppliedException;
import org.opendaylight.yangtools.yang.data.api.schema.tree.DataValidationFailedException;
import org.opendaylight.yangtools.yang.data.api.schema.tree.IncorrectDataStructureException;
-import org.opendaylight.yangtools.yang.data.api.schema.tree.ModificationType;
import org.opendaylight.yangtools.yang.data.api.schema.tree.spi.TreeNode;
import org.opendaylight.yangtools.yang.data.api.schema.tree.spi.Version;
import org.opendaylight.yangtools.yang.model.api.AugmentationSchema;
@Override
public void verifyStructure(final ModifiedNode modification) throws IllegalArgumentException {
- if (modification.getType() == ModificationType.WRITE) {
+ if (modification.getOperation() == LogicalOperation.WRITE) {
verifyWrittenStructure(modification.getWrittenValue());
}
}
@Override
public final void checkApplicable(final YangInstanceIdentifier path,final NodeModification modification, final Optional<TreeNode> current) throws DataValidationFailedException {
- switch (modification.getType()) {
+ switch (modification.getOperation()) {
case DELETE:
checkDeleteApplicable(modification, current);
- case SUBTREE_MODIFIED:
+ case TOUCH:
checkSubtreeModificationApplicable(path, modification, current);
return;
case WRITE:
case MERGE:
checkMergeApplicable(path, modification, current);
return;
- case UNMODIFIED:
+ case NONE:
return;
default:
- throw new UnsupportedOperationException("Suplied modification type "+ modification.getType()+ "is not supported.");
+ throw new UnsupportedOperationException("Suplied modification type "+ modification.getOperation()+ "is not supported.");
}
}
public final Optional<TreeNode> apply(final ModifiedNode modification,
final Optional<TreeNode> currentMeta, final Version version) {
- switch (modification.getType()) {
+ switch (modification.getOperation()) {
case DELETE:
return modification.setSnapshot(Optional.<TreeNode> absent());
- case SUBTREE_MODIFIED:
+ case TOUCH:
Preconditions.checkArgument(currentMeta.isPresent(), "Metadata not available for modification",
modification);
return modification.setSnapshot(Optional.of(applySubtreeChange(modification, currentMeta.get(),
return modification.setSnapshot(Optional.of(result));
case WRITE:
return modification.setSnapshot(Optional.of(applyWrite(modification, currentMeta, version)));
- case UNMODIFIED:
+ case NONE:
return currentMeta;
default:
throw new IllegalArgumentException("Provided modification type is not supported.");