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