2 * Copyright (c) 2014 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.controller.sal.dom.broker.util
10 import org.opendaylight.yangtools.yang.data.api.CompositeNode
11 import org.opendaylight.yangtools.yang.model.api.ContainerSchemaNode
12 import static com.google.common.base.Preconditions.*;
13 import org.opendaylight.yangtools.yang.data.impl.CompositeNodeTOImpl
14 import java.util.ArrayList
16 import org.opendaylight.yangtools.yang.model.api.DataNodeContainer
17 import org.opendaylight.yangtools.yang.model.api.ListSchemaNode
18 import org.opendaylight.yangtools.yang.data.api.Node
19 import org.opendaylight.yangtools.yang.model.api.DataSchemaNode
21 import org.opendaylight.yangtools.yang.model.api.LeafSchemaNode
22 import org.opendaylight.yangtools.yang.model.api.LeafListSchemaNode
23 import java.util.Collections
24 import java.util.HashSet
25 import org.opendaylight.yangtools.yang.common.QName
26 import static extension org.opendaylight.controller.sal.dom.broker.util.YangDataUtils.*;
28 class YangDataOperations {
30 static def CompositeNode merge(DataSchemaNode schema, CompositeNode stored, CompositeNode modified, boolean config) {
31 if (stored === null) {
35 if (schema instanceof ListSchemaNode || schema instanceof ContainerSchemaNode) {
36 return mergeContainer(schema as DataNodeContainer, stored, modified, config);
38 throw new IllegalArgumentException("Supplied node is not data node container.");
41 private def static checkConfigurational(DataSchemaNode node, boolean config) {
43 checkArgument(node.configuration, "Supplied composite node is not configurational.");
47 private static dispatch def Iterable<? extends Node<?>> mergeMultiple(LeafSchemaNode node, List<Node<?>> original,
48 List<Node<?>> modified, boolean configurational) {
49 checkArgument(original.size === 1);
50 checkArgument(modified.size === 1);
55 private static dispatch def Iterable<? extends Node<?>> mergeMultiple(LeafListSchemaNode node,
56 List<Node<?>> original, List<Node<?>> modified, boolean configurational) {
60 private static dispatch def Iterable<? extends Node<?>> mergeMultiple(ContainerSchemaNode node,
61 List<Node<?>> original, List<Node<?>> modified, boolean configurational) {
62 checkArgument(original.size === 1);
63 checkArgument(modified.size === 1);
64 return Collections.singletonList(
65 merge(node, original.get(0) as CompositeNode, modified.get(0) as CompositeNode, configurational));
68 private static dispatch def Iterable<? extends Node<?>> mergeMultiple(ListSchemaNode node, List<Node<?>> original,
69 List<Node<?>> modified, boolean configurational) {
71 if(node.keyDefinition === null || node.keyDefinition.empty) {
74 val originalMap = (original as List).toIndexMap(node.keyDefinition);
75 val modifiedMap = (modified as List).toIndexMap(node.keyDefinition);
77 val List<Node<?>> mergedNodes = new ArrayList(original.size + modified.size);
78 for(entry : modifiedMap.entrySet) {
79 val originalEntry = originalMap.get(entry.key);
80 if(originalEntry != null) {
81 originalMap.remove(entry.key);
82 mergedNodes.add(merge(node,originalEntry,entry.value,configurational));
84 mergedNodes.add(entry.value);
87 mergedNodes.addAll(originalMap.values);
91 static private def CompositeNode mergeContainer(DataNodeContainer schema, CompositeNode stored,
92 CompositeNode modified, boolean config) {
97 checkNotNull(modified)
98 checkArgument(stored.nodeType == modified.nodeType);
100 val mergedChildNodes = new ArrayList<Node<?>>(stored.children.size + modified.children.size);
102 val toProcess = new HashSet<QName>(stored.keySet);
103 toProcess.addAll(modified.keySet);
105 for (qname : toProcess) {
106 val schemaChild = schema.getDataChildByName(qname);
107 val storedChildren = stored.get(qname);
108 val modifiedChildren = modified.get(qname);
110 if (modifiedChildren !== null && !modifiedChildren.empty) {
111 if (storedChildren === null || storedChildren.empty || schemaChild === null) {
112 mergedChildNodes.addAll(modifiedChildren);
114 mergedChildNodes.addAll(mergeMultiple(schemaChild, storedChildren, modifiedChildren, config));
116 } else if (storedChildren !== null && !storedChildren.empty) {
117 mergedChildNodes.addAll(storedChildren);
120 return new CompositeNodeTOImpl(stored.nodeType, null, mergedChildNodes);