2 * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved.
\r
4 * This program and the accompanying materials are made available under the
\r
5 * terms of the Eclipse Public License v1.0 which accompanies this distribution,
\r
6 * and is available at http://www.eclipse.org/legal/epl-v10.html
\r
8 package org.opendaylight.yangtools.yang.data.impl;
\r
10 import java.util.HashSet;
\r
11 import java.util.List;
\r
12 import java.util.Map;
\r
13 import java.util.Set;
\r
15 import org.opendaylight.yangtools.yang.common.QName;
\r
16 import org.opendaylight.yangtools.yang.data.api.CompositeNode;
\r
17 import org.opendaylight.yangtools.yang.data.api.ModifyAction;
\r
18 import org.opendaylight.yangtools.yang.data.api.MutableCompositeNode;
\r
19 import org.opendaylight.yangtools.yang.data.api.MutableNode;
\r
20 import org.opendaylight.yangtools.yang.data.api.MutableSimpleNode;
\r
21 import org.opendaylight.yangtools.yang.data.api.Node;
\r
22 import org.opendaylight.yangtools.yang.data.api.NodeModificationBuilder;
\r
23 import org.opendaylight.yangtools.yang.model.api.ListSchemaNode;
\r
24 import org.opendaylight.yangtools.yang.model.api.SchemaContext;
\r
27 * @author michal.rehak
\r
30 public class NodeModificationBuilderImpl implements NodeModificationBuilder {
\r
32 private SchemaContext context;
\r
34 private Set<MutableNode<?>> changeLog;
\r
35 private LazyNodeToNodeMap originalToMutable;
\r
38 * @param originalTreeRootNode
\r
41 public NodeModificationBuilderImpl(CompositeNode originalTreeRootNode, SchemaContext context) {
\r
42 this.context = context;
\r
43 originalToMutable = new LazyNodeToNodeMap();
\r
44 changeLog = new HashSet<>();
\r
51 private void addModificationToLog(MutableNode<?> modNode, ModifyAction action) {
\r
52 modNode.setModifyAction(action);
\r
53 changeLog.add(modNode);
\r
57 public void addNode(MutableSimpleNode<?> newNode) {
\r
58 NodeUtils.fixParentRelation(newNode);
\r
59 addModificationToLog(newNode, ModifyAction.CREATE);
\r
63 public void addNode(MutableCompositeNode newNode) {
\r
64 NodeUtils.fixParentRelation(newNode);
\r
65 addModificationToLog(newNode, ModifyAction.CREATE);
\r
69 public void replaceNode(MutableSimpleNode<?> replacementNode) {
\r
70 addModificationToLog(replacementNode, ModifyAction.REPLACE);
\r
74 public void replaceNode(MutableCompositeNode replacementNode) {
\r
75 addModificationToLog(replacementNode, ModifyAction.REPLACE);
\r
79 public void deleteNode(MutableCompositeNode deadNode) {
\r
80 addModificationToLog(deadNode, ModifyAction.DELETE);
\r
84 public void deleteNode(MutableSimpleNode<?> deadNode) {
\r
85 addModificationToLog(deadNode, ModifyAction.DELETE);
\r
89 public void removeNode(MutableSimpleNode<?> deadNode) {
\r
90 addModificationToLog(deadNode, ModifyAction.REMOVE);
\r
94 public void removeNode(MutableCompositeNode deadNode) {
\r
95 addModificationToLog(deadNode, ModifyAction.REMOVE);
\r
99 public void mergeNode(MutableCompositeNode alteredNode) {
\r
100 addModificationToLog(alteredNode, ModifyAction.MERGE);
\r
104 * @return minimalistic tree containing diffs only
\r
107 public CompositeNode buildDiffTree() {
\r
108 Set<Node<?>> wanted = new HashSet<>();
\r
110 // walk changeLog, collect all required nodes
\r
111 for (MutableNode<?> mutant : changeLog) {
\r
112 wanted.addAll(collectSelfAndAllParents(mutant));
\r
115 // walk wanted and add relevant keys
\r
116 Map<String, ListSchemaNode> mapOfLists = NodeUtils.buildMapOfListNodes(context);
\r
117 for (Node<?> outlaw : wanted) {
\r
118 if (outlaw instanceof CompositeNode) {
\r
119 String path = NodeUtils.buildPath(outlaw);
\r
120 if (mapOfLists.containsKey(path)) {
\r
121 ListSchemaNode listSchema = mapOfLists.get(path);
\r
122 if (listSchema.getQName().equals(outlaw.getNodeType())) {
\r
123 // try to add key subnode to wanted list
\r
124 List<QName> supportedKeys = listSchema.getKeyDefinition();
\r
125 CompositeNode outlawOriginal = ((MutableCompositeNode) outlaw).getOriginal();
\r
126 for (Node<?> outlawOriginalChild : outlawOriginal.getChildren()) {
\r
127 if (supportedKeys.contains(outlawOriginalChild.getNodeType())) {
\r
128 originalToMutable.getMutableEquivalent(outlawOriginalChild);
\r
136 return originalToMutable.getMutableRoot();
\r
140 * @param focusedDescendant
\r
141 * @return set of parents and focusedAncestor itself
\r
143 private static Set<Node<?>> collectSelfAndAllParents(Node<?> focusedDescendant) {
\r
144 Set<Node<?>> family = new HashSet<>();
\r
145 Node<?> tmpNode = focusedDescendant;
\r
146 while (tmpNode != null) {
\r
147 family.add(tmpNode);
\r
148 tmpNode = tmpNode.getParent();
\r
154 * @param originalNode
\r
155 * @return mutable version of given node
\r
158 public Node<?> getMutableEquivalent(Node<?> originalNode) {
\r
159 return originalToMutable.getMutableEquivalent(originalNode);
\r