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