Converted BindingGenerator and ParserUtils to xtend
[yangtools.git] / yang / yang-parser-impl / src / main / java / org / opendaylight / yangtools / yang / parser / builder / impl / ModuleBuilder.java
1 /*\r
2  * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.\r
3  *\r
4  * This program and the accompanying materials are made available under the\r
5  * terms of the Eclipse Public License v1.0 which accompanies this distribution,\r
6  * and is available at http://www.eclipse.org/legal/epl-v10.html\r
7  */\r
8 package org.opendaylight.yangtools.yang.parser.builder.impl;\r
9 \r
10 import java.net.URI;\r
11 import java.util.ArrayList;\r
12 import java.util.Collections;\r
13 import java.util.Date;\r
14 import java.util.HashSet;\r
15 import java.util.LinkedHashSet;\r
16 import java.util.LinkedList;\r
17 import java.util.List;\r
18 import java.util.Map;\r
19 import java.util.Set;\r
20 import java.util.TreeMap;\r
21 import java.util.TreeSet;\r
22 \r
23 import org.opendaylight.yangtools.yang.common.QName;\r
24 import org.opendaylight.yangtools.yang.model.api.AugmentationSchema;\r
25 import org.opendaylight.yangtools.yang.model.api.DataSchemaNode;\r
26 import org.opendaylight.yangtools.yang.model.api.Deviation;\r
27 import org.opendaylight.yangtools.yang.model.api.ExtensionDefinition;\r
28 import org.opendaylight.yangtools.yang.model.api.FeatureDefinition;\r
29 import org.opendaylight.yangtools.yang.model.api.GroupingDefinition;\r
30 import org.opendaylight.yangtools.yang.model.api.IdentitySchemaNode;\r
31 import org.opendaylight.yangtools.yang.model.api.Module;\r
32 import org.opendaylight.yangtools.yang.model.api.ModuleImport;\r
33 import org.opendaylight.yangtools.yang.model.api.NotificationDefinition;\r
34 import org.opendaylight.yangtools.yang.model.api.RpcDefinition;\r
35 import org.opendaylight.yangtools.yang.model.api.SchemaPath;\r
36 import org.opendaylight.yangtools.yang.model.api.TypeDefinition;\r
37 import org.opendaylight.yangtools.yang.model.api.UnknownSchemaNode;\r
38 import org.opendaylight.yangtools.yang.model.api.UsesNode;\r
39 import org.opendaylight.yangtools.yang.parser.builder.api.AbstractDataNodeContainerBuilder;\r
40 import org.opendaylight.yangtools.yang.parser.builder.api.AugmentationSchemaBuilder;\r
41 import org.opendaylight.yangtools.yang.parser.builder.api.Builder;\r
42 import org.opendaylight.yangtools.yang.parser.builder.api.DataNodeContainerBuilder;\r
43 import org.opendaylight.yangtools.yang.parser.builder.api.DataSchemaNodeBuilder;\r
44 import org.opendaylight.yangtools.yang.parser.builder.api.GroupingBuilder;\r
45 import org.opendaylight.yangtools.yang.parser.builder.api.SchemaNodeBuilder;\r
46 import org.opendaylight.yangtools.yang.parser.builder.api.TypeAwareBuilder;\r
47 import org.opendaylight.yangtools.yang.parser.builder.api.TypeDefinitionBuilder;\r
48 import org.opendaylight.yangtools.yang.parser.builder.api.UsesNodeBuilder;\r
49 import org.opendaylight.yangtools.yang.parser.util.Comparators;\r
50 import org.opendaylight.yangtools.yang.parser.util.RefineHolder;\r
51 import org.opendaylight.yangtools.yang.parser.util.YangParseException;\r
52 \r
53 /**\r
54  * Builder of Module object. If this module is dependent on external\r
55  * module/modules, these dependencies must be resolved before module is built,\r
56  * otherwise result may not be valid.\r
57  */\r
58 public class ModuleBuilder extends AbstractDataNodeContainerBuilder {\r
59     private final ModuleImpl instance;\r
60     private final String name;\r
61     private final SchemaPath schemaPath;\r
62     private URI namespace;\r
63     private String prefix;\r
64     private Date revision;\r
65 \r
66     private final LinkedList<Builder> actualPath = new LinkedList<Builder>();\r
67     private final Set<TypeAwareBuilder> dirtyNodes = new HashSet<TypeAwareBuilder>();\r
68 \r
69     private final Set<ModuleImport> imports = new HashSet<ModuleImport>();\r
70     private final List<AugmentationSchemaBuilder> addedAugments = new ArrayList<AugmentationSchemaBuilder>();\r
71     private final List<AugmentationSchemaBuilder> allAugments = new ArrayList<AugmentationSchemaBuilder>();\r
72     private final Set<UsesNodeBuilder> addedUsesNodes = new HashSet<UsesNodeBuilder>();\r
73     private final List<UsesNodeBuilder> allUsesNodes = new ArrayList<UsesNodeBuilder>();\r
74     private final Set<RpcDefinitionBuilder> addedRpcs = new HashSet<RpcDefinitionBuilder>();\r
75     private final Set<NotificationBuilder> addedNotifications = new HashSet<NotificationBuilder>();\r
76     private final Set<IdentitySchemaNodeBuilder> addedIdentities = new HashSet<IdentitySchemaNodeBuilder>();\r
77     private final Set<FeatureBuilder> addedFeatures = new HashSet<FeatureBuilder>();\r
78     private final Set<DeviationBuilder> addedDeviations = new HashSet<DeviationBuilder>();\r
79     private final Set<TypeDefinitionBuilder> addedTypedefs = new HashSet<TypeDefinitionBuilder>();\r
80     private final List<ExtensionBuilder> addedExtensions = new ArrayList<ExtensionBuilder>();\r
81     private final List<UnknownSchemaNodeBuilder> allUnknownNodes = new ArrayList<UnknownSchemaNodeBuilder>();\r
82 \r
83     public ModuleBuilder(final String name) {\r
84         super(name, 0, null);\r
85         this.name = name;\r
86         schemaPath = new SchemaPath(Collections.<QName>emptyList(), true);\r
87         instance = new ModuleImpl(name);\r
88         actualPath.push(this);\r
89     }\r
90 \r
91     /**\r
92      * Build new Module object based on this builder.\r
93      */\r
94     @Override\r
95     public Module build() {\r
96         instance.setPrefix(prefix);\r
97         instance.setRevision(revision);\r
98         instance.setImports(imports);\r
99         instance.setNamespace(namespace);\r
100 \r
101         // TYPEDEFS\r
102         final Set<TypeDefinition<?>> typedefs = new TreeSet<TypeDefinition<?>>(Comparators.SCHEMA_NODE_COMP);\r
103         for (TypeDefinitionBuilder tdb : addedTypedefs) {\r
104             typedefs.add(tdb.build());\r
105         }\r
106         instance.setTypeDefinitions(typedefs);\r
107 \r
108         // CHILD NODES\r
109         final Map<QName, DataSchemaNode> children = new TreeMap<QName, DataSchemaNode>(Comparators.QNAME_COMP);\r
110         for (DataSchemaNodeBuilder child : addedChildNodes) {\r
111             children.put(child.getQName(), child.build());\r
112         }\r
113         instance.setChildNodes(children);\r
114 \r
115         // GROUPINGS\r
116         final Set<GroupingDefinition> groupings = new TreeSet<GroupingDefinition>(Comparators.SCHEMA_NODE_COMP);\r
117         for (GroupingBuilder gb : addedGroupings) {\r
118             groupings.add(gb.build());\r
119         }\r
120         instance.setGroupings(groupings);\r
121 \r
122         // USES\r
123         final Set<UsesNode> usesDefinitions = new HashSet<UsesNode>();\r
124         for (UsesNodeBuilder unb : addedUsesNodes) {\r
125             usesDefinitions.add(unb.build());\r
126         }\r
127         instance.setUses(usesDefinitions);\r
128 \r
129         // FEATURES\r
130         final Set<FeatureDefinition> features = new TreeSet<FeatureDefinition>(Comparators.SCHEMA_NODE_COMP);\r
131         for (FeatureBuilder fb : addedFeatures) {\r
132             features.add(fb.build());\r
133         }\r
134         instance.setFeatures(features);\r
135 \r
136         // NOTIFICATIONS\r
137         final Set<NotificationDefinition> notifications = new TreeSet<NotificationDefinition>(\r
138                 Comparators.SCHEMA_NODE_COMP);\r
139         for (NotificationBuilder entry : addedNotifications) {\r
140             notifications.add(entry.build());\r
141         }\r
142         instance.setNotifications(notifications);\r
143 \r
144         // AUGMENTATIONS\r
145         final Set<AugmentationSchema> augmentations = new HashSet<AugmentationSchema>();\r
146         for (AugmentationSchemaBuilder builder : addedAugments) {\r
147             augmentations.add(builder.build());\r
148         }\r
149         instance.setAugmentations(augmentations);\r
150 \r
151         // RPCs\r
152         final Set<RpcDefinition> rpcs = new TreeSet<RpcDefinition>(Comparators.SCHEMA_NODE_COMP);\r
153         for (RpcDefinitionBuilder rpc : addedRpcs) {\r
154             rpcs.add(rpc.build());\r
155         }\r
156         instance.setRpcs(rpcs);\r
157 \r
158         // DEVIATIONS\r
159         final Set<Deviation> deviations = new HashSet<Deviation>();\r
160         for (DeviationBuilder entry : addedDeviations) {\r
161             deviations.add(entry.build());\r
162         }\r
163         instance.setDeviations(deviations);\r
164 \r
165         // EXTENSIONS\r
166         final List<ExtensionDefinition> extensions = new ArrayList<ExtensionDefinition>();\r
167         for (ExtensionBuilder eb : addedExtensions) {\r
168             extensions.add(eb.build());\r
169         }\r
170         Collections.sort(extensions, Comparators.SCHEMA_NODE_COMP);\r
171         instance.setExtensionSchemaNodes(extensions);\r
172 \r
173         // IDENTITIES\r
174         final Set<IdentitySchemaNode> identities = new TreeSet<IdentitySchemaNode>(Comparators.SCHEMA_NODE_COMP);\r
175         for (IdentitySchemaNodeBuilder id : addedIdentities) {\r
176             identities.add(id.build());\r
177         }\r
178         instance.setIdentities(identities);\r
179 \r
180         // UNKNOWN NODES\r
181         final List<UnknownSchemaNode> unknownNodes = new ArrayList<UnknownSchemaNode>();\r
182         for (UnknownSchemaNodeBuilder unb : addedUnknownNodes) {\r
183             unknownNodes.add(unb.build());\r
184         }\r
185         instance.setUnknownSchemaNodes(unknownNodes);\r
186 \r
187         return instance;\r
188     }\r
189 \r
190     public boolean isAllUsesDataCollected() {\r
191         for(UsesNodeBuilder usesNode : allUsesNodes) {\r
192             if(!usesNode.isDataCollected()) {\r
193                 return false;\r
194             }\r
195         }\r
196         return true;\r
197     }\r
198 \r
199     @Override\r
200     public void setParent(Builder parent) {\r
201         throw new YangParseException(name, 0, "Can not set parent to module");\r
202     }\r
203 \r
204     @Override\r
205     public SchemaPath getPath() {\r
206         return schemaPath;\r
207     }\r
208 \r
209     @Override\r
210     public Set<TypeDefinitionBuilder> getTypeDefinitionBuilders() {\r
211         return addedTypedefs;\r
212     }\r
213 \r
214     public void enterNode(final Builder node) {\r
215         actualPath.push(node);\r
216     }\r
217 \r
218     public void exitNode() {\r
219         actualPath.pop();\r
220     }\r
221 \r
222     public Builder getActualNode() {\r
223         if (actualPath.isEmpty()) {\r
224             return null;\r
225         } else {\r
226             return actualPath.get(0);\r
227         }\r
228     }\r
229 \r
230     public Builder getActualParent() {\r
231         if (actualPath.size() < 2) {\r
232             return null;\r
233         } else {\r
234             return actualPath.get(1);\r
235         }\r
236     }\r
237 \r
238     public Set<TypeAwareBuilder> getDirtyNodes() {\r
239         return dirtyNodes;\r
240     }\r
241 \r
242     public List<AugmentationSchemaBuilder> getAllAugments() {\r
243         return allAugments;\r
244     }\r
245 \r
246     public Set<IdentitySchemaNodeBuilder> getIdentities() {\r
247         return addedIdentities;\r
248     }\r
249 \r
250     public List<UsesNodeBuilder> getAllUsesNodes() {\r
251         return allUsesNodes;\r
252     }\r
253 \r
254     public Set<DeviationBuilder> getDeviations() {\r
255         return addedDeviations;\r
256     }\r
257 \r
258     public List<ExtensionBuilder> getExtensions() {\r
259         return addedExtensions;\r
260     }\r
261 \r
262     public List<UnknownSchemaNodeBuilder> getAllUnknownNodes() {\r
263         return allUnknownNodes;\r
264     }\r
265 \r
266     public String getName() {\r
267         return name;\r
268     }\r
269 \r
270     public URI getNamespace() {\r
271         return namespace;\r
272     }\r
273 \r
274     public void setNamespace(final URI namespace) {\r
275         this.namespace = namespace;\r
276     }\r
277 \r
278     public String getPrefix() {\r
279         return prefix;\r
280     }\r
281 \r
282     public Date getRevision() {\r
283         return revision;\r
284     }\r
285 \r
286     public void markActualNodeDirty() {\r
287         final TypeAwareBuilder nodeBuilder = (TypeAwareBuilder) getActualNode();\r
288         dirtyNodes.add(nodeBuilder);\r
289     }\r
290 \r
291     public void setRevision(final Date revision) {\r
292         this.revision = revision;\r
293     }\r
294 \r
295     public void setPrefix(final String prefix) {\r
296         this.prefix = prefix;\r
297     }\r
298 \r
299     public void setYangVersion(final String yangVersion) {\r
300         instance.setYangVersion(yangVersion);\r
301     }\r
302 \r
303     public void setDescription(final String description) {\r
304         instance.setDescription(description);\r
305     }\r
306 \r
307     public void setReference(final String reference) {\r
308         instance.setReference(reference);\r
309     }\r
310 \r
311     public void setOrganization(final String organization) {\r
312         instance.setOrganization(organization);\r
313     }\r
314 \r
315     public void setContact(final String contact) {\r
316         instance.setContact(contact);\r
317     }\r
318 \r
319     public boolean addModuleImport(final String moduleName, final Date revision, final String prefix) {\r
320         final ModuleImport moduleImport = createModuleImport(moduleName, revision, prefix);\r
321         return imports.add(moduleImport);\r
322     }\r
323 \r
324     public Set<ModuleImport> getModuleImports() {\r
325         return imports;\r
326     }\r
327 \r
328     public ExtensionBuilder addExtension(final QName qname, final int line) {\r
329         final String extName = qname.getLocalName();\r
330         for (ExtensionBuilder addedExtension : addedExtensions) {\r
331             if (addedExtension.getQName().getLocalName().equals(extName)) {\r
332                 throw new YangParseException(moduleName, line, "Can not add extension '" + extName\r
333                         + "': extension with same name already declared at line " + addedExtension.getLine());\r
334             }\r
335         }\r
336         final ExtensionBuilder builder = new ExtensionBuilder(name, line, qname);\r
337         addedExtensions.add(builder);\r
338         return builder;\r
339     }\r
340 \r
341     public ContainerSchemaNodeBuilder addContainerNode(final int line, final QName qname, final SchemaPath schemaPath) {\r
342         final ContainerSchemaNodeBuilder builder = new ContainerSchemaNodeBuilder(name, line, qname, schemaPath);\r
343 \r
344         Builder parent = getActualNode();\r
345         builder.setParent(parent);\r
346         addChildToParent(parent, builder, qname.getLocalName());\r
347 \r
348         return builder;\r
349     }\r
350 \r
351     public ListSchemaNodeBuilder addListNode(final int line, final QName qname, final SchemaPath schemaPath) {\r
352         final ListSchemaNodeBuilder builder = new ListSchemaNodeBuilder(name, line, qname, schemaPath);\r
353 \r
354         Builder parent = getActualNode();\r
355         builder.setParent(parent);\r
356         addChildToParent(parent, builder, qname.getLocalName());\r
357 \r
358         return builder;\r
359     }\r
360 \r
361     public LeafSchemaNodeBuilder addLeafNode(final int line, final QName qname, final SchemaPath schemaPath) {\r
362         final LeafSchemaNodeBuilder builder = new LeafSchemaNodeBuilder(name, line, qname, schemaPath);\r
363 \r
364         Builder parent = getActualNode();\r
365         builder.setParent(parent);\r
366         addChildToParent(parent, builder, qname.getLocalName());\r
367 \r
368         return builder;\r
369     }\r
370 \r
371     public LeafListSchemaNodeBuilder addLeafListNode(final int line, final QName qname, final SchemaPath schemaPath) {\r
372         final LeafListSchemaNodeBuilder builder = new LeafListSchemaNodeBuilder(name, line, qname, schemaPath);\r
373 \r
374         Builder parent = getActualNode();\r
375         builder.setParent(parent);\r
376         addChildToParent(parent, builder, qname.getLocalName());\r
377 \r
378         return builder;\r
379     }\r
380 \r
381     public GroupingBuilder addGrouping(final int line, final QName qname) {\r
382         final GroupingBuilder builder = new GroupingBuilderImpl(name, line, qname);\r
383 \r
384         Builder parent = getActualNode();\r
385         builder.setParent(parent);\r
386 \r
387         String groupingName = qname.getLocalName();\r
388         if (parent.equals(this)) {\r
389             for (GroupingBuilder addedGrouping : addedGroupings) {\r
390                 if (addedGrouping.getQName().getLocalName().equals(groupingName)) {\r
391                     throw new YangParseException(name, line, "grouping with same name '" + groupingName\r
392                             + "' already declared at line " + addedGrouping.getLine());\r
393                 }\r
394             }\r
395             addedGroupings.add(builder);\r
396         } else {\r
397             if (parent instanceof DataNodeContainerBuilder) {\r
398                 DataNodeContainerBuilder parentNode = (DataNodeContainerBuilder) parent;\r
399                 for (GroupingBuilder addedGrouping : parentNode.getGroupingBuilders()) {\r
400                     if (addedGrouping.getQName().getLocalName().equals(groupingName)) {\r
401                         throw new YangParseException(name, line, "grouping with same name '" + groupingName\r
402                                 + "' already declared at line " + addedGrouping.getLine());\r
403                     }\r
404                 }\r
405                 parentNode.addGrouping(builder);\r
406             } else if (parent instanceof RpcDefinitionBuilder) {\r
407                 RpcDefinitionBuilder parentNode = (RpcDefinitionBuilder) parent;\r
408                 for (GroupingBuilder child : parentNode.getGroupings()) {\r
409                     if (child.getQName().getLocalName().equals(groupingName)) {\r
410                         throw new YangParseException(name, line, "grouping with same name '" + groupingName\r
411                                 + "' already declared at line " + child.getLine());\r
412                     }\r
413                 }\r
414                 parentNode.addGrouping(builder);\r
415             } else {\r
416                 throw new YangParseException(name, line, "Unresolved parent of grouping " + groupingName);\r
417             }\r
418         }\r
419 \r
420         return builder;\r
421     }\r
422 \r
423     public AugmentationSchemaBuilder addAugment(final int line, final String augmentTargetStr) {\r
424         final AugmentationSchemaBuilder builder = new AugmentationSchemaBuilderImpl(name, line, augmentTargetStr);\r
425 \r
426         Builder parent = getActualNode();\r
427         builder.setParent(parent);\r
428 \r
429         if (parent.equals(this)) {\r
430             // augment can be declared only under 'module' ...\r
431             addedAugments.add(builder);\r
432         } else {\r
433             // ... or 'uses' statement\r
434             if (parent instanceof UsesNodeBuilder) {\r
435                 ((UsesNodeBuilder) parent).addAugment(builder);\r
436             } else {\r
437                 throw new YangParseException(name, line, "Augment can be declared only under module or uses statement.");\r
438             }\r
439         }\r
440         allAugments.add(builder);\r
441 \r
442         return builder;\r
443     }\r
444 \r
445     @Override\r
446     public Set<UsesNodeBuilder> getUsesNodes() {\r
447         return addedUsesNodes;\r
448     }\r
449 \r
450     @Override\r
451     public void addUsesNode(UsesNodeBuilder usesBuilder) {\r
452         addedUsesNodes.add(usesBuilder);\r
453         allUsesNodes.add(usesBuilder);\r
454     }\r
455 \r
456     public UsesNodeBuilder addUsesNode(final int line, final String groupingPathStr) {\r
457         final UsesNodeBuilder usesBuilder = new UsesNodeBuilderImpl(name, line, groupingPathStr);\r
458 \r
459         Builder parent = getActualNode();\r
460         usesBuilder.setParent(parent);\r
461 \r
462         if (parent.equals(this)) {\r
463             addedUsesNodes.add(usesBuilder);\r
464         } else {\r
465             if (!(parent instanceof DataNodeContainerBuilder)) {\r
466                 throw new YangParseException(name, line, "Unresolved parent of uses '" + groupingPathStr + "'.");\r
467             }\r
468             ((DataNodeContainerBuilder) parent).addUsesNode(usesBuilder);\r
469         }\r
470         allUsesNodes.add(usesBuilder);\r
471         return usesBuilder;\r
472     }\r
473 \r
474     public void addRefine(final RefineHolder refine) {\r
475         final Builder parent = getActualNode();\r
476         if (!(parent instanceof UsesNodeBuilder)) {\r
477             throw new YangParseException(name, refine.getLine(), "refine can be defined only in uses statement");\r
478         }\r
479         ((UsesNodeBuilder) parent).addRefine(refine);\r
480         refine.setParent(parent);\r
481     }\r
482 \r
483     public RpcDefinitionBuilder addRpc(final int line, final QName qname) {\r
484         Builder parent = getActualNode();\r
485         if (!(parent.equals(this))) {\r
486             throw new YangParseException(name, line, "rpc can be defined only in module or submodule");\r
487         }\r
488 \r
489         final RpcDefinitionBuilder rpcBuilder = new RpcDefinitionBuilder(name, line, qname);\r
490         rpcBuilder.setParent(parent);\r
491 \r
492         String rpcName = qname.getLocalName();\r
493         for (RpcDefinitionBuilder rpc : addedRpcs) {\r
494             if (rpc.getQName().getLocalName().equals(rpcName)) {\r
495                 throw new YangParseException(name, line, "rpc with same name '" + rpcName\r
496                         + "' already declared at line " + rpc.getLine());\r
497             }\r
498         }\r
499         for (DataSchemaNodeBuilder addedChild : addedChildNodes) {\r
500             if (addedChild.getQName().getLocalName().equals(rpcName)) {\r
501                 throw new YangParseException(name, line, "Can not add rpc: node with same name '" + rpcName\r
502                         + "' already declared at line " + addedChild.getLine());\r
503             }\r
504         }\r
505         for (NotificationBuilder addedNotification : addedNotifications) {\r
506             if (addedNotification.getQName().getLocalName().equals(rpcName)) {\r
507                 throw new YangParseException(name, line, "Can not add rpc: notification with same name '" + rpcName\r
508                         + "' already declared at line " + addedNotification.getLine());\r
509             }\r
510         }\r
511         addedRpcs.add(rpcBuilder);\r
512         return rpcBuilder;\r
513     }\r
514 \r
515     public ContainerSchemaNodeBuilder addRpcInput(final int line, final QName qname, final SchemaPath schemaPath) {\r
516         final Builder parent = getActualNode();\r
517         if (!(parent instanceof RpcDefinitionBuilder)) {\r
518             throw new YangParseException(name, line, "input can be defined only in rpc statement");\r
519         }\r
520         final RpcDefinitionBuilder rpc = (RpcDefinitionBuilder) parent;\r
521 \r
522         final ContainerSchemaNodeBuilder inputBuilder = new ContainerSchemaNodeBuilder(name, line, qname, schemaPath);\r
523         inputBuilder.setParent(rpc);\r
524 \r
525         rpc.setInput(inputBuilder);\r
526         return inputBuilder;\r
527     }\r
528 \r
529     public ContainerSchemaNodeBuilder addRpcOutput(final SchemaPath schemaPath, final QName qname, final int line) {\r
530         final Builder parent = getActualNode();\r
531         if (!(parent instanceof RpcDefinitionBuilder)) {\r
532             throw new YangParseException(name, line, "output can be defined only in rpc statement");\r
533         }\r
534         final RpcDefinitionBuilder rpc = (RpcDefinitionBuilder) parent;\r
535 \r
536         final ContainerSchemaNodeBuilder outputBuilder = new ContainerSchemaNodeBuilder(name, line, qname, schemaPath);\r
537         outputBuilder.setParent(rpc);\r
538 \r
539         rpc.setOutput(outputBuilder);\r
540         return outputBuilder;\r
541     }\r
542 \r
543     public NotificationBuilder addNotification(final int line, final QName qname) {\r
544         final Builder parent = getActualNode();\r
545         if (!(parent.equals(this))) {\r
546             throw new YangParseException(name, line, "notification can be defined only in module or submodule");\r
547         }\r
548 \r
549         String notificationName = qname.getLocalName();\r
550         for (NotificationBuilder nb : addedNotifications) {\r
551             if (nb.getQName().equals(qname)) {\r
552                 throw new YangParseException(name, line, "notification with same name '" + notificationName\r
553                         + "' already declared at line " + nb.getLine());\r
554             }\r
555         }\r
556         for (RpcDefinitionBuilder rpc : addedRpcs) {\r
557             if (rpc.getQName().getLocalName().equals(notificationName)) {\r
558                 throw new YangParseException(name, line, "Can not add notification: rpc with same name '"\r
559                         + notificationName + "' already declared at line " + rpc.getLine());\r
560             }\r
561         }\r
562         for (DataSchemaNodeBuilder addedChild : addedChildNodes) {\r
563             if (addedChild.getQName().getLocalName().equals(notificationName)) {\r
564                 throw new YangParseException(name, line, "Can not add notification: node with same name '"\r
565                         + notificationName + "' already declared at line " + addedChild.getLine());\r
566             }\r
567         }\r
568 \r
569         final NotificationBuilder builder = new NotificationBuilder(name, line, qname);\r
570         builder.setParent(parent);\r
571         addedNotifications.add(builder);\r
572 \r
573         return builder;\r
574     }\r
575 \r
576     public FeatureBuilder addFeature(final int line, final QName qname) {\r
577         Builder parent = getActualNode();\r
578         if (!(parent.equals(this))) {\r
579             throw new YangParseException(name, line, "feature can be defined only in module or submodule");\r
580         }\r
581 \r
582         final FeatureBuilder builder = new FeatureBuilder(name, line, qname);\r
583         builder.setParent(parent);\r
584 \r
585         String featureName = qname.getLocalName();\r
586         for (FeatureBuilder addedFeature : addedFeatures) {\r
587             if (addedFeature.getQName().getLocalName().equals(featureName)) {\r
588                 throw new YangParseException(name, line, "feature with same name '" + featureName\r
589                         + "' already declared at line " + addedFeature.getLine());\r
590             }\r
591         }\r
592         addedFeatures.add(builder);\r
593         return builder;\r
594     }\r
595 \r
596     public ChoiceBuilder addChoice(final int line, final QName qname) {\r
597         final ChoiceBuilder builder = new ChoiceBuilder(name, line, qname);\r
598 \r
599         Builder parent = getActualNode();\r
600         builder.setParent(parent);\r
601         addChildToParent(parent, builder, qname.getLocalName());\r
602 \r
603         return builder;\r
604     }\r
605 \r
606     public ChoiceCaseBuilder addCase(final int line, final QName qname) {\r
607         Builder parent = getActualNode();\r
608         if (parent == null || parent.equals(this)) {\r
609             throw new YangParseException(name, line, "'case' parent not found");\r
610         }\r
611 \r
612         final ChoiceCaseBuilder builder = new ChoiceCaseBuilder(name, line, qname);\r
613         builder.setParent(parent);\r
614 \r
615         if (parent instanceof ChoiceBuilder) {\r
616             ((ChoiceBuilder) parent).addCase(builder);\r
617         } else if (parent instanceof AugmentationSchemaBuilder) {\r
618             ((AugmentationSchemaBuilder) parent).addChildNode(builder);\r
619         } else {\r
620             throw new YangParseException(name, line, "Unresolved parent of 'case' " + qname.getLocalName());\r
621         }\r
622 \r
623         return builder;\r
624     }\r
625 \r
626     public AnyXmlBuilder addAnyXml(final int line, final QName qname, final SchemaPath schemaPath) {\r
627         final AnyXmlBuilder builder = new AnyXmlBuilder(name, line, qname, schemaPath);\r
628 \r
629         Builder parent = getActualNode();\r
630         builder.setParent(parent);\r
631         addChildToParent(parent, builder, qname.getLocalName());\r
632 \r
633         return builder;\r
634     }\r
635 \r
636     @Override\r
637     public void addTypedef(TypeDefinitionBuilder typedefBuilder) {\r
638         String nodeName = typedefBuilder.getQName().getLocalName();\r
639         for (TypeDefinitionBuilder tdb : addedTypedefs) {\r
640             if (tdb.getQName().getLocalName().equals(nodeName)) {\r
641                 throw new YangParseException(name, typedefBuilder.getLine(), "typedef with same name '" + nodeName\r
642                         + "' already declared at line " + tdb.getLine());\r
643             }\r
644         }\r
645         addedTypedefs.add(typedefBuilder);\r
646     }\r
647 \r
648     public TypeDefinitionBuilderImpl addTypedef(final int line, final QName qname) {\r
649         final TypeDefinitionBuilderImpl builder = new TypeDefinitionBuilderImpl(name, line, qname);\r
650 \r
651         Builder parent = getActualNode();\r
652         builder.setParent(parent);\r
653 \r
654         String typedefName = qname.getLocalName();\r
655         if (parent.equals(this)) {\r
656             for (TypeDefinitionBuilder tdb : addedTypedefs) {\r
657                 if (tdb.getQName().getLocalName().equals(typedefName)) {\r
658                     throw new YangParseException(name, line, "typedef with same name '" + typedefName\r
659                             + "' already declared at line " + tdb.getLine());\r
660                 }\r
661             }\r
662             addedTypedefs.add(builder);\r
663         } else {\r
664             if (parent instanceof DataNodeContainerBuilder) {\r
665                 DataNodeContainerBuilder parentNode = (DataNodeContainerBuilder) parent;\r
666                 for (TypeDefinitionBuilder child : parentNode.getTypeDefinitionBuilders()) {\r
667                     if (child.getQName().getLocalName().equals(typedefName)) {\r
668                         throw new YangParseException(name, line, "typedef with same name '" + typedefName\r
669                                 + "' already declared at line " + child.getLine());\r
670                     }\r
671                 }\r
672                 parentNode.addTypedef(builder);\r
673             } else if (parent instanceof RpcDefinitionBuilder) {\r
674                 RpcDefinitionBuilder rpcParent = (RpcDefinitionBuilder) parent;\r
675                 for (TypeDefinitionBuilder tdb : rpcParent.getTypeDefinitions()) {\r
676                     if (tdb.getQName().getLocalName().equals(builder.getQName().getLocalName())) {\r
677                         throw new YangParseException(name, line, "typedef with same name '" + typedefName\r
678                                 + "' already declared at line " + tdb.getLine());\r
679                     }\r
680                 }\r
681                 rpcParent.addTypedef(builder);\r
682             } else {\r
683                 throw new YangParseException(name, line, "Unresolved parent of typedef " + typedefName);\r
684             }\r
685         }\r
686 \r
687         return builder;\r
688     }\r
689 \r
690     public void setType(final TypeDefinition<?> type) {\r
691         Builder parent = getActualNode();\r
692         if (parent == null || !(parent instanceof TypeAwareBuilder)) {\r
693             throw new YangParseException("Failed to set type '" + type.getQName().getLocalName()\r
694                     + "'. Invalid parent node: " + parent);\r
695         }\r
696         ((TypeAwareBuilder) parent).setType(type);\r
697     }\r
698 \r
699     public UnionTypeBuilder addUnionType(final int line, final URI namespace, final Date revision) {\r
700         final Builder parent = getActualNode();\r
701         if (parent == null) {\r
702             throw new YangParseException(name, line, "Unresolved parent of union type");\r
703         } else {\r
704             final UnionTypeBuilder union = new UnionTypeBuilder(name, line);\r
705             if (parent instanceof TypeAwareBuilder) {\r
706                 ((TypeAwareBuilder) parent).setTypedef(union);\r
707                 return union;\r
708             } else {\r
709                 throw new YangParseException(name, line, "Invalid parent of union type.");\r
710             }\r
711         }\r
712     }\r
713 \r
714     public void addIdentityrefType(final int line, final SchemaPath schemaPath, final String baseString) {\r
715         final IdentityrefTypeBuilder identityref = new IdentityrefTypeBuilder(name, line, baseString, schemaPath);\r
716 \r
717         final Builder parent = getActualNode();\r
718         if (parent == null) {\r
719             throw new YangParseException(name, line, "Unresolved parent of identityref type.");\r
720         } else {\r
721             if (parent instanceof TypeAwareBuilder) {\r
722                 final TypeAwareBuilder typeParent = (TypeAwareBuilder) parent;\r
723                 typeParent.setTypedef(identityref);\r
724                 dirtyNodes.add(typeParent);\r
725             } else {\r
726                 throw new YangParseException(name, line, "Invalid parent of identityref type.");\r
727             }\r
728         }\r
729     }\r
730 \r
731     public DeviationBuilder addDeviation(final int line, final String targetPath) {\r
732         Builder parent = getActualNode();\r
733         if (!(parent.equals(this))) {\r
734             throw new YangParseException(name, line, "deviation can be defined only in module or submodule");\r
735         }\r
736 \r
737         final DeviationBuilder builder = new DeviationBuilder(name, line, targetPath);\r
738         builder.setParent(parent);\r
739         addedDeviations.add(builder);\r
740         return builder;\r
741     }\r
742 \r
743     public IdentitySchemaNodeBuilder addIdentity(final QName qname, final int line) {\r
744         Builder parent = getActualNode();\r
745         if (!(parent.equals(this))) {\r
746             throw new YangParseException(name, line, "identity can be defined only in module or submodule");\r
747         }\r
748         String identityName = qname.getLocalName();\r
749         for (IdentitySchemaNodeBuilder idBuilder : addedIdentities) {\r
750             if (idBuilder.getQName().equals(qname)) {\r
751                 throw new YangParseException(name, line, "identity with same name '" + identityName\r
752                         + "' already declared at line " + idBuilder.getLine());\r
753             }\r
754         }\r
755 \r
756         final IdentitySchemaNodeBuilder builder = new IdentitySchemaNodeBuilder(name, line, qname);\r
757         builder.setParent(parent);\r
758         addedIdentities.add(builder);\r
759         return builder;\r
760     }\r
761 \r
762     @Override\r
763     public void addUnknownNodeBuilder(final UnknownSchemaNodeBuilder builder) {\r
764         addedUnknownNodes.add(builder);\r
765         allUnknownNodes.add(builder);\r
766     }\r
767 \r
768     public UnknownSchemaNodeBuilder addUnknownSchemaNode(final int line, final QName qname) {\r
769         final Builder parent = getActualNode();\r
770         final UnknownSchemaNodeBuilder builder = new UnknownSchemaNodeBuilder(name, line, qname);\r
771         builder.setParent(parent);\r
772         allUnknownNodes.add(builder);\r
773 \r
774         if (parent.equals(this)) {\r
775             addedUnknownNodes.add(builder);\r
776         } else {\r
777             if (parent instanceof SchemaNodeBuilder) {\r
778                 ((SchemaNodeBuilder) parent).addUnknownNodeBuilder(builder);\r
779             } else if (parent instanceof DataNodeContainerBuilder) {\r
780                 ((DataNodeContainerBuilder) parent).addUnknownNodeBuilder(builder);\r
781             } else if (parent instanceof RefineHolder) {\r
782                 ((RefineHolder) parent).addUnknownNodeBuilder(builder);\r
783             } else {\r
784                 throw new YangParseException(name, line, "Unresolved parent of unknown node '" + qname.getLocalName()\r
785                         + "'");\r
786             }\r
787         }\r
788 \r
789         return builder;\r
790     }\r
791     \r
792     public Set<RpcDefinitionBuilder> getRpcs() {\r
793         return addedRpcs;\r
794     }\r
795 \r
796     public Set<NotificationBuilder> getNotifications() {\r
797         return addedNotifications;\r
798     }\r
799     \r
800     @Override\r
801     public String toString() {\r
802         return "module " + name;\r
803     }\r
804 \r
805     private final class ModuleImpl implements Module {\r
806         private URI namespace;\r
807         private final String name;\r
808         private Date revision;\r
809         private String prefix;\r
810         private String yangVersion;\r
811         private String description;\r
812         private String reference;\r
813         private String organization;\r
814         private String contact;\r
815         private Set<ModuleImport> imports = Collections.emptySet();\r
816         private Set<FeatureDefinition> features = Collections.emptySet();\r
817         private Set<TypeDefinition<?>> typeDefinitions = Collections.emptySet();\r
818         private Set<NotificationDefinition> notifications = Collections.emptySet();\r
819         private Set<AugmentationSchema> augmentations = Collections.emptySet();\r
820         private Set<RpcDefinition> rpcs = Collections.emptySet();\r
821         private Set<Deviation> deviations = Collections.emptySet();\r
822         private Map<QName, DataSchemaNode> childNodes = Collections.emptyMap();\r
823         private Set<GroupingDefinition> groupings = Collections.emptySet();\r
824         private Set<UsesNode> uses = Collections.emptySet();\r
825         private List<ExtensionDefinition> extensionNodes = Collections.emptyList();\r
826         private Set<IdentitySchemaNode> identities = Collections.emptySet();\r
827         private List<UnknownSchemaNode> unknownNodes = Collections.emptyList();\r
828 \r
829         private ModuleImpl(String name) {\r
830             this.name = name;\r
831         }\r
832 \r
833         @Override\r
834         public URI getNamespace() {\r
835             return namespace;\r
836         }\r
837 \r
838         private void setNamespace(URI namespace) {\r
839             this.namespace = namespace;\r
840         }\r
841 \r
842         @Override\r
843         public String getName() {\r
844             return name;\r
845         }\r
846 \r
847         @Override\r
848         public Date getRevision() {\r
849             return revision;\r
850         }\r
851 \r
852         private void setRevision(Date revision) {\r
853             this.revision = revision;\r
854         }\r
855 \r
856         @Override\r
857         public String getPrefix() {\r
858             return prefix;\r
859         }\r
860 \r
861         private void setPrefix(String prefix) {\r
862             this.prefix = prefix;\r
863         }\r
864 \r
865         @Override\r
866         public String getYangVersion() {\r
867             return yangVersion;\r
868         }\r
869 \r
870         private void setYangVersion(String yangVersion) {\r
871             this.yangVersion = yangVersion;\r
872         }\r
873 \r
874         @Override\r
875         public String getDescription() {\r
876             return description;\r
877         }\r
878 \r
879         private void setDescription(String description) {\r
880             this.description = description;\r
881         }\r
882 \r
883         @Override\r
884         public String getReference() {\r
885             return reference;\r
886         }\r
887 \r
888         private void setReference(String reference) {\r
889             this.reference = reference;\r
890         }\r
891 \r
892         @Override\r
893         public String getOrganization() {\r
894             return organization;\r
895         }\r
896 \r
897         private void setOrganization(String organization) {\r
898             this.organization = organization;\r
899         }\r
900 \r
901         @Override\r
902         public String getContact() {\r
903             return contact;\r
904         }\r
905 \r
906         private void setContact(String contact) {\r
907             this.contact = contact;\r
908         }\r
909 \r
910         @Override\r
911         public Set<ModuleImport> getImports() {\r
912             return imports;\r
913         }\r
914 \r
915         private void setImports(Set<ModuleImport> imports) {\r
916             if (imports != null) {\r
917                 this.imports = imports;\r
918             }\r
919         }\r
920 \r
921         @Override\r
922         public Set<FeatureDefinition> getFeatures() {\r
923             return features;\r
924         }\r
925 \r
926         private void setFeatures(Set<FeatureDefinition> features) {\r
927             if (features != null) {\r
928                 this.features = features;\r
929             }\r
930         }\r
931 \r
932         @Override\r
933         public Set<TypeDefinition<?>> getTypeDefinitions() {\r
934             return typeDefinitions;\r
935         }\r
936 \r
937         private void setTypeDefinitions(Set<TypeDefinition<?>> typeDefinitions) {\r
938             if (typeDefinitions != null) {\r
939                 this.typeDefinitions = typeDefinitions;\r
940             }\r
941         }\r
942 \r
943         @Override\r
944         public Set<NotificationDefinition> getNotifications() {\r
945             return notifications;\r
946         }\r
947 \r
948         private void setNotifications(Set<NotificationDefinition> notifications) {\r
949             if (notifications != null) {\r
950                 this.notifications = notifications;\r
951             }\r
952         }\r
953 \r
954         @Override\r
955         public Set<AugmentationSchema> getAugmentations() {\r
956             return augmentations;\r
957         }\r
958 \r
959         private void setAugmentations(Set<AugmentationSchema> augmentations) {\r
960             if (augmentations != null) {\r
961                 this.augmentations = augmentations;\r
962             }\r
963         }\r
964 \r
965         @Override\r
966         public Set<RpcDefinition> getRpcs() {\r
967             return rpcs;\r
968         }\r
969 \r
970         private void setRpcs(Set<RpcDefinition> rpcs) {\r
971             if (rpcs != null) {\r
972                 this.rpcs = rpcs;\r
973             }\r
974         }\r
975 \r
976         @Override\r
977         public Set<Deviation> getDeviations() {\r
978             return deviations;\r
979         }\r
980 \r
981         private void setDeviations(Set<Deviation> deviations) {\r
982             if (deviations != null) {\r
983                 this.deviations = deviations;\r
984             }\r
985         }\r
986 \r
987         @Override\r
988         public Set<DataSchemaNode> getChildNodes() {\r
989             return new LinkedHashSet<DataSchemaNode>(childNodes.values());\r
990         }\r
991 \r
992         private void setChildNodes(Map<QName, DataSchemaNode> childNodes) {\r
993             if (childNodes != null) {\r
994                 this.childNodes = childNodes;\r
995             }\r
996         }\r
997 \r
998         @Override\r
999         public Set<GroupingDefinition> getGroupings() {\r
1000             return groupings;\r
1001         }\r
1002 \r
1003         private void setGroupings(Set<GroupingDefinition> groupings) {\r
1004             if (groupings != null) {\r
1005                 this.groupings = groupings;\r
1006             }\r
1007         }\r
1008 \r
1009         @Override\r
1010         public Set<UsesNode> getUses() {\r
1011             return uses;\r
1012         }\r
1013 \r
1014         private void setUses(Set<UsesNode> uses) {\r
1015             if (uses != null) {\r
1016                 this.uses = uses;\r
1017             }\r
1018         }\r
1019 \r
1020         @Override\r
1021         public List<ExtensionDefinition> getExtensionSchemaNodes() {\r
1022             return extensionNodes;\r
1023         }\r
1024 \r
1025         private void setExtensionSchemaNodes(final List<ExtensionDefinition> extensionNodes) {\r
1026             if (extensionNodes != null) {\r
1027                 this.extensionNodes = extensionNodes;\r
1028             }\r
1029         }\r
1030 \r
1031         @Override\r
1032         public Set<IdentitySchemaNode> getIdentities() {\r
1033             return identities;\r
1034         }\r
1035 \r
1036         private void setIdentities(final Set<IdentitySchemaNode> identities) {\r
1037             if (identities != null) {\r
1038                 this.identities = identities;\r
1039             }\r
1040         }\r
1041 \r
1042         @Override\r
1043         public List<UnknownSchemaNode> getUnknownSchemaNodes() {\r
1044             return unknownNodes;\r
1045         }\r
1046 \r
1047         private void setUnknownSchemaNodes(final List<UnknownSchemaNode> unknownNodes) {\r
1048             if (unknownNodes != null) {\r
1049                 this.unknownNodes = unknownNodes;\r
1050             }\r
1051         }\r
1052 \r
1053         @Override\r
1054         public DataSchemaNode getDataChildByName(QName name) {\r
1055             return childNodes.get(name);\r
1056         }\r
1057 \r
1058         @Override\r
1059         public DataSchemaNode getDataChildByName(String name) {\r
1060             DataSchemaNode result = null;\r
1061             for (Map.Entry<QName, DataSchemaNode> entry : childNodes.entrySet()) {\r
1062                 if (entry.getKey().getLocalName().equals(name)) {\r
1063                     result = entry.getValue();\r
1064                     break;\r
1065                 }\r
1066             }\r
1067             return result;\r
1068         }\r
1069 \r
1070         @Override\r
1071         public int hashCode() {\r
1072             final int prime = 31;\r
1073             int result = 1;\r
1074             result = prime * result + ((namespace == null) ? 0 : namespace.hashCode());\r
1075             result = prime * result + ((name == null) ? 0 : name.hashCode());\r
1076             result = prime * result + ((revision == null) ? 0 : revision.hashCode());\r
1077             result = prime * result + ((prefix == null) ? 0 : prefix.hashCode());\r
1078             result = prime * result + ((yangVersion == null) ? 0 : yangVersion.hashCode());\r
1079             return result;\r
1080         }\r
1081 \r
1082         @Override\r
1083         public boolean equals(Object obj) {\r
1084             if (this == obj) {\r
1085                 return true;\r
1086             }\r
1087             if (obj == null) {\r
1088                 return false;\r
1089             }\r
1090             if (getClass() != obj.getClass()) {\r
1091                 return false;\r
1092             }\r
1093             ModuleImpl other = (ModuleImpl) obj;\r
1094             if (namespace == null) {\r
1095                 if (other.namespace != null) {\r
1096                     return false;\r
1097                 }\r
1098             } else if (!namespace.equals(other.namespace)) {\r
1099                 return false;\r
1100             }\r
1101             if (name == null) {\r
1102                 if (other.name != null) {\r
1103                     return false;\r
1104                 }\r
1105             } else if (!name.equals(other.name)) {\r
1106                 return false;\r
1107             }\r
1108             if (revision == null) {\r
1109                 if (other.revision != null) {\r
1110                     return false;\r
1111                 }\r
1112             } else if (!revision.equals(other.revision)) {\r
1113                 return false;\r
1114             }\r
1115             if (prefix == null) {\r
1116                 if (other.prefix != null) {\r
1117                     return false;\r
1118                 }\r
1119             } else if (!prefix.equals(other.prefix)) {\r
1120                 return false;\r
1121             }\r
1122             if (yangVersion == null) {\r
1123                 if (other.yangVersion != null) {\r
1124                     return false;\r
1125                 }\r
1126             } else if (!yangVersion.equals(other.yangVersion)) {\r
1127                 return false;\r
1128             }\r
1129             return true;\r
1130         }\r
1131 \r
1132         @Override\r
1133         public String toString() {\r
1134             StringBuilder sb = new StringBuilder(ModuleImpl.class.getSimpleName());\r
1135             sb.append("[");\r
1136             sb.append("name=" + name);\r
1137             sb.append(", namespace=" + namespace);\r
1138             sb.append(", revision=" + revision);\r
1139             sb.append(", prefix=" + prefix);\r
1140             sb.append(", yangVersion=" + yangVersion);\r
1141             sb.append("]");\r
1142             return sb.toString();\r
1143         }\r
1144     }\r
1145 \r
1146     /**\r
1147      * Add child to parent. Method checks for duplicates and add given child\r
1148      * node to parent. If node with same name is found, throws exception. If\r
1149      * parent is null, child node will be added directly to module.\r
1150      *\r
1151      * @param parent\r
1152      * @param child\r
1153      * @param childName\r
1154      */\r
1155     private void addChildToParent(final Builder parent, final DataSchemaNodeBuilder child, final String childName) {\r
1156         final int line = child.getLine();\r
1157         if (parent.equals(this)) {\r
1158             // if parent == null => node is defined under module\r
1159             // All leafs, leaf-lists, lists, containers, choices, rpcs,\r
1160             // notifications, and anyxmls defined within a parent node or at the\r
1161             // top level of the module or its submodules share the same\r
1162             // identifier namespace.\r
1163             for (DataSchemaNodeBuilder childNode : addedChildNodes) {\r
1164                 if (childNode.getQName().getLocalName().equals(childName)) {\r
1165                     throw new YangParseException(name, line, "Can not add '" + child\r
1166                             + "': node with same name already declared at line " + childNode.getLine());\r
1167                 }\r
1168             }\r
1169             for (RpcDefinitionBuilder rpc : addedRpcs) {\r
1170                 if (rpc.getQName().getLocalName().equals(childName)) {\r
1171                     throw new YangParseException(name, line, "Can not add '" + child\r
1172                             + "': rpc with same name already declared at line " + rpc.getLine());\r
1173                 }\r
1174             }\r
1175             for (NotificationBuilder notification : addedNotifications) {\r
1176                 if (notification.getQName().getLocalName().equals(childName)) {\r
1177                     throw new YangParseException(name, line, "Can not add '" + child\r
1178                             + "': notification with same name already declared at line " + notification.getLine());\r
1179                 }\r
1180             }\r
1181             addedChildNodes.add(child);\r
1182         } else {\r
1183             if(parent instanceof AugmentationSchemaBuilder) {\r
1184                 child.setAugmenting(true);\r
1185             }\r
1186             // no need for checking rpc and notification because they can be\r
1187             // defined only under module or submodule\r
1188             if (parent instanceof DataNodeContainerBuilder) {\r
1189                 DataNodeContainerBuilder parentNode = (DataNodeContainerBuilder) parent;\r
1190                 for (DataSchemaNodeBuilder childNode : parentNode.getChildNodeBuilders()) {\r
1191                     if (childNode.getQName().getLocalName().equals(childName)) {\r
1192                         throw new YangParseException(name, line, "Can not add '" + child + "': node with same name '"\r
1193                                 + childName + "' already declared at line " + childNode.getLine());\r
1194                     }\r
1195                 }\r
1196                 parentNode.addChildNode(child);\r
1197             } else if (parent instanceof ChoiceBuilder) {\r
1198                 ChoiceBuilder parentNode = (ChoiceBuilder) parent;\r
1199                 for (ChoiceCaseBuilder caseBuilder : parentNode.getCases()) {\r
1200                     if (caseBuilder.getQName().getLocalName().equals(childName)) {\r
1201                         throw new YangParseException(name, line, "Can not add '" + child + "': case with same name '"\r
1202                                 + childName + "' already declared at line " + caseBuilder.getLine());\r
1203                     }\r
1204                 }\r
1205                 parentNode.addCase(child);\r
1206             } else {\r
1207                 throw new YangParseException(name, line, "Unresolved parent of node '" + childName + "'.");\r
1208             }\r
1209         }\r
1210     }\r
1211 \r
1212     private ModuleImport createModuleImport(final String moduleName, final Date revision, final String prefix) {\r
1213         final ModuleImport moduleImport = new ModuleImport() {\r
1214             @Override\r
1215             public String getModuleName() {\r
1216                 return moduleName;\r
1217             }\r
1218 \r
1219             @Override\r
1220             public Date getRevision() {\r
1221                 return revision;\r
1222             }\r
1223 \r
1224             @Override\r
1225             public String getPrefix() {\r
1226                 return prefix;\r
1227             }\r
1228 \r
1229             @Override\r
1230             public int hashCode() {\r
1231                 final int prime = 31;\r
1232                 int result = 1;\r
1233                 result = prime * result + ((moduleName == null) ? 0 : moduleName.hashCode());\r
1234                 result = prime * result + ((revision == null) ? 0 : revision.hashCode());\r
1235                 result = prime * result + ((prefix == null) ? 0 : prefix.hashCode());\r
1236                 return result;\r
1237             }\r
1238 \r
1239             @Override\r
1240             public boolean equals(Object obj) {\r
1241                 if (this == obj) {\r
1242                     return true;\r
1243                 }\r
1244                 if (obj == null) {\r
1245                     return false;\r
1246                 }\r
1247                 if (getClass() != obj.getClass()) {\r
1248                     return false;\r
1249                 }\r
1250                 ModuleImport other = (ModuleImport) obj;\r
1251                 if (getModuleName() == null) {\r
1252                     if (other.getModuleName() != null) {\r
1253                         return false;\r
1254                     }\r
1255                 } else if (!getModuleName().equals(other.getModuleName())) {\r
1256                     return false;\r
1257                 }\r
1258                 if (getRevision() == null) {\r
1259                     if (other.getRevision() != null) {\r
1260                         return false;\r
1261                     }\r
1262                 } else if (!getRevision().equals(other.getRevision())) {\r
1263                     return false;\r
1264                 }\r
1265                 if (getPrefix() == null) {\r
1266                     if (other.getPrefix() != null) {\r
1267                         return false;\r
1268                     }\r
1269                 } else if (!getPrefix().equals(other.getPrefix())) {\r
1270                     return false;\r
1271                 }\r
1272                 return true;\r
1273             }\r
1274 \r
1275             @Override\r
1276             public String toString() {\r
1277                 return "ModuleImport[moduleName=" + moduleName + ", revision=" + revision + ", prefix=" + prefix + "]";\r
1278             }\r
1279         };\r
1280         return moduleImport;\r
1281     }\r
1282 \r
1283 }\r