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