X-Git-Url: https://git.opendaylight.org/gerrit/gitweb?a=blobdiff_plain;f=yang%2Fyang-data-impl%2Fsrc%2Fmain%2Fjava%2Forg%2Fopendaylight%2Fyangtools%2Fyang%2Fdata%2Fimpl%2Fschema%2Ftree%2FOperationWithModification.java;h=a375a90d74dcbca18df6ffb06ccb916727b7c09d;hb=adc2275288a6055dda77692b5a742835eb15af3b;hp=fd43ce9a6d87eaa02e1e96ff456d9b1f9e502013;hpb=b57c902bda90f50549d1b3a6340c7a8111cfa3da;p=yangtools.git diff --git a/yang/yang-data-impl/src/main/java/org/opendaylight/yangtools/yang/data/impl/schema/tree/OperationWithModification.java b/yang/yang-data-impl/src/main/java/org/opendaylight/yangtools/yang/data/impl/schema/tree/OperationWithModification.java index fd43ce9a6d..a375a90d74 100644 --- a/yang/yang-data-impl/src/main/java/org/opendaylight/yangtools/yang/data/impl/schema/tree/OperationWithModification.java +++ b/yang/yang-data-impl/src/main/java/org/opendaylight/yangtools/yang/data/impl/schema/tree/OperationWithModification.java @@ -7,10 +7,11 @@ */ package org.opendaylight.yangtools.yang.data.impl.schema.tree; - 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; @@ -27,12 +28,55 @@ final class OperationWithModification { void write(final NormalizedNode value) { modification.write(value); - applyOperation.verifyStructure(modification); + /** + * Fast validation of structure, full validation on written data will be run during seal. + */ + applyOperation.verifyStructure(value, false); } - void merge(final NormalizedNode data) { + private void recursiveMerge(final NormalizedNode data) { + if (data instanceof NormalizedNodeContainer) { + @SuppressWarnings({ "rawtypes", "unchecked" }) + final + NormalizedNodeContainer> dataContainer = (NormalizedNodeContainer) data; + + /* + * if there was write before on this node and it is of NormalizedNodeContainer type + * merge would overwrite our changes. So we create write modifications from data children to + * retain children created by past write operation. + * These writes will then be pushed down in the tree while there are merge modifications on these children + */ + if (modification.getOperation().equals(LogicalOperation.WRITE)) { + @SuppressWarnings({ "rawtypes", "unchecked" }) + final + NormalizedNodeContainer> odlDataContainer = + (NormalizedNodeContainer) modification.getWrittenValue(); + for (final NormalizedNode child : odlDataContainer.getValue()) { + final PathArgument childId = child.getIdentifier(); + forChild(childId).write(child); + } + } + for (final NormalizedNode child : dataContainer.getValue()) { + final PathArgument childId = child.getIdentifier(); + forChild(childId).recursiveMerge(child); + } + } + modification.merge(data); - applyOperation.verifyStructure(modification); + } + + void merge(final NormalizedNode 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. + * + * FIXME: Should be this moved to recursive merge and run for each node? + */ + applyOperation.verifyStructure(data, false); + recursiveMerge(data); } void delete() { @@ -56,18 +100,13 @@ final class OperationWithModification { return new OperationWithModification(operation, modification); } - public 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; - } + private OperationWithModification forChild(final PathArgument childId) { + final Optional maybeChildOp = applyOperation.getChild(childId); + Preconditions.checkArgument(maybeChildOp.isPresent(), "Attempted to apply operation to non-existent child %s", childId); - ModifiedNode childMod = modification.modifyChild(childId, isOrdered); + final ModificationApplyOperation childOp = maybeChildOp.get(); + final ModifiedNode childMod = modification.modifyChild(childId, childOp.getChildPolicy()); - return from(childOp,childMod); + return from(childOp, childMod); } }