1 package org.opendaylight.yangtools.yang.util
3 import org.opendaylight.yangtools.yang.data.api.CompositeNode
4 import org.opendaylight.yangtools.yang.model.api.ContainerSchemaNode
5 import static com.google.common.base.Preconditions.*;
6 import org.opendaylight.yangtools.yang.data.impl.CompositeNodeTOImpl
7 import java.util.ArrayList
9 import org.opendaylight.yangtools.yang.model.api.DataNodeContainer
10 import org.opendaylight.yangtools.yang.model.api.ListSchemaNode
11 import org.opendaylight.yangtools.yang.data.api.Node
12 import org.opendaylight.yangtools.yang.model.api.DataSchemaNode
14 import org.opendaylight.yangtools.yang.model.api.LeafSchemaNode
15 import org.opendaylight.yangtools.yang.model.api.LeafListSchemaNode
16 import java.util.Collections
17 import static extension org.opendaylight.yangtools.yang.util.YangDataUtils.*;
18 import java.util.HashSet
19 import org.opendaylight.yangtools.yang.common.QName
21 class YangDataOperations {
23 static def CompositeNode merge(DataSchemaNode schema, CompositeNode stored, CompositeNode modified, boolean config) {
24 checkConfigurational(schema, config);
25 if (stored === null) {
29 if (schema instanceof ListSchemaNode || schema instanceof ContainerSchemaNode) {
30 return mergeContainer(schema as DataNodeContainer, stored, modified, config);
32 throw new IllegalArgumentException("Supplied node is not data node container.");
35 private def static checkConfigurational(DataSchemaNode node, boolean config) {
37 checkArgument(node.configuration, "Supplied composite node is not configurational.");
41 private static dispatch def Iterable<? extends Node<?>> mergeMultiple(LeafSchemaNode node, List<Node<?>> original,
42 List<Node<?>> modified, boolean configurational) {
43 checkArgument(original.size === 1);
44 checkArgument(modified.size === 1);
45 checkConfigurational(node, configurational);
49 private static dispatch def Iterable<? extends Node<?>> mergeMultiple(LeafListSchemaNode node,
50 List<Node<?>> original, List<Node<?>> modified, boolean configurational) {
54 private static dispatch def Iterable<? extends Node<?>> mergeMultiple(ContainerSchemaNode node,
55 List<Node<?>> original, List<Node<?>> modified, boolean configurational) {
56 checkArgument(original.size === 1);
57 checkArgument(modified.size === 1);
58 return Collections.singletonList(
59 merge(node, original.get(0) as CompositeNode, modified.get(0) as CompositeNode, configurational));
62 private static dispatch def Iterable<? extends Node<?>> mergeMultiple(ListSchemaNode node, List<Node<?>> original,
63 List<Node<?>> modified, boolean configurational) {
64 checkConfigurational(node,configurational);
65 if(node.keyDefinition === null || node.keyDefinition.empty) {
68 val originalMap = (original as List).toIndexMap(node.keyDefinition);
69 val modifiedMap = (modified as List).toIndexMap(node.keyDefinition);
71 val List<Node<?>> mergedNodes = new ArrayList(original.size + modified.size);
72 for(entry : modifiedMap.entrySet) {
73 val originalEntry = originalMap.get(entry.key);
74 if(originalEntry != null) {
75 originalMap.remove(entry.key);
76 mergedNodes.add(merge(node,originalEntry,entry.value,configurational));
80 mergedNodes.addAll(originalMap.values);
84 static private def CompositeNode mergeContainer(DataNodeContainer schema, CompositeNode stored,
85 CompositeNode modified, boolean config) {
90 checkNotNull(modified)
91 checkArgument(stored.nodeType == modified.nodeType);
93 val mergedChildNodes = new ArrayList<Node<?>>(stored.children.size + modified.children.size);
95 val toProcess = new HashSet<QName>(stored.keySet);
96 toProcess.addAll(modified.keySet);
98 for (qname : toProcess) {
99 val schemaChild = schema.getDataChildByName(qname);
100 val storedChildren = stored.get(qname);
101 val modifiedChildren = modified.get(qname);
103 if (modifiedChildren !== null && !modifiedChildren.empty) {
104 if (storedChildren === null || storedChildren.empty || schemaChild === null) {
105 mergedChildNodes.addAll(modifiedChildren);
107 mergedChildNodes.addAll(mergeMultiple(schemaChild, storedChildren, modifiedChildren, config));
109 } else if (storedChildren !== null && !storedChildren.empty) {
110 mergedChildNodes.addAll(storedChildren);
113 return new CompositeNodeTOImpl(stored.nodeType, null, mergedChildNodes);