Clean YangStatementParserListenerImpl up
[yangtools.git] / yang / yang-data-operations / src / main / java / org / opendaylight / yangtools / yang / data / operations / MapNodeModification.java
1 /*
2  * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.
3  *
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
7  */
8
9 package org.opendaylight.yangtools.yang.data.operations;
10
11 import com.google.common.base.Optional;
12 import com.google.common.collect.Maps;
13 import java.util.Map;
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;
20
21 public class MapNodeModification implements Modification<ListSchemaNode, MapNode> {
22
23     public static final MapEntryNodeModification MAP_ENTRY_NODE_MODIFICATION = new MapEntryNodeModification();
24
25     @Override
26     public Optional<MapNode> modify(ListSchemaNode schema, Optional<MapNode> actual,
27                                     Optional<MapNode> modification, OperationStack operationStack) throws DataModificationException {
28
29         // Merge or None operation on parent, leaving actual if modification not present
30         if (!modification.isPresent()) {
31             return actual;
32         }
33
34         Map<YangInstanceIdentifier.NodeIdentifierWithPredicates, MapEntryNode> resultNodes = Maps.newLinkedHashMap();
35         if(actual.isPresent()) {
36             resultNodes.putAll(mapEntries(actual.get()));
37         }
38
39         // TODO implement ordering for modification nodes
40
41         for (MapEntryNode mapEntryModification : modification.get().getValue()) {
42
43             operationStack.enteringNode(mapEntryModification);
44
45             YangInstanceIdentifier.NodeIdentifierWithPredicates entryKey = mapEntryModification.getIdentifier();
46
47             switch (operationStack.getCurrentOperation()) {
48             case NONE:
49                 DataModificationException.DataMissingException.check(schema.getQName(), actual, mapEntryModification);
50             case MERGE: {
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();
55                 } else {
56                     mergedListNode = mapEntryModification;
57                 }
58
59                 resultNodes.put(mergedListNode.getIdentifier(), mergedListNode);
60                 break;
61             }
62             case CREATE: {
63                 DataModificationException.DataExistsException.check(schema.getQName(), actual, mapEntryModification);
64             }
65             case REPLACE: {
66                 resultNodes.put(entryKey, mapEntryModification);
67                 break;
68             }
69             case DELETE: {
70                 DataModificationException.DataMissingException.check(schema.getQName(), actual, mapEntryModification);
71             }
72             case REMOVE: {
73                 if (resultNodes.containsKey(entryKey)) {
74                     resultNodes.remove(entryKey);
75                 }
76                 break;
77             }
78             default:
79                 throw new UnsupportedOperationException(String.format("Unable to perform operation: %s on: %s, unknown", operationStack.getCurrentOperation(), schema));
80             }
81
82             operationStack.exitingNode(mapEntryModification);
83         }
84         return build(schema, resultNodes);
85     }
86
87     private Optional<MapNode> build(ListSchemaNode schema, Map<YangInstanceIdentifier.NodeIdentifierWithPredicates, MapEntryNode> resultNodes) {
88         if(resultNodes.isEmpty()) {
89             return Optional.absent();
90         }
91
92         CollectionNodeBuilder<MapEntryNode, MapNode> b = Builders.mapBuilder(schema);
93
94         for (MapEntryNode child : resultNodes.values()) {
95             b.withChild(child);
96         }
97
98         return Optional.of(b.build());
99     }
100
101     private Map<YangInstanceIdentifier.NodeIdentifierWithPredicates, MapEntryNode> mapEntries(MapNode mapNode) {
102         Map<YangInstanceIdentifier.NodeIdentifierWithPredicates, MapEntryNode> mapped = Maps.newLinkedHashMap();
103
104         for (MapEntryNode mapEntryNode : mapNode.getValue()) {
105             mapped.put(mapEntryNode.getIdentifier(), mapEntryNode);
106         }
107
108         return mapped;
109     }
110
111 }