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.impl;
10 import java.util.HashSet;
11 import java.util.List;
15 import org.opendaylight.yangtools.yang.common.QName;
16 import org.opendaylight.yangtools.yang.data.api.CompositeNode;
17 import org.opendaylight.yangtools.yang.data.api.ModifyAction;
18 import org.opendaylight.yangtools.yang.data.api.MutableCompositeNode;
19 import org.opendaylight.yangtools.yang.data.api.MutableNode;
20 import org.opendaylight.yangtools.yang.data.api.MutableSimpleNode;
21 import org.opendaylight.yangtools.yang.data.api.Node;
22 import org.opendaylight.yangtools.yang.data.api.NodeModificationBuilder;
23 import org.opendaylight.yangtools.yang.model.api.ListSchemaNode;
24 import org.opendaylight.yangtools.yang.model.api.SchemaContext;
27 * @author michal.rehak
30 public class NodeModificationBuilderImpl implements NodeModificationBuilder {
32 private final SchemaContext context;
34 private final Set<MutableNode<?>> changeLog;
35 private final LazyNodeToNodeMap originalToMutable;
40 public NodeModificationBuilderImpl(final SchemaContext context) {
41 this.context = context;
42 originalToMutable = new LazyNodeToNodeMap();
43 changeLog = new HashSet<>();
50 private void addModificationToLog(final MutableNode<?> modNode, final ModifyAction action) {
51 modNode.setModifyAction(action);
52 changeLog.add(modNode);
56 public void addNode(final MutableSimpleNode<?> newNode) {
57 NodeUtils.fixParentRelation(newNode);
58 addModificationToLog(newNode, ModifyAction.CREATE);
62 public void addNode(final MutableCompositeNode newNode) {
63 NodeUtils.fixParentRelation(newNode);
64 addModificationToLog(newNode, ModifyAction.CREATE);
68 public void replaceNode(final MutableSimpleNode<?> replacementNode) {
69 addModificationToLog(replacementNode, ModifyAction.REPLACE);
73 public void replaceNode(final MutableCompositeNode replacementNode) {
74 addModificationToLog(replacementNode, ModifyAction.REPLACE);
78 public void deleteNode(final MutableCompositeNode deadNode) {
79 addModificationToLog(deadNode, ModifyAction.DELETE);
83 public void deleteNode(final MutableSimpleNode<?> deadNode) {
84 addModificationToLog(deadNode, ModifyAction.DELETE);
88 public void removeNode(final MutableSimpleNode<?> deadNode) {
89 addModificationToLog(deadNode, ModifyAction.REMOVE);
93 public void removeNode(final MutableCompositeNode deadNode) {
94 addModificationToLog(deadNode, ModifyAction.REMOVE);
98 public void mergeNode(final MutableCompositeNode alteredNode) {
99 addModificationToLog(alteredNode, ModifyAction.MERGE);
103 * @return minimalistic tree containing diffs only
106 public CompositeNode buildDiffTree() {
107 Set<Node<?>> wanted = new HashSet<>();
109 // walk changeLog, collect all required nodes
110 for (MutableNode<?> mutant : changeLog) {
111 wanted.addAll(collectSelfAndAllParents(mutant));
114 // walk wanted and add relevant keys
115 Map<String, ListSchemaNode> mapOfLists = NodeUtils.buildMapOfListNodes(context);
116 for (Node<?> outlaw : wanted) {
117 if (outlaw instanceof CompositeNode) {
118 String path = NodeUtils.buildPath(outlaw);
119 if (mapOfLists.containsKey(path)) {
120 ListSchemaNode listSchema = mapOfLists.get(path);
121 if (listSchema.getQName().equals(outlaw.getNodeType())) {
122 // try to add key subnode to wanted list
123 List<QName> supportedKeys = listSchema.getKeyDefinition();
124 CompositeNode outlawOriginal = ((MutableCompositeNode) outlaw).getOriginal();
125 for (Node<?> outlawOriginalChild : outlawOriginal.getValue()) {
126 if (supportedKeys.contains(outlawOriginalChild.getNodeType())) {
127 originalToMutable.getMutableEquivalent(outlawOriginalChild);
135 return originalToMutable.getMutableRoot();
139 * @param focusedDescendant
140 * @return set of parents and focusedAncestor itself
142 private static Set<Node<?>> collectSelfAndAllParents(final Node<?> focusedDescendant) {
143 Set<Node<?>> family = new HashSet<>();
144 Node<?> tmpNode = focusedDescendant;
145 while (tmpNode != null) {
147 tmpNode = tmpNode.getParent();
153 * @param originalNode
154 * @return mutable version of given node
157 public Node<?> getMutableEquivalent(final Node<?> originalNode) {
158 return originalToMutable.getMutableEquivalent(originalNode);