2 * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved.
4 * This program and the accompanying materials are made available under the
5 * terms of the Eclipse Public License v1.0 which accompanies this distribution,
6 * and is available at http://www.eclipse.org/legal/epl-v10.html
9 package org.opendaylight.yangtools.yang.data.operations;
11 import com.google.common.base.Optional;
12 import com.google.common.collect.Maps;
14 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
15 import org.opendaylight.yangtools.yang.data.api.schema.MapEntryNode;
16 import org.opendaylight.yangtools.yang.data.api.schema.MapNode;
17 import org.opendaylight.yangtools.yang.data.impl.schema.Builders;
18 import org.opendaylight.yangtools.yang.data.impl.schema.builder.api.CollectionNodeBuilder;
19 import org.opendaylight.yangtools.yang.model.api.ListSchemaNode;
21 public class MapNodeModification implements Modification<ListSchemaNode, MapNode> {
23 public static final MapEntryNodeModification MAP_ENTRY_NODE_MODIFICATION = new MapEntryNodeModification();
26 public Optional<MapNode> modify(ListSchemaNode schema, Optional<MapNode> actual,
27 Optional<MapNode> modification, OperationStack operationStack) throws DataModificationException {
29 // Merge or None operation on parent, leaving actual if modification not present
30 if (!modification.isPresent()) {
34 Map<YangInstanceIdentifier.NodeIdentifierWithPredicates, MapEntryNode> resultNodes = Maps.newLinkedHashMap();
35 if(actual.isPresent()) {
36 resultNodes.putAll(mapEntries(actual.get()));
39 // TODO implement ordering for modification nodes
41 for (MapEntryNode mapEntryModification : modification.get().getValue()) {
43 operationStack.enteringNode(mapEntryModification);
45 YangInstanceIdentifier.NodeIdentifierWithPredicates entryKey = mapEntryModification.getIdentifier();
47 switch (operationStack.getCurrentOperation()) {
49 DataModificationException.DataMissingException.check(schema.getQName(), actual, mapEntryModification);
51 MapEntryNode mergedListNode;
52 if (resultNodes.containsKey(entryKey)) {
53 MapEntryNode actualEntry = resultNodes.get(entryKey);
54 mergedListNode = MAP_ENTRY_NODE_MODIFICATION.modify(schema, Optional.of(actualEntry), Optional.of(mapEntryModification), operationStack).get();
56 mergedListNode = mapEntryModification;
59 resultNodes.put(mergedListNode.getIdentifier(), mergedListNode);
63 DataModificationException.DataExistsException.check(schema.getQName(), actual, mapEntryModification);
66 resultNodes.put(entryKey, mapEntryModification);
70 DataModificationException.DataMissingException.check(schema.getQName(), actual, mapEntryModification);
73 if (resultNodes.containsKey(entryKey)) {
74 resultNodes.remove(entryKey);
79 throw new UnsupportedOperationException(String.format("Unable to perform operation: %s on: %s, unknown", operationStack.getCurrentOperation(), schema));
82 operationStack.exitingNode(mapEntryModification);
84 return build(schema, resultNodes);
87 private Optional<MapNode> build(ListSchemaNode schema, Map<YangInstanceIdentifier.NodeIdentifierWithPredicates, MapEntryNode> resultNodes) {
88 if(resultNodes.isEmpty()) {
89 return Optional.absent();
92 CollectionNodeBuilder<MapEntryNode, MapNode> b = Builders.mapBuilder(schema);
94 for (MapEntryNode child : resultNodes.values()) {
98 return Optional.of(b.build());
101 private Map<YangInstanceIdentifier.NodeIdentifierWithPredicates, MapEntryNode> mapEntries(MapNode mapNode) {
102 Map<YangInstanceIdentifier.NodeIdentifierWithPredicates, MapEntryNode> mapped = Maps.newLinkedHashMap();
104 for (MapEntryNode mapEntryNode : mapNode.getValue()) {
105 mapped.put(mapEntryNode.getIdentifier(), mapEntryNode);