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