- public static abstract class ValueNodeModificationStrategy<T extends DataSchemaNode> extends SchemaAwareApplyOperation {
-
- private final T schema;
- private final Class<? extends NormalizedNode<?, ?>> nodeClass;
-
- protected ValueNodeModificationStrategy(final T schema, final Class<? extends NormalizedNode<?, ?>> 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<ModificationApplyOperation> 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<StoreMetadataNode> 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<StoreMetadataNode> current) throws DataPreconditionFailedException {
- throw new DataPreconditionFailedException(path, "Subtree modification is not allowed.");
- }
-
- }
-
- public static class LeafSetEntryModificationStrategy extends ValueNodeModificationStrategy<LeafListSchemaNode> {
-
- @SuppressWarnings({ "unchecked", "rawtypes" })
- protected LeafSetEntryModificationStrategy(final LeafListSchemaNode schema) {
- super(schema, (Class) LeafSetEntryNode.class);
- }
- }
-
- public static class LeafModificationStrategy extends ValueNodeModificationStrategy<LeafSchemaNode> {
-
- @SuppressWarnings({ "unchecked", "rawtypes" })
- protected LeafModificationStrategy(final LeafSchemaNode schema) {
- super(schema, (Class) LeafNode.class);
- }
- }
-
- public static abstract class NormalizedNodeContainerModificationStrategy extends SchemaAwareApplyOperation {
-
- private final Class<? extends NormalizedNode<?, ?>> nodeClass;
-
- protected NormalizedNodeContainerModificationStrategy(final Class<? extends NormalizedNode<?, ?>> 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<StoreMetadataNode> 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<StoreMetadataNode> 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);
- 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<NodeModification> modifications, final StoreMetadataNode meta,
- final StoreNodeCompositeBuilder builder, final UnsignedLong nodeVersion) {
-
- for (NodeModification mod : modifications) {
- final PathArgument id = mod.getIdentifier();
- final Optional<StoreMetadataNode> cm = meta.getChild(id);
-
- Optional<StoreMetadataNode> 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<StoreMetadataNode> 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<StoreMetadataNode> current) throws DataPreconditionFailedException {
- StoreMetadataNode currentMeta = current.get();
- for (NodeModification childMod : modification.getModifications()) {
- PathArgument childId = childMod.getIdentifier();
- Optional<StoreMetadataNode> 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<StoreMetadataNode> current) throws DataPreconditionFailedException {
- if(current.isPresent()) {
- checkChildPreconditions(path,modification,current);
- }
- }
-
- @SuppressWarnings("rawtypes")
- protected abstract NormalizedNodeContainerBuilder createBuilder(NormalizedNode<?, ?> original);
- }
-
- public static abstract class DataNodeContainerModificationStrategy<T extends DataNodeContainer> extends NormalizedNodeContainerModificationStrategy {
-
- private final T schema;
- private final LoadingCache<PathArgument, ModificationApplyOperation> childCache = CacheBuilder.newBuilder()
- .build(CacheLoader.from(new Function<PathArgument, ModificationApplyOperation>() {
-
- @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<? extends NormalizedNode<?, ?>> nodeClass) {
- super(nodeClass);
- this.schema = schema;
- }
-
- protected T getSchema() {
- return schema;
- }
-
- @Override
- public Optional<ModificationApplyOperation> getChild(final PathArgument identifier) {
- try {
- return Optional.<ModificationApplyOperation> 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<ContainerSchemaNode> {
-
- 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<ListSchemaNode> {
-
- 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<AugmentationSchema> {
-
- 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<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();
-
- 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<ModificationApplyOperation> 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<ListSchemaNode> {
-
- 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<ModificationApplyOperation> entryStrategy;
-
- @SuppressWarnings({ "unchecked", "rawtypes" })
- protected UnorderedLeafSetModificationStrategy(final LeafListSchemaNode schema) {
- super((Class) LeafSetNode.class);
- entryStrategy = Optional.<ModificationApplyOperation> 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<ModificationApplyOperation> getChild(final PathArgument identifier) {
- if (identifier instanceof NodeWithValue) {
- return entryStrategy;
- }
- return Optional.absent();
- }
- }
-
- public static class OrderedLeafSetModificationStrategy extends NormalizedNodeContainerModificationStrategy {
-
- private final Optional<ModificationApplyOperation> entryStrategy;
-
- @SuppressWarnings({ "unchecked", "rawtypes" })
- protected OrderedLeafSetModificationStrategy(final LeafListSchemaNode schema) {
- super((Class) LeafSetNode.class);
- entryStrategy = Optional.<ModificationApplyOperation> of(new LeafSetEntryModificationStrategy(schema));
- }
-
- @SuppressWarnings("rawtypes")
- @Override
- protected NormalizedNodeContainerBuilder createBuilder(final NormalizedNode<?, ?> original) {
- checkArgument(original instanceof OrderedLeafSetNode<?>);
- return ImmutableOrderedLeafSetNodeBuilder.create((OrderedLeafSetNode<?>) original);
- }