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