Refactored YANG types resolving.
[controller.git] / opendaylight / sal / yang-prototype / code-generator / yang-model-parser-impl / src / main / java / org / opendaylight / controller / yang / model / parser / builder / impl / ModuleBuilder.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.model.parser.builder.impl;
9
10 import java.net.URI;
11 import java.util.ArrayList;
12 import java.util.Collections;
13 import java.util.Date;
14 import java.util.HashMap;
15 import java.util.HashSet;
16 import java.util.List;
17 import java.util.Map;
18 import java.util.Set;
19
20 import org.opendaylight.controller.yang.common.QName;
21 import org.opendaylight.controller.yang.model.api.AugmentationSchema;
22 import org.opendaylight.controller.yang.model.api.DataSchemaNode;
23 import org.opendaylight.controller.yang.model.api.Deviation;
24 import org.opendaylight.controller.yang.model.api.ExtensionDefinition;
25 import org.opendaylight.controller.yang.model.api.FeatureDefinition;
26 import org.opendaylight.controller.yang.model.api.GroupingDefinition;
27 import org.opendaylight.controller.yang.model.api.IdentitySchemaNode;
28 import org.opendaylight.controller.yang.model.api.Module;
29 import org.opendaylight.controller.yang.model.api.ModuleImport;
30 import org.opendaylight.controller.yang.model.api.NotificationDefinition;
31 import org.opendaylight.controller.yang.model.api.RpcDefinition;
32 import org.opendaylight.controller.yang.model.api.TypeDefinition;
33 import org.opendaylight.controller.yang.model.api.UsesNode;
34 import org.opendaylight.controller.yang.model.parser.builder.api.AugmentationSchemaBuilder;
35 import org.opendaylight.controller.yang.model.parser.builder.api.Builder;
36 import org.opendaylight.controller.yang.model.parser.builder.api.ChildNodeBuilder;
37 import org.opendaylight.controller.yang.model.parser.builder.api.DataSchemaNodeBuilder;
38 import org.opendaylight.controller.yang.model.parser.builder.api.GroupingBuilder;
39 import org.opendaylight.controller.yang.model.parser.builder.api.TypeAwareBuilder;
40 import org.opendaylight.controller.yang.model.parser.builder.api.TypeDefinitionAwareBuilder;
41 import org.opendaylight.controller.yang.model.parser.builder.api.TypeDefinitionBuilder;
42 import org.opendaylight.controller.yang.model.parser.builder.api.UsesNodeBuilder;
43 import org.opendaylight.controller.yang.model.parser.util.YangParseException;
44
45 /**
46  * This builder builds Module object. If this module is dependent on external
47  * module/modules, these dependencies must be resolved before module is built,
48  * otherwise result may not be valid.
49  */
50 public class ModuleBuilder implements Builder {
51
52     private final ModuleImpl instance;
53     private final String name;
54     private String prefix;
55     private Date revision;
56
57     private final Set<ModuleImport> imports = new HashSet<ModuleImport>();
58     private Set<AugmentationSchema> augmentations;
59
60     /**
61      * All nodes, that can contain other nodes
62      */
63     private final Map<List<String>, Builder> moduleNodes = new HashMap<List<String>, Builder>();
64
65     /**
66      * Holds all child (DataSchemaNode) nodes: anyxml, choice, case, container,
67      * list, leaf, leaf-list.
68      */
69     private final Map<List<String>, DataSchemaNodeBuilder> addedChilds = new HashMap<List<String>, DataSchemaNodeBuilder>();
70
71     private final Map<List<String>, GroupingBuilder> addedGroupings = new HashMap<List<String>, GroupingBuilder>();
72     private final Set<AugmentationSchemaBuilder> addedAugments = new HashSet<AugmentationSchemaBuilder>();
73     private final Map<List<String>, UsesNodeBuilder> addedUsesNodes = new HashMap<List<String>, UsesNodeBuilder>();
74     private final Map<List<String>, RpcDefinitionBuilder> addedRpcs = new HashMap<List<String>, RpcDefinitionBuilder>();
75     private final Set<NotificationBuilder> addedNotifications = new HashSet<NotificationBuilder>();
76     private final Set<IdentitySchemaNodeBuilder> addedIdentities = new HashSet<IdentitySchemaNodeBuilder>();
77     private final Map<List<String>, FeatureBuilder> addedFeatures = new HashMap<List<String>, FeatureBuilder>();
78     private final Map<String, DeviationBuilder> addedDeviations = new HashMap<String, DeviationBuilder>();
79     private final Map<List<String>, TypeDefinitionBuilder> addedTypedefs = new HashMap<List<String>, TypeDefinitionBuilder>();
80     private final List<ExtensionBuilder> addedExtensions = new ArrayList<ExtensionBuilder>();
81
82     private final Map<List<String>, TypeAwareBuilder> dirtyNodes = new HashMap<List<String>, TypeAwareBuilder>();
83
84     public ModuleBuilder(String name) {
85         this.name = name;
86         instance = new ModuleImpl(name);
87     }
88
89
90     /**
91      * Build new Module object based on this builder.
92      */
93     @Override
94     public Module build() {
95         instance.setImports(imports);
96
97         // TYPEDEFS
98         final Set<TypeDefinition<?>> typedefs = buildModuleTypedefs(addedTypedefs);
99         instance.setTypeDefinitions(typedefs);
100
101         // CHILD NODES
102         final Map<QName, DataSchemaNode> childNodes = buildModuleChildNodes(addedChilds);
103         instance.setChildNodes(childNodes);
104
105         // GROUPINGS
106         final Set<GroupingDefinition> groupings = buildModuleGroupings(addedGroupings);
107         instance.setGroupings(groupings);
108
109         // USES
110         final Set<UsesNode> usesDefinitions = buildUsesNodes(addedUsesNodes);
111         instance.setUses(usesDefinitions);
112
113         // FEATURES
114         final Set<FeatureDefinition> features = buildModuleFeatures(addedFeatures);
115         instance.setFeatures(features);
116
117         // NOTIFICATIONS
118         final Set<NotificationDefinition> notifications = new HashSet<NotificationDefinition>();
119         for (NotificationBuilder entry : addedNotifications) {
120             notifications.add((NotificationDefinition) entry.build());
121         }
122         instance.setNotifications(notifications);
123
124         // AUGMENTATIONS
125         instance.setAugmentations(augmentations);
126
127         // RPCs
128         final Set<RpcDefinition> rpcs = buildModuleRpcs(addedRpcs);
129         instance.setRpcs(rpcs);
130
131         // DEVIATIONS
132         final Set<Deviation> deviations = new HashSet<Deviation>();
133         for (Map.Entry<String, DeviationBuilder> entry : addedDeviations
134                 .entrySet()) {
135             deviations.add(entry.getValue().build());
136         }
137         instance.setDeviations(deviations);
138
139         // EXTENSIONS
140         final List<ExtensionDefinition> extensions = new ArrayList<ExtensionDefinition>();
141         for(ExtensionBuilder b : addedExtensions) {
142             extensions.add(b.build());
143         }
144         instance.setExtensionSchemaNodes(extensions);
145
146         // IDENTITIES
147         final Set<IdentitySchemaNode> identities = new HashSet<IdentitySchemaNode>();
148         for(IdentitySchemaNodeBuilder idBuilder : addedIdentities) {
149             identities.add(idBuilder.build());
150         }
151         instance.setIdentities(identities);
152
153         return instance;
154     }
155
156     public Builder getNode(List<String> path) {
157         return moduleNodes.get(path);
158     }
159
160     public Map<List<String>, TypeAwareBuilder> getDirtyNodes() {
161         return dirtyNodes;
162     }
163
164     public Set<AugmentationSchemaBuilder> getAddedAugments() {
165         return addedAugments;
166     }
167
168     public Set<IdentitySchemaNodeBuilder> getAddedIdentities() {
169         return addedIdentities;
170     }
171
172     public String getName() {
173         return name;
174     }
175
176     public String getPrefix() {
177         return prefix;
178     }
179
180     public Date getRevision() {
181         return revision;
182     }
183
184     public void addDirtyNode(List<String> path) {
185         List<String> dirtyNodePath = new ArrayList<String>(path);
186         TypeAwareBuilder nodeBuilder = (TypeAwareBuilder) moduleNodes
187                 .get(dirtyNodePath);
188         dirtyNodes.put(dirtyNodePath, nodeBuilder);
189     }
190
191     public void setNamespace(URI namespace) {
192         instance.setNamespace(namespace);
193     }
194
195     public void setRevision(Date revision) {
196         this.revision = revision;
197         instance.setRevision(revision);
198     }
199
200     public void setPrefix(String prefix) {
201         this.prefix = prefix;
202         instance.setPrefix(prefix);
203     }
204
205     public void setYangVersion(String yangVersion) {
206         instance.setYangVersion(yangVersion);
207     }
208
209     public void setDescription(String description) {
210         instance.setDescription(description);
211     }
212
213     public void setReference(String reference) {
214         instance.setReference(reference);
215     }
216
217     public void setOrganization(String organization) {
218         instance.setOrganization(organization);
219     }
220
221     public void setContact(String contact) {
222         instance.setContact(contact);
223     }
224
225     public void setAugmentations(Set<AugmentationSchema> augmentations) {
226         this.augmentations = augmentations;
227     }
228
229     public boolean addModuleImport(final String moduleName,
230             final Date revision, final String prefix) {
231         ModuleImport moduleImport = createModuleImport(moduleName, revision,
232                 prefix);
233         return imports.add(moduleImport);
234     }
235
236     public Set<ModuleImport> getModuleImports() {
237         return imports;
238     }
239
240     public ExtensionBuilder addExtension(QName qname) {
241         return new ExtensionBuilder(qname);
242     }
243
244     public ContainerSchemaNodeBuilder addContainerNode(QName containerName,
245             List<String> parentPath) {
246         List<String> pathToNode = new ArrayList<String>(parentPath);
247
248         ContainerSchemaNodeBuilder containerBuilder = new ContainerSchemaNodeBuilder(
249                 containerName);
250
251         ChildNodeBuilder parent = (ChildNodeBuilder) moduleNodes
252                 .get(pathToNode);
253         if (parent != null) {
254             if(parent instanceof AugmentationSchemaBuilder) {
255                 containerBuilder.setAugmenting(true);
256             }
257             parent.addChildNode(containerBuilder);
258         }
259
260         pathToNode.add(containerName.getLocalName());
261         moduleNodes.put(pathToNode, containerBuilder);
262         addedChilds.put(pathToNode, containerBuilder);
263
264         return containerBuilder;
265     }
266
267     public ListSchemaNodeBuilder addListNode(QName listName,
268             List<String> parentPath) {
269         List<String> pathToNode = new ArrayList<String>(parentPath);
270
271         ListSchemaNodeBuilder listBuilder = new ListSchemaNodeBuilder(listName);
272
273         ChildNodeBuilder parent = (ChildNodeBuilder) moduleNodes
274                 .get(pathToNode);
275         if (parent != null) {
276             if(parent instanceof AugmentationSchemaBuilder) {
277                 listBuilder.setAugmenting(true);
278             }
279             parent.addChildNode(listBuilder);
280         }
281
282         pathToNode.add(listName.getLocalName());
283         moduleNodes.put(pathToNode, listBuilder);
284         addedChilds.put(pathToNode, listBuilder);
285
286         return listBuilder;
287     }
288
289     public LeafSchemaNodeBuilder addLeafNode(QName leafName,
290             List<String> parentPath) {
291         List<String> pathToNode = new ArrayList<String>(parentPath);
292
293         LeafSchemaNodeBuilder leafBuilder = new LeafSchemaNodeBuilder(leafName);
294
295         ChildNodeBuilder parent = (ChildNodeBuilder) moduleNodes.get(pathToNode);
296         if (parent != null) {
297             if(parent instanceof AugmentationSchemaBuilder) {
298                 leafBuilder.setAugmenting(true);
299             }
300             parent.addChildNode(leafBuilder);
301         }
302
303         pathToNode.add(leafName.getLocalName());
304         addedChilds.put(pathToNode, leafBuilder);
305         moduleNodes.put(pathToNode, leafBuilder);
306
307         return leafBuilder;
308     }
309
310     public LeafListSchemaNodeBuilder addLeafListNode(QName leafListName,
311             List<String> parentPath) {
312         List<String> pathToNode = new ArrayList<String>(parentPath);
313
314         LeafListSchemaNodeBuilder leafListBuilder = new LeafListSchemaNodeBuilder(
315                 leafListName);
316         ChildNodeBuilder parent = (ChildNodeBuilder) moduleNodes.get(pathToNode);
317         if (parent != null) {
318             if(parent instanceof AugmentationSchemaBuilder) {
319                 leafListBuilder.setAugmenting(true);
320             }
321             parent.addChildNode(leafListBuilder);
322         }
323
324         pathToNode.add(leafListName.getLocalName());
325         addedChilds.put(pathToNode, leafListBuilder);
326         moduleNodes.put(pathToNode, leafListBuilder);
327
328         return leafListBuilder;
329     }
330
331     public GroupingBuilder addGrouping(QName qname, List<String> parentPath) {
332         List<String> pathToGroup = new ArrayList<String>(parentPath);
333
334         GroupingBuilder builder = new GroupingBuilderImpl(qname);
335         ChildNodeBuilder parentNodeBuilder = (ChildNodeBuilder) moduleNodes.get(pathToGroup);
336         if (parentNodeBuilder != null) {
337             parentNodeBuilder.addGrouping(builder);
338         }
339
340         pathToGroup.add(qname.getLocalName());
341         moduleNodes.put(pathToGroup, builder);
342         addedGroupings.put(pathToGroup, builder);
343
344         return builder;
345     }
346
347     public AugmentationSchemaBuilder addAugment(String name,
348             List<String> parentPath) {
349         List<String> pathToAugment = new ArrayList<String>(parentPath);
350
351         AugmentationSchemaBuilder builder = new AugmentationSchemaBuilderImpl(name);
352
353         // augment can only be in 'module' or 'uses' statement
354         UsesNodeBuilder parent = addedUsesNodes.get(pathToAugment);
355         if (parent != null) {
356             parent.addAugment(builder);
357         }
358
359         pathToAugment.add(name);
360         moduleNodes.put(pathToAugment, builder);
361         addedAugments.add(builder);
362
363         return builder;
364     }
365
366     public UsesNodeBuilder addUsesNode(String groupingPathStr,
367             List<String> parentPath) {
368         List<String> pathToUses = new ArrayList<String>(parentPath);
369
370         UsesNodeBuilder usesBuilder = new UsesNodeBuilderImpl(groupingPathStr);
371
372         ChildNodeBuilder parent = (ChildNodeBuilder) moduleNodes.get(pathToUses);
373         if (parent != null) {
374             parent.addUsesNode(usesBuilder);
375         }
376
377         pathToUses.add(groupingPathStr);
378         addedUsesNodes.put(pathToUses, usesBuilder);
379
380         return usesBuilder;
381     }
382
383     public RpcDefinitionBuilder addRpc(QName qname, List<String> parentPath) {
384         List<String> pathToRpc = new ArrayList<String>(parentPath);
385
386         RpcDefinitionBuilder rpcBuilder = new RpcDefinitionBuilder(qname);
387
388         pathToRpc.add(qname.getLocalName());
389         addedRpcs.put(pathToRpc, rpcBuilder);
390
391         QName inputQName = new QName(qname.getNamespace(), qname.getRevision(),
392                 qname.getPrefix(), "input");
393         ContainerSchemaNodeBuilder inputBuilder = new ContainerSchemaNodeBuilder(inputQName);
394         List<String> pathToInput = new ArrayList<String>(pathToRpc);
395         pathToInput.add("input");
396         moduleNodes.put(pathToInput, inputBuilder);
397         rpcBuilder.setInput(inputBuilder);
398
399         QName outputQName = new QName(qname.getNamespace(),
400                 qname.getRevision(), qname.getPrefix(), "output");
401         ContainerSchemaNodeBuilder outputBuilder = new ContainerSchemaNodeBuilder(outputQName);
402         List<String> pathToOutput = new ArrayList<String>(pathToRpc);
403         pathToOutput.add("output");
404         moduleNodes.put(pathToOutput, outputBuilder);
405         rpcBuilder.setOutput(outputBuilder);
406
407         return rpcBuilder;
408     }
409
410     public NotificationBuilder addNotification(QName notificationName,
411             List<String> parentPath) {
412         List<String> pathToNotification = new ArrayList<String>(parentPath);
413
414         NotificationBuilder builder = new NotificationBuilder(
415                 notificationName);
416
417         pathToNotification.add(notificationName.getLocalName());
418         moduleNodes.put(pathToNotification, builder);
419         addedNotifications.add(builder);
420
421         return builder;
422     }
423
424     public FeatureBuilder addFeature(QName featureName, List<String> parentPath) {
425         List<String> pathToFeature = new ArrayList<String>(parentPath);
426         pathToFeature.add(featureName.getLocalName());
427
428         FeatureBuilder builder = new FeatureBuilder(featureName);
429         addedFeatures.put(pathToFeature, builder);
430         return builder;
431     }
432
433     public TypedefBuilder addTypedef(QName typeDefName, List<String> parentPath) {
434         List<String> pathToType = new ArrayList<String>(parentPath);
435         TypedefBuilder builder = new TypedefBuilder(typeDefName);
436         TypeDefinitionAwareBuilder parent = (TypeDefinitionAwareBuilder) moduleNodes.get(pathToType);
437         if (parent != null) {
438             parent.addTypedef(builder);
439         }
440         pathToType.add(typeDefName.getLocalName());
441         addedTypedefs.put(pathToType, builder);
442         moduleNodes.put(pathToType, builder);
443         return builder;
444     }
445
446     public Set<TypeDefinitionBuilder> getModuleTypedefs() {
447         Set<TypeDefinitionBuilder> typedefs = new HashSet<TypeDefinitionBuilder>();
448         for (Map.Entry<List<String>, TypeDefinitionBuilder> entry : addedTypedefs.entrySet()) {
449             if (entry.getKey().size() == 2) {
450                 typedefs.add(entry.getValue());
451             }
452         }
453         return typedefs;
454     }
455
456     public void setType(TypeDefinition<?> type, List<String> parentPath) {
457         TypeAwareBuilder parent = (TypeAwareBuilder) moduleNodes.get(parentPath);
458         if(parent == null) {
459             throw new YangParseException("Failed to set type '"+ type.getQName().getLocalName() +"'. Parent node not found.");
460         }
461         parent.setType(type);
462     }
463
464     public void addUnionType(List<String> parentPath) {
465         TypeAwareBuilder parent = (TypeAwareBuilder) moduleNodes.get(parentPath);
466         UnionTypeBuilder union = new UnionTypeBuilder();
467         parent.setType(union);
468
469         List<String> path = new ArrayList<String>(parentPath);
470         path.add("union");
471
472         moduleNodes.put(path, union);
473     }
474
475     public DeviationBuilder addDeviation(String targetPath) {
476         DeviationBuilder builder = new DeviationBuilder(targetPath);
477         addedDeviations.put(targetPath, builder);
478         return builder;
479     }
480
481     public IdentitySchemaNodeBuilder addIdentity(QName qname) {
482         IdentitySchemaNodeBuilder builder = new IdentitySchemaNodeBuilder(qname);
483         addedIdentities.add(builder);
484         return builder;
485     }
486
487     public void addConfiguration(boolean configuration, List<String> parentPath) {
488         Builder builder = moduleNodes.get(parentPath);
489         if (builder instanceof DeviationBuilder) {
490             // skip
491             // TODO
492         } else {
493             DataSchemaNodeBuilder configBuilder = (DataSchemaNodeBuilder) moduleNodes.get(parentPath);
494             configBuilder.setConfiguration(configuration);
495         }
496     }
497
498     public UnknownSchemaNodeBuilder addUnknownSchemaNode(QName qname, List<String> parentPath) {
499         return new UnknownSchemaNodeBuilder(qname);
500     }
501
502
503     private class ModuleImpl implements Module {
504         private URI namespace;
505         private final String name;
506         private Date revision;
507         private String prefix;
508         private String yangVersion;
509         private String description;
510         private String reference;
511         private String organization;
512         private String contact;
513         private Set<ModuleImport> imports = Collections.emptySet();
514         private Set<FeatureDefinition> features = Collections.emptySet();
515         private Set<TypeDefinition<?>> typeDefinitions = Collections.emptySet();
516         private Set<NotificationDefinition> notifications = Collections.emptySet();
517         private Set<AugmentationSchema> augmentations = Collections.emptySet();
518         private Set<RpcDefinition> rpcs = Collections.emptySet();
519         private Set<Deviation> deviations = Collections.emptySet();
520         private Map<QName, DataSchemaNode> childNodes = Collections.emptyMap();
521         private Set<GroupingDefinition> groupings = Collections.emptySet();
522         private Set<UsesNode> uses = Collections.emptySet();
523         private List<ExtensionDefinition> extensionNodes = Collections.emptyList();
524         private Set<IdentitySchemaNode> identities = Collections.emptySet();
525
526         private ModuleImpl(String name) {
527             this.name = name;
528         }
529
530         @Override
531         public URI getNamespace() {
532             return namespace;
533         }
534
535         private void setNamespace(URI namespace) {
536             this.namespace = namespace;
537         }
538
539         @Override
540         public String getName() {
541             return name;
542         }
543
544         @Override
545         public Date getRevision() {
546             return revision;
547         }
548
549         private void setRevision(Date revision) {
550             this.revision = revision;
551         }
552
553         @Override
554         public String getPrefix() {
555             return prefix;
556         }
557
558         private void setPrefix(String prefix) {
559             this.prefix = prefix;
560         }
561
562         @Override
563         public String getYangVersion() {
564             return yangVersion;
565         }
566
567         private void setYangVersion(String yangVersion) {
568             this.yangVersion = yangVersion;
569         }
570
571         @Override
572         public String getDescription() {
573             return description;
574         }
575
576         private void setDescription(String description) {
577             this.description = description;
578         }
579
580         @Override
581         public String getReference() {
582             return reference;
583         }
584
585         private void setReference(String reference) {
586             this.reference = reference;
587         }
588
589         @Override
590         public String getOrganization() {
591             return organization;
592         }
593
594         private void setOrganization(String organization) {
595             this.organization = organization;
596         }
597
598         @Override
599         public String getContact() {
600             return contact;
601         }
602
603         private void setContact(String contact) {
604             this.contact = contact;
605         }
606
607         @Override
608         public Set<ModuleImport> getImports() {
609             return imports;
610         }
611
612         private void setImports(Set<ModuleImport> imports) {
613             if(imports != null) {
614                 this.imports = imports;
615             }
616         }
617
618         @Override
619         public Set<FeatureDefinition> getFeatures() {
620             return features;
621         }
622
623         private void setFeatures(Set<FeatureDefinition> features) {
624             if(features != null) {
625                 this.features = features;
626             }
627         }
628
629         @Override
630         public Set<TypeDefinition<?>> getTypeDefinitions() {
631             return typeDefinitions;
632         }
633
634         private void setTypeDefinitions(Set<TypeDefinition<?>> typeDefinitions) {
635             if(typeDefinitions != null) {
636                 this.typeDefinitions = typeDefinitions;
637             }
638         }
639
640         @Override
641         public Set<NotificationDefinition> getNotifications() {
642             return notifications;
643         }
644
645         private void setNotifications(Set<NotificationDefinition> notifications) {
646             if(notifications != null) {
647                 this.notifications = notifications;
648             }
649         }
650
651         @Override
652         public Set<AugmentationSchema> getAugmentations() {
653             return augmentations;
654         }
655
656         private void setAugmentations(Set<AugmentationSchema> augmentations) {
657             if(augmentations != null) {
658                 this.augmentations = augmentations;
659             }
660         }
661
662         @Override
663         public Set<RpcDefinition> getRpcs() {
664             return rpcs;
665         }
666
667         private void setRpcs(Set<RpcDefinition> rpcs) {
668             if(rpcs != null) {
669                 this.rpcs = rpcs;
670             }
671         }
672
673         @Override
674         public Set<Deviation> getDeviations() {
675             return deviations;
676         }
677
678         private void setDeviations(Set<Deviation> deviations) {
679             if(deviations != null) {
680                 this.deviations = deviations;
681             }
682         }
683
684         @Override
685         public Set<DataSchemaNode> getChildNodes() {
686             return new HashSet<DataSchemaNode>(childNodes.values());
687         }
688
689         private void setChildNodes(Map<QName, DataSchemaNode> childNodes) {
690             if(childNodes != null) {
691                 this.childNodes = childNodes;
692             }
693         }
694
695         @Override
696         public Set<GroupingDefinition> getGroupings() {
697             return groupings;
698         }
699
700         private void setGroupings(Set<GroupingDefinition> groupings) {
701             if(groupings != null) {
702                 this.groupings = groupings;
703             }
704         }
705
706         @Override
707         public Set<UsesNode> getUses() {
708             return uses;
709         }
710
711         private void setUses(Set<UsesNode> uses) {
712             if(uses != null) {
713                 this.uses = uses;
714             }
715         }
716
717         @Override
718         public List<ExtensionDefinition> getExtensionSchemaNodes() {
719             return extensionNodes;
720         }
721
722         private void setExtensionSchemaNodes(List<ExtensionDefinition> extensionSchemaNodes) {
723             if(extensionSchemaNodes != null) {
724                 this.extensionNodes = extensionSchemaNodes;
725             }
726         }
727
728         @Override
729         public Set<IdentitySchemaNode> getIdentities() {
730             return identities;
731         }
732
733         private void setIdentities(Set<IdentitySchemaNode> identities) {
734             if(identities != null) {
735                 this.identities = identities;
736             }
737         }
738
739         @Override
740         public DataSchemaNode getDataChildByName(QName name) {
741             return childNodes.get(name);
742         }
743
744         @Override
745         public DataSchemaNode getDataChildByName(String name) {
746             DataSchemaNode result = null;
747             for (Map.Entry<QName, DataSchemaNode> entry : childNodes.entrySet()) {
748                 if (entry.getKey().getLocalName().equals(name)) {
749                     result = entry.getValue();
750                     break;
751                 }
752             }
753             return result;
754         }
755
756         @Override
757         public int hashCode() {
758             final int prime = 31;
759             int result = 1;
760             result = prime * result + ((namespace == null) ? 0 : namespace.hashCode());
761             result = prime * result + ((name == null) ? 0 : name.hashCode());
762             result = prime * result + ((revision == null) ? 0 : revision.hashCode());
763             result = prime * result + ((prefix == null) ? 0 : prefix.hashCode());
764             result = prime * result + ((yangVersion == null) ? 0 : yangVersion.hashCode());
765             return result;
766         }
767
768         @Override
769         public boolean equals(Object obj) {
770             if (this == obj) {
771                 return true;
772             }
773             if (obj == null) {
774                 return false;
775             }
776             if (getClass() != obj.getClass()) {
777                 return false;
778             }
779             ModuleImpl other = (ModuleImpl) obj;
780             if (namespace == null) {
781                 if (other.namespace != null) {
782                     return false;
783                 }
784             } else if (!namespace.equals(other.namespace)) {
785                 return false;
786             }
787             if (name == null) {
788                 if (other.name != null) {
789                     return false;
790                 }
791             } else if (!name.equals(other.name)) {
792                 return false;
793             }
794             if (revision == null) {
795                 if (other.revision != null) {
796                     return false;
797                 }
798             } else if (!revision.equals(other.revision)) {
799                 return false;
800             }
801             if (prefix == null) {
802                 if (other.prefix != null) {
803                     return false;
804                 }
805             } else if (!prefix.equals(other.prefix)) {
806                 return false;
807             }
808             if (yangVersion == null) {
809                 if (other.yangVersion != null) {
810                     return false;
811                 }
812             } else if (!yangVersion.equals(other.yangVersion)) {
813                 return false;
814             }
815             return true;
816         }
817
818         @Override
819         public String toString() {
820             StringBuilder sb = new StringBuilder(
821                     ModuleImpl.class.getSimpleName());
822             sb.append("[\n");
823             sb.append("name=" + name + ",\n");
824             sb.append("namespace=" + namespace + ",\n");
825             sb.append("revision=" + revision + ",\n");
826             sb.append("prefix=" + prefix + ",\n");
827             sb.append("yangVersion=" + yangVersion + ",\n");
828             sb.append("description=" + description + ",\n");
829             sb.append("reference=" + reference + ",\n");
830             sb.append("organization=" + organization + ",\n");
831             sb.append("contact=" + contact + ",\n");
832             sb.append("childNodes=" + childNodes.values() + ",\n");
833             sb.append("groupings=" + groupings + ",\n");
834             sb.append("imports=" + imports + ",\n");
835             sb.append("features=" + features + ",\n");
836             sb.append("typeDefinitions=" + typeDefinitions + ",\n");
837             sb.append("notifications=" + notifications + ",\n");
838             sb.append("augmentations=" + augmentations + ",\n");
839             sb.append("rpcs=" + rpcs + ",\n");
840             sb.append("deviations=" + deviations + "\n");
841             sb.append("uses=" + uses + "\n");
842             sb.append("]");
843             return sb.toString();
844         }
845     }
846
847     private ModuleImport createModuleImport(final String moduleName,
848             final Date revision, final String prefix) {
849         ModuleImport moduleImport = new ModuleImport() {
850             @Override
851             public String getModuleName() {
852                 return moduleName;
853             }
854
855             @Override
856             public Date getRevision() {
857                 return revision;
858             }
859
860             @Override
861             public String getPrefix() {
862                 return prefix;
863             }
864
865             @Override
866             public int hashCode() {
867                 final int prime = 31;
868                 int result = 1;
869                 result = prime * result
870                         + ((moduleName == null) ? 0 : moduleName.hashCode());
871                 result = prime * result
872                         + ((revision == null) ? 0 : revision.hashCode());
873                 result = prime * result
874                         + ((prefix == null) ? 0 : prefix.hashCode());
875                 return result;
876             }
877
878             @Override
879             public boolean equals(Object obj) {
880                 if (this == obj) {
881                     return true;
882                 }
883                 if (obj == null) {
884                     return false;
885                 }
886                 if (getClass() != obj.getClass()) {
887                     return false;
888                 }
889                 ModuleImport other = (ModuleImport) obj;
890                 if (getModuleName() == null) {
891                     if (other.getModuleName() != null) {
892                         return false;
893                     }
894                 } else if (!getModuleName().equals(other.getModuleName())) {
895                     return false;
896                 }
897                 if (getRevision() == null) {
898                     if (other.getRevision() != null) {
899                         return false;
900                     }
901                 } else if (!getRevision().equals(other.getRevision())) {
902                     return false;
903                 }
904                 if (getPrefix() == null) {
905                     if (other.getPrefix() != null) {
906                         return false;
907                     }
908                 } else if (!getPrefix().equals(other.getPrefix())) {
909                     return false;
910                 }
911                 return true;
912             }
913
914             @Override
915             public String toString() {
916                 return "ModuleImport[moduleName=" + moduleName + ", revision="
917                         + revision + ", prefix=" + prefix + "]";
918             }
919         };
920         return moduleImport;
921     }
922
923     /**
924      * Traverse through given addedChilds and add only direct module childs.
925      * Direct module child path size is 2 (1. module name, 2. child name).
926      *
927      * @param addedChilds
928      * @return map of children, where key is child QName and value is child
929      *         itself
930      */
931     private Map<QName, DataSchemaNode> buildModuleChildNodes(
932             Map<List<String>, DataSchemaNodeBuilder> addedChilds) {
933         final Map<QName, DataSchemaNode> childNodes = new HashMap<QName, DataSchemaNode>();
934         for (Map.Entry<List<String>, DataSchemaNodeBuilder> entry : addedChilds.entrySet()) {
935             List<String> path = entry.getKey();
936             DataSchemaNodeBuilder child = entry.getValue();
937             if (path.size() == 2) {
938                 DataSchemaNode node = child.build();
939                 QName qname = node.getQName();
940                 childNodes.put(qname, node);
941             }
942         }
943         return childNodes;
944     }
945
946     /**
947      * Traverse through given addedGroupings and add only direct module
948      * groupings. Direct module grouping path size is 2 (1. module name, 2.
949      * grouping name).
950      *
951      * @param addedGroupings
952      * @return set of built GroupingDefinition objects
953      */
954     private Set<GroupingDefinition> buildModuleGroupings(
955             Map<List<String>, GroupingBuilder> addedGroupings) {
956         final Set<GroupingDefinition> groupings = new HashSet<GroupingDefinition>();
957         for (Map.Entry<List<String>, GroupingBuilder> entry : addedGroupings
958                 .entrySet()) {
959             if (entry.getKey().size() == 2) {
960                 groupings.add(entry.getValue().build());
961             }
962         }
963         return groupings;
964     }
965
966     /**
967      * Traverse through given addedRpcs and build RpcDefinition objects.
968      *
969      * @param addedRpcs
970      * @return set of built RpcDefinition objects
971      */
972     private Set<RpcDefinition> buildModuleRpcs(
973             Map<List<String>, RpcDefinitionBuilder> addedRpcs) {
974         final Set<RpcDefinition> rpcs = new HashSet<RpcDefinition>();
975         RpcDefinitionBuilder builder;
976         for (Map.Entry<List<String>, RpcDefinitionBuilder> entry : addedRpcs
977                 .entrySet()) {
978             builder = entry.getValue();
979             RpcDefinition rpc = builder.build();
980             rpcs.add(rpc);
981         }
982         return rpcs;
983     }
984
985     /**
986      * Traverse through given addedTypedefs and add only direct module typedef
987      * statements. Direct module typedef path size is 2 (1. module name, 2.
988      * typedef name).
989      *
990      * @param addedTypedefs
991      * @return set of built module typedef statements
992      */
993     private Set<TypeDefinition<?>> buildModuleTypedefs(
994             Map<List<String>, TypeDefinitionBuilder> addedTypedefs) {
995         Set<TypeDefinition<?>> typedefs = new HashSet<TypeDefinition<?>>();
996         for (Map.Entry<List<String>, TypeDefinitionBuilder> entry : addedTypedefs.entrySet()) {
997             List<String> key = entry.getKey();
998             TypeDefinitionBuilder typedefBuilder = entry.getValue();
999             if (key.size() == 2) {
1000                 TypeDefinition<? extends TypeDefinition<?>> node = typedefBuilder.build();
1001                 typedefs.add(node);
1002             }
1003         }
1004         return typedefs;
1005     }
1006
1007     /**
1008      * Traverse through given addedUsesNodes and add only direct module uses
1009      * nodes. Direct module uses node path size is 2 (1. module name, 2. uses
1010      * name).
1011      *
1012      * @param addedUsesNodes
1013      * @return set of built module uses nodes
1014      */
1015     private Set<UsesNode> buildUsesNodes(
1016             Map<List<String>, UsesNodeBuilder> addedUsesNodes) {
1017         final Set<UsesNode> usesNodeDefinitions = new HashSet<UsesNode>();
1018         for (Map.Entry<List<String>, UsesNodeBuilder> entry : addedUsesNodes
1019                 .entrySet()) {
1020             if (entry.getKey().size() == 2) {
1021                 usesNodeDefinitions.add(entry.getValue().build());
1022             }
1023         }
1024         return usesNodeDefinitions;
1025     }
1026
1027     /**
1028      * Traverse through given addedFeatures and add only direct module features.
1029      * Direct module feature path size is 2 (1. module name, 2. feature name).
1030      *
1031      * @param addedFeatures
1032      * @return set of built module features
1033      */
1034     private Set<FeatureDefinition> buildModuleFeatures(
1035             Map<List<String>, FeatureBuilder> addedFeatures) {
1036         Set<FeatureDefinition> features = new HashSet<FeatureDefinition>();
1037         for (Map.Entry<List<String>, FeatureBuilder> entry : addedFeatures
1038                 .entrySet()) {
1039             if (entry.getKey().size() == 2) {
1040                 features.add(entry.getValue().build());
1041             }
1042         }
1043         return features;
1044     }
1045
1046 }