1 package org.opendaylight.yangtools.yang.unified.doc.generator
\r
3 import org.opendaylight.yangtools.yang.model.api.SchemaContext
\r
6 import org.opendaylight.yangtools.yang.model.api.Module
\r
7 import java.io.IOException
\r
8 import java.util.HashSet
\r
9 import java.io.BufferedWriter
\r
10 import java.io.OutputStreamWriter;
\r
11 import org.opendaylight.yangtools.yang.model.api.DataSchemaNode
\r
12 import org.opendaylight.yangtools.yang.model.api.ListSchemaNode
\r
13 import org.opendaylight.yangtools.yang.model.api.TypeDefinition
\r
14 import org.opendaylight.yangtools.yang.model.api.SchemaNode
\r
15 import org.opendaylight.yangtools.yang.model.util.ExtendedType
\r
16 import org.opendaylight.yangtools.yang.model.api.type.StringTypeDefinition
\r
17 import java.text.SimpleDateFormat
\r
18 import java.util.Collection
\r
19 import org.opendaylight.yangtools.yang.model.api.type.LengthConstraint
\r
20 import org.opendaylight.yangtools.yang.model.api.type.BinaryTypeDefinition
\r
21 import org.opendaylight.yangtools.yang.model.api.type.DecimalTypeDefinition
\r
22 import org.opendaylight.yangtools.yang.model.api.type.RangeConstraint
\r
23 import org.opendaylight.yangtools.yang.model.api.type.IntegerTypeDefinition
\r
24 import org.opendaylight.yangtools.yang.model.api.type.UnsignedIntegerTypeDefinition
\r
25 import org.opendaylight.yangtools.yang.model.api.NotificationDefinition
\r
26 import org.opendaylight.yangtools.yang.model.api.DataNodeContainer
\r
27 import org.slf4j.LoggerFactory
\r
28 import org.slf4j.Logger
\r
29 import java.util.List
\r
30 import org.opendaylight.yangtools.yang.common.QName
\r
31 import org.opendaylight.yangtools.yang.model.api.RpcDefinition
\r
32 import org.opendaylight.yangtools.yang.model.api.ExtensionDefinition
\r
33 import java.util.ArrayList
\r
34 import java.util.Map
\r
35 import org.opendaylight.yangtools.yang.model.api.SchemaPath
\r
37 import org.sonatype.plexus.build.incremental.BuildContext;
\r
38 import org.sonatype.plexus.build.incremental.DefaultBuildContext;
\r
40 import org.opendaylight.yangtools.yang.model.api.ChoiceNode
\r
41 import org.opendaylight.yangtools.yang.model.api.ChoiceCaseNode
\r
42 import org.opendaylight.yangtools.yang.model.api.ContainerSchemaNode
\r
43 import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier
\r
44 import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier.NodeIdentifierWithPredicates
\r
45 import java.util.LinkedHashMap
\r
46 import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier.NodeIdentifier
\r
47 import org.opendaylight.yangtools.yang.model.api.LeafSchemaNode
\r
48 import org.opendaylight.yangtools.yang.model.api.LeafListSchemaNode
\rimport java.util.HashMap
49 import org.opendaylight.yangtools.yang.model.api.AnyXmlSchemaNode
51 class GeneratorImpl {
\r
54 static val REVISION_FORMAT = new SimpleDateFormat("yyyy-MM-dd")
\r
55 static val Logger LOG = LoggerFactory.getLogger(GeneratorImpl)
\r
56 static val BuildContext CTX = new DefaultBuildContext();
\r
57 var Module currentModule;
\r
60 def generate(SchemaContext context, File targetPath, Set<Module> modulesToGen) throws IOException {
\r
63 val it = new HashSet;
\r
64 for (module : modulesToGen) {
\r
65 add(generateDocumentation(module, context));
\r
70 def generateDocumentation(Module module, SchemaContext ctx) {
\r
71 val destination = new File(path, '''«module.name».html''')
\r
73 val fw = new OutputStreamWriter(CTX.newFileOutputStream(destination))
\r
74 val bw = new BufferedWriter(fw)
\r
75 currentModule = module;
\r
76 bw.append(generate(module, ctx));
\r
79 } catch (IOException e) {
\r
80 LOG.error(e.getMessage());
\r
85 def generate(Module module, SchemaContext ctx) '''
\r
89 <title>«module.name»</title>
\r
97 def body(Module module, SchemaContext ctx) '''
\r
100 «typeDefinitions(module)»
\r
102 «identities(module)»
\r
104 «groupings(module)»
\r
106 «dataStore(module)»
\r
108 «childNodes(module)»
\r
110 «notifications(module)»
\r
112 «augmentations(module, ctx)»
\r
116 «extensions(module)»
\r
123 def typeDefinitions(Module module) {
\r
124 val Set<TypeDefinition<?>> typedefs = module.typeDefinitions
\r
125 if (typedefs.empty) {
\r
129 <h2>Type Definitions</h2>
\r
131 «FOR typedef : typedefs»
\r
133 «strong("typedef " + typedef.QName.localName)»
\r
135 «typedef.descAndRefLi»
\r
136 «typedef.restrictions»
\r
144 private def identities(Module module) {
\r
145 if (module.identities.empty) {
\r
149 <h2>Identities</h2>
\r
151 «FOR identity : module.identities»
\r
153 «strong("identity " + identity.QName.localName)»
\r
155 «identity.descAndRefLi»
\r
156 «IF identity.baseIdentity != null»
\r
157 «listItem("base", identity.baseIdentity.QName.localName)»
\r
166 private def groupings(Module module) {
\r
167 if (module.groupings.empty) {
\r
173 «FOR grouping : module.groupings»
\r
175 «strong("grouping " + grouping.QName.localName)»
\r
177 «grouping.descAndRefLi»
\r
185 def dataStore(Module module) {
\r
186 if (module.childNodes.empty) {
\r
190 <h2>Datastore Structure</h2>
\r
195 def augmentations(Module module, SchemaContext context) {
\r
196 if (module.augmentations.empty) {
\r
200 <h2>Augmentations</h2>
\r
203 «FOR augment : module.augmentations»
\r
205 <h3>Target [«schemaPathAsRestconfPath(module, augment.targetPath, context)»]</h3>
\r
206 «augment.description»
\r
207 «IF augment.reference !== null»
\r
208 Reference «augment.reference»
\r
210 «IF augment.whenCondition !== null»
\r
211 When «augment.whenCondition.toString»
\r
213 «augment.childNodes.printChildren(3,InstanceIdentifier.builder().toInstance())»
\r
220 def notifications(Module module) {
\r
221 val Set<NotificationDefinition> notificationdefs = module.notifications
\r
222 if (notificationdefs.empty) {
\r
227 <h2>Notifications</h2>
\r
228 «FOR notificationdef : notificationdefs»
\r
230 <h3>«notificationdef.nodeName»</h3>
\r
231 «notificationdef.descAndRef»
\r
232 «notificationdef.childNodes.printChildren(3,InstanceIdentifier.builder().toInstance())»
\r
237 def rpcs(Module module) {
\r
238 if (module.rpcs.empty) {
\r
243 <h2>RPC Definitions</h2>
\r
244 «FOR rpc : module.rpcs»
\r
245 <h3>«rpc.nodeName»</h3>
\r
246 «rpc.rpcInfo(InstanceIdentifier.builder().node(rpc.QName).toInstance())»
\r
252 def extensions(Module module) {
\r
253 if (module.extensionSchemaNodes.empty) {
\r
257 <h2>Extensions</h2>
\r
258 «FOR ext : module.extensionSchemaNodes»
\r
260 <h3>«ext.nodeName»</h3>
\r
262 «extensionInfo(ext)»
\r
267 def features(Module module) {
\r
268 if (module.features.empty) {
\r
275 «FOR feature : module.features»
\r
277 «strong("feature " + feature.QName.localName)»
\r
279 «feature.descAndRefLi»
\r
287 def header(Module module) '''
\r
288 <h1>«module.name»</h1>
\r
290 <h2>Base Information</h2>
\r
293 <dd>«pre(module.prefix)»</dd>
\r
295 <dd>«pre(module.namespace.toString)»</dd>
\r
297 <dd>«pre(REVISION_FORMAT.format(module.revision))»</dd>
\r
299 «FOR imp : module.imports BEFORE "<dt>Imports</dt>" »
\r
300 <dd>«code(imp.prefix)» = «code(imp.moduleName)»</dd>
\r
305 def code(String string) '''<code>«string»</code>'''
\r
307 def process(Module module) {
\r
308 throw new UnsupportedOperationException("TODO: auto-generated method stub")
\r
311 def CharSequence tree(Module module) '''
\r
312 «strong("module " + module.name)»
\r
313 «module.childNodes.treeSet(InstanceIdentifier.builder.toInstance())»
\r
316 private def dispatch CharSequence tree(ChoiceNode node,InstanceIdentifier path) '''
\r
317 «node.nodeName» (choice)
\r
318 «casesTree(node.cases,path)»
\r
321 def casesTree(Set<ChoiceCaseNode> nodes,InstanceIdentifier path) '''
\r
326 «node.childNodes.treeSet(path)»
\r
332 private def dispatch CharSequence tree(DataSchemaNode node,InstanceIdentifier path) '''
\r
336 private def dispatch CharSequence tree(ListSchemaNode node,InstanceIdentifier path) '''
\r
337 «val newPath = path.append(node)»
\r
338 «localLink(newPath,node.nodeName)»
\r
339 «node.childNodes.treeSet(newPath)»
\r
342 private def dispatch CharSequence tree(ContainerSchemaNode node,InstanceIdentifier path) '''
\r
343 «val newPath = path.append(node)»
\r
344 «localLink(newPath,node.nodeName)»
\r
345 «node.childNodes.treeSet(newPath)»
\r
348 def CharSequence childNodes(Module module) '''
\r
349 «val childNodes = module.childNodes»
\r
350 «IF childNodes !== null && !childNodes.empty»
\r
351 <h2>Child nodes</h2>
\r
353 «childNodes.printChildren(3,InstanceIdentifier.builder().toInstance())»
\r
357 def CharSequence printChildren(Set<DataSchemaNode> nodes, int level, InstanceIdentifier path) {
\r
358 val anyxmlNodes = nodes.filter(AnyXmlSchemaNode)
\r
359 val leafNodes = nodes.filter(LeafSchemaNode)
\r
360 val leafListNodes = nodes.filter(LeafListSchemaNode)
\r
361 val choices = nodes.filter(ChoiceNode)
\r
362 val cases = nodes.filter(ChoiceCaseNode)
\r
363 val containers = nodes.filter(ContainerSchemaNode)
\r
364 val lists = nodes.filter(ListSchemaNode)
\r
366 «IF ((anyxmlNodes.size + leafNodes.size + leafListNodes.size + containers.size + lists.size) > 0)»
\r
367 <h3>Direct children</h3>
\r
369 «FOR childNode : anyxmlNodes»
\r
370 «childNode.printShortInfo(level,path)»
\r
372 «FOR childNode : leafNodes»
\r
373 «childNode.printShortInfo(level,path)»
\r
375 «FOR childNode : leafListNodes»
\r
376 «childNode.printShortInfo(level,path)»
\r
378 «FOR childNode : containers»
\r
379 «childNode.printShortInfo(level,path)»
\r
381 «FOR childNode : lists»
\r
382 «childNode.printShortInfo(level,path)»
\r
387 «IF !path.path.empty»
\r
388 <h3>XML example</h3>
\r
389 «nodes.xmlExample(path.path.last.nodeType,path)»
\r
392 «FOR childNode : containers»
\r
393 «childNode.printInfo(level,path)»
\r
395 «FOR childNode : lists»
\r
396 «childNode.printInfo(level,path)»
\r
398 «FOR childNode : choices»
\r
399 «childNode.printInfo(level,path)»
\r
401 «FOR childNode : cases»
\r
402 «childNode.printInfo(level,path)»
\r
408 def CharSequence xmlExample(Set<DataSchemaNode> nodes, QName name,InstanceIdentifier path) '''
\r
410 «xmlExampleTag(name,nodes.xmplExampleTags(path))»
\r
414 def CharSequence xmplExampleTags(Set<DataSchemaNode> nodes, InstanceIdentifier identifier) '''
\r
415 <!-- Child nodes -->
\r
417 <!-- «node.QName.localName» -->
\r
418 «node.asXmlExampleTag(identifier)»
\r
423 private def dispatch CharSequence asXmlExampleTag(LeafSchemaNode node, InstanceIdentifier identifier) '''
\r
424 «node.QName.xmlExampleTag("...")»
\r
427 private def dispatch CharSequence asXmlExampleTag(LeafListSchemaNode node, InstanceIdentifier identifier) '''
\r
428 <!-- This node could appear multiple times -->
\r
429 «node.QName.xmlExampleTag("...")»
\r
432 private def dispatch CharSequence asXmlExampleTag(ContainerSchemaNode node, InstanceIdentifier identifier) '''
\r
433 <!-- See «localLink(identifier.append(node),"definition")» for child nodes. -->
\r
434 «node.QName.xmlExampleTag("...")»
\r
438 private def dispatch CharSequence asXmlExampleTag(ListSchemaNode node, InstanceIdentifier identifier) '''
\r
439 <!-- See «localLink(identifier.append(node),"definition")» for child nodes. -->
\r
440 <!-- This node could appear multiple times -->
\r
441 «node.QName.xmlExampleTag("...")»
\r
445 private def dispatch CharSequence asXmlExampleTag(DataSchemaNode node, InstanceIdentifier identifier) '''
\r
450 def xmlExampleTag(QName name, CharSequence data) {
\r
451 return '''<«name.localName» xmlns="«name.namespace»">«data»</«name.localName»>'''
\r
454 def header(int level,QName name) '''<h«level»>«name.localName»</h«level»>'''
\r
457 def header(int level,InstanceIdentifier name) '''
\r
458 <h«level» id="«FOR cmp : name.path SEPARATOR "/"»«cmp.nodeType.localName»«ENDFOR»">
\r
459 «FOR cmp : name.path SEPARATOR "/"»«cmp.nodeType.localName»«ENDFOR»
\r
465 private def dispatch CharSequence printInfo(DataSchemaNode node, int level, InstanceIdentifier path) '''
\r
466 «header(level+1,node.QName)»
\r
469 private def dispatch CharSequence printInfo(ContainerSchemaNode node, int level, InstanceIdentifier path) '''
\r
470 «val newPath = path.append(node)»
\r
471 «header(level,newPath)»
\r
474 <dd>«newPath.asXmlPath»</dd>
\r
475 <dt>Restconf path</dt>
\r
476 <dd>«code(newPath.asRestconfPath)»</dd>
\r
478 «node.childNodes.printChildren(level,newPath)»
\r
481 private def dispatch CharSequence printInfo(ListSchemaNode node, int level, InstanceIdentifier path) '''
\r
482 «val newPath = path.append(node)»
\r
483 «header(level,newPath)»
\r
486 <dd>«newPath.asXmlPath»</dd>
\r
487 <dt>Restconf path</dt>
\r
488 <dd>«code(newPath.asRestconfPath)»</dd>
\r
490 «node.childNodes.printChildren(level,newPath)»
\r
493 private def dispatch CharSequence printInfo(ChoiceNode node, int level, InstanceIdentifier path) '''
\r
494 «val Set<DataSchemaNode> choiceCases = new HashSet(node.cases)»
\r
495 «choiceCases.printChildren(level,path)»
\r
498 private def dispatch CharSequence printInfo(ChoiceCaseNode node, int level, InstanceIdentifier path) '''
\r
499 «node.childNodes.printChildren(level,path)»
\r
504 def CharSequence printShortInfo(ContainerSchemaNode node, int level, InstanceIdentifier path) {
\r
505 val newPath = path.append(node);
\r
507 <li>«strong(localLink(newPath,node.QName.localName))» (container)</li>
\r
511 def CharSequence printShortInfo(ListSchemaNode node, int level, InstanceIdentifier path) {
\r
512 val newPath = path.append(node);
\r
514 <li>«strong(localLink(newPath,node.QName.localName))» (list)</li>
\r
518 def CharSequence printShortInfo(AnyXmlSchemaNode node, int level, InstanceIdentifier path) {
\r
520 <li>«strong((node.QName.localName))» (anyxml)</li>
\r
524 def CharSequence printShortInfo(LeafSchemaNode node, int level, InstanceIdentifier path) {
\r
526 <li>«strong((node.QName.localName))» (leaf)</li>
\r
530 def CharSequence printShortInfo(LeafListSchemaNode node, int level, InstanceIdentifier path) {
\r
532 <li>«strong((node.QName.localName))» (leaf-list)</li>
\r
536 def CharSequence localLink(InstanceIdentifier identifier, CharSequence text) '''
\r
537 <a href="#«FOR cmp : identifier.path SEPARATOR "/"»«cmp.nodeType.localName»«ENDFOR»">«text»</a>
\r
541 private def dispatch InstanceIdentifier append(InstanceIdentifier identifier, ContainerSchemaNode node) {
\r
542 val pathArguments = new ArrayList(identifier.path)
\r
543 pathArguments.add(new NodeIdentifier(node.QName));
\r
544 return new InstanceIdentifier(pathArguments);
\r
547 private def dispatch InstanceIdentifier append(InstanceIdentifier identifier, ListSchemaNode node) {
\r
548 val pathArguments = new ArrayList(identifier.path)
\r
549 val keyValues = new LinkedHashMap<QName,Object>();
\r
550 if(node.keyDefinition != null) {
\r
551 for(definition : node.keyDefinition) {
\r
552 keyValues.put(definition,new Object);
\r
555 pathArguments.add(new NodeIdentifierWithPredicates(node.QName,keyValues));
\r
556 return new InstanceIdentifier(pathArguments);
\r
560 def asXmlPath(InstanceIdentifier identifier) {
\r
564 def asRestconfPath(InstanceIdentifier identifier) {
\r
565 val it = new StringBuilder();
\r
566 append(currentModule.name)
\r
568 var previous = false;
\r
569 for(arg : identifier.path) {
\r
570 if(previous) append("/")
\r
571 append(arg.nodeType.localName);
\r
573 if(arg instanceof NodeIdentifierWithPredicates) {
\r
574 val nodeIdentifier = arg as NodeIdentifierWithPredicates;
\r
575 for(qname : nodeIdentifier.keyValues.keySet) {
\r
577 append(qname.localName)
\r
583 return it.toString;
\r
586 private def String schemaPathAsRestconfPath(Module module, SchemaPath schemaPath, SchemaContext ctx) {
\r
587 val Map<String, String> imports = new HashMap();
\r
588 for (mImport : module.imports) {
\r
589 imports.put(mImport.prefix, mImport.moduleName)
\r
592 val List<QName> path = schemaPath.path
\r
593 val StringBuilder pathString = new StringBuilder()
\r
594 if (schemaPath.absolute) {
\r
595 pathString.append("/")
\r
598 val QName qname = path.get(0)
\r
599 var Object parent = ctx.findModuleByNamespaceAndRevision(qname.namespace, qname.revision)
\r
601 for (name : path) {
\r
602 if (parent instanceof DataNodeContainer) {
\r
603 var SchemaNode node = (parent as DataNodeContainer).getDataChildByName(name)
\r
604 if (node == null && (parent instanceof Module)) {
\r
605 val notifications = (parent as Module).notifications;
\r
606 for (notification : notifications) {
\r
607 if (notification.QName.localName.equals(name.localName)) {
\r
608 node = notification
\r
613 if (!(node instanceof ChoiceNode) && !(node instanceof ChoiceCaseNode)) {
\r
614 var String prefix = node.QName.prefix
\r
615 var String moduleName
\r
616 if (prefix == null || "".equals(prefix) || prefix.equals(module.prefix)) {
\r
617 moduleName = module.name
\r
619 moduleName = imports.get(prefix)
\r
621 pathString.append(moduleName)
\r
622 pathString.append(":")
\r
623 pathString.append(node.QName.localName)
\r
624 pathString.append("/")
\r
627 } else if (parent instanceof ChoiceNode) {
\r
628 parent = (parent as ChoiceNode).getCaseNodeByName(qname.localName)
\r
631 return pathString.toString;
\r
635 def CharSequence childNodesInfoTree(Map<SchemaPath, DataSchemaNode> childNodes) '''
\r
636 «IF childNodes !== null && !childNodes.empty»
\r
637 «FOR child : childNodes.values»
\r
638 «childInfo(child, childNodes)»
\r
643 def CharSequence childInfo(DataSchemaNode node, Map<SchemaPath, DataSchemaNode> childNodes) '''
\r
644 «val String path = nodeSchemaPathToPath(node, childNodes)»
\r
649 «node.descAndRefLi»
\r
655 private def CharSequence treeSet(Collection<DataSchemaNode> childNodes, InstanceIdentifier path) '''
\r
656 «IF childNodes !== null && !childNodes.empty»
\r
658 «FOR child : childNodes»
\r
667 def listKeys(ListSchemaNode node) '''
\r
668 [«FOR key : node.keyDefinition SEPARATOR " "»«key.localName»«ENDFOR»]
\r
671 private def CharSequence rpcInfo(RpcDefinition rpc,InstanceIdentifier path) '''
\r
675 «rpc.input.tree(path)»
\r
678 «rpc.output.tree(path)»
\r
683 private def CharSequence extensionInfo(ExtensionDefinition ext) '''
\r
686 «listItem("Argument", ext.argument)»
\r
690 private def dispatch CharSequence tree(Void obj, InstanceIdentifier path) '''
\r
695 /* #################### RESTRICTIONS #################### */
\r
696 private def restrictions(TypeDefinition<?> type) '''
\r
701 private def dispatch toLength(TypeDefinition<?> type) {
\r
704 private def dispatch toLength(BinaryTypeDefinition type) '''
\r
705 «type.lengthConstraints.toLengthStmt»
\r
708 private def dispatch toLength(StringTypeDefinition type) '''
\r
709 «type.lengthConstraints.toLengthStmt»
\r
712 private def dispatch toLength(ExtendedType type) '''
\r
713 «type.lengthConstraints.toLengthStmt»
\r
716 private def dispatch toRange(TypeDefinition<?> type) {
\r
719 private def dispatch toRange(DecimalTypeDefinition type) '''
\r
720 «type.rangeConstraints.toRangeStmt»
\r
723 private def dispatch toRange(IntegerTypeDefinition type) '''
\r
724 «type.rangeConstraints.toRangeStmt»
\r
727 private def dispatch toRange(UnsignedIntegerTypeDefinition type) '''
\r
728 «type.rangeConstraints.toRangeStmt»
\r
731 private def dispatch toRange(ExtendedType type) '''
\r
732 «type.rangeConstraints.toRangeStmt»
\r
735 def toLengthStmt(Collection<LengthConstraint> lengths) '''
\r
736 «IF lengths != null && !lengths.empty»
\r
737 «listItem("Length restrictions")»
\r
739 «FOR length : lengths»
\r
741 «IF length.min == length.max»
\r
744 <«length.min», «length.max»>
\r
752 def toRangeStmt(Collection<RangeConstraint> ranges) '''
\r
753 «IF ranges != null && !ranges.empty»
\r
754 «listItem("Range restrictions")»
\r
756 «FOR range : ranges»
\r
758 «IF range.min == range.max»
\r
761 <«range.min», «range.max»>
\r
771 /* #################### UTILITY #################### */
\r
772 private def String strong(CharSequence str) '''<strong>«str»</strong>'''
\r
773 private def italic(CharSequence str) '''<i>«str»</i>'''
\r
774 private def pre(CharSequence str) '''<pre>«str»</pre>'''
\r
776 def CharSequence descAndRefLi(SchemaNode node) '''
\r
777 «listItem(node.description)»
\r
778 «listItem("Reference", node.reference)»
\r
781 def CharSequence descAndRef(SchemaNode node) '''
\r
783 «IF node.reference !== null»
\r
784 Reference «node.reference»
\r
788 private def listItem(String value) '''
\r
789 «IF value !== null && !value.empty»
\r
796 private def listItem(String name, String value) '''
\r
797 «IF value !== null && !value.empty»
\r
804 private def String nodeSchemaPathToPath(DataSchemaNode node, Map<SchemaPath, DataSchemaNode> childNodes) {
\r
805 if (node instanceof ChoiceNode || node instanceof ChoiceCaseNode) {
\r
809 val path = node.path.path
\r
810 val absolute = node.path.absolute;
\r
811 var StringBuilder result = new StringBuilder
\r
815 if (path !== null && !path.empty) {
\r
816 val List<QName> actual = new ArrayList()
\r
818 for (pathElement : path) {
\r
819 actual.add(pathElement)
\r
820 val DataSchemaNode nodeByPath = childNodes.get(new SchemaPath(actual, absolute))
\r
821 if (!(nodeByPath instanceof ChoiceNode) && !(nodeByPath instanceof ChoiceCaseNode)) {
\r
822 result.append(pathElement.localName)
\r
823 if (i != path.size - 1) {
\r
830 return result.toString
\r
833 private def void collectChildNodes(Collection<DataSchemaNode> source, Map<SchemaPath, DataSchemaNode> destination) {
\r
834 for (node : source) {
\r
835 destination.put(node.path, node)
\r
836 if (node instanceof DataNodeContainer) {
\r
837 collectChildNodes((node as DataNodeContainer).childNodes, destination)
\r
839 if (node instanceof ChoiceNode) {
\r
840 val List<DataSchemaNode> choiceCases = new ArrayList()
\r
841 for (caseNode : (node as ChoiceNode).cases) {
\r
842 choiceCases.add(caseNode)
\r
844 collectChildNodes(choiceCases, destination)
\r
849 private def dispatch addedByInfo(SchemaNode node) '''
\r
852 private def dispatch addedByInfo(DataSchemaNode node) '''
\r
853 «IF node.augmenting»(A)«ENDIF»«IF node.addedByUses»(U)«ENDIF»
\r
856 private def dispatch isAddedBy(SchemaNode node) {
\r
860 private def dispatch isAddedBy(DataSchemaNode node) {
\r
861 if (node.augmenting || node.addedByUses) {
\r
868 private def dispatch nodeName(SchemaNode node) '''
\r
869 «IF node.isAddedBy»
\r
870 «italic(node.QName.localName)»«node.addedByInfo»
\r
872 «node.QName.localName»«node.addedByInfo»
\r
876 private def dispatch nodeName(ContainerSchemaNode node) '''
\r
877 «IF node.isAddedBy»
\r
878 «strong(italic(node.QName.localName))»«node.addedByInfo»
\r
880 «strong(node.QName.localName)»«node.addedByInfo»
\r
884 private def dispatch nodeName(ListSchemaNode node) '''
\r
885 «IF node.isAddedBy»
\r
886 «strong(italic(node.QName.localName))» «IF node.keyDefinition !== null && !node.keyDefinition.empty»«node.listKeys»«ENDIF»«node.addedByInfo»
\r
888 «strong(node.QName.localName)» «IF node.keyDefinition !== null && !node.keyDefinition.empty»«node.listKeys»«ENDIF»
\r