Merge "Fix for Bug 511 (model + integration-test)"
[yangtools.git] / yang / yang-data-impl / src / main / java / org / opendaylight / yangtools / yang / data / impl / MutableCompositeNodeTOImpl.java
1 /*
2  * Copyright (c) 2013 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.yangtools.yang.data.impl;
9
10 import org.opendaylight.yangtools.yang.common.QName;
11 import org.opendaylight.yangtools.yang.data.api.CompositeNode;
12 import org.opendaylight.yangtools.yang.data.api.ModifyAction;
13 import org.opendaylight.yangtools.yang.data.api.MutableCompositeNode;
14 import org.opendaylight.yangtools.yang.data.api.Node;
15 import org.opendaylight.yangtools.yang.data.api.SimpleNode;
16
17 import java.io.IOException;
18 import java.io.ObjectInputStream;
19 import java.io.ObjectOutputStream;
20 import java.io.Serializable;
21 import java.util.ArrayList;
22 import java.util.Collection;
23 import java.util.Collections;
24 import java.util.HashMap;
25 import java.util.List;
26 import java.util.Map;
27 import java.util.Set;
28
29 /**
30  * @author michal.rehak
31  * 
32  */
33 public class MutableCompositeNodeTOImpl extends AbstractNodeTO<List<Node<?>>> implements MutableCompositeNode, Serializable {
34
35     private static final long serialVersionUID = 100L;
36
37     private Map<QName, List<Node<?>>> nodeMap = new HashMap<>();
38     private CompositeNode original;
39
40     public MutableCompositeNodeTOImpl(QName qname, CompositeNode parent, List<Node<?>> value, ModifyAction modifyAction) {
41         super(qname, parent, value, modifyAction);
42         init();
43     }
44
45     /**
46      * update nodeMap - it should be invoked after children was changed
47      */
48     @Override
49     public void init() {
50         if (!getChildren().isEmpty()) {
51             nodeMap = NodeUtils.buildNodeMap(getChildren());
52         }
53     }
54
55     @Override
56     public List<Node<?>> getChildren() {
57         return getValue() == null ? new ArrayList<Node<?>>() : getValue();
58     }
59
60     @Override
61     public List<Node<?>> setValue(List<Node<?>> value) {
62         List<Node<?>> oldVal = super.setValue(value);
63         init();
64         return oldVal;
65     }
66
67     @Override
68     public void setModifyAction(ModifyAction action) {
69         super.setModificationAction(action);
70     }
71
72     protected Map<QName, List<Node<?>>> getNodeMap() {
73         return nodeMap;
74     }
75
76     @Override
77     public MutableCompositeNode asMutable() {
78         return this;
79     }
80
81     @Override
82     public CompositeNode getOriginal() {
83         return original;
84     }
85
86     /**
87      * @param original
88      *            the original to set
89      */
90     public void setOriginal(CompositeNode original) {
91         this.original = original;
92     }
93
94     @Override
95     public SimpleNode<?> getFirstSimpleByName(QName leafQName) {
96         List<SimpleNode<?>> list = getSimpleNodesByName(leafQName);
97         if (list.isEmpty()) {
98             return null;
99         }
100         return list.get(0);
101     }
102
103     @Override
104     public List<CompositeNode> getCompositesByName(QName children) {
105         List<Node<?>> toFilter = getNodeMap().get(children);
106         if (toFilter == null) {
107             return Collections.emptyList();
108         }
109         List<CompositeNode> list = new ArrayList<CompositeNode>();
110         for (Node<?> node : toFilter) {
111             if (node instanceof CompositeNode) {
112                 list.add((CompositeNode) node);
113             }
114         }
115         return list;
116     }
117
118     @Override
119     public List<SimpleNode<?>> getSimpleNodesByName(QName children) {
120         List<Node<?>> toFilter = getNodeMap().get(children);
121         if (toFilter == null) {
122             return Collections.emptyList();
123         }
124         List<SimpleNode<?>> list = new ArrayList<SimpleNode<?>>();
125
126         for (Node<?> node : toFilter) {
127             if (node instanceof SimpleNode<?>) {
128                 list.add((SimpleNode<?>) node);
129             }
130         }
131         return list;
132     }
133
134     @Override
135     public CompositeNode getFirstCompositeByName(QName container) {
136         List<CompositeNode> list = getCompositesByName(container);
137         if (list.isEmpty()) {
138             return null;
139         }
140         return list.get(0);
141     }
142
143     /**
144      * @param leaf
145      * @return TODO:: do we need this method?
146      */
147     public SimpleNode<?> getFirstLeafByName(QName leaf) {
148         List<SimpleNode<?>> list = getSimpleNodesByName(leaf);
149         if (list.isEmpty()) {
150             return null;
151         }
152         return list.get(0);
153     }
154
155     @Override
156     public List<CompositeNode> getCompositesByName(String children) {
157         return getCompositesByName(new QName(getNodeType(), children));
158     }
159
160     @Override
161     public List<SimpleNode<?>> getSimpleNodesByName(String children) {
162         return getSimpleNodesByName(new QName(getNodeType(), children));
163     }
164
165     @Override
166     public String toString() {
167         return super.toString() + ", children.size = " + (getChildren() != null ? getChildren().size() : "n/a");
168     }
169
170     @Override
171     public void clear() {
172         nodeMap.clear();
173     }
174
175     @Override
176     public boolean containsKey(Object key) {
177         return nodeMap.containsKey(key);
178     }
179
180     @Override
181     public boolean containsValue(Object value) {
182         return nodeMap.containsValue(value);
183     }
184
185     @Override
186     public Set<java.util.Map.Entry<QName, List<Node<?>>>> entrySet() {
187         return nodeMap.entrySet();
188     }
189
190     @Override
191     public boolean equals(Object obj) {
192         return super.equals(obj);
193     }
194
195     @Override
196     public int size() {
197         return nodeMap.size();
198     }
199
200     @Override
201     public boolean isEmpty() {
202         return nodeMap.isEmpty();
203     }
204
205     @Override
206     public List<Node<?>> get(Object key) {
207         return nodeMap.get(key);
208     }
209
210     @Override
211     public List<Node<?>> put(QName key, List<Node<?>> value) {
212         return nodeMap.put(key, value);
213     }
214
215     @Override
216     public List<Node<?>> remove(Object key) {
217         return nodeMap.remove(key);
218     }
219
220     @Override
221     public void putAll(Map<? extends QName, ? extends List<Node<?>>> m) {
222         nodeMap.putAll(m);
223     }
224
225     @Override
226     public Set<QName> keySet() {
227         return nodeMap.keySet();
228     }
229
230     @Override
231     public Collection<List<Node<?>>> values() {
232         return nodeMap.values();
233     }
234
235   // Serialization related
236
237     private void readObject(ObjectInputStream aStream) throws IOException, ClassNotFoundException {
238         aStream.defaultReadObject();
239         QName qName = (QName)aStream.readObject();
240         CompositeNode parent = (CompositeNode) aStream.readObject();
241         List<Node<?>> value = (List<Node<?>>) aStream.readObject();
242         ModifyAction modifyAction = (ModifyAction) aStream.readObject();
243
244         init(qName, parent, value, modifyAction);
245     }
246
247     private void writeObject(ObjectOutputStream aStream) throws IOException {
248         aStream.defaultWriteObject();
249         //manually serialize superclass
250         aStream.writeObject(getQName());
251         aStream.writeObject(getParent());
252         aStream.writeObject(getValue());
253         aStream.writeObject(getModificationAction());
254     }
255 }