Merge "Fix for Bug 308."
[yangtools.git] / yang / yang-parser-impl / src / main / java / org / opendaylight / yangtools / yang / parser / builder / impl / ListSchemaNodeBuilder.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.ArrayList;
12 import java.util.Collections;
13 import java.util.Date;
14 import java.util.HashSet;
15 import java.util.List;
16 import java.util.Set;
17 import java.util.TreeSet;
18
19 import org.opendaylight.yangtools.yang.common.QName;
20 import org.opendaylight.yangtools.yang.model.api.*;
21 import org.opendaylight.yangtools.yang.parser.builder.api.AbstractDataNodeContainerBuilder;
22 import org.opendaylight.yangtools.yang.parser.builder.api.AugmentationSchemaBuilder;
23 import org.opendaylight.yangtools.yang.parser.builder.api.AugmentationTargetBuilder;
24 import org.opendaylight.yangtools.yang.parser.builder.api.DataSchemaNodeBuilder;
25 import org.opendaylight.yangtools.yang.parser.builder.api.GroupingBuilder;
26 import org.opendaylight.yangtools.yang.parser.builder.api.TypeDefinitionBuilder;
27 import org.opendaylight.yangtools.yang.parser.builder.api.UsesNodeBuilder;
28 import org.opendaylight.yangtools.yang.parser.util.Comparators;
29 import org.opendaylight.yangtools.yang.parser.util.ParserUtils;
30 import org.opendaylight.yangtools.yang.parser.util.YangParseException;
31
32 public final class ListSchemaNodeBuilder extends AbstractDataNodeContainerBuilder implements DataSchemaNodeBuilder,
33         AugmentationTargetBuilder {
34     private boolean isBuilt;
35     private final ListSchemaNodeImpl instance;
36     // SchemaNode args
37     private SchemaPath schemaPath;
38     // DataSchemaNode args
39     private final ConstraintsBuilder constraints;
40     // AugmentationTarget args
41     private final List<AugmentationSchema> augmentations = new ArrayList<>();
42     private final List<AugmentationSchemaBuilder> augmentationBuilders = new ArrayList<>();
43
44
45     public ListSchemaNodeBuilder(final String moduleName, final int line, final QName qname, final SchemaPath path) {
46         super(moduleName, line, qname);
47         this.schemaPath = path;
48         instance = new ListSchemaNodeImpl(qname, path);
49         constraints = new ConstraintsBuilder(moduleName, line);
50     }
51
52     public ListSchemaNodeBuilder(final String moduleName, final int line, final QName qname, final SchemaPath path, final ListSchemaNode base) {
53         super(moduleName, line, qname);
54         schemaPath = path;
55         instance = new ListSchemaNodeImpl(qname, path);
56         constraints = new ConstraintsBuilder(moduleName, line, base.getConstraints());
57
58         instance.keyDefinition = base.getKeyDefinition();
59         instance.userOrdered = base.isUserOrdered();
60
61         instance.description = base.getDescription();
62         instance.reference = base.getReference();
63         instance.status = base.getStatus();
64         instance.augmenting = base.isAugmenting();
65         instance.addedByUses = base.isAddedByUses();
66         instance.configuration = base.isConfiguration();
67         instance.constraints = base.getConstraints();
68         instance.augmentations.addAll(base.getAvailableAugmentations());
69
70         URI ns = qname.getNamespace();
71         Date rev = qname.getRevision();
72         String pref = qname.getPrefix();
73         addedChildNodes.addAll(ParserUtils.wrapChildNodes(moduleName, line, base.getChildNodes(), path, ns, rev, pref));
74         addedGroupings.addAll(ParserUtils.wrapGroupings(moduleName, line, base.getGroupings(), path, ns, rev, pref));
75         addedTypedefs.addAll(ParserUtils.wrapTypedefs(moduleName, line, base, path, ns, rev, pref));
76         addedUnknownNodes.addAll(ParserUtils.wrapUnknownNodes(moduleName, line, base.getUnknownSchemaNodes(), path, ns,
77                 rev, pref));
78
79         instance.uses.addAll(base.getUses());
80     }
81
82     @Override
83     public ListSchemaNode build() {
84         if (!isBuilt) {
85             // CHILD NODES
86             for (DataSchemaNodeBuilder node : addedChildNodes) {
87                 childNodes.add(node.build());
88             }
89             instance.addChildNodes(childNodes);
90
91             // TYPEDEFS
92             for (TypeDefinitionBuilder entry : addedTypedefs) {
93                 typedefs.add(entry.build());
94             }
95             instance.addTypeDefinitions(typedefs);
96
97             // USES
98             for (UsesNodeBuilder builder : addedUsesNodes) {
99                 usesNodes.add(builder.build());
100             }
101             instance.addUses(usesNodes);
102
103             // GROUPINGS
104             for (GroupingBuilder builder : addedGroupings) {
105                 groupings.add(builder.build());
106             }
107             instance.addGroupings(groupings);
108
109             // AUGMENTATIONS
110             for (AugmentationSchemaBuilder builder : augmentationBuilders) {
111                 augmentations.add(builder.build());
112             }
113             instance.addAvailableAugmentations(new HashSet<>(augmentations));
114
115             // UNKNOWN NODES
116             for (UnknownSchemaNodeBuilder b : addedUnknownNodes) {
117                 unknownNodes.add(b.build());
118             }
119             Collections.sort(unknownNodes, Comparators.SCHEMA_NODE_COMP);
120             instance.addUnknownSchemaNodes(unknownNodes);
121
122             instance.setConstraints(constraints.build());
123
124             isBuilt = true;
125         }
126         return instance;
127     }
128
129     @Override
130     public Set<TypeDefinitionBuilder> getTypeDefinitionBuilders() {
131         return addedTypedefs;
132     }
133
134     @Override
135     public void addTypedef(final TypeDefinitionBuilder type) {
136         String typeName = type.getQName().getLocalName();
137         for (TypeDefinitionBuilder addedTypedef : addedTypedefs) {
138             if (addedTypedef.getQName().getLocalName().equals(typeName)) {
139                 throw new YangParseException(moduleName, type.getLine(), "Can not add typedef '" + typeName
140                         + "': typedef with same name already declared at line " + addedTypedef.getLine());
141             }
142         }
143         addedTypedefs.add(type);
144     }
145
146     @Override
147     public SchemaPath getPath() {
148         return instance.path;
149     }
150
151     @Override
152     public void setPath(SchemaPath path) {
153         instance.path = path;
154     }
155
156     @Override
157     public String getDescription() {
158         return instance.description;
159     }
160
161     @Override
162     public void setDescription(final String description) {
163         instance.description = description;
164     }
165
166     @Override
167     public String getReference() {
168         return instance.reference;
169     }
170
171     @Override
172     public void setReference(final String reference) {
173         instance.reference = reference;
174     }
175
176     @Override
177     public Status getStatus() {
178         return instance.status;
179     }
180
181     @Override
182     public void setStatus(Status status) {
183         if (status != null) {
184             instance.status = status;
185         }
186     }
187
188     @Override
189     public void addAugmentation(AugmentationSchemaBuilder augment) {
190         augmentationBuilders.add(augment);
191     }
192
193     public List<AugmentationSchemaBuilder> getAugmentationBuilders() {
194         return augmentationBuilders;
195     }
196
197     public List<QName> getKeyDefinition() {
198         return instance.keyDefinition;
199     }
200
201     public void setKeyDefinition(final List<QName> keyDefinition) {
202         instance.keyDefinition = keyDefinition;
203     }
204
205     @Override
206     public boolean isAugmenting() {
207         return instance.augmenting;
208     }
209
210     @Override
211     public void setAugmenting(boolean augmenting) {
212         instance.augmenting = augmenting;
213     }
214
215     @Override
216     public boolean isAddedByUses() {
217         return instance.addedByUses;
218     }
219
220     @Override
221     public void setAddedByUses(final boolean addedByUses) {
222         instance.addedByUses = addedByUses;
223     }
224
225     @Override
226     public Boolean isConfiguration() {
227         return instance.configuration;
228     }
229
230     @Override
231     public void setConfiguration(Boolean configuration) {
232         instance.configuration = configuration;
233     }
234
235     @Override
236     public ConstraintsBuilder getConstraints() {
237         return constraints;
238     }
239
240     public boolean isUserOrdered() {
241         return instance.userOrdered;
242     }
243
244     public void setUserOrdered(final boolean userOrdered) {
245         instance.userOrdered = userOrdered;
246     }
247
248     @Override
249     public int hashCode() {
250         final int prime = 31;
251         int result = 1;
252         result = prime * result + ((schemaPath == null) ? 0 : schemaPath.hashCode());
253         return result;
254     }
255
256     @Override
257     public boolean equals(Object obj) {
258         if (this == obj) {
259             return true;
260         }
261         if (obj == null) {
262             return false;
263         }
264         if (getClass() != obj.getClass()) {
265             return false;
266         }
267         ListSchemaNodeBuilder other = (ListSchemaNodeBuilder) obj;
268         if (schemaPath == null) {
269             if (other.schemaPath != null) {
270                 return false;
271             }
272         } else if (!schemaPath.equals(other.schemaPath)) {
273             return false;
274         }
275         if (parentBuilder == null) {
276             if (other.parentBuilder != null) {
277                 return false;
278             }
279         } else if (!parentBuilder.equals(other.parentBuilder)) {
280             return false;
281         }
282         return true;
283     }
284
285     @Override
286     public String toString() {
287         return "list " + qname.getLocalName();
288     }
289
290     public final class ListSchemaNodeImpl implements ListSchemaNode {
291         private final QName qname;
292         private SchemaPath path;
293         private String description;
294         private String reference;
295         private Status status = Status.CURRENT;
296         private List<QName> keyDefinition = Collections.emptyList();
297         private boolean augmenting;
298         private boolean addedByUses;
299         private boolean configuration;
300         private ConstraintDefinition constraints;
301         private final Set<AugmentationSchema> augmentations = new HashSet<>();
302         private final Set<DataSchemaNode> childNodes = new TreeSet<>(Comparators.SCHEMA_NODE_COMP);
303         private final Set<TypeDefinition<?>> typeDefinitions = new TreeSet<>(Comparators.SCHEMA_NODE_COMP);
304         private final Set<GroupingDefinition> groupings = new TreeSet<>(Comparators.SCHEMA_NODE_COMP);
305         private final Set<UsesNode> uses = new HashSet<>();
306         private boolean userOrdered;
307         private final List<UnknownSchemaNode> unknownNodes = new ArrayList<>();
308
309         private ListSchemaNodeImpl(final QName qname, final SchemaPath path) {
310             this.qname = qname;
311             this.path = path;
312         }
313
314         @Override
315         public QName getQName() {
316             return qname;
317         }
318
319         @Override
320         public SchemaPath getPath() {
321             return path;
322         }
323
324         @Override
325         public String getDescription() {
326             return description;
327         }
328
329         @Override
330         public String getReference() {
331             return reference;
332         }
333
334         @Override
335         public Status getStatus() {
336             return status;
337         }
338
339         @Override
340         public List<QName> getKeyDefinition() {
341             return keyDefinition;
342         }
343
344         @Override
345         public boolean isAugmenting() {
346             return augmenting;
347         }
348
349         @Override
350         public boolean isAddedByUses() {
351             return addedByUses;
352         }
353
354         @Override
355         public boolean isConfiguration() {
356             return configuration;
357         }
358
359         @Override
360         public ConstraintDefinition getConstraints() {
361             return constraints;
362         }
363
364         private void setConstraints(ConstraintDefinition constraints) {
365             this.constraints = constraints;
366         }
367
368         @Override
369         public Set<AugmentationSchema> getAvailableAugmentations() {
370             return Collections.unmodifiableSet(augmentations);
371         }
372
373         private void addAvailableAugmentations(Set<AugmentationSchema> augmentations) {
374             if (augmentations != null) {
375                 this.augmentations.addAll(augmentations);
376             }
377         }
378
379         @Override
380         public Set<DataSchemaNode> getChildNodes() {
381             return Collections.unmodifiableSet(childNodes);
382         }
383
384         private void addChildNodes(Set<DataSchemaNode> childNodes) {
385             if (childNodes != null) {
386                 this.childNodes.addAll(childNodes);
387             }
388         }
389
390         @Override
391         public Set<GroupingDefinition> getGroupings() {
392             return Collections.unmodifiableSet(groupings);
393         }
394
395         private void addGroupings(Set<GroupingDefinition> groupings) {
396             if (groupings != null) {
397                 this.groupings.addAll(groupings);
398             }
399         }
400
401         @Override
402         public Set<TypeDefinition<?>> getTypeDefinitions() {
403             return Collections.unmodifiableSet(typeDefinitions);
404         }
405
406         private void addTypeDefinitions(Set<TypeDefinition<?>> typeDefinitions) {
407             if (typeDefinitions != null) {
408                 this.typeDefinitions.addAll(typeDefinitions);
409             }
410         }
411
412         @Override
413         public Set<UsesNode> getUses() {
414             return Collections.unmodifiableSet(uses);
415         }
416
417         private void addUses(Set<UsesNode> uses) {
418             if (uses != null) {
419                 this.uses.addAll(uses);
420             }
421         }
422
423         @Override
424         public DataSchemaNode getDataChildByName(QName name) {
425             return getChildNode(childNodes, name);
426         }
427
428         @Override
429         public DataSchemaNode getDataChildByName(String name) {
430             return getChildNode(childNodes, name);
431         }
432
433         @Override
434         public boolean isUserOrdered() {
435             return userOrdered;
436         }
437
438         @Override
439         public List<UnknownSchemaNode> getUnknownSchemaNodes() {
440             return Collections.unmodifiableList(unknownNodes);
441         }
442
443         private void addUnknownSchemaNodes(List<UnknownSchemaNode> unknownNodes) {
444             if (unknownNodes != null) {
445                 this.unknownNodes.addAll(unknownNodes);
446             }
447         }
448
449         @Override
450         public int hashCode() {
451             final int prime = 31;
452             int result = 1;
453             result = prime * result + ((qname == null) ? 0 : qname.hashCode());
454             result = prime * result + ((path == null) ? 0 : path.hashCode());
455             return result;
456         }
457
458         @Override
459         public boolean equals(Object obj) {
460             if (this == obj) {
461                 return true;
462             }
463             if (obj == null) {
464                 return false;
465             }
466             if (getClass() != obj.getClass()) {
467                 return false;
468             }
469             final ListSchemaNodeImpl other = (ListSchemaNodeImpl) obj;
470             if (qname == null) {
471                 if (other.qname != null) {
472                     return false;
473                 }
474             } else if (!qname.equals(other.qname)) {
475                 return false;
476             }
477             if (path == null) {
478                 if (other.path != null) {
479                     return false;
480                 }
481             } else if (!path.equals(other.path)) {
482                 return false;
483             }
484             return true;
485         }
486
487         @Override
488         public String toString() {
489             return "list " + qname.getLocalName();
490         }
491     }
492
493 }