*/
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.NormalizedNodeContainer;
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);
}
void write(final NormalizedNode<?, ?> value) {
modification.write(value);
- applyOperation.verifyStructure(modification);
- }
-
- private void recursiveMerge(final NormalizedNode<?,?> data) {
- if (data instanceof NormalizedNodeContainer<?,?,?>) {
- @SuppressWarnings({ "rawtypes", "unchecked" })
- NormalizedNodeContainer<?,?,NormalizedNode<PathArgument, ?>> dataContainer = (NormalizedNodeContainer) data;
- for (NormalizedNode<PathArgument, ?> child : dataContainer.getValue()) {
- PathArgument childId = child.getIdentifier();
- forChild(childId).recursiveMerge(child);
- }
- }
-
- modification.merge(data);
+ /**
+ * Fast validation of structure, full validation on written data will be run during seal.
+ */
+ applyOperation.verifyStructure(value, false);
}
- void merge(final NormalizedNode<?, ?> data) {
+ 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.
+ * 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(modification.asNewlyWritten(data));
- recursiveMerge(data);
+ applyOperation.verifyStructure(data, true);
+ applyOperation.mergeIntoModifiedNode(modification, data, version);
}
void delete() {
modification.delete();
}
+ /**
+ * 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() {
return modification;
}
final ModifiedNode modification) {
return new OperationWithModification(operation, modification);
}
-
- private OperationWithModification forChild(final PathArgument childId) {
- ModificationApplyOperation childOp = applyOperation.getChild(childId).get();
-
- final boolean isOrdered;
- if (childOp instanceof SchemaAwareApplyOperation) {
- isOrdered = ((SchemaAwareApplyOperation) childOp).isOrdered();
- } else {
- isOrdered = true;
- }
-
- ModifiedNode childMod = modification.modifyChild(childId, isOrdered);
-
- return from(childOp,childMod);
- }
}