*/
package org.opendaylight.yangtools.yang.data.impl.schema.tree;
-
+import com.google.common.base.Function;
import com.google.common.base.Optional;
+import com.google.common.base.Preconditions;
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.tree.spi.TreeNode;
import org.opendaylight.yangtools.yang.data.api.schema.tree.spi.Version;
final class OperationWithModification {
+ private static final Function<TreeNode, NormalizedNode<?, ?>> READ_DATA = new Function<TreeNode, NormalizedNode<?, ?>>() {
+ @Override
+ public NormalizedNode<?, ?> apply(final TreeNode input) {
+ return input.getData();
+ }
+ };
private final ModifiedNode modification;
-
private final ModificationApplyOperation applyOperation;
private OperationWithModification(final ModificationApplyOperation op, final ModifiedNode mod) {
- this.modification = mod;
- this.applyOperation = op;
+ this.modification = Preconditions.checkNotNull(mod);
+ this.applyOperation = Preconditions.checkNotNull(op);
}
- public OperationWithModification write(final NormalizedNode<?, ?> value) {
+ void write(final NormalizedNode<?, ?> value) {
modification.write(value);
- applyOperation.verifyStructure(modification);
- return this;
+ /**
+ * Fast validation of structure, full validation on written data will be run during seal.
+ */
+ applyOperation.verifyStructure(value, false);
+ }
+
+ void merge(final NormalizedNode<?, ?> data, final Version version) {
+ /*
+ * A merge operation will end up overwriting parts of the tree, retaining others. We want to
+ * make sure we do not validate the complete resulting structure, but rather just what was
+ * written. In order to do that, we first pretend the data was written, run verification and
+ * then perform the merge -- with the explicit assumption that adding the newly-validated
+ * data with the previously-validated data will not result in invalid data.
+ */
+ applyOperation.verifyStructure(data, true);
+ applyOperation.mergeIntoModifiedNode(modification, data, version);
}
- public OperationWithModification delete() {
+ void delete() {
modification.delete();
- return this;
+ }
+
+ /**
+ * Read a particular child. If the child has been modified and does not have a stable
+ * view, one will we instantiated with specified version.
+ *
+ * @param child
+ * @param version
+ * @return
+ */
+ Optional<NormalizedNode<?, ?>> read(final PathArgument child, final Version version) {
+ final Optional<ModifiedNode> maybeChild = modification.getChild(child);
+ if (maybeChild.isPresent()) {
+ final ModifiedNode childNode = maybeChild.get();
+
+ Optional<TreeNode> snapshot = childNode.getSnapshot();
+ if (snapshot == null) {
+ // Snapshot is not present, force instantiation
+ snapshot = applyOperation.getChild(child).get().apply(childNode, childNode.getOriginal(), version);
+ }
+
+ return snapshot.transform(READ_DATA);
+ }
+
+ Optional<TreeNode> snapshot = modification.getSnapshot();
+ if (snapshot == null) {
+ snapshot = apply(modification.getOriginal(), version);
+ }
+
+ if (snapshot.isPresent()) {
+ return snapshot.get().getChild(child).transform(READ_DATA);
+ }
+
+ return Optional.absent();
}
public ModifiedNode getModification() {
public static OperationWithModification from(final ModificationApplyOperation operation,
final ModifiedNode modification) {
return new OperationWithModification(operation, modification);
-
- }
-
- public void merge(final NormalizedNode<?, ?> data) {
- modification.merge(data);
- applyOperation.verifyStructure(modification);
-
- }
-
- public OperationWithModification forChild(final PathArgument childId) {
- ModifiedNode childMod = modification.modifyChild(childId);
- Optional<ModificationApplyOperation> childOp = applyOperation.getChild(childId);
- return from(childOp.get(),childMod);
}
}