import com.google.common.base.Optional;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.Iterables;
-import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier;
-import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier.NodeIdentifier;
-import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier.NodeIdentifierWithPredicates;
-import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier.NodeWithValue;
-import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier.PathArgument;
+import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
import org.opendaylight.yangtools.yang.data.api.schema.LeafSetNode;
import org.opendaylight.yangtools.yang.data.api.schema.MapNode;
import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
import org.opendaylight.yangtools.yang.data.api.schema.OrderedMapNode;
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.ModifiedNodeDoesNotExistException;
import org.opendaylight.yangtools.yang.data.api.schema.tree.spi.MutableTreeNode;
import org.opendaylight.yangtools.yang.data.api.schema.tree.spi.TreeNode;
import org.opendaylight.yangtools.yang.data.api.schema.tree.spi.TreeNodeFactory;
}
}
- @Override
- protected void checkWriteApplicable(final InstanceIdentifier path, final NodeModification modification,
- final Optional<TreeNode> current) throws DataValidationFailedException {
- // FIXME: Implement proper write check for replacement of node container
- // prerequisite is to have transaction chain available for clients
- // otherwise this will break chained writes to same node.
- }
-
@SuppressWarnings("rawtypes")
@Override
protected void verifyWrittenStructure(final NormalizedNode<?, ?> writtenValue) {
return mutateChildren(mutable, dataBuilder, version, modification.getChildren());
}
+ /**
+ * Applies write/remove diff operation for each modification child in modification subtree.
+ * Operation also sets the Data tree references for each Tree Node (Index Node) in meta (MutableTreeNode) structure.
+ *
+ * @param meta MutableTreeNode (IndexTreeNode)
+ * @param data DataBuilder
+ * @param nodeVersion Version of TreeNode
+ * @param modifications modification operations to apply
+ * @return Sealed immutable copy of TreeNode structure with all Data Node references set.
+ */
@SuppressWarnings({ "rawtypes", "unchecked" })
private TreeNode mutateChildren(final MutableTreeNode meta, final NormalizedNodeContainerBuilder data,
final Version nodeVersion, final Iterable<ModifiedNode> modifications) {
for (ModifiedNode mod : modifications) {
- final PathArgument id = mod.getIdentifier();
+ final YangInstanceIdentifier.PathArgument id = mod.getIdentifier();
final Optional<TreeNode> cm = meta.getChild(id);
Optional<TreeNode> result = resolveChildOperation(id).apply(mod, cm, nodeVersion);
}
@Override
- protected void checkSubtreeModificationApplicable(final InstanceIdentifier path, final NodeModification modification,
+ protected void checkSubtreeModificationApplicable(final YangInstanceIdentifier path, final NodeModification modification,
final Optional<TreeNode> current) throws DataValidationFailedException {
+ if (!modification.getOriginal().isPresent() && !current.isPresent()) {
+ throw new ModifiedNodeDoesNotExistException(path, String.format("Node %s does not exist. Cannot apply modification to its children.", path));
+ }
+
SchemaAwareApplyOperation.checkConflicting(path, current.isPresent(), "Node was deleted by other transaction.");
checkChildPreconditions(path, modification, current);
}
- private void checkChildPreconditions(final InstanceIdentifier path, final NodeModification modification, final Optional<TreeNode> current) throws DataValidationFailedException {
+ private void checkChildPreconditions(final YangInstanceIdentifier path, final NodeModification modification, final Optional<TreeNode> current) throws DataValidationFailedException {
final TreeNode currentMeta = current.get();
for (NodeModification childMod : modification.getChildren()) {
- final PathArgument childId = childMod.getIdentifier();
+ final YangInstanceIdentifier.PathArgument childId = childMod.getIdentifier();
final Optional<TreeNode> childMeta = currentMeta.getChild(childId);
- InstanceIdentifier childPath = path.node(childId);
+ YangInstanceIdentifier childPath = path.node(childId);
resolveChildOperation(childId).checkApplicable(childPath, childMod, childMeta);
}
}
@Override
- protected void checkMergeApplicable(final InstanceIdentifier path, final NodeModification modification,
+ protected void checkMergeApplicable(final YangInstanceIdentifier path, final NodeModification modification,
final Optional<TreeNode> current) throws DataValidationFailedException {
if(current.isPresent()) {
checkChildPreconditions(path, modification,current);
public static class ChoiceModificationStrategy extends NormalizedNodeContainerModificationStrategy {
- private final Map<PathArgument, ModificationApplyOperation> childNodes;
+ private final Map<YangInstanceIdentifier.PathArgument, ModificationApplyOperation> childNodes;
public ChoiceModificationStrategy(final ChoiceNode schemaNode) {
super(org.opendaylight.yangtools.yang.data.api.schema.ChoiceNode.class);
- ImmutableMap.Builder<PathArgument, ModificationApplyOperation> child = ImmutableMap.builder();
+ ImmutableMap.Builder<YangInstanceIdentifier.PathArgument, ModificationApplyOperation> child = ImmutableMap.builder();
for (ChoiceCaseNode caze : schemaNode.getCases()) {
for (DataSchemaNode cazeChild : caze.getChildNodes()) {
SchemaAwareApplyOperation childNode = SchemaAwareApplyOperation.from(cazeChild);
- child.put(new NodeIdentifier(cazeChild.getQName()), childNode);
+ child.put(new YangInstanceIdentifier.NodeIdentifier(cazeChild.getQName()), childNode);
}
}
childNodes = child.build();
}
@Override
- public Optional<ModificationApplyOperation> getChild(final PathArgument child) {
+ public Optional<ModificationApplyOperation> getChild(final YangInstanceIdentifier.PathArgument child) {
return Optional.fromNullable(childNodes.get(child));
}
entryStrategy = Optional.<ModificationApplyOperation> of(new ValueNodeModificationStrategy.LeafSetEntryModificationStrategy(schema));
}
+ @Override
+ boolean isOrdered() {
+ return true;
+ }
+
@SuppressWarnings("rawtypes")
@Override
protected NormalizedNodeContainerBuilder createBuilder(final NormalizedNode<?, ?> original) {
}
@Override
- public Optional<ModificationApplyOperation> getChild(final PathArgument identifier) {
- if (identifier instanceof NodeWithValue) {
+ public Optional<ModificationApplyOperation> getChild(final YangInstanceIdentifier.PathArgument identifier) {
+ if (identifier instanceof YangInstanceIdentifier.NodeWithValue) {
return entryStrategy;
}
return Optional.absent();
entryStrategy = Optional.<ModificationApplyOperation> of(new DataNodeContainerModificationStrategy.ListEntryModificationStrategy(schema));
}
+ @Override
+ boolean isOrdered() {
+ return true;
+ }
+
@SuppressWarnings("rawtypes")
@Override
protected NormalizedNodeContainerBuilder createBuilder(final NormalizedNode<?, ?> original) {
}
@Override
- public Optional<ModificationApplyOperation> getChild(final PathArgument identifier) {
- if (identifier instanceof NodeIdentifierWithPredicates) {
+ public Optional<ModificationApplyOperation> getChild(final YangInstanceIdentifier.PathArgument identifier) {
+ if (identifier instanceof YangInstanceIdentifier.NodeIdentifierWithPredicates) {
return entryStrategy;
}
return Optional.absent();
}
@Override
- public Optional<ModificationApplyOperation> getChild(final PathArgument identifier) {
- if (identifier instanceof NodeWithValue) {
+ public Optional<ModificationApplyOperation> getChild(final YangInstanceIdentifier.PathArgument identifier) {
+ if (identifier instanceof YangInstanceIdentifier.NodeWithValue) {
return entryStrategy;
}
return Optional.absent();
}
@Override
- public Optional<ModificationApplyOperation> getChild(final PathArgument identifier) {
- if (identifier instanceof NodeIdentifierWithPredicates) {
+ public Optional<ModificationApplyOperation> getChild(final YangInstanceIdentifier.PathArgument identifier) {
+ if (identifier instanceof YangInstanceIdentifier.NodeIdentifierWithPredicates) {
return entryStrategy;
}
return Optional.absent();