X-Git-Url: https://git.opendaylight.org/gerrit/gitweb?p=controller.git;a=blobdiff_plain;f=opendaylight%2Fmd-sal%2Fsal-dom-broker%2Fsrc%2Fmain%2Fjava%2Forg%2Fopendaylight%2Fcontroller%2Fmd%2Fsal%2Fdom%2Fstore%2Fimpl%2Ftree%2Fdata%2FSchemaAwareApplyOperation.java;h=6ef76adacf9cc478f36b5c9914b9704b16ffd05c;hp=c3c027340cf7274d395fe3028bf2477ff7f70822;hb=c78ba1f70be123609b88f43ce40f8555f1bc2ec7;hpb=f0c8b7e497b66a57cc6e24bc953b0ad336fe0785 diff --git a/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/store/impl/tree/data/SchemaAwareApplyOperation.java b/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/store/impl/tree/data/SchemaAwareApplyOperation.java index c3c027340c..6ef76adacf 100644 --- a/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/store/impl/tree/data/SchemaAwareApplyOperation.java +++ b/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/store/impl/tree/data/SchemaAwareApplyOperation.java @@ -9,49 +9,28 @@ package org.opendaylight.controller.md.sal.dom.store.impl.tree.data; import static com.google.common.base.Preconditions.checkArgument; -import java.util.HashSet; import java.util.List; -import java.util.Map; -import java.util.Set; -import java.util.concurrent.ExecutionException; import org.opendaylight.controller.md.sal.dom.store.impl.tree.DataPreconditionFailedException; import org.opendaylight.controller.md.sal.dom.store.impl.tree.ModificationType; -import org.opendaylight.controller.md.sal.dom.store.impl.tree.StoreUtils; +import org.opendaylight.controller.md.sal.dom.store.impl.tree.data.DataNodeContainerModificationStrategy.ContainerModificationStrategy; +import org.opendaylight.controller.md.sal.dom.store.impl.tree.data.DataNodeContainerModificationStrategy.UnkeyedListItemModificationStrategy; +import org.opendaylight.controller.md.sal.dom.store.impl.tree.data.NormalizedNodeContainerModificationStrategy.ChoiceModificationStrategy; +import org.opendaylight.controller.md.sal.dom.store.impl.tree.data.NormalizedNodeContainerModificationStrategy.OrderedLeafSetModificationStrategy; +import org.opendaylight.controller.md.sal.dom.store.impl.tree.data.NormalizedNodeContainerModificationStrategy.OrderedMapModificationStrategy; +import org.opendaylight.controller.md.sal.dom.store.impl.tree.data.NormalizedNodeContainerModificationStrategy.UnorderedLeafSetModificationStrategy; +import org.opendaylight.controller.md.sal.dom.store.impl.tree.data.ValueNodeModificationStrategy.LeafModificationStrategy; +import org.opendaylight.controller.md.sal.dom.store.impl.tree.spi.TreeNode; +import org.opendaylight.controller.md.sal.dom.store.impl.tree.spi.TreeNodeFactory; +import org.opendaylight.controller.md.sal.dom.store.impl.tree.spi.Version; import org.opendaylight.yangtools.yang.common.QName; import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier; import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier.AugmentationIdentifier; 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.schema.AugmentationNode; -import org.opendaylight.yangtools.yang.data.api.schema.ContainerNode; -import org.opendaylight.yangtools.yang.data.api.schema.LeafNode; -import org.opendaylight.yangtools.yang.data.api.schema.LeafSetEntryNode; -import org.opendaylight.yangtools.yang.data.api.schema.LeafSetNode; -import org.opendaylight.yangtools.yang.data.api.schema.MapEntryNode; -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.NormalizedNodeContainer; -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.UnkeyedListEntryNode; -import org.opendaylight.yangtools.yang.data.impl.schema.builder.api.DataContainerNodeBuilder; -import org.opendaylight.yangtools.yang.data.impl.schema.builder.api.NormalizedNodeContainerBuilder; -import org.opendaylight.yangtools.yang.data.impl.schema.builder.impl.ImmutableAugmentationNodeBuilder; -import org.opendaylight.yangtools.yang.data.impl.schema.builder.impl.ImmutableChoiceNodeBuilder; -import org.opendaylight.yangtools.yang.data.impl.schema.builder.impl.ImmutableContainerNodeBuilder; -import org.opendaylight.yangtools.yang.data.impl.schema.builder.impl.ImmutableLeafSetNodeBuilder; -import org.opendaylight.yangtools.yang.data.impl.schema.builder.impl.ImmutableMapEntryNodeBuilder; -import org.opendaylight.yangtools.yang.data.impl.schema.builder.impl.ImmutableMapNodeBuilder; -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.data.impl.schema.builder.impl.ImmutableUnkeyedListEntryNodeBuilder; -import org.opendaylight.yangtools.yang.data.impl.schema.transform.base.AugmentationSchemaProxy; import org.opendaylight.yangtools.yang.model.api.AugmentationSchema; import org.opendaylight.yangtools.yang.model.api.AugmentationTarget; -import org.opendaylight.yangtools.yang.model.api.ChoiceCaseNode; import org.opendaylight.yangtools.yang.model.api.ChoiceNode; import org.opendaylight.yangtools.yang.model.api.ContainerSchemaNode; import org.opendaylight.yangtools.yang.model.api.DataNodeContainer; @@ -59,17 +38,14 @@ import org.opendaylight.yangtools.yang.model.api.DataSchemaNode; import org.opendaylight.yangtools.yang.model.api.LeafListSchemaNode; import org.opendaylight.yangtools.yang.model.api.LeafSchemaNode; import org.opendaylight.yangtools.yang.model.api.ListSchemaNode; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; -import com.google.common.base.Function; import com.google.common.base.Optional; import com.google.common.base.Preconditions; -import com.google.common.cache.CacheBuilder; -import com.google.common.cache.CacheLoader; -import com.google.common.cache.LoadingCache; -import com.google.common.collect.ImmutableMap; -import com.google.common.primitives.UnsignedLong; abstract class SchemaAwareApplyOperation implements ModificationApplyOperation { + private static final Logger LOG = LoggerFactory.getLogger(SchemaAwareApplyOperation.class); public static SchemaAwareApplyOperation from(final DataSchemaNode schemaNode) { if (schemaNode instanceof ContainerSchemaNode) { @@ -86,6 +62,33 @@ abstract class SchemaAwareApplyOperation implements ModificationApplyOperation { throw new IllegalArgumentException("Not supported schema node type for " + schemaNode.getClass()); } + public static SchemaAwareApplyOperation from(final DataNodeContainer resolvedTree, + final AugmentationTarget augSchemas, final AugmentationIdentifier identifier) { + AugmentationSchema augSchema = null; + + allAugments: + for (AugmentationSchema potential : augSchemas.getAvailableAugmentations()) { + for (DataSchemaNode child : potential.getChildNodes()) { + if (identifier.getPossibleChildNames().contains(child.getQName())) { + augSchema = potential; + break allAugments; + } + } + } + + if (augSchema != null) { + return new DataNodeContainerModificationStrategy.AugmentationModificationStrategy(augSchema, resolvedTree); + } + return null; + } + + public static boolean checkDataPrecondition(final InstanceIdentifier path, final boolean condition, final String message) throws DataPreconditionFailedException { + if(!condition) { + throw new DataPreconditionFailedException(path, message); + } + return condition; + } + private static SchemaAwareApplyOperation fromListSchemaNode(final ListSchemaNode schemaNode) { List keyDefinition = schemaNode.getKeyDefinition(); if (keyDefinition == null || keyDefinition.isEmpty()) { @@ -95,7 +98,7 @@ abstract class SchemaAwareApplyOperation implements ModificationApplyOperation { return new OrderedMapModificationStrategy(schemaNode); } - return new UnorderedMapModificationStrategy(schemaNode); + return new NormalizedNodeContainerModificationStrategy.UnorderedMapModificationStrategy(schemaNode); } private static SchemaAwareApplyOperation fromLeafListSchemaNode(final LeafListSchemaNode schemaNode) { @@ -106,25 +109,11 @@ abstract class SchemaAwareApplyOperation implements ModificationApplyOperation { } } - - public static SchemaAwareApplyOperation from(final DataNodeContainer resolvedTree, - final AugmentationTarget augSchemas, final AugmentationIdentifier identifier) { - AugmentationSchema augSchema = null; - - allAugments: - for (AugmentationSchema potential : augSchemas.getAvailableAugmentations()) { - for (DataSchemaNode child : potential.getChildNodes()) { - if (identifier.getPossibleChildNames().contains(child.getQName())) { - augSchema = potential; - break allAugments; - } - } - } - - if (augSchema != null) { - return new AugmentationModificationStrategy(augSchema, resolvedTree); - } - return null; + private static final void checkNotConflicting(final InstanceIdentifier path, final TreeNode original, final TreeNode current) throws DataPreconditionFailedException { + checkDataPrecondition(path, original.getVersion().equals(current.getVersion()), + "Node was replaced by other transaction."); + checkDataPrecondition(path, original.getSubtreeVersion().equals(current.getSubtreeVersion()), + "Node children was modified by other transaction"); } protected final ModificationApplyOperation resolveChildOperation(final PathArgument child) { @@ -134,38 +123,36 @@ abstract class SchemaAwareApplyOperation implements ModificationApplyOperation { } @Override - public void verifyStructure(final NodeModification modification) throws IllegalArgumentException { - if (modification.getModificationType() == ModificationType.WRITE) { + public void verifyStructure(final ModifiedNode modification) throws IllegalArgumentException { + if (modification.getType() == ModificationType.WRITE) { verifyWrittenStructure(modification.getWrittenValue()); } } - protected abstract void verifyWrittenStructure(NormalizedNode writtenValue); - @Override - public void checkApplicable(final InstanceIdentifier path,final NodeModification modification, final Optional current) throws DataPreconditionFailedException { - switch (modification.getModificationType()) { + public final void checkApplicable(final InstanceIdentifier path,final NodeModification modification, final Optional current) throws DataPreconditionFailedException { + switch (modification.getType()) { case DELETE: checkDeleteApplicable(modification, current); case SUBTREE_MODIFIED: - checkSubtreeModificationApplicable(path,modification, current); + checkSubtreeModificationApplicable(path, modification, current); return; case WRITE: - checkWriteApplicable(path,modification, current); + checkWriteApplicable(path, modification, current); return; case MERGE: - checkMergeApplicable(path,modification,current); + checkMergeApplicable(path, modification, current); return; case UNMODIFIED: return; default: - throw new UnsupportedOperationException("Suplied modification type "+modification.getModificationType()+ "is not supported."); + throw new UnsupportedOperationException("Suplied modification type "+ modification.getType()+ "is not supported."); } } - protected void checkMergeApplicable(final InstanceIdentifier path,final NodeModification modification, final Optional current) throws DataPreconditionFailedException { - Optional original = modification.getOriginal(); + protected void checkMergeApplicable(final InstanceIdentifier path, final NodeModification modification, final Optional current) throws DataPreconditionFailedException { + Optional original = modification.getOriginal(); if (original.isPresent() && current.isPresent()) { /* * We need to do conflict detection only and only if the value of leaf changed @@ -174,50 +161,45 @@ abstract class SchemaAwareApplyOperation implements ModificationApplyOperation { * leads to same data. */ if(!original.get().getData().equals(current.get().getData())) { - - checkNotConflicting(path,original.get(), current.get()); + checkNotConflicting(path, original.get(), current.get()); } } } - protected void checkWriteApplicable(final InstanceIdentifier path,final NodeModification modification, final Optional current) throws DataPreconditionFailedException { - Optional original = modification.getOriginal(); + protected void checkWriteApplicable(final InstanceIdentifier path, final NodeModification modification, final Optional current) throws DataPreconditionFailedException { + Optional original = modification.getOriginal(); if (original.isPresent() && current.isPresent()) { - checkNotConflicting(path,original.get(), current.get()); + checkNotConflicting(path, original.get(), current.get()); } else if(original.isPresent()) { throw new DataPreconditionFailedException(path,"Node was deleted by other transaction."); } } - protected static final void checkNotConflicting(final InstanceIdentifier path,final StoreMetadataNode original, final StoreMetadataNode current) throws DataPreconditionFailedException { - checkDataPrecondition(path, original.getNodeVersion().equals(current.getNodeVersion()),"Node was replaced by other transaction."); - checkDataPrecondition(path,original.getSubtreeVersion().equals(current.getSubtreeVersion()), "Node children was modified by other transaction"); - } - - protected abstract void checkSubtreeModificationApplicable(InstanceIdentifier path,final NodeModification modification, - final Optional current) throws DataPreconditionFailedException; - - private void checkDeleteApplicable(final NodeModification modification, final Optional current) { + private void checkDeleteApplicable(final NodeModification modification, final Optional current) { + // Delete is always applicable, we do not expose it to subclasses + if (current.isPresent()) { + LOG.trace("Delete operation turned to no-op on missing node {}", modification); + } } @Override - public final Optional apply(final NodeModification modification, - final Optional currentMeta, final UnsignedLong subtreeVersion) { + public final Optional apply(final ModifiedNode modification, + final Optional currentMeta, final Version version) { - switch (modification.getModificationType()) { + switch (modification.getType()) { case DELETE: - return modification.storeSnapshot(Optional. absent()); + return modification.storeSnapshot(Optional. absent()); case SUBTREE_MODIFIED: Preconditions.checkArgument(currentMeta.isPresent(), "Metadata not available for modification", modification); return modification.storeSnapshot(Optional.of(applySubtreeChange(modification, currentMeta.get(), - subtreeVersion))); + version))); case MERGE: if(currentMeta.isPresent()) { - return modification.storeSnapshot(Optional.of(applyMerge(modification,currentMeta.get(),subtreeVersion))); + return modification.storeSnapshot(Optional.of(applyMerge(modification,currentMeta.get(), version))); } // Fallback to write is intentional - if node is not preexisting merge is same as write case WRITE: - return modification.storeSnapshot(Optional.of(applyWrite(modification, currentMeta, subtreeVersion))); + return modification.storeSnapshot(Optional.of(applyWrite(modification, currentMeta, version))); case UNMODIFIED: return currentMeta; default: @@ -225,409 +207,19 @@ abstract class SchemaAwareApplyOperation implements ModificationApplyOperation { } } - protected abstract StoreMetadataNode applyMerge(NodeModification modification, - StoreMetadataNode currentMeta, UnsignedLong subtreeVersion); - - protected abstract StoreMetadataNode applyWrite(NodeModification modification, - Optional currentMeta, UnsignedLong subtreeVersion); - - protected abstract StoreMetadataNode applySubtreeChange(NodeModification modification, - StoreMetadataNode currentMeta, UnsignedLong subtreeVersion); - - public static abstract class ValueNodeModificationStrategy extends SchemaAwareApplyOperation { - - private final T schema; - private final Class> nodeClass; - - protected ValueNodeModificationStrategy(final T schema, final Class> nodeClass) { - super(); - this.schema = schema; - this.nodeClass = nodeClass; - } - - @Override - protected void verifyWrittenStructure(final NormalizedNode writtenValue) { - checkArgument(nodeClass.isInstance(writtenValue), "Node should must be of type %s", nodeClass); - } - - @Override - public Optional getChild(final PathArgument child) { - throw new UnsupportedOperationException("Node " + schema.getPath() - + "is leaf type node. Child nodes not allowed"); - } - - @Override - protected StoreMetadataNode applySubtreeChange(final NodeModification modification, - final StoreMetadataNode currentMeta, final UnsignedLong subtreeVersion) { - throw new UnsupportedOperationException("Node " + schema.getPath() - + "is leaf type node. Subtree change is not allowed."); - } - - @Override - protected StoreMetadataNode applyMerge(final NodeModification modification, final StoreMetadataNode currentMeta, - final UnsignedLong subtreeVersion) { - return applyWrite(modification, Optional.of(currentMeta), subtreeVersion); - } - - @Override - protected StoreMetadataNode applyWrite(final NodeModification modification, - final Optional currentMeta, final UnsignedLong subtreeVersion) { - return StoreMetadataNode.builder(subtreeVersion).setSubtreeVersion(subtreeVersion) - .setData(modification.getWrittenValue()).build(); - } - - @Override - protected void checkSubtreeModificationApplicable(final InstanceIdentifier path,final NodeModification modification, - final Optional current) throws DataPreconditionFailedException { - throw new DataPreconditionFailedException(path, "Subtree modification is not allowed."); - } - - } - - public static class LeafSetEntryModificationStrategy extends ValueNodeModificationStrategy { - - @SuppressWarnings({ "unchecked", "rawtypes" }) - protected LeafSetEntryModificationStrategy(final LeafListSchemaNode schema) { - super(schema, (Class) LeafSetEntryNode.class); - } - } - - public static class LeafModificationStrategy extends ValueNodeModificationStrategy { - - @SuppressWarnings({ "unchecked", "rawtypes" }) - protected LeafModificationStrategy(final LeafSchemaNode schema) { - super(schema, (Class) LeafNode.class); - } - } - - public static abstract class NormalizedNodeContainerModificationStrategy extends SchemaAwareApplyOperation { - - private final Class> nodeClass; - - protected NormalizedNodeContainerModificationStrategy(final Class> nodeClass) { - this.nodeClass = nodeClass; - } - - @Override - public void verifyStructure(final NodeModification modification) throws IllegalArgumentException { - if (modification.getModificationType() == ModificationType.WRITE) { - - } - for (NodeModification childModification : modification.getModifications()) { - resolveChildOperation(childModification.getIdentifier()).verifyStructure(childModification); - } - } - - @Override - protected void checkWriteApplicable(final InstanceIdentifier path, final NodeModification modification, - final Optional current) throws DataPreconditionFailedException { - // 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) { - checkArgument(nodeClass.isInstance(writtenValue), "Node should must be of type %s", nodeClass); - checkArgument(writtenValue instanceof NormalizedNodeContainer); - - NormalizedNodeContainer container = (NormalizedNodeContainer) writtenValue; - for (Object child : container.getValue()) { - checkArgument(child instanceof NormalizedNode); - - /* - * FIXME: fail-fast semantics: - * - * We can validate the data structure here, aborting the commit - * before it ever progresses to being committed. - */ - } - } - - @Override - protected StoreMetadataNode applyWrite(final NodeModification modification, - final Optional currentMeta, final UnsignedLong subtreeVersion) { - - NormalizedNode newValue = modification.getWrittenValue(); - - final UnsignedLong nodeVersion; - if (currentMeta.isPresent()) { - nodeVersion = StoreUtils.increase(currentMeta.get().getNodeVersion()); - } else { - nodeVersion = subtreeVersion; - } - - final StoreMetadataNode newValueMeta = StoreMetadataNode.createRecursively(newValue, nodeVersion, nodeVersion); - if (!modification.hasAdditionalModifications()) { - return newValueMeta; - } - - @SuppressWarnings("rawtypes") - NormalizedNodeContainerBuilder dataBuilder = createBuilder(newValue); - StoreNodeCompositeBuilder builder = StoreNodeCompositeBuilder.create(nodeVersion, dataBuilder) // - .setSubtreeVersion(subtreeVersion); - - return mutateChildren(modification.getModifications(), newValueMeta, builder, nodeVersion); - } - - @Override - protected StoreMetadataNode applyMerge(final NodeModification modification, final StoreMetadataNode currentMeta, - final UnsignedLong subtreeVersion) { - // For Node Containers - merge is same as subtree change - we only replace children. - return applySubtreeChange(modification, currentMeta, subtreeVersion); - } - - @Override - public StoreMetadataNode applySubtreeChange(final NodeModification modification, - final StoreMetadataNode currentMeta, final UnsignedLong subtreeVersion) { - // Bump subtree version to its new target - final UnsignedLong updatedSubtreeVersion = StoreUtils.increase(currentMeta.getSubtreeVersion()); - - @SuppressWarnings("rawtypes") - NormalizedNodeContainerBuilder dataBuilder = createBuilder(currentMeta.getData()); - StoreNodeCompositeBuilder builder = StoreNodeCompositeBuilder.create(dataBuilder, currentMeta) - .setIdentifier(modification.getIdentifier()) - .setSubtreeVersion(updatedSubtreeVersion); - - return mutateChildren(modification.getModifications(), currentMeta, builder, updatedSubtreeVersion); - } - - private StoreMetadataNode mutateChildren(final Iterable modifications, final StoreMetadataNode meta, - final StoreNodeCompositeBuilder builder, final UnsignedLong nodeVersion) { - - for (NodeModification mod : modifications) { - final PathArgument id = mod.getIdentifier(); - final Optional cm = meta.getChild(id); - - Optional result = resolveChildOperation(id).apply(mod, cm, nodeVersion); - if (result.isPresent()) { - builder.add(result.get()); - } else { - builder.remove(id); - } - } - - return builder.build(); - } - - @Override - protected void checkSubtreeModificationApplicable(final InstanceIdentifier path,final NodeModification modification, - final Optional current) throws DataPreconditionFailedException { - checkDataPrecondition(path, current.isPresent(), "Node was deleted by other transaction."); - checkChildPreconditions(path,modification,current); - - } - - private void checkChildPreconditions(final InstanceIdentifier path, final NodeModification modification, final Optional current) throws DataPreconditionFailedException { - StoreMetadataNode currentMeta = current.get(); - for (NodeModification childMod : modification.getModifications()) { - PathArgument childId = childMod.getIdentifier(); - Optional childMeta = currentMeta.getChild(childId); - InstanceIdentifier childPath = StoreUtils.append(path, childId); - resolveChildOperation(childId).checkApplicable(childPath,childMod, childMeta); - } - } - - @Override - protected void checkMergeApplicable(final InstanceIdentifier path, final NodeModification modification, - final Optional current) throws DataPreconditionFailedException { - if(current.isPresent()) { - checkChildPreconditions(path,modification,current); - } - } - - @SuppressWarnings("rawtypes") - protected abstract NormalizedNodeContainerBuilder createBuilder(NormalizedNode original); - } - - public static abstract class DataNodeContainerModificationStrategy extends NormalizedNodeContainerModificationStrategy { - - private final T schema; - private final LoadingCache childCache = CacheBuilder.newBuilder() - .build(CacheLoader.from(new Function() { - - @Override - public ModificationApplyOperation apply(final PathArgument identifier) { - if (identifier instanceof AugmentationIdentifier && schema instanceof AugmentationTarget) { - return from(schema, (AugmentationTarget) schema, (AugmentationIdentifier) identifier); - } - - DataSchemaNode child = schema.getDataChildByName(identifier.getNodeType()); - if (child == null) { - return null; - } - return from(child); - } - })); - - protected DataNodeContainerModificationStrategy(final T schema, - final Class> nodeClass) { - super(nodeClass); - this.schema = schema; - } - - protected T getSchema() { - return schema; - } - - @Override - public Optional getChild(final PathArgument identifier) { - try { - return Optional. fromNullable(childCache.get(identifier)); - } catch (ExecutionException e) { - return Optional.absent(); - } - } - - @Override - @SuppressWarnings("rawtypes") - protected abstract DataContainerNodeBuilder createBuilder(NormalizedNode original); - - @Override - public String toString() { - return getClass().getSimpleName() + " [" + schema + "]"; - } - - } - - public static class ContainerModificationStrategy extends DataNodeContainerModificationStrategy { - - public ContainerModificationStrategy(final ContainerSchemaNode schemaNode) { - super(schemaNode, ContainerNode.class); - } - - @Override - @SuppressWarnings("rawtypes") - protected DataContainerNodeBuilder createBuilder(final NormalizedNode original) { - checkArgument(original instanceof ContainerNode); - return ImmutableContainerNodeBuilder.create((ContainerNode) original); - } - } - - public static class UnkeyedListItemModificationStrategy extends DataNodeContainerModificationStrategy { - - public UnkeyedListItemModificationStrategy(final ListSchemaNode schemaNode) { - super(schemaNode, UnkeyedListEntryNode.class); - } - - @Override - @SuppressWarnings("rawtypes") - protected DataContainerNodeBuilder createBuilder(final NormalizedNode original) { - checkArgument(original instanceof UnkeyedListEntryNode); - return ImmutableUnkeyedListEntryNodeBuilder.create((UnkeyedListEntryNode) original); - } - } - - public static class AugmentationModificationStrategy extends DataNodeContainerModificationStrategy { - - protected AugmentationModificationStrategy(final AugmentationSchema schema, final DataNodeContainer resolved) { - super(createAugmentProxy(schema,resolved), AugmentationNode.class); - } - - @Override - @SuppressWarnings("rawtypes") - protected DataContainerNodeBuilder createBuilder(final NormalizedNode original) { - checkArgument(original instanceof AugmentationNode); - return ImmutableAugmentationNodeBuilder.create((AugmentationNode) original); - } - } - - public static class ChoiceModificationStrategy extends NormalizedNodeContainerModificationStrategy { - - private final Map childNodes; - - public ChoiceModificationStrategy(final ChoiceNode schemaNode) { - super(org.opendaylight.yangtools.yang.data.api.schema.ChoiceNode.class); - ImmutableMap.Builder child = ImmutableMap.builder(); - - for (ChoiceCaseNode caze : schemaNode.getCases()) { - for (DataSchemaNode cazeChild : caze.getChildNodes()) { - SchemaAwareApplyOperation childNode = from(cazeChild); - child.put(new NodeIdentifier(cazeChild.getQName()), childNode); - } - } - childNodes = child.build(); - } - - @Override - public Optional getChild(final PathArgument child) { - return Optional.fromNullable(childNodes.get(child)); - } - - @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); - } - } - - public static class ListEntryModificationStrategy extends DataNodeContainerModificationStrategy { - - protected ListEntryModificationStrategy(final ListSchemaNode schema) { - super(schema, MapEntryNode.class); - } - - @Override - @SuppressWarnings("rawtypes") - protected final DataContainerNodeBuilder createBuilder(final NormalizedNode original) { - checkArgument(original instanceof MapEntryNode); - return ImmutableMapEntryNodeBuilder.create((MapEntryNode) original); - } - } - - public static class UnorderedLeafSetModificationStrategy extends NormalizedNodeContainerModificationStrategy { - - private final Optional entryStrategy; - - @SuppressWarnings({ "unchecked", "rawtypes" }) - protected UnorderedLeafSetModificationStrategy(final LeafListSchemaNode schema) { - super((Class) LeafSetNode.class); - entryStrategy = Optional. of(new LeafSetEntryModificationStrategy(schema)); - } - - @SuppressWarnings("rawtypes") - @Override - protected NormalizedNodeContainerBuilder createBuilder(final NormalizedNode original) { - checkArgument(original instanceof LeafSetNode); - return ImmutableLeafSetNodeBuilder.create((LeafSetNode) original); - } - - @Override - public Optional getChild(final PathArgument identifier) { - if (identifier instanceof NodeWithValue) { - return entryStrategy; - } - return Optional.absent(); - } - } - - public static class OrderedLeafSetModificationStrategy extends NormalizedNodeContainerModificationStrategy { + protected abstract TreeNode applyMerge(ModifiedNode modification, + TreeNode currentMeta, Version version); - private final Optional entryStrategy; + protected abstract TreeNode applyWrite(ModifiedNode modification, + Optional currentMeta, Version version); - @SuppressWarnings({ "unchecked", "rawtypes" }) - protected OrderedLeafSetModificationStrategy(final LeafListSchemaNode schema) { - super((Class) LeafSetNode.class); - entryStrategy = Optional. of(new LeafSetEntryModificationStrategy(schema)); - } + protected abstract TreeNode applySubtreeChange(ModifiedNode modification, + TreeNode currentMeta, Version version); - @SuppressWarnings("rawtypes") - @Override - protected NormalizedNodeContainerBuilder createBuilder(final NormalizedNode original) { - checkArgument(original instanceof OrderedLeafSetNode); - return ImmutableOrderedLeafSetNodeBuilder.create((OrderedLeafSetNode) original); - } + protected abstract void checkSubtreeModificationApplicable(InstanceIdentifier path, final NodeModification modification, + final Optional current) throws DataPreconditionFailedException; - @Override - public Optional getChild(final PathArgument identifier) { - if (identifier instanceof NodeWithValue) { - return entryStrategy; - } - return Optional.absent(); - } - } + protected abstract void verifyWrittenStructure(NormalizedNode writtenValue); public static class UnkeyedListModificationStrategy extends SchemaAwareApplyOperation { @@ -638,21 +230,21 @@ abstract class SchemaAwareApplyOperation implements ModificationApplyOperation { } @Override - protected StoreMetadataNode applyMerge(final NodeModification modification, final StoreMetadataNode currentMeta, - final UnsignedLong subtreeVersion) { - return applyWrite(modification, Optional.of(currentMeta), subtreeVersion); + protected TreeNode applyMerge(final ModifiedNode modification, final TreeNode currentMeta, + final Version version) { + return applyWrite(modification, Optional.of(currentMeta), version); } @Override - protected StoreMetadataNode applySubtreeChange(final NodeModification modification, - final StoreMetadataNode currentMeta, final UnsignedLong subtreeVersion) { + protected TreeNode applySubtreeChange(final ModifiedNode modification, + final TreeNode currentMeta, final Version version) { throw new UnsupportedOperationException("UnkeyedList does not support subtree change."); } @Override - protected StoreMetadataNode applyWrite(final NodeModification modification, - final Optional currentMeta, final UnsignedLong subtreeVersion) { - return StoreMetadataNode.createRecursively(modification.getWrittenValue(), subtreeVersion); + protected TreeNode applyWrite(final ModifiedNode modification, + final Optional currentMeta, final Version version) { + return TreeNodeFactory.createTreeNode(modification.getWrittenValue(), version); } @Override @@ -669,86 +261,9 @@ abstract class SchemaAwareApplyOperation implements ModificationApplyOperation { } @Override - protected void checkSubtreeModificationApplicable(final InstanceIdentifier path,final NodeModification modification, - final Optional current) throws DataPreconditionFailedException { + protected void checkSubtreeModificationApplicable(final InstanceIdentifier path, final NodeModification modification, + final Optional current) throws DataPreconditionFailedException { throw new DataPreconditionFailedException(path, "Subtree modification is not allowed."); } - - } - - public static class UnorderedMapModificationStrategy extends NormalizedNodeContainerModificationStrategy { - - private final Optional entryStrategy; - - protected UnorderedMapModificationStrategy(final ListSchemaNode schema) { - super(MapNode.class); - entryStrategy = Optional. of(new ListEntryModificationStrategy(schema)); - } - - @SuppressWarnings("rawtypes") - @Override - protected NormalizedNodeContainerBuilder createBuilder(final NormalizedNode original) { - checkArgument(original instanceof MapNode); - return ImmutableMapNodeBuilder.create((MapNode) original); - } - - @Override - public Optional getChild(final PathArgument identifier) { - if (identifier instanceof NodeIdentifierWithPredicates) { - return entryStrategy; - } - return Optional.absent(); - } - - @Override - public String toString() { - return "UnorderedMapModificationStrategy [entry=" + entryStrategy + "]"; - } } - - public static class OrderedMapModificationStrategy extends NormalizedNodeContainerModificationStrategy { - - private final Optional entryStrategy; - - protected OrderedMapModificationStrategy(final ListSchemaNode schema) { - super(OrderedMapNode.class); - entryStrategy = Optional. of(new ListEntryModificationStrategy(schema)); - } - - @SuppressWarnings("rawtypes") - @Override - protected NormalizedNodeContainerBuilder createBuilder(final NormalizedNode original) { - checkArgument(original instanceof OrderedMapNode); - return ImmutableOrderedMapNodeBuilder.create((OrderedMapNode) original); - } - - @Override - public Optional getChild(final PathArgument identifier) { - if (identifier instanceof NodeIdentifierWithPredicates) { - return entryStrategy; - } - return Optional.absent(); - } - - @Override - public String toString() { - return "OrderedMapModificationStrategy [entry=" + entryStrategy + "]"; - } - } - - public static AugmentationSchema createAugmentProxy(final AugmentationSchema schema, final DataNodeContainer resolved) { - Set realChildSchemas = new HashSet<>(); - for(DataSchemaNode augChild : schema.getChildNodes()) { - realChildSchemas.add(resolved.getDataChildByName(augChild.getQName())); - } - return new AugmentationSchemaProxy(schema, realChildSchemas); - } - - public static boolean checkDataPrecondition(final InstanceIdentifier path, final boolean condition, final String message) throws DataPreconditionFailedException { - if(!condition) { - throw new DataPreconditionFailedException(path, message); - } - return condition; - } - }