BUG-692 Improve log message when negotiation fails
[controller.git] / opendaylight / md-sal / sal-dom-broker / src / main / java / org / opendaylight / controller / sal / dom / broker / util / YangDataOperations.java
1 /*
2  * Copyright (c) 2014 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 package org.opendaylight.controller.sal.dom.broker.util;
9
10 import static com.google.common.base.Preconditions.checkArgument;
11
12 import java.util.ArrayList;
13 import java.util.Arrays;
14 import java.util.Collections;
15 import java.util.HashSet;
16 import java.util.List;
17 import java.util.Map;
18 import java.util.Objects;
19 import java.util.Set;
20
21 import org.opendaylight.yangtools.yang.common.QName;
22 import org.opendaylight.yangtools.yang.data.api.CompositeNode;
23 import org.opendaylight.yangtools.yang.data.api.Node;
24 import org.opendaylight.yangtools.yang.data.impl.CompositeNodeTOImpl;
25 import org.opendaylight.yangtools.yang.model.api.ContainerSchemaNode;
26 import org.opendaylight.yangtools.yang.model.api.DataNodeContainer;
27 import org.opendaylight.yangtools.yang.model.api.DataSchemaNode;
28 import org.opendaylight.yangtools.yang.model.api.LeafListSchemaNode;
29 import org.opendaylight.yangtools.yang.model.api.LeafSchemaNode;
30 import org.opendaylight.yangtools.yang.model.api.ListSchemaNode;
31
32 import com.google.common.base.Preconditions;
33 import com.google.common.collect.Iterables;
34
35 public class YangDataOperations {
36
37     public static CompositeNode merge(final DataSchemaNode schema,
38             final CompositeNode stored, final CompositeNode modified,
39             final boolean config) {
40         if (stored == null) {
41             return modified;
42         }
43
44         Preconditions.checkArgument(schema instanceof ListSchemaNode
45                 || schema instanceof ContainerSchemaNode,
46                 "Supplied node is not data node container.");
47
48         return YangDataOperations.mergeContainer((DataNodeContainer) schema,
49                 stored, modified, config);
50     }
51
52     private static Iterable<? extends Node<?>> _mergeMultiple(
53             final LeafSchemaNode node, final List<Node<?>> original,
54             final List<Node<?>> modified, final boolean configurational) {
55         checkArgument(original.size() == 1);
56         checkArgument(modified.size() == 1);
57
58         return modified;
59     }
60
61     private static Iterable<? extends Node<?>> _mergeMultiple(
62             final LeafListSchemaNode node, final List<Node<?>> original,
63             final List<Node<?>> modified, final boolean configurational) {
64         return modified;
65     }
66
67     private static Iterable<? extends Node<?>> _mergeMultiple(
68             final ContainerSchemaNode node, final List<Node<?>> original,
69             final List<Node<?>> modified, final boolean configurational) {
70         checkArgument(original.size() == 1);
71         checkArgument(modified.size() == 1);
72         return Collections.singletonList(merge(node,
73                 (CompositeNode) original.get(0),
74                 (CompositeNode) modified.get(0), configurational));
75     }
76
77     private static Iterable<? extends Node<?>> _mergeMultiple(
78             final ListSchemaNode node, final List<Node<?>> original,
79             final List<Node<?>> modified, final boolean configurational) {
80
81         if (node.getKeyDefinition() == null
82                 || node.getKeyDefinition().isEmpty()) {
83             return modified;
84         }
85         @SuppressWarnings({ "unchecked", "rawtypes" })
86         final Map<Map<QName, Object>, CompositeNode> originalMap = YangDataUtils
87                 .toIndexMap((List) original, node.getKeyDefinition());
88         @SuppressWarnings({ "unchecked", "rawtypes" })
89         final Map<Map<QName, Object>, CompositeNode> modifiedMap = YangDataUtils
90                 .toIndexMap((List) modified, node.getKeyDefinition());
91
92         final List<Node<?>> mergedNodes = new ArrayList<Node<?>>(
93                 original.size() + modified.size());
94         for (final Map.Entry<Map<QName, Object>, CompositeNode> entry : modifiedMap
95                 .entrySet()) {
96             final CompositeNode originalEntry = originalMap.get(entry.getKey());
97             if (originalEntry != null) {
98                 originalMap.remove(entry.getKey());
99                 mergedNodes.add(merge(node, originalEntry, entry.getValue(),
100                         configurational));
101             } else {
102                 mergedNodes.add(entry.getValue());
103             }
104         }
105         mergedNodes.addAll(originalMap.values());
106         return mergedNodes;
107     }
108
109     private static Iterable<? extends Node<?>> mergeMultiple(
110             final DataSchemaNode node, final List<Node<?>> original,
111             final List<Node<?>> modified, final boolean configurational) {
112         if (node instanceof ContainerSchemaNode) {
113             return _mergeMultiple((ContainerSchemaNode) node, original,
114                     modified, configurational);
115         } else if (node instanceof LeafListSchemaNode) {
116             return _mergeMultiple((LeafListSchemaNode) node, original,
117                     modified, configurational);
118         } else if (node instanceof LeafSchemaNode) {
119             return _mergeMultiple((LeafSchemaNode) node, original, modified,
120                     configurational);
121         } else if (node instanceof ListSchemaNode) {
122             return _mergeMultiple((ListSchemaNode) node, original, modified,
123                     configurational);
124         } else {
125             throw new IllegalArgumentException("Unhandled parameter types: "
126                     + Arrays.<Object> asList(node, original, modified,
127                             configurational).toString());
128         }
129     }
130
131     private static CompositeNode mergeContainer(final DataNodeContainer schema,
132             final CompositeNode stored, final CompositeNode modified,
133             final boolean config) {
134         if (stored == null) {
135             return modified;
136         }
137         Preconditions.checkNotNull(stored);
138         Preconditions.checkNotNull(modified);
139         Preconditions.checkArgument(Objects.equals(stored.getNodeType(),
140                 modified.getNodeType()));
141
142         final List<Node<?>> mergedChildNodes = new ArrayList<Node<?>>(stored
143                 .getChildren().size() + modified.getChildren().size());
144         final Set<QName> toProcess = new HashSet<QName>(stored.keySet());
145         toProcess.addAll(modified.keySet());
146
147         for (QName qname : toProcess) {
148             final DataSchemaNode schemaChild = schema.getDataChildByName(qname);
149             final List<Node<?>> storedChildren = stored.get(qname);
150             final List<Node<?>> modifiedChildren = modified.get(qname);
151
152             if (modifiedChildren != null && !modifiedChildren.isEmpty()) {
153                 if (storedChildren == null || storedChildren.isEmpty()
154                         || schemaChild == null) {
155                     mergedChildNodes.addAll(modifiedChildren);
156                 } else {
157                     final Iterable<? extends Node<?>> _mergeMultiple = mergeMultiple(
158                             schemaChild, storedChildren, modifiedChildren,
159                             config);
160                     Iterables.addAll(mergedChildNodes, _mergeMultiple);
161                 }
162             } else if (storedChildren != null && !storedChildren.isEmpty()) {
163                 mergedChildNodes.addAll(storedChildren);
164             }
165         }
166         return new CompositeNodeTOImpl(stored.getNodeType(), null,
167                 mergedChildNodes);
168     }
169 }