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
8 package org.opendaylight.yangtools.yang.data.operations;
12 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
13 import org.opendaylight.yangtools.yang.data.api.schema.MapEntryNode;
14 import org.opendaylight.yangtools.yang.data.api.schema.MapNode;
15 import org.opendaylight.yangtools.yang.data.impl.schema.Builders;
16 import org.opendaylight.yangtools.yang.data.impl.schema.builder.api.CollectionNodeBuilder;
17 import org.opendaylight.yangtools.yang.model.api.ListSchemaNode;
19 import com.google.common.base.Optional;
20 import com.google.common.collect.Maps;
22 public class MapNodeModification implements Modification<ListSchemaNode, MapNode> {
24 public static final MapEntryNodeModification MAP_ENTRY_NODE_MODIFICATION = new MapEntryNodeModification();
27 public Optional<MapNode> modify(ListSchemaNode schema, Optional<MapNode> actual,
28 Optional<MapNode> modification, OperationStack operationStack) throws DataModificationException {
30 // Merge or None operation on parent, leaving actual if modification not present
31 if (modification.isPresent() == false)
34 Map<YangInstanceIdentifier.NodeIdentifierWithPredicates, MapEntryNode> resultNodes = Maps.newLinkedHashMap();
35 if(actual.isPresent())
36 resultNodes.putAll(mapEntries(actual.get()));
38 // TODO implement ordering for modification nodes
40 for (MapEntryNode mapEntryModification : modification.get().getValue()) {
42 operationStack.enteringNode(mapEntryModification);
44 YangInstanceIdentifier.NodeIdentifierWithPredicates entryKey = mapEntryModification.getIdentifier();
46 switch (operationStack.getCurrentOperation()) {
48 DataModificationException.DataMissingException.check(schema.getQName(), actual, mapEntryModification);
50 MapEntryNode mergedListNode;
51 if (resultNodes.containsKey(entryKey)) {
52 MapEntryNode actualEntry = resultNodes.get(entryKey);
53 mergedListNode = MAP_ENTRY_NODE_MODIFICATION.modify(schema, Optional.of(actualEntry), Optional.of(mapEntryModification), operationStack).get();
55 mergedListNode = mapEntryModification;
58 resultNodes.put(mergedListNode.getIdentifier(), mergedListNode);
62 DataModificationException.DataExistsException.check(schema.getQName(), actual, mapEntryModification);
65 resultNodes.put(entryKey, mapEntryModification);
69 DataModificationException.DataMissingException.check(schema.getQName(), actual, mapEntryModification);
72 if (resultNodes.containsKey(entryKey)) {
73 resultNodes.remove(entryKey);
78 throw new UnsupportedOperationException(String.format("Unable to perform operation: %s on: %s, unknown", operationStack.getCurrentOperation(), schema));
81 operationStack.exitingNode(mapEntryModification);
83 return build(schema, resultNodes);
86 private Optional<MapNode> build(ListSchemaNode schema, Map<YangInstanceIdentifier.NodeIdentifierWithPredicates, MapEntryNode> resultNodes) {
87 if(resultNodes.isEmpty())
88 return Optional.absent();
90 CollectionNodeBuilder<MapEntryNode, MapNode> b = Builders.mapBuilder(schema);
92 for (MapEntryNode child : resultNodes.values()) {
96 return Optional.of(b.build());
99 private Map<YangInstanceIdentifier.NodeIdentifierWithPredicates, MapEntryNode> mapEntries(MapNode mapNode) {
100 Map<YangInstanceIdentifier.NodeIdentifierWithPredicates, MapEntryNode> mapped = Maps.newLinkedHashMap();
102 for (MapEntryNode mapEntryNode : mapNode.getValue()) {
103 mapped.put(mapEntryNode.getIdentifier(), mapEntryNode);