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