51239575fd5410c9f4c733b9f47e3d6c2c0dc7ea
[yangtools.git] / yang / yang-parser-impl / src / main / java / org / opendaylight / yangtools / yang / parser / builder / impl / GroupingBuilderImpl.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.parser.builder.impl;
9
10 import java.net.URI;
11 import java.util.Date;
12 import java.util.HashSet;
13 import java.util.List;
14 import java.util.Set;
15
16 import org.opendaylight.yangtools.yang.common.QName;
17 import org.opendaylight.yangtools.yang.model.api.DataSchemaNode;
18 import org.opendaylight.yangtools.yang.model.api.GroupingDefinition;
19 import org.opendaylight.yangtools.yang.model.api.SchemaPath;
20 import org.opendaylight.yangtools.yang.model.api.Status;
21 import org.opendaylight.yangtools.yang.model.api.TypeDefinition;
22 import org.opendaylight.yangtools.yang.model.api.UnknownSchemaNode;
23 import org.opendaylight.yangtools.yang.model.api.UsesNode;
24 import org.opendaylight.yangtools.yang.parser.builder.api.Builder;
25 import org.opendaylight.yangtools.yang.parser.builder.api.DataSchemaNodeBuilder;
26 import org.opendaylight.yangtools.yang.parser.builder.api.GroupingBuilder;
27 import org.opendaylight.yangtools.yang.parser.builder.api.TypeDefinitionBuilder;
28 import org.opendaylight.yangtools.yang.parser.builder.api.UnknownSchemaNodeBuilder;
29 import org.opendaylight.yangtools.yang.parser.builder.api.UsesNodeBuilder;
30 import org.opendaylight.yangtools.yang.parser.builder.util.AbstractDataNodeContainerBuilder;
31 import org.opendaylight.yangtools.yang.parser.util.YangParseException;
32
33 import com.google.common.base.Preconditions;
34 import com.google.common.collect.ImmutableList;
35 import com.google.common.collect.ImmutableSet;
36
37 public final class GroupingBuilderImpl extends AbstractDataNodeContainerBuilder implements GroupingBuilder {
38     private GroupingDefinitionImpl instance;
39     // SchemaNode args
40     private SchemaPath schemaPath;
41     private String description;
42     private String reference;
43     private Status status = Status.CURRENT;
44     // DataSchemaNode args
45     private boolean addedByUses;
46
47     public GroupingBuilderImpl(final String moduleName, final int line, final QName qname, final SchemaPath path) {
48         super(moduleName, line, qname);
49         this.schemaPath = Preconditions.checkNotNull(path, "Schema Path must not be null");
50     }
51
52     public GroupingBuilderImpl(final String moduleName, final int line, final QName qname, final SchemaPath path,
53             final GroupingDefinition base) {
54         this(moduleName, line, base.getQName(),path);
55
56         description = base.getDescription();
57         reference = base.getReference();
58         status = base.getStatus();
59         addedByUses = base.isAddedByUses();
60
61         URI ns = qname.getNamespace();
62         Date rev = qname.getRevision();
63         String pref = qname.getPrefix();
64         addedChildNodes.addAll(BuilderUtils.wrapChildNodes(moduleName, line, base.getChildNodes(), path, ns, rev, pref));
65         addedGroupings.addAll(BuilderUtils.wrapGroupings(moduleName, line, base.getGroupings(), path, ns, rev, pref));
66         addedTypedefs.addAll(BuilderUtils.wrapTypedefs(moduleName, line, base, path, ns, rev, pref));
67         addedUnknownNodes.addAll(BuilderUtils.wrapUnknownNodes(moduleName, line, base.getUnknownSchemaNodes(), path, ns,
68                 rev, pref));
69
70         usesNodes.addAll(base.getUses());
71     }
72
73     @Override
74     public GroupingDefinition build() {
75         if (instance != null) {
76             return instance;
77         }
78
79         instance = new GroupingDefinitionImpl(qname, schemaPath);
80
81         instance.description = description;
82         instance.reference = reference;
83         instance.status = status;
84         instance.addedByUses = addedByUses;
85
86         // CHILD NODES
87         for (DataSchemaNodeBuilder node : addedChildNodes) {
88             childNodes.put(node.getQName(), node.build());
89         }
90         instance.childNodes = ImmutableSet.copyOf(childNodes.values());
91
92         // GROUPINGS
93         for (GroupingBuilder builder : addedGroupings) {
94             groupings.add(builder.build());
95         }
96         instance.groupings = ImmutableSet.copyOf(groupings);
97
98         // TYPEDEFS
99         for (TypeDefinitionBuilder entry : addedTypedefs) {
100             typedefs.add(entry.build());
101         }
102         instance.typeDefinitions = ImmutableSet.copyOf(typedefs);
103
104         // USES
105         for (UsesNodeBuilder builder : addedUsesNodes) {
106             usesNodes.add(builder.build());
107         }
108         instance.uses = ImmutableSet.copyOf(usesNodes);
109
110         // UNKNOWN NODES
111         for (UnknownSchemaNodeBuilder b : addedUnknownNodes) {
112             unknownNodes.add(b.build());
113         }
114         instance.unknownNodes = ImmutableList.copyOf(unknownNodes);
115
116         return instance;
117     }
118
119     @Override
120     public Set<DataSchemaNodeBuilder> instantiateChildNodes(final Builder newParent) {
121         final Set<DataSchemaNodeBuilder> nodes = new HashSet<>();
122         for (DataSchemaNodeBuilder node : addedChildNodes) {
123             DataSchemaNodeBuilder copy = CopyUtils.copy(node, newParent, true);
124             BuilderUtils.setNodeAddedByUses(copy);
125             nodes.add(copy);
126         }
127         return nodes;
128     }
129
130     @Override
131     public Set<TypeDefinitionBuilder> instantiateTypedefs(final Builder newParent) {
132         final Set<TypeDefinitionBuilder> nodes = new HashSet<>();
133         for (TypeDefinitionBuilder node : addedTypedefs) {
134             TypeDefinitionBuilder copy = CopyUtils.copy(node, newParent, true);
135             nodes.add(copy);
136         }
137         return nodes;
138     }
139
140     @Override
141     public Set<GroupingBuilder> instantiateGroupings(final Builder newParent) {
142         final Set<GroupingBuilder> nodes = new HashSet<>();
143         for (GroupingBuilder node : addedGroupings) {
144             GroupingBuilder copy = CopyUtils.copy(node, newParent, true);
145             copy.setAddedByUses(true);
146             for (DataSchemaNodeBuilder childNode : copy.getChildNodeBuilders()) {
147                 BuilderUtils.setNodeAddedByUses(childNode);
148             }
149             nodes.add(copy);
150         }
151         return nodes;
152     }
153
154     @Override
155     public Set<UnknownSchemaNodeBuilder> instantiateUnknownNodes(final Builder newParent) {
156         final Set<UnknownSchemaNodeBuilder> nodes = new HashSet<>();
157         for (UnknownSchemaNodeBuilder node : addedUnknownNodes) {
158             UnknownSchemaNodeBuilderImpl copy = CopyUtils.copy(node, newParent, true);
159             copy.setAddedByUses(true);
160             nodes.add(copy);
161         }
162         return nodes;
163     }
164
165     @Override
166     public Set<TypeDefinitionBuilder> getTypeDefinitionBuilders() {
167         return addedTypedefs;
168     }
169
170     @Override
171     public void addTypedef(final TypeDefinitionBuilder type) {
172         String typeName = type.getQName().getLocalName();
173         for (TypeDefinitionBuilder addedTypedef : addedTypedefs) {
174             throw new YangParseException(getModuleName(), type.getLine(), "Can not add typedef '" + typeName
175                     + "': typedef with same name already declared at line " + addedTypedef.getLine());
176         }
177         addedTypedefs.add(type);
178     }
179
180     @Override
181     public SchemaPath getPath() {
182         return schemaPath;
183     }
184
185     @Override
186     public void setPath(final SchemaPath path) {
187         this.schemaPath = path;
188     }
189
190     @Override
191     public String getDescription() {
192         return description;
193     }
194
195     @Override
196     public void setDescription(final String description) {
197         this.description = description;
198     }
199
200     @Override
201     public String getReference() {
202         return reference;
203     }
204
205     @Override
206     public void setReference(final String reference) {
207         this.reference = reference;
208     }
209
210     @Override
211     public Status getStatus() {
212         return status;
213     }
214
215     @Override
216     public void setStatus(final Status status) {
217         this.status = Preconditions.checkNotNull(status, "status cannot be null");
218     }
219
220     @Override
221     public boolean isAddedByUses() {
222         return addedByUses;
223     }
224
225     @Override
226     public void setAddedByUses(final boolean addedByUses) {
227         this.addedByUses = addedByUses;
228     }
229
230     @Override
231     public String toString() {
232         return "grouping " + qname.getLocalName();
233     }
234
235     @Override
236     public int hashCode() {
237         final int prime = 31;
238         int result = 1;
239         result = prime * result + ((getParent() == null) ? 0 : getParent().hashCode());
240         result = prime * result + ((schemaPath == null) ? 0 : schemaPath.hashCode());
241         return result;
242     }
243
244     @Override
245     public boolean equals(final Object obj) {
246         if (this == obj) {
247             return true;
248         }
249         if (obj == null) {
250             return false;
251         }
252         if (getClass() != obj.getClass()) {
253             return false;
254         }
255         if (!super.equals(obj)) {
256             return false;
257         }
258         final GroupingBuilderImpl other = (GroupingBuilderImpl) obj;
259         if (getParent() == null) {
260             if (other.getParent() != null) {
261                 return false;
262             }
263         } else if (!getParent().equals(other.getParent())) {
264             return false;
265         }
266         if (schemaPath == null) {
267             if (other.schemaPath != null) {
268                 return false;
269             }
270         } else if (!schemaPath.equals(other.schemaPath)) {
271             return false;
272         }
273         return true;
274     }
275
276     private static final class GroupingDefinitionImpl implements GroupingDefinition {
277         private final QName qname;
278         private final SchemaPath path;
279         private String description;
280         private String reference;
281         private Status status;
282         private boolean addedByUses;
283         private ImmutableSet<DataSchemaNode> childNodes;
284         private ImmutableSet<GroupingDefinition> groupings;
285         private ImmutableSet<TypeDefinition<?>> typeDefinitions;
286         private ImmutableSet<UsesNode> uses;
287         private ImmutableList<UnknownSchemaNode> unknownNodes;
288
289         private GroupingDefinitionImpl(final QName qname, final SchemaPath path) {
290             this.qname = qname;
291             this.path = path;
292         }
293
294         @Override
295         public QName getQName() {
296             return qname;
297         }
298
299         @Override
300         public SchemaPath getPath() {
301             return path;
302         }
303
304         @Override
305         public String getDescription() {
306             return description;
307         }
308
309         @Override
310         public String getReference() {
311             return reference;
312         }
313
314         @Override
315         public Status getStatus() {
316             return status;
317         }
318
319         @Override
320         public boolean isAddedByUses() {
321             return addedByUses;
322         }
323
324         @Override
325         public Set<DataSchemaNode> getChildNodes() {
326             return childNodes;
327         }
328
329         @Override
330         public Set<GroupingDefinition> getGroupings() {
331             return groupings;
332         }
333
334         @Override
335         public Set<UsesNode> getUses() {
336             return uses;
337         }
338
339         @Override
340         public Set<TypeDefinition<?>> getTypeDefinitions() {
341             return typeDefinitions;
342         }
343
344         @Override
345         public List<UnknownSchemaNode> getUnknownSchemaNodes() {
346             return unknownNodes;
347         }
348
349         @Override
350         public DataSchemaNode getDataChildByName(final QName name) {
351             return getChildNode(childNodes, name);
352         }
353
354         @Override
355         public DataSchemaNode getDataChildByName(final String name) {
356             return getChildNode(childNodes, name);
357         }
358
359         @Override
360         public int hashCode() {
361             final int prime = 31;
362             int result = 1;
363             result = prime * result + ((qname == null) ? 0 : qname.hashCode());
364             result = prime * result + ((path == null) ? 0 : path.hashCode());
365             return result;
366         }
367
368         @Override
369         public boolean equals(final Object obj) {
370             if (this == obj) {
371                 return true;
372             }
373             if (obj == null) {
374                 return false;
375             }
376             if (getClass() != obj.getClass()) {
377                 return false;
378             }
379             final GroupingDefinitionImpl other = (GroupingDefinitionImpl) obj;
380             if (qname == null) {
381                 if (other.qname != null) {
382                     return false;
383                 }
384             } else if (!qname.equals(other.qname)) {
385                 return false;
386             }
387             if (path == null) {
388                 if (other.path != null) {
389                     return false;
390                 }
391             } else if (!path.equals(other.path)) {
392                 return false;
393             }
394             return true;
395         }
396
397         @Override
398         public String toString() {
399             StringBuilder sb = new StringBuilder(GroupingDefinitionImpl.class.getSimpleName());
400             sb.append("[");
401             sb.append("qname=" + qname);
402             sb.append("]");
403             return sb.toString();
404         }
405     }
406
407 }