import static com.google.common.base.Preconditions.checkArgument;
import com.google.common.base.Optional;
import com.google.common.collect.ImmutableMap;
-import com.google.common.collect.Iterables;
+import java.util.Collection;
import java.util.Map;
import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
+import org.opendaylight.yangtools.yang.data.api.schema.ChoiceNode;
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.OrderedLeafSetNode;
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.impl.schema.builder.impl.ImmutableOrderedLeafSetNodeBuilder;
import org.opendaylight.yangtools.yang.data.impl.schema.builder.impl.ImmutableOrderedMapNodeBuilder;
import org.opendaylight.yangtools.yang.model.api.ChoiceCaseNode;
-import org.opendaylight.yangtools.yang.model.api.ChoiceNode;
+import org.opendaylight.yangtools.yang.model.api.ChoiceSchemaNode;
import org.opendaylight.yangtools.yang.model.api.DataSchemaNode;
import org.opendaylight.yangtools.yang.model.api.LeafListSchemaNode;
import org.opendaylight.yangtools.yang.model.api.ListSchemaNode;
@SuppressWarnings("rawtypes")
@Override
protected void verifyWrittenStructure(final NormalizedNode<?, ?> writtenValue) {
- checkArgument(nodeClass.isInstance(writtenValue), "Node should must be of type %s", nodeClass);
+ checkArgument(nodeClass.isInstance(writtenValue), "Node %s is not of type %s", writtenValue, nodeClass);
checkArgument(writtenValue instanceof NormalizedNodeContainer);
NormalizedNodeContainer container = (NormalizedNodeContainer) writtenValue;
final NormalizedNode<?, ?> newValue = modification.getWrittenValue();
final TreeNode newValueMeta = TreeNodeFactory.createTreeNode(newValue, version);
- if (Iterables.isEmpty(modification.getChildren())) {
+ if (modification.getChildren().isEmpty()) {
return newValueMeta;
}
* As it turns out, once we materialize the written data, we can share the
* code path with the subtree change. So let's create an unsealed TreeNode
* and run the common parts on it -- which end with the node being sealed.
+ *
+ * FIXME: this code needs to be moved out from the prepare() path and into
+ * the read() and seal() paths. Merging of writes needs to be charged
+ * to the code which originated this, not to the code which is
+ * attempting to make it visible.
*/
final MutableTreeNode mutable = newValueMeta.mutable();
mutable.setSubtreeVersion(version);
protected TreeNode applyMerge(final ModifiedNode modification, final TreeNode currentMeta,
final Version version) {
// For Node Containers - merge is same as subtree change - we only replace children.
+ modification.resolveModificationType(ModificationType.SUBTREE_MODIFIED);
return applySubtreeChange(modification, currentMeta, version);
}
final MutableTreeNode newMeta = currentMeta.mutable();
newMeta.setSubtreeVersion(version);
+ /*
+ * The user has issued an empty merge operation. In this case we do not perform
+ * a data tree mutation, do not pass GO, and do not collect useless garbage.
+ */
+ final Collection<ModifiedNode> children = modification.getChildren();
+ if (children.isEmpty()) {
+ newMeta.setData(currentMeta.getData());
+ return newMeta.seal();
+ }
+
@SuppressWarnings("rawtypes")
NormalizedNodeContainerBuilder dataBuilder = createBuilder(currentMeta.getData());
- return mutateChildren(newMeta, dataBuilder, version, modification.getChildren());
+ return mutateChildren(newMeta, dataBuilder, version, children);
}
@Override
private final Map<YangInstanceIdentifier.PathArgument, ModificationApplyOperation> childNodes;
- public ChoiceModificationStrategy(final ChoiceNode schemaNode) {
- super(org.opendaylight.yangtools.yang.data.api.schema.ChoiceNode.class);
+ public ChoiceModificationStrategy(final ChoiceSchemaNode schemaNode) {
+ super(ChoiceNode.class);
ImmutableMap.Builder<YangInstanceIdentifier.PathArgument, ModificationApplyOperation> child = ImmutableMap.builder();
for (ChoiceCaseNode caze : schemaNode.getCases()) {
@Override
@SuppressWarnings("rawtypes")
protected DataContainerNodeBuilder createBuilder(final NormalizedNode<?, ?> original) {
- checkArgument(original instanceof org.opendaylight.yangtools.yang.data.api.schema.ChoiceNode);
- return ImmutableChoiceNodeBuilder.create((org.opendaylight.yangtools.yang.data.api.schema.ChoiceNode) original);
+ checkArgument(original instanceof ChoiceNode);
+ return ImmutableChoiceNodeBuilder.create((ChoiceNode) original);
}
}