1 package org.opendaylight.controller.md.sal.dom.store.impl;
3 import static com.google.common.base.Preconditions.checkArgument;
8 import java.util.concurrent.ExecutionException;
10 import org.opendaylight.controller.md.sal.dom.store.impl.tree.ModificationType;
11 import org.opendaylight.controller.md.sal.dom.store.impl.tree.NodeModification;
12 import org.opendaylight.controller.md.sal.dom.store.impl.tree.StoreMetadataNode;
13 import org.opendaylight.controller.md.sal.dom.store.impl.tree.StoreNodeCompositeBuilder;
14 import org.opendaylight.yangtools.yang.common.QName;
15 import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier.AugmentationIdentifier;
16 import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier.NodeIdentifier;
17 import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier.NodeIdentifierWithPredicates;
18 import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier.NodeWithValue;
19 import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier.PathArgument;
20 import org.opendaylight.yangtools.yang.data.api.schema.AugmentationNode;
21 import org.opendaylight.yangtools.yang.data.api.schema.ContainerNode;
22 import org.opendaylight.yangtools.yang.data.api.schema.LeafNode;
23 import org.opendaylight.yangtools.yang.data.api.schema.LeafSetEntryNode;
24 import org.opendaylight.yangtools.yang.data.api.schema.LeafSetNode;
25 import org.opendaylight.yangtools.yang.data.api.schema.MapEntryNode;
26 import org.opendaylight.yangtools.yang.data.api.schema.MapNode;
27 import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
28 import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNodeContainer;
29 import org.opendaylight.yangtools.yang.data.api.schema.OrderedMapNode;
30 import org.opendaylight.yangtools.yang.data.api.schema.UnkeyedListEntryNode;
31 import org.opendaylight.yangtools.yang.data.impl.schema.Builders;
32 import org.opendaylight.yangtools.yang.data.impl.schema.builder.api.DataContainerNodeBuilder;
33 import org.opendaylight.yangtools.yang.data.impl.schema.builder.api.NormalizedNodeContainerBuilder;
34 import org.opendaylight.yangtools.yang.data.impl.schema.builder.impl.ImmutableChoiceNodeBuilder;
35 import org.opendaylight.yangtools.yang.data.impl.schema.builder.impl.ImmutableContainerNodeBuilder;
36 import org.opendaylight.yangtools.yang.data.impl.schema.builder.impl.ImmutableLeafSetNodeBuilder;
37 import org.opendaylight.yangtools.yang.data.impl.schema.builder.impl.ImmutableMapEntryNodeBuilder;
38 import org.opendaylight.yangtools.yang.data.impl.schema.builder.impl.ImmutableMapNodeBuilder;
39 import org.opendaylight.yangtools.yang.data.impl.schema.builder.impl.ImmutableOrderedMapNodeBuilder;
40 import org.opendaylight.yangtools.yang.data.impl.schema.builder.impl.ImmutableUnkeyedListEntryNodeBuilder;
41 import org.opendaylight.yangtools.yang.model.api.AugmentationSchema;
42 import org.opendaylight.yangtools.yang.model.api.AugmentationTarget;
43 import org.opendaylight.yangtools.yang.model.api.ChoiceCaseNode;
44 import org.opendaylight.yangtools.yang.model.api.ChoiceNode;
45 import org.opendaylight.yangtools.yang.model.api.ContainerSchemaNode;
46 import org.opendaylight.yangtools.yang.model.api.DataNodeContainer;
47 import org.opendaylight.yangtools.yang.model.api.DataSchemaNode;
48 import org.opendaylight.yangtools.yang.model.api.LeafListSchemaNode;
49 import org.opendaylight.yangtools.yang.model.api.LeafSchemaNode;
50 import org.opendaylight.yangtools.yang.model.api.ListSchemaNode;
52 import com.google.common.base.Function;
53 import com.google.common.base.Optional;
54 import com.google.common.base.Preconditions;
55 import com.google.common.cache.CacheBuilder;
56 import com.google.common.cache.CacheLoader;
57 import com.google.common.cache.LoadingCache;
58 import com.google.common.collect.ImmutableMap;
59 import com.google.common.collect.ImmutableSet;
60 import com.google.common.collect.ImmutableSet.Builder;
61 import com.google.common.primitives.UnsignedLong;
63 public abstract class SchemaAwareApplyOperation implements ModificationApplyOperation {
65 public static SchemaAwareApplyOperation from(final DataSchemaNode schemaNode) {
66 if (schemaNode instanceof ContainerSchemaNode) {
67 return new ContainerModificationStrategy((ContainerSchemaNode) schemaNode);
68 } else if (schemaNode instanceof ListSchemaNode) {
69 return fromListSchemaNode((ListSchemaNode) schemaNode);
70 } else if (schemaNode instanceof ChoiceNode) {
71 return new ChoiceModificationStrategy((ChoiceNode) schemaNode);
72 } else if (schemaNode instanceof LeafListSchemaNode) {
73 return new LeafSetEntryModificationStrategy((LeafListSchemaNode) schemaNode);
74 } else if (schemaNode instanceof LeafSchemaNode) {
75 return new LeafModificationStrategy((LeafSchemaNode) schemaNode);
77 throw new IllegalArgumentException("Not supported schema node type for " + schemaNode.getClass());
80 private static SchemaAwareApplyOperation fromListSchemaNode(final ListSchemaNode schemaNode) {
81 List<QName> keyDefinition = schemaNode.getKeyDefinition();
82 if (keyDefinition == null || keyDefinition.isEmpty()) {
83 return new UnkeyedListModificationStrategy(schemaNode);
85 if (schemaNode.isUserOrdered()) {
86 return new OrderedMapModificationStrategy(schemaNode);
89 return new UnorderedMapModificationStrategy(schemaNode);
92 public static SchemaAwareApplyOperation from(final DataNodeContainer resolvedTree,
93 final AugmentationTarget augSchemas, final AugmentationIdentifier identifier) {
94 AugmentationSchema augSchema = null;
95 allAugments: for (AugmentationSchema potential : augSchemas.getAvailableAugmentations()) {
96 boolean containsAll = true;
97 for (DataSchemaNode child : potential.getChildNodes()) {
98 if (identifier.getPossibleChildNames().contains(child.getQName())) {
99 augSchema = potential;
104 if (augSchema != null) {
105 return new AugmentationModificationStrategy(augSchema, resolvedTree);
110 protected final ModificationApplyOperation resolveChildOperation(final PathArgument child) {
111 Optional<ModificationApplyOperation> potential = getChild(child);
112 checkArgument(potential.isPresent(), "Operation for child %s is not defined.", child);
113 return potential.get();
117 public void verifyStructure(final NodeModification modification) throws IllegalArgumentException {
118 if (modification.getModificationType() == ModificationType.WRITE) {
119 verifyWritenStructure(modification.getWritenValue());
123 protected abstract void verifyWritenStructure(NormalizedNode<?, ?> writenValue);
126 public boolean isApplicable(final NodeModification modification, final Optional<StoreMetadataNode> current) {
127 switch (modification.getModificationType()) {
129 return isDeleteApplicable(modification, current);
130 case SUBTREE_MODIFIED:
131 return isSubtreeModificationApplicable(modification, current);
133 return isWriteApplicable(modification, current);
141 protected boolean isWriteApplicable(final NodeModification modification, final Optional<StoreMetadataNode> current) {
142 Optional<StoreMetadataNode> original = modification.getOriginal();
143 if (original.isPresent() && current.isPresent()) {
144 return isNotConflicting(original.get(), current.get());
145 } else if (current.isPresent()) {
152 protected final boolean isNotConflicting(final StoreMetadataNode original, final StoreMetadataNode current) {
153 return original.getNodeVersion().equals(current.getNodeVersion())
154 && original.getSubtreeVersion().equals(current.getSubtreeVersion());
157 protected abstract boolean isSubtreeModificationApplicable(final NodeModification modification,
158 final Optional<StoreMetadataNode> current);
160 private boolean isDeleteApplicable(final NodeModification modification, final Optional<StoreMetadataNode> current) {
161 // FiXME: Add delete conflict detection.
166 public final Optional<StoreMetadataNode> apply(final NodeModification modification,
167 final Optional<StoreMetadataNode> currentMeta, final UnsignedLong subtreeVersion) {
169 switch (modification.getModificationType()) {
171 return modification.storeSnapshot(Optional.<StoreMetadataNode> absent());
172 case SUBTREE_MODIFIED:
173 Preconditions.checkArgument(currentMeta.isPresent(), "Metadata not available for modification",
175 return modification.storeSnapshot(Optional.of(applySubtreeChange(modification, currentMeta.get(),
178 return modification.storeSnapshot(Optional.of(applyWrite(modification, currentMeta, subtreeVersion)));
182 throw new IllegalArgumentException("Provided modification type is not supported.");
186 protected abstract StoreMetadataNode applyWrite(NodeModification modification,
187 Optional<StoreMetadataNode> currentMeta, UnsignedLong subtreeVersion);
189 protected abstract StoreMetadataNode applySubtreeChange(NodeModification modification,
190 StoreMetadataNode currentMeta, UnsignedLong subtreeVersion);
192 public static abstract class ValueNodeModificationStrategy<T extends DataSchemaNode> extends
193 SchemaAwareApplyOperation {
195 private final T schema;
196 private final Class<? extends NormalizedNode<?, ?>> nodeClass;
198 protected ValueNodeModificationStrategy(final T schema, final Class<? extends NormalizedNode<?, ?>> nodeClass) {
200 this.schema = schema;
201 this.nodeClass = nodeClass;
205 protected void verifyWritenStructure(final NormalizedNode<?, ?> writenValue) {
206 checkArgument(nodeClass.isInstance(writenValue), "Node should must be of type %s", nodeClass);
210 public Optional<ModificationApplyOperation> getChild(final PathArgument child) {
211 throw new UnsupportedOperationException("Node " + schema.getPath()
212 + "is leaf type node. Child nodes not allowed");
216 protected StoreMetadataNode applySubtreeChange(final NodeModification modification,
217 final StoreMetadataNode currentMeta, final UnsignedLong subtreeVersion) {
218 throw new UnsupportedOperationException("Node " + schema.getPath()
219 + "is leaf type node. Subtree change is not allowed.");
223 protected StoreMetadataNode applyWrite(final NodeModification modification,
224 final Optional<StoreMetadataNode> currentMeta, final UnsignedLong subtreeVersion) {
225 UnsignedLong nodeVersion = subtreeVersion;
226 if (currentMeta.isPresent()) {
227 nodeVersion = StoreUtils.increase(currentMeta.get().getNodeVersion());
230 return StoreMetadataNode.builder().setNodeVersion(nodeVersion).setSubtreeVersion(subtreeVersion)
231 .setData(modification.getWritenValue()).build();
235 protected boolean isSubtreeModificationApplicable(final NodeModification modification,
236 final Optional<StoreMetadataNode> current) {
242 public static class LeafSetEntryModificationStrategy extends ValueNodeModificationStrategy<LeafListSchemaNode> {
244 @SuppressWarnings({ "unchecked", "rawtypes" })
245 protected LeafSetEntryModificationStrategy(final LeafListSchemaNode schema) {
246 super(schema, (Class) LeafSetEntryNode.class);
250 public static class LeafModificationStrategy extends ValueNodeModificationStrategy<LeafSchemaNode> {
252 @SuppressWarnings({ "unchecked", "rawtypes" })
253 protected LeafModificationStrategy(final LeafSchemaNode schema) {
254 super(schema, (Class) LeafNode.class);
258 public static abstract class NormalizedNodeContainerModificationStrategy extends SchemaAwareApplyOperation {
260 private final Class<? extends NormalizedNode<?, ?>> nodeClass;
262 protected NormalizedNodeContainerModificationStrategy(final Class<? extends NormalizedNode<?, ?>> nodeClass) {
263 this.nodeClass = nodeClass;
267 public void verifyStructure(final NodeModification modification) throws IllegalArgumentException {
268 if (modification.getModificationType() == ModificationType.WRITE) {
271 for (NodeModification childModification : modification.getModifications()) {
272 resolveChildOperation(childModification.getIdentifier()).verifyStructure(childModification);
276 @SuppressWarnings("rawtypes")
278 protected void verifyWritenStructure(final NormalizedNode<?, ?> writenValue) {
279 checkArgument(nodeClass.isInstance(writenValue), "Node should must be of type %s", nodeClass);
280 checkArgument(writenValue instanceof NormalizedNodeContainer);
281 NormalizedNodeContainer writenCont = (NormalizedNodeContainer) writenValue;
282 for (Object child : writenCont.getValue()) {
283 checkArgument(child instanceof NormalizedNode);
284 NormalizedNode childNode = (NormalizedNode) child;
289 protected StoreMetadataNode applyWrite(final NodeModification modification,
290 final Optional<StoreMetadataNode> currentMeta, final UnsignedLong subtreeVersion) {
292 NormalizedNode<?, ?> newValue = modification.getWritenValue();
294 UnsignedLong nodeVersion = subtreeVersion;
295 if (currentMeta.isPresent()) {
296 nodeVersion = StoreUtils.increase(currentMeta.get().getNodeVersion());
298 StoreMetadataNode newValueMeta = StoreMetadataNode.createRecursively(newValue, nodeVersion, nodeVersion);
300 if (!modification.hasAdditionalModifications()) {
303 @SuppressWarnings("rawtypes")
304 NormalizedNodeContainerBuilder dataBuilder = createBuilder(modification.getIdentifier());
305 StoreNodeCompositeBuilder builder = StoreNodeCompositeBuilder.from(dataBuilder) //
306 .setNodeVersion(nodeVersion) //
307 .setSubtreeVersion(subtreeVersion);
309 Set<PathArgument> processedPreexisting = applyPreexistingChildren(modification, newValueMeta.getChildren(),
310 builder, nodeVersion);
311 applyNewChildren(modification, processedPreexisting, builder, nodeVersion);
313 return builder.build();
318 public StoreMetadataNode applySubtreeChange(final NodeModification modification,
319 final StoreMetadataNode currentMeta, final UnsignedLong subtreeVersion) {
321 UnsignedLong updatedSubtreeVersion = StoreUtils.increase(currentMeta.getSubtreeVersion());
322 @SuppressWarnings("rawtypes")
323 NormalizedNodeContainerBuilder dataBuilder = createBuilder(modification.getIdentifier());
324 StoreNodeCompositeBuilder builder = StoreNodeCompositeBuilder.from(dataBuilder)
325 .setIdentifier(modification.getIdentifier()).setNodeVersion(currentMeta.getNodeVersion())
326 .setSubtreeVersion(updatedSubtreeVersion);
327 // We process preexisting nodes
328 Set<PathArgument> processedPreexisting = applyPreexistingChildren(modification, currentMeta.getChildren(),
329 builder, updatedSubtreeVersion);
330 applyNewChildren(modification, processedPreexisting, builder, updatedSubtreeVersion);
331 return builder.build();
334 private void applyNewChildren(final NodeModification modification, final Set<PathArgument> ignore,
335 final StoreNodeCompositeBuilder builder, final UnsignedLong subtreeVersion) {
336 for (NodeModification childModification : modification.getModifications()) {
337 PathArgument childIdentifier = childModification.getIdentifier();
338 // We skip allready processed modifications
339 if (ignore.contains(childIdentifier)) {
343 builder.addIfPresent(resolveChildOperation(childIdentifier) //
344 .apply(childModification, Optional.<StoreMetadataNode> absent(), subtreeVersion));
348 private Set<PathArgument> applyPreexistingChildren(final NodeModification modification,
349 final Iterable<StoreMetadataNode> children, final StoreNodeCompositeBuilder nodeBuilder,
350 final UnsignedLong subtreeVersion) {
351 Builder<PathArgument> processedModifications = ImmutableSet.<PathArgument> builder();
352 for (StoreMetadataNode childMeta : children) {
353 PathArgument childIdentifier = childMeta.getIdentifier();
354 // We retrieve Child modification metadata
355 Optional<NodeModification> childModification = modification.getChild(childIdentifier);
357 if (childModification.isPresent()) {
358 processedModifications.add(childIdentifier);
359 Optional<StoreMetadataNode> result = resolveChildOperation(childIdentifier) //
360 .apply(childModification.get(), Optional.of(childMeta), subtreeVersion);
361 nodeBuilder.addIfPresent(result);
363 // Child is unmodified - reuse existing metadata and data
365 nodeBuilder.add(childMeta);
368 return processedModifications.build();
372 protected boolean isSubtreeModificationApplicable(final NodeModification modification,
373 final Optional<StoreMetadataNode> current) {
374 if (false == current.isPresent()) {
377 boolean result = true;
378 StoreMetadataNode currentMeta = current.get();
379 for (NodeModification childMod : modification.getModifications()) {
380 PathArgument childId = childMod.getIdentifier();
381 Optional<StoreMetadataNode> childMeta = currentMeta.getChild(childId);
382 result &= resolveChildOperation(childId).isApplicable(childMod, childMeta);
387 @SuppressWarnings("rawtypes")
388 protected abstract NormalizedNodeContainerBuilder createBuilder(PathArgument identifier);
391 public static abstract class DataNodeContainerModificationStrategy<T extends DataNodeContainer> extends
392 NormalizedNodeContainerModificationStrategy {
394 private final T schema;
395 private final LoadingCache<PathArgument, ModificationApplyOperation> childCache = CacheBuilder.newBuilder()
396 .build(CacheLoader.from(new Function<PathArgument, ModificationApplyOperation>() {
399 public ModificationApplyOperation apply(final PathArgument identifier) {
400 if (identifier instanceof AugmentationIdentifier && schema instanceof AugmentationTarget) {
401 return from(schema, (AugmentationTarget) schema, (AugmentationIdentifier) identifier);
404 DataSchemaNode child = schema.getDataChildByName(identifier.getNodeType());
412 protected DataNodeContainerModificationStrategy(final T schema,
413 final Class<? extends NormalizedNode<?, ?>> nodeClass) {
415 this.schema = schema;
418 protected T getSchema() {
423 public Optional<ModificationApplyOperation> getChild(final PathArgument identifier) {
425 return Optional.<ModificationApplyOperation> fromNullable(childCache.get(identifier));
426 } catch (ExecutionException e) {
427 return Optional.absent();
432 @SuppressWarnings("rawtypes")
433 protected abstract DataContainerNodeBuilder createBuilder(PathArgument identifier);
436 public String toString() {
437 return getClass().getSimpleName() + " [" + schema + "]";
442 public static class ContainerModificationStrategy extends
443 DataNodeContainerModificationStrategy<ContainerSchemaNode> {
445 public ContainerModificationStrategy(final ContainerSchemaNode schemaNode) {
446 super(schemaNode, ContainerNode.class);
450 @SuppressWarnings("rawtypes")
451 protected DataContainerNodeBuilder createBuilder(final PathArgument identifier) {
452 // TODO Auto-generated method stub
453 checkArgument(identifier instanceof NodeIdentifier);
454 return ImmutableContainerNodeBuilder.create().withNodeIdentifier((NodeIdentifier) identifier);
459 public static class UnkeyedListItemModificationStrategy extends
460 DataNodeContainerModificationStrategy<ListSchemaNode> {
462 public UnkeyedListItemModificationStrategy(final ListSchemaNode schemaNode) {
463 super(schemaNode, UnkeyedListEntryNode.class);
467 @SuppressWarnings("rawtypes")
468 protected DataContainerNodeBuilder createBuilder(final PathArgument identifier) {
469 checkArgument(identifier instanceof NodeIdentifier);
470 return ImmutableUnkeyedListEntryNodeBuilder.create().withNodeIdentifier((NodeIdentifier) identifier);
475 public static class AugmentationModificationStrategy extends
476 DataNodeContainerModificationStrategy<AugmentationSchema> {
478 protected AugmentationModificationStrategy(final AugmentationSchema schema, final DataNodeContainer resolved) {
479 super(schema, AugmentationNode.class);
480 // FIXME: Use resolved children instead of unresolved.
485 protected DataContainerNodeBuilder createBuilder(final PathArgument identifier) {
486 return Builders.augmentationBuilder().withNodeIdentifier((AugmentationIdentifier) identifier);
491 public static class ChoiceModificationStrategy extends NormalizedNodeContainerModificationStrategy {
493 private final ChoiceNode schema;
494 private final Map<PathArgument, ModificationApplyOperation> childNodes;
496 public ChoiceModificationStrategy(final ChoiceNode schemaNode) {
497 super(org.opendaylight.yangtools.yang.data.api.schema.ChoiceNode.class);
498 this.schema = schemaNode;
499 ImmutableMap.Builder<PathArgument, ModificationApplyOperation> child = ImmutableMap.builder();
501 for (ChoiceCaseNode caze : schemaNode.getCases()) {
502 for (DataSchemaNode cazeChild : caze.getChildNodes()) {
503 SchemaAwareApplyOperation childNode = from(cazeChild);
504 child.put(new NodeIdentifier(cazeChild.getQName()), childNode);
507 childNodes = child.build();
511 public Optional<ModificationApplyOperation> getChild(final PathArgument child) {
512 return Optional.fromNullable(childNodes.get(child));
516 @SuppressWarnings("rawtypes")
517 protected DataContainerNodeBuilder createBuilder(final PathArgument identifier) {
518 checkArgument(identifier instanceof NodeIdentifier);
519 return ImmutableChoiceNodeBuilder.create().withNodeIdentifier((NodeIdentifier) identifier);
524 public static class ListEntryModificationStrategy extends DataNodeContainerModificationStrategy<ListSchemaNode> {
526 protected ListEntryModificationStrategy(final ListSchemaNode schema) {
527 super(schema, MapEntryNode.class);
531 @SuppressWarnings("rawtypes")
532 protected final DataContainerNodeBuilder createBuilder(final PathArgument identifier) {
533 return ImmutableMapEntryNodeBuilder.create().withNodeIdentifier((NodeIdentifierWithPredicates) identifier);
538 public static class LeafSetModificationStrategy extends NormalizedNodeContainerModificationStrategy {
540 private final Optional<ModificationApplyOperation> entryStrategy;
542 @SuppressWarnings({ "unchecked", "rawtypes" })
543 protected LeafSetModificationStrategy(final LeafListSchemaNode schema) {
544 super((Class) LeafSetNode.class);
545 entryStrategy = Optional.<ModificationApplyOperation> of(new LeafSetEntryModificationStrategy(schema));
548 @SuppressWarnings("rawtypes")
550 protected NormalizedNodeContainerBuilder createBuilder(final PathArgument identifier) {
551 return ImmutableLeafSetNodeBuilder.create().withNodeIdentifier((NodeIdentifier) identifier);
555 public Optional<ModificationApplyOperation> getChild(final PathArgument identifier) {
556 if (identifier instanceof NodeWithValue) {
557 return entryStrategy;
559 return Optional.absent();
564 public static class UnkeyedListModificationStrategy extends SchemaAwareApplyOperation {
566 private final Optional<ModificationApplyOperation> entryStrategy;
568 protected UnkeyedListModificationStrategy(final ListSchemaNode schema) {
569 entryStrategy = Optional.<ModificationApplyOperation> of(new UnkeyedListItemModificationStrategy(schema));
575 protected StoreMetadataNode applySubtreeChange(final NodeModification modification,
576 final StoreMetadataNode currentMeta, final UnsignedLong subtreeVersion) {
577 throw new UnsupportedOperationException("UnkeyedList does not support subtree change.");
581 protected StoreMetadataNode applyWrite(final NodeModification modification,
582 final Optional<StoreMetadataNode> currentMeta, final UnsignedLong subtreeVersion) {
583 return StoreMetadataNode.createRecursively(modification.getWritenValue(), subtreeVersion);
587 public Optional<ModificationApplyOperation> getChild(final PathArgument child) {
588 if (child instanceof NodeIdentifier) {
589 return entryStrategy;
591 return Optional.absent();
595 protected void verifyWritenStructure(final NormalizedNode<?, ?> writenValue) {
600 protected boolean isSubtreeModificationApplicable(final NodeModification modification,
601 final Optional<StoreMetadataNode> current) {
607 public static class UnorderedMapModificationStrategy extends NormalizedNodeContainerModificationStrategy {
609 private final Optional<ModificationApplyOperation> entryStrategy;
611 protected UnorderedMapModificationStrategy(final ListSchemaNode schema) {
612 super(MapNode.class);
613 entryStrategy = Optional.<ModificationApplyOperation> of(new ListEntryModificationStrategy(schema));
616 @SuppressWarnings("rawtypes")
618 protected NormalizedNodeContainerBuilder createBuilder(final PathArgument identifier) {
619 return ImmutableMapNodeBuilder.create().withNodeIdentifier((NodeIdentifier) identifier);
623 public Optional<ModificationApplyOperation> getChild(final PathArgument identifier) {
624 if (identifier instanceof NodeIdentifierWithPredicates) {
625 return entryStrategy;
627 return Optional.absent();
631 public String toString() {
632 return "UnorderedMapModificationStrategy [entry=" + entryStrategy + "]";
636 public static class OrderedMapModificationStrategy extends NormalizedNodeContainerModificationStrategy {
638 private final Optional<ModificationApplyOperation> entryStrategy;
640 protected OrderedMapModificationStrategy(final ListSchemaNode schema) {
641 super(OrderedMapNode.class);
642 entryStrategy = Optional.<ModificationApplyOperation> of(new ListEntryModificationStrategy(schema));
645 @SuppressWarnings("rawtypes")
647 protected NormalizedNodeContainerBuilder createBuilder(final PathArgument identifier) {
648 return ImmutableOrderedMapNodeBuilder.create().withNodeIdentifier((NodeIdentifier) identifier);
652 public Optional<ModificationApplyOperation> getChild(final PathArgument identifier) {
653 if (identifier instanceof NodeIdentifierWithPredicates) {
654 return entryStrategy;
656 return Optional.absent();
660 public String toString() {
661 return "OrderedMapModificationStrategy [entry=" + entryStrategy + "]";
665 public void verifyIdentifier(final PathArgument identifier) {