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