Merge "Bug 2512: Initial design of YANG statement meta-model."
[yangtools.git] / yang / yang-data-impl / src / main / java / org / opendaylight / yangtools / yang / data / impl / ImmutableCompositeNode.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 com.google.common.collect.ImmutableList;
11 import com.google.common.collect.ImmutableMap;
12
13 import java.io.IOException;
14 import java.io.ObjectInputStream;
15 import java.io.ObjectOutputStream;
16 import java.io.Serializable;
17 import java.util.ArrayList;
18 import java.util.Collection;
19 import java.util.Collections;
20 import java.util.HashMap;
21 import java.util.List;
22 import java.util.Map;
23 import java.util.Set;
24
25 import org.opendaylight.yangtools.concepts.Immutable;
26 import org.opendaylight.yangtools.yang.common.QName;
27 import org.opendaylight.yangtools.yang.data.api.AttributesContainer;
28 import org.opendaylight.yangtools.yang.data.api.CompositeNode;
29 import org.opendaylight.yangtools.yang.data.api.ModifyAction;
30 import org.opendaylight.yangtools.yang.data.api.MutableCompositeNode;
31 import org.opendaylight.yangtools.yang.data.api.Node;
32 import org.opendaylight.yangtools.yang.data.api.SimpleNode;
33 import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNodeContainer;
34 import org.opendaylight.yangtools.yang.data.impl.util.AbstractCompositeNodeBuilder;
35 import org.opendaylight.yangtools.yang.data.impl.util.CompositeNodeBuilder;
36
37 /**
38  * @deprecated Use one of the {@link NormalizedNodeContainer} implementations.
39  */
40 @Deprecated
41 public final class ImmutableCompositeNode extends AbstractNodeTO<List<Node<?>>> implements Immutable, CompositeNode, AttributesContainer, Serializable {
42
43     private static final long serialVersionUID = 100L;
44
45     private Map<QName, List<Node<?>>> nodeMap = new HashMap<>();
46
47     private final Map<QName, String> attributes;
48
49
50
51     /**
52      * @param qname
53      * @param parent
54      *            use null to create top composite node (without parent)
55      * @param value
56      */
57     private ImmutableCompositeNode(final QName qname, final Map<QName,String> attributes,final List<Node<?>> value) {
58         super(qname, null, ImmutableList.copyOf(value));
59         if(attributes == null) {
60             this.attributes = ImmutableMap.<QName, String>of();
61         } else {
62             this.attributes = ImmutableMap.copyOf(attributes);
63         }
64         init();
65     }
66
67     /**
68      * @param qname
69      * @param value
70      * @param modifyAction
71      */
72     public ImmutableCompositeNode(final QName qname, final List<Node<?>> value, final ModifyAction modifyAction) {
73         super(qname, null, value, modifyAction);
74         attributes = ImmutableMap.of();
75         init();
76     }
77
78     protected void init() {
79         if (getValue() != null) {
80             nodeMap = NodeUtils.buildNodeMap(getValue());
81         }
82     }
83
84     protected Map<QName, List<Node<?>>> getNodeMap() {
85         return nodeMap;
86     }
87
88     @Override
89     public List<Node<?>> getChildren() {
90         return Collections.unmodifiableList(getValue() == null ? new ArrayList<Node<?>>() : getValue());
91     }
92
93     @Override
94     public SimpleNode<?> getFirstSimpleByName(final QName leafQName) {
95         List<SimpleNode<?>> list = getSimpleNodesByName(leafQName);
96         if (list.isEmpty()) {
97             return null;
98         }
99         return list.get(0);
100     }
101
102     @Override
103     public List<CompositeNode> getCompositesByName(final QName children) {
104         List<Node<?>> toFilter = getNodeMap().get(children);
105         if (toFilter == null) {
106             return Collections.emptyList();
107         }
108         List<CompositeNode> list = new ArrayList<CompositeNode>();
109         for (Node<?> node : toFilter) {
110             if (node instanceof CompositeNode) {
111                 list.add((CompositeNode) node);
112             }
113         }
114         return list;
115     }
116
117     @Override
118     public List<SimpleNode<?>> getSimpleNodesByName(final QName children) {
119         List<Node<?>> toFilter = getNodeMap().get(children);
120         if (toFilter == null) {
121             return Collections.emptyList();
122         }
123         List<SimpleNode<?>> list = new ArrayList<SimpleNode<?>>();
124
125         for (Node<?> node : toFilter) {
126             if (node instanceof SimpleNode<?>) {
127                 list.add((SimpleNode<?>) node);
128             }
129         }
130         return list;
131     }
132
133     @Override
134     public CompositeNode getFirstCompositeByName(final QName container) {
135         List<CompositeNode> list = getCompositesByName(container);
136         if (list.isEmpty()) {
137             return null;
138         }
139         return list.get(0);
140     }
141
142     @Override
143     public Map<QName, String> getAttributes() {
144         return attributes;
145     }
146
147     @Override
148     public String getAttributeValue(final QName key) {
149         return attributes.get(key);
150     }
151
152     /**
153      * @param leaf
154      * @return TODO:: do we need this method?
155      */
156     public SimpleNode<?> getFirstLeafByName(final QName leaf) {
157         List<SimpleNode<?>> list = getSimpleNodesByName(leaf);
158         if (list.isEmpty()) {
159             return null;
160         }
161         return list.get(0);
162     }
163
164     @Override
165     public List<CompositeNode> getCompositesByName(final String children) {
166         return getCompositesByName(QName.create(getNodeType(), children));
167     }
168
169     @Override
170     public List<SimpleNode<?>> getSimpleNodesByName(final String children) {
171         return getSimpleNodesByName(QName.create(getNodeType(), children));
172     }
173
174     @Override
175     public MutableCompositeNode asMutable() {
176         throw new IllegalAccessError("cast to mutable is not supported - " + getClass().getSimpleName());
177     }
178
179     @Override
180     public String toString() {
181         return super.toString() + ", children.size = " + (!getChildren().isEmpty() ? getChildren().size() : "n/a");
182     }
183
184     @Override
185     public void clear() {
186         nodeMap.clear();
187     }
188
189     @Override
190     public boolean containsKey(final Object key) {
191         return nodeMap.containsKey(key);
192     }
193
194     @Override
195     public boolean containsValue(final Object value) {
196         return nodeMap.containsValue(value);
197     }
198
199     @Override
200     public Set<java.util.Map.Entry<QName, List<Node<?>>>> entrySet() {
201         return nodeMap.entrySet();
202     }
203
204     @Override
205     public int size() {
206         return nodeMap.size();
207     }
208
209     @Override
210     public boolean isEmpty() {
211         return nodeMap.isEmpty();
212     }
213
214     @Override
215     public List<Node<?>> get(final Object key) {
216         return nodeMap.get(key);
217     }
218
219     @Override
220     public List<Node<?>> put(final QName key, final List<Node<?>> value) {
221         return nodeMap.put(key, value);
222     }
223
224     @Override
225     public List<Node<?>> remove(final Object key) {
226         return nodeMap.remove(key);
227     }
228
229     @Override
230     public void putAll(final Map<? extends QName, ? extends List<Node<?>>> m) {
231         nodeMap.putAll(m);
232     }
233
234     @Override
235     public Set<QName> keySet() {
236         return nodeMap.keySet();
237     }
238
239     @Override
240     public Collection<List<Node<?>>> values() {
241         return nodeMap.values();
242     }
243
244     // Serialization related
245
246     private void readObject(final ObjectInputStream aStream) throws IOException, ClassNotFoundException {
247         aStream.defaultReadObject();
248         QName qName = (QName) aStream.readObject();
249         CompositeNode parent = (CompositeNode) aStream.readObject();
250         @SuppressWarnings("unchecked")
251         List<Node<?>> value = (List<Node<?>>) aStream.readObject();
252         ModifyAction modifyAction = (ModifyAction) aStream.readObject();
253
254         init(qName, parent, value, modifyAction);
255     }
256
257     private void writeObject(final ObjectOutputStream aStream) throws IOException {
258         aStream.defaultWriteObject();
259         // manually serialize superclass
260         aStream.writeObject(getQName());
261         aStream.writeObject(getParent());
262         aStream.writeObject(getValue());
263         aStream.writeObject(getModificationAction());
264     }
265
266     public static CompositeNodeBuilder<ImmutableCompositeNode> builder() {
267         return new ImmutableCompositeNodeBuilder();
268     }
269
270     private static class ImmutableCompositeNodeBuilder extends AbstractCompositeNodeBuilder<ImmutableCompositeNode> {
271
272         @Override
273         public AbstractCompositeNodeBuilder<ImmutableCompositeNode> addLeaf(final QName leafName, final Object leafValue) {
274             add(new SimpleNodeTOImpl<Object>(leafName, null, leafValue));
275             return this;
276         }
277
278         @Override
279         public ImmutableCompositeNode build() {
280             return ImmutableCompositeNode.create(this.getQName(), this.getAttributes(), this.getChildNodes());
281         }
282
283         @Deprecated
284         public ImmutableCompositeNode toInstance() {
285             return ImmutableCompositeNode.create(this.getQName(), this.getAttributes(), this.getChildNodes());
286         }
287
288     }
289
290     public static ImmutableCompositeNode create(final QName qName, final List<Node<?>> childNodes) {
291         return new ImmutableCompositeNode(qName, ImmutableMap.<QName, String>of(),childNodes);
292     }
293
294     public static ImmutableCompositeNode create(final QName qName, final Map<QName, String> attributes, final List<Node<?>> childNodes) {
295         return new ImmutableCompositeNode(qName, attributes,childNodes);
296     }
297
298     public static ImmutableCompositeNode create(final QName qName, final List<Node<?>> childNodes, final ModifyAction modifyAction) {
299         return new ImmutableCompositeNode(qName, childNodes, modifyAction);
300     }
301 }