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