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%2FAbstractNodeContainerModificationStrategy.java;h=342745b735999cb1266d5b9b07b22f7601d89d59;hb=bf009ab944ceb87cbd348ee5b1e23eaefe2577da;hp=4821b404a06e1688faa79071aec5d7ec018aeca4;hpb=641fc551dba4beb342e811681914f5e5db46bb6f;p=yangtools.git diff --git a/yang/yang-data-impl/src/main/java/org/opendaylight/yangtools/yang/data/impl/schema/tree/AbstractNodeContainerModificationStrategy.java b/yang/yang-data-impl/src/main/java/org/opendaylight/yangtools/yang/data/impl/schema/tree/AbstractNodeContainerModificationStrategy.java index 4821b404a0..342745b735 100644 --- a/yang/yang-data-impl/src/main/java/org/opendaylight/yangtools/yang/data/impl/schema/tree/AbstractNodeContainerModificationStrategy.java +++ b/yang/yang-data-impl/src/main/java/org/opendaylight/yangtools/yang/data/impl/schema/tree/AbstractNodeContainerModificationStrategy.java @@ -10,16 +10,17 @@ package org.opendaylight.yangtools.yang.data.impl.schema.tree; import static com.google.common.base.Preconditions.checkArgument; import static java.util.Objects.requireNonNull; -import com.google.common.base.MoreObjects; import com.google.common.base.MoreObjects.ToStringHelper; import com.google.common.base.Verify; import java.util.Collection; import java.util.Optional; import org.eclipse.jdt.annotation.NonNull; +import org.eclipse.jdt.annotation.Nullable; 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.tree.ConflictingModificationAppliedException; import org.opendaylight.yangtools.yang.data.api.schema.tree.DataTreeConfiguration; import org.opendaylight.yangtools.yang.data.api.schema.tree.DataValidationFailedException; import org.opendaylight.yangtools.yang.data.api.schema.tree.ModificationType; @@ -78,6 +79,13 @@ abstract class AbstractNodeContainerModificationStrategy } } + /** + * Fake TreeNode version used in + * {@link #checkTouchApplicable(ModificationPath, NodeModification, Optional, Version)} + * It is okay to use a global constant, as the delegate will ignore it anyway. + */ + private static final Version FAKE_VERSION = Version.initial(); + private final NormalizedNodeContainerSupport support; private final boolean verifyChildrenStructure; @@ -103,16 +111,14 @@ abstract class AbstractNodeContainerModificationStrategy final void verifyValueChildren(final NormalizedNode writtenValue) { if (verifyChildrenStructure) { final NormalizedNodeContainer container = (NormalizedNodeContainer) writtenValue; - for (final Object child : container.getValue()) { - checkArgument(child instanceof NormalizedNode); - final NormalizedNode castedChild = (NormalizedNode) child; - final Optional childOp = getChild(castedChild.getIdentifier()); + for (final NormalizedNode child : container.getValue()) { + final Optional childOp = getChild(child.getIdentifier()); if (childOp.isPresent()) { - childOp.get().fullVerifyStructure(castedChild); + childOp.get().fullVerifyStructure(child); } else { throw new SchemaValidationFailedException(String.format( "Node %s is not a valid child of %s according to the schema.", - castedChild.getIdentifier(), container.getIdentifier())); + child.getIdentifier(), container.getIdentifier())); } } @@ -144,23 +150,21 @@ abstract class AbstractNodeContainerModificationStrategy @Override protected final void recursivelyVerifyStructure(final NormalizedNode value) { final NormalizedNodeContainer container = (NormalizedNodeContainer) value; - for (final Object child : container.getValue()) { - checkArgument(child instanceof NormalizedNode); - final NormalizedNode castedChild = (NormalizedNode) child; - final Optional childOp = getChild(castedChild.getIdentifier()); + for (final NormalizedNode child : container.getValue()) { + final Optional childOp = getChild(child.getIdentifier()); if (!childOp.isPresent()) { throw new SchemaValidationFailedException( String.format("Node %s is not a valid child of %s according to the schema.", - castedChild.getIdentifier(), container.getIdentifier())); + child.getIdentifier(), container.getIdentifier())); } - childOp.get().recursivelyVerifyStructure(castedChild); + childOp.get().recursivelyVerifyStructure(child); } } @Override protected TreeNode applyWrite(final ModifiedNode modification, final NormalizedNode newValue, - final Optional currentMeta, final Version version) { + final Optional currentMeta, final Version version) { final TreeNode newValueMeta = TreeNodeFactory.createTreeNode(newValue, version); if (modification.getChildren().isEmpty()) { @@ -212,9 +216,9 @@ abstract class AbstractNodeContainerModificationStrategy for (final ModifiedNode mod : modifications) { final PathArgument id = mod.getIdentifier(); - final Optional cm = meta.getChild(id); + final Optional cm = meta.getChild(id); - final Optional result = resolveChildOperation(id).apply(mod, cm, nodeVersion); + final Optional result = resolveChildOperation(id).apply(mod, cm, nodeVersion); if (result.isPresent()) { final TreeNode tn = result.get(); meta.addChild(tn); @@ -239,9 +243,7 @@ abstract class AbstractNodeContainerModificationStrategy final NormalizedNode value = modification.getWrittenValue(); Verify.verify(value instanceof NormalizedNodeContainer, "Attempted to merge non-container %s", value); - @SuppressWarnings({"unchecked", "rawtypes"}) - final Collection> children = ((NormalizedNodeContainer) value).getValue(); - for (final NormalizedNode c : children) { + for (final NormalizedNode c : ((NormalizedNodeContainer) value).getValue()) { final PathArgument id = c.getIdentifier(); modification.modifyChild(id, resolveChildOperation(id), version); } @@ -249,7 +251,7 @@ abstract class AbstractNodeContainerModificationStrategy } private void mergeChildrenIntoModification(final ModifiedNode modification, - final Collection> children, final Version version) { + final Collection> children, final Version version) { for (final NormalizedNode c : children) { final ModificationApplyOperation childOp = resolveChildOperation(c.getIdentifier()); final ModifiedNode childNode = modification.modifyChild(c.getIdentifier(), childOp, version); @@ -260,8 +262,8 @@ abstract class AbstractNodeContainerModificationStrategy @Override final void mergeIntoModifiedNode(final ModifiedNode modification, final NormalizedNode value, final Version version) { - @SuppressWarnings({ "unchecked", "rawtypes" }) - final Collection> children = ((NormalizedNodeContainer)value).getValue(); + final Collection> children = + ((NormalizedNodeContainer)value).getValue(); switch (modification.getOperation()) { case NONE: @@ -293,7 +295,7 @@ abstract class AbstractNodeContainerModificationStrategy // and then append any child entries. if (!modification.getChildren().isEmpty()) { // Version does not matter here as we'll throw it out - final Optional current = apply(modification, modification.getOriginal(), + final Optional current = apply(modification, modification.getOriginal(), Version.initial()); if (current.isPresent()) { modification.updateValue(LogicalOperation.WRITE, current.get().getData()); @@ -355,20 +357,45 @@ abstract class AbstractNodeContainerModificationStrategy @Override protected final void checkTouchApplicable(final ModificationPath path, final NodeModification modification, - final Optional current, final Version version) throws DataValidationFailedException { - if (!modification.getOriginal().isPresent() && !current.isPresent()) { - final YangInstanceIdentifier id = path.toInstanceIdentifier(); - throw new ModifiedNodeDoesNotExistException(id, - String.format("Node %s does not exist. Cannot apply modification to its children.", id)); + final Optional current, final Version version) throws DataValidationFailedException { + final TreeNode currentNode; + if (!current.isPresent()) { + currentNode = defaultTreeNode(); + if (currentNode == null) { + if (!modification.getOriginal().isPresent()) { + final YangInstanceIdentifier id = path.toInstanceIdentifier(); + throw new ModifiedNodeDoesNotExistException(id, + String.format("Node %s does not exist. Cannot apply modification to its children.", id)); + } + + throw new ConflictingModificationAppliedException(path.toInstanceIdentifier(), + "Node was deleted by other transaction."); + } + } else { + currentNode = current.get(); } - checkConflicting(path, current.isPresent(), "Node was deleted by other transaction."); - checkChildPreconditions(path, modification, current.get(), version); + checkChildPreconditions(path, modification, currentNode, version); + } + + /** + * Return the default tree node. Default implementation does nothing, but can be overridden to call + * {@link #defaultTreeNode(NormalizedNode)}. + * + * @return Default empty tree node, or null if no default is available + */ + @Nullable TreeNode defaultTreeNode() { + // Defaults to no recovery + return null; + } + + static final TreeNode defaultTreeNode(final NormalizedNode emptyNode) { + return TreeNodeFactory.createTreeNode(emptyNode, FAKE_VERSION); } @Override protected final void checkMergeApplicable(final ModificationPath path, final NodeModification modification, - final Optional current, final Version version) throws DataValidationFailedException { + final Optional current, final Version version) throws DataValidationFailedException { if (current.isPresent()) { checkChildPreconditions(path, modification, current.get(), version); } @@ -385,7 +412,7 @@ abstract class AbstractNodeContainerModificationStrategy final TreeNode current, final Version version) throws DataValidationFailedException { for (final NodeModification childMod : modification.getChildren()) { final PathArgument childId = childMod.getIdentifier(); - final Optional childMeta = current.getChild(childId); + final Optional childMeta = current.getChild(childId); path.push(childId); try { @@ -397,10 +424,6 @@ abstract class AbstractNodeContainerModificationStrategy } @Override - public final String toString() { - return addToStringAttributes(MoreObjects.toStringHelper(this)).toString(); - } - ToStringHelper addToStringAttributes(final ToStringHelper helper) { return helper.add("support", support).add("verifyChildren", verifyChildrenStructure); }