2 * Copyright (c) 2014 Cisco Systems, Inc. and others. All rights reserved.
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
8 package org.opendaylight.yangtools.yang.unified.doc.generator
\r
10 import org.opendaylight.yangtools.yang.model.api.SchemaContext
\r
12 import java.util.Set
\r
13 import org.opendaylight.yangtools.yang.model.api.Module
\r
14 import java.io.IOException
\r
15 import java.util.HashSet
\r
16 import java.io.BufferedWriter
\r
17 import java.io.OutputStreamWriter;
\r
18 import org.opendaylight.yangtools.yang.model.api.DataSchemaNode
\r
19 import org.opendaylight.yangtools.yang.model.api.ListSchemaNode
\r
20 import org.opendaylight.yangtools.yang.model.api.TypeDefinition
\r
21 import org.opendaylight.yangtools.yang.model.api.SchemaNode
\r
22 import org.opendaylight.yangtools.yang.model.util.ExtendedType
\r
23 import org.opendaylight.yangtools.yang.model.api.type.StringTypeDefinition
\r
24 import java.text.SimpleDateFormat
\r
25 import java.util.Collection
\r
26 import org.opendaylight.yangtools.yang.model.api.type.LengthConstraint
\r
27 import org.opendaylight.yangtools.yang.model.api.type.BinaryTypeDefinition
\r
28 import org.opendaylight.yangtools.yang.model.api.type.DecimalTypeDefinition
\r
29 import org.opendaylight.yangtools.yang.model.api.type.RangeConstraint
\r
30 import org.opendaylight.yangtools.yang.model.api.type.IntegerTypeDefinition
\r
31 import org.opendaylight.yangtools.yang.model.api.type.UnsignedIntegerTypeDefinition
\r
32 import org.opendaylight.yangtools.yang.model.api.NotificationDefinition
\r
33 import org.opendaylight.yangtools.yang.model.api.DataNodeContainer
\r
34 import org.slf4j.LoggerFactory
\r
35 import org.slf4j.Logger
\r
36 import java.util.List
\r
37 import org.opendaylight.yangtools.yang.common.QName
\r
38 import org.opendaylight.yangtools.yang.model.api.RpcDefinition
\r
39 import org.opendaylight.yangtools.yang.model.api.ExtensionDefinition
\r
40 import java.util.ArrayList
\r
41 import java.util.Map
\r
42 import org.opendaylight.yangtools.yang.model.api.SchemaPath
\r
44 import org.sonatype.plexus.build.incremental.BuildContext;
\r
45 import org.sonatype.plexus.build.incremental.DefaultBuildContext;
\r
47 import org.opendaylight.yangtools.yang.model.api.ChoiceNode
\r
48 import org.opendaylight.yangtools.yang.model.api.ChoiceCaseNode
\r
49 import org.opendaylight.yangtools.yang.model.api.ContainerSchemaNode
\r
50 import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier
\r
51 import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier.NodeIdentifierWithPredicates
\r
52 import java.util.LinkedHashMap
\r
53 import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier.NodeIdentifier
\r
54 import org.opendaylight.yangtools.yang.model.api.LeafSchemaNode
\r
55 import org.opendaylight.yangtools.yang.model.api.LeafListSchemaNode
\rimport java.util.HashMap
56 import org.opendaylight.yangtools.yang.model.api.AnyXmlSchemaNode
58 class GeneratorImpl {
\r
61 static val REVISION_FORMAT = new SimpleDateFormat("yyyy-MM-dd")
\r
62 static val Logger LOG = LoggerFactory.getLogger(GeneratorImpl)
\r
63 static val BuildContext CTX = new DefaultBuildContext();
\r
64 var Module currentModule;
\r
67 def generate(SchemaContext context, File targetPath, Set<Module> modulesToGen) throws IOException {
\r
70 val it = new HashSet;
\r
71 for (module : modulesToGen) {
\r
72 add(generateDocumentation(module, context));
\r
77 def generateDocumentation(Module module, SchemaContext ctx) {
\r
78 val destination = new File(path, '''«module.name».html''')
\r
80 val fw = new OutputStreamWriter(CTX.newFileOutputStream(destination))
\r
81 val bw = new BufferedWriter(fw)
\r
82 currentModule = module;
\r
83 bw.append(generate(module, ctx));
\r
86 } catch (IOException e) {
\r
87 LOG.error(e.getMessage());
\r
92 def generate(Module module, SchemaContext ctx) '''
\r
96 <title>«module.name»</title>
\r
104 def body(Module module, SchemaContext ctx) '''
\r
107 «typeDefinitions(module)»
\r
109 «identities(module)»
\r
111 «groupings(module)»
\r
113 «dataStore(module)»
\r
115 «childNodes(module)»
\r
117 «notifications(module)»
\r
119 «augmentations(module, ctx)»
\r
123 «extensions(module)»
\r
130 def typeDefinitions(Module module) {
\r
131 val Set<TypeDefinition<?>> typedefs = module.typeDefinitions
\r
132 if (typedefs.empty) {
\r
136 <h2>Type Definitions</h2>
\r
138 «FOR typedef : typedefs»
\r
140 «strong("typedef " + typedef.QName.localName)»
\r
142 «typedef.descAndRefLi»
\r
143 «typedef.restrictions»
\r
151 private def identities(Module module) {
\r
152 if (module.identities.empty) {
\r
156 <h2>Identities</h2>
\r
158 «FOR identity : module.identities»
\r
160 «strong("identity " + identity.QName.localName)»
\r
162 «identity.descAndRefLi»
\r
163 «IF identity.baseIdentity != null»
\r
164 «listItem("base", identity.baseIdentity.QName.localName)»
\r
173 private def groupings(Module module) {
\r
174 if (module.groupings.empty) {
\r
180 «FOR grouping : module.groupings»
\r
182 «strong("grouping " + grouping.QName.localName)»
\r
184 «grouping.descAndRefLi»
\r
192 def dataStore(Module module) {
\r
193 if (module.childNodes.empty) {
\r
197 <h2>Datastore Structure</h2>
\r
202 def augmentations(Module module, SchemaContext context) {
\r
203 if (module.augmentations.empty) {
\r
207 <h2>Augmentations</h2>
\r
210 «FOR augment : module.augmentations»
\r
212 <h3>Target [«schemaPathAsRestconfPath(module, augment.targetPath, context)»]</h3>
\r
213 «augment.description»
\r
214 «IF augment.reference !== null»
\r
215 Reference «augment.reference»
\r
217 «IF augment.whenCondition !== null»
\r
218 When «augment.whenCondition.toString»
\r
220 «augment.childNodes.printChildren(3,InstanceIdentifier.builder().toInstance())»
\r
227 def notifications(Module module) {
\r
228 val Set<NotificationDefinition> notificationdefs = module.notifications
\r
229 if (notificationdefs.empty) {
\r
234 <h2>Notifications</h2>
\r
235 «FOR notificationdef : notificationdefs»
\r
237 <h3>«notificationdef.nodeName»</h3>
\r
238 «notificationdef.descAndRef»
\r
239 «notificationdef.childNodes.printChildren(3,InstanceIdentifier.builder().toInstance())»
\r
244 def rpcs(Module module) {
\r
245 if (module.rpcs.empty) {
\r
250 <h2>RPC Definitions</h2>
\r
251 «FOR rpc : module.rpcs»
\r
252 <h3>«rpc.nodeName»</h3>
\r
253 «rpc.rpcInfo(InstanceIdentifier.builder().node(rpc.QName).toInstance())»
\r
259 def extensions(Module module) {
\r
260 if (module.extensionSchemaNodes.empty) {
\r
264 <h2>Extensions</h2>
\r
265 «FOR ext : module.extensionSchemaNodes»
\r
267 <h3>«ext.nodeName»</h3>
\r
269 «extensionInfo(ext)»
\r
274 def features(Module module) {
\r
275 if (module.features.empty) {
\r
282 «FOR feature : module.features»
\r
284 «strong("feature " + feature.QName.localName)»
\r
286 «feature.descAndRefLi»
\r
294 def header(Module module) '''
\r
295 <h1>«module.name»</h1>
\r
297 <h2>Base Information</h2>
\r
300 <dd>«pre(module.prefix)»</dd>
\r
302 <dd>«pre(module.namespace.toString)»</dd>
\r
304 <dd>«pre(REVISION_FORMAT.format(module.revision))»</dd>
\r
306 «FOR imp : module.imports BEFORE "<dt>Imports</dt>" »
\r
307 <dd>«code(imp.prefix)» = «code(imp.moduleName)»</dd>
\r
312 def code(String string) '''<code>«string»</code>'''
\r
314 def process(Module module) {
\r
315 throw new UnsupportedOperationException("TODO: auto-generated method stub")
\r
318 def CharSequence tree(Module module) '''
\r
319 «strong("module " + module.name)»
\r
320 «module.childNodes.treeSet(InstanceIdentifier.builder.toInstance())»
\r
323 private def dispatch CharSequence tree(ChoiceNode node,InstanceIdentifier path) '''
\r
324 «node.nodeName» (choice)
\r
325 «casesTree(node.cases,path)»
\r
328 def casesTree(Set<ChoiceCaseNode> nodes,InstanceIdentifier path) '''
\r
333 «node.childNodes.treeSet(path)»
\r
339 private def dispatch CharSequence tree(DataSchemaNode node,InstanceIdentifier path) '''
\r
343 private def dispatch CharSequence tree(ListSchemaNode node,InstanceIdentifier path) '''
\r
344 «val newPath = path.append(node)»
\r
345 «localLink(newPath,node.nodeName)»
\r
346 «node.childNodes.treeSet(newPath)»
\r
349 private def dispatch CharSequence tree(ContainerSchemaNode node,InstanceIdentifier path) '''
\r
350 «val newPath = path.append(node)»
\r
351 «localLink(newPath,node.nodeName)»
\r
352 «node.childNodes.treeSet(newPath)»
\r
355 def CharSequence childNodes(Module module) '''
\r
356 «val childNodes = module.childNodes»
\r
357 «IF childNodes !== null && !childNodes.empty»
\r
358 <h2>Child nodes</h2>
\r
360 «childNodes.printChildren(3,InstanceIdentifier.builder().toInstance())»
\r
364 def CharSequence printChildren(Set<DataSchemaNode> nodes, int level, InstanceIdentifier path) {
\r
365 val anyxmlNodes = nodes.filter(AnyXmlSchemaNode)
\r
366 val leafNodes = nodes.filter(LeafSchemaNode)
\r
367 val leafListNodes = nodes.filter(LeafListSchemaNode)
\r
368 val choices = nodes.filter(ChoiceNode)
\r
369 val cases = nodes.filter(ChoiceCaseNode)
\r
370 val containers = nodes.filter(ContainerSchemaNode)
\r
371 val lists = nodes.filter(ListSchemaNode)
\r
373 «IF ((anyxmlNodes.size + leafNodes.size + leafListNodes.size + containers.size + lists.size) > 0)»
\r
374 <h3>Direct children</h3>
\r
376 «FOR childNode : anyxmlNodes»
\r
377 «childNode.printShortInfo(level,path)»
\r
379 «FOR childNode : leafNodes»
\r
380 «childNode.printShortInfo(level,path)»
\r
382 «FOR childNode : leafListNodes»
\r
383 «childNode.printShortInfo(level,path)»
\r
385 «FOR childNode : containers»
\r
386 «childNode.printShortInfo(level,path)»
\r
388 «FOR childNode : lists»
\r
389 «childNode.printShortInfo(level,path)»
\r
394 «IF !path.path.empty»
\r
395 <h3>XML example</h3>
\r
396 «nodes.xmlExample(path.path.last.nodeType,path)»
\r
399 «FOR childNode : containers»
\r
400 «childNode.printInfo(level,path)»
\r
402 «FOR childNode : lists»
\r
403 «childNode.printInfo(level,path)»
\r
405 «FOR childNode : choices»
\r
406 «childNode.printInfo(level,path)»
\r
408 «FOR childNode : cases»
\r
409 «childNode.printInfo(level,path)»
\r
415 def CharSequence xmlExample(Set<DataSchemaNode> nodes, QName name,InstanceIdentifier path) '''
\r
417 «xmlExampleTag(name,nodes.xmplExampleTags(path))»
\r
421 def CharSequence xmplExampleTags(Set<DataSchemaNode> nodes, InstanceIdentifier identifier) '''
\r
422 <!-- Child nodes -->
\r
424 <!-- «node.QName.localName» -->
\r
425 «node.asXmlExampleTag(identifier)»
\r
430 private def dispatch CharSequence asXmlExampleTag(LeafSchemaNode node, InstanceIdentifier identifier) '''
\r
431 «node.QName.xmlExampleTag("...")»
\r
434 private def dispatch CharSequence asXmlExampleTag(LeafListSchemaNode node, InstanceIdentifier identifier) '''
\r
435 <!-- This node could appear multiple times -->
\r
436 «node.QName.xmlExampleTag("...")»
\r
439 private def dispatch CharSequence asXmlExampleTag(ContainerSchemaNode node, InstanceIdentifier identifier) '''
\r
440 <!-- See «localLink(identifier.append(node),"definition")» for child nodes. -->
\r
441 «node.QName.xmlExampleTag("...")»
\r
445 private def dispatch CharSequence asXmlExampleTag(ListSchemaNode node, InstanceIdentifier identifier) '''
\r
446 <!-- See «localLink(identifier.append(node),"definition")» for child nodes. -->
\r
447 <!-- This node could appear multiple times -->
\r
448 «node.QName.xmlExampleTag("...")»
\r
452 private def dispatch CharSequence asXmlExampleTag(DataSchemaNode node, InstanceIdentifier identifier) '''
\r
457 def xmlExampleTag(QName name, CharSequence data) {
\r
458 return '''<«name.localName» xmlns="«name.namespace»">«data»</«name.localName»>'''
\r
461 def header(int level,QName name) '''<h«level»>«name.localName»</h«level»>'''
\r
464 def header(int level,InstanceIdentifier name) '''
\r
465 <h«level» id="«FOR cmp : name.path SEPARATOR "/"»«cmp.nodeType.localName»«ENDFOR»">
\r
466 «FOR cmp : name.path SEPARATOR "/"»«cmp.nodeType.localName»«ENDFOR»
\r
472 private def dispatch CharSequence printInfo(DataSchemaNode node, int level, InstanceIdentifier path) '''
\r
473 «header(level+1,node.QName)»
\r
476 private def dispatch CharSequence printInfo(ContainerSchemaNode node, int level, InstanceIdentifier path) '''
\r
477 «val newPath = path.append(node)»
\r
478 «header(level,newPath)»
\r
481 <dd>«newPath.asXmlPath»</dd>
\r
482 <dt>Restconf path</dt>
\r
483 <dd>«code(newPath.asRestconfPath)»</dd>
\r
485 «node.childNodes.printChildren(level,newPath)»
\r
488 private def dispatch CharSequence printInfo(ListSchemaNode node, int level, InstanceIdentifier path) '''
\r
489 «val newPath = path.append(node)»
\r
490 «header(level,newPath)»
\r
493 <dd>«newPath.asXmlPath»</dd>
\r
494 <dt>Restconf path</dt>
\r
495 <dd>«code(newPath.asRestconfPath)»</dd>
\r
497 «node.childNodes.printChildren(level,newPath)»
\r
500 private def dispatch CharSequence printInfo(ChoiceNode node, int level, InstanceIdentifier path) '''
\r
501 «val Set<DataSchemaNode> choiceCases = new HashSet(node.cases)»
\r
502 «choiceCases.printChildren(level,path)»
\r
505 private def dispatch CharSequence printInfo(ChoiceCaseNode node, int level, InstanceIdentifier path) '''
\r
506 «node.childNodes.printChildren(level,path)»
\r
511 def CharSequence printShortInfo(ContainerSchemaNode node, int level, InstanceIdentifier path) {
\r
512 val newPath = path.append(node);
\r
514 <li>«strong(localLink(newPath,node.QName.localName))» (container)</li>
\r
518 def CharSequence printShortInfo(ListSchemaNode node, int level, InstanceIdentifier path) {
\r
519 val newPath = path.append(node);
\r
521 <li>«strong(localLink(newPath,node.QName.localName))» (list)</li>
\r
525 def CharSequence printShortInfo(AnyXmlSchemaNode node, int level, InstanceIdentifier path) {
\r
527 <li>«strong((node.QName.localName))» (anyxml)</li>
\r
531 def CharSequence printShortInfo(LeafSchemaNode node, int level, InstanceIdentifier path) {
\r
533 <li>«strong((node.QName.localName))» (leaf)</li>
\r
537 def CharSequence printShortInfo(LeafListSchemaNode node, int level, InstanceIdentifier path) {
\r
539 <li>«strong((node.QName.localName))» (leaf-list)</li>
\r
543 def CharSequence localLink(InstanceIdentifier identifier, CharSequence text) '''
\r
544 <a href="#«FOR cmp : identifier.path SEPARATOR "/"»«cmp.nodeType.localName»«ENDFOR»">«text»</a>
\r
548 private def dispatch InstanceIdentifier append(InstanceIdentifier identifier, ContainerSchemaNode node) {
\r
549 val pathArguments = new ArrayList(identifier.path)
\r
550 pathArguments.add(new NodeIdentifier(node.QName));
\r
551 return new InstanceIdentifier(pathArguments);
\r
554 private def dispatch InstanceIdentifier append(InstanceIdentifier identifier, ListSchemaNode node) {
\r
555 val pathArguments = new ArrayList(identifier.path)
\r
556 val keyValues = new LinkedHashMap<QName,Object>();
\r
557 if(node.keyDefinition != null) {
\r
558 for(definition : node.keyDefinition) {
\r
559 keyValues.put(definition,new Object);
\r
562 pathArguments.add(new NodeIdentifierWithPredicates(node.QName,keyValues));
\r
563 return new InstanceIdentifier(pathArguments);
\r
567 def asXmlPath(InstanceIdentifier identifier) {
\r
571 def asRestconfPath(InstanceIdentifier identifier) {
\r
572 val it = new StringBuilder();
\r
573 append(currentModule.name)
\r
575 var previous = false;
\r
576 for(arg : identifier.path) {
\r
577 if(previous) append("/")
\r
578 append(arg.nodeType.localName);
\r
580 if(arg instanceof NodeIdentifierWithPredicates) {
\r
581 val nodeIdentifier = arg as NodeIdentifierWithPredicates;
\r
582 for(qname : nodeIdentifier.keyValues.keySet) {
\r
584 append(qname.localName)
\r
590 return it.toString;
\r
593 private def String schemaPathAsRestconfPath(Module module, SchemaPath schemaPath, SchemaContext ctx) {
\r
594 val Map<String, String> imports = new HashMap();
\r
595 for (mImport : module.imports) {
\r
596 imports.put(mImport.prefix, mImport.moduleName)
\r
599 val List<QName> path = schemaPath.path
\r
600 val StringBuilder pathString = new StringBuilder()
\r
601 if (schemaPath.absolute) {
\r
602 pathString.append("/")
\r
605 val QName qname = path.get(0)
\r
606 var Object parent = ctx.findModuleByNamespaceAndRevision(qname.namespace, qname.revision)
\r
608 for (name : path) {
\r
609 if (parent instanceof DataNodeContainer) {
\r
610 var SchemaNode node = (parent as DataNodeContainer).getDataChildByName(name)
\r
611 if (node == null && (parent instanceof Module)) {
\r
612 val notifications = (parent as Module).notifications;
\r
613 for (notification : notifications) {
\r
614 if (notification.QName.equals(name)) {
\r
615 node = notification
\r
619 if (node == null && (parent instanceof Module)) {
620 val rpcs = (parent as Module).rpcs;
622 if (rpc.QName.equals(name)) {
628 if (!(node instanceof ChoiceNode) && !(node instanceof ChoiceCaseNode)) {
\r
629 var String prefix = name.prefix
\r
630 var String moduleName
\r
631 if (prefix == null || "".equals(prefix) || prefix.equals(module.prefix)) {
\r
632 moduleName = module.name
\r
634 moduleName = imports.get(prefix)
\r
636 pathString.append(moduleName)
\r
637 pathString.append(":")
\r
638 pathString.append(name.localName)
\r
639 pathString.append("/")
\r
642 } else if (parent instanceof ChoiceNode) {
\r
643 parent = (parent as ChoiceNode).getCaseNodeByName(qname.localName)
\r
646 return pathString.toString;
\r
650 def CharSequence childNodesInfoTree(Map<SchemaPath, DataSchemaNode> childNodes) '''
\r
651 «IF childNodes !== null && !childNodes.empty»
\r
652 «FOR child : childNodes.values»
\r
653 «childInfo(child, childNodes)»
\r
658 def CharSequence childInfo(DataSchemaNode node, Map<SchemaPath, DataSchemaNode> childNodes) '''
\r
659 «val String path = nodeSchemaPathToPath(node, childNodes)»
\r
664 «node.descAndRefLi»
\r
670 private def CharSequence treeSet(Collection<DataSchemaNode> childNodes, InstanceIdentifier path) '''
\r
671 «IF childNodes !== null && !childNodes.empty»
\r
673 «FOR child : childNodes»
\r
682 def listKeys(ListSchemaNode node) '''
\r
683 [«FOR key : node.keyDefinition SEPARATOR " "»«key.localName»«ENDFOR»]
\r
686 private def CharSequence rpcInfo(RpcDefinition rpc,InstanceIdentifier path) '''
\r
690 «rpc.input.tree(path)»
\r
693 «rpc.output.tree(path)»
\r
698 private def CharSequence extensionInfo(ExtensionDefinition ext) '''
\r
701 «listItem("Argument", ext.argument)»
\r
705 private def dispatch CharSequence tree(Void obj, InstanceIdentifier path) '''
\r
710 /* #################### RESTRICTIONS #################### */
\r
711 private def restrictions(TypeDefinition<?> type) '''
\r
716 private def dispatch toLength(TypeDefinition<?> type) {
\r
719 private def dispatch toLength(BinaryTypeDefinition type) '''
\r
720 «type.lengthConstraints.toLengthStmt»
\r
723 private def dispatch toLength(StringTypeDefinition type) '''
\r
724 «type.lengthConstraints.toLengthStmt»
\r
727 private def dispatch toLength(ExtendedType type) '''
\r
728 «type.lengthConstraints.toLengthStmt»
\r
731 private def dispatch toRange(TypeDefinition<?> type) {
\r
734 private def dispatch toRange(DecimalTypeDefinition type) '''
\r
735 «type.rangeConstraints.toRangeStmt»
\r
738 private def dispatch toRange(IntegerTypeDefinition type) '''
\r
739 «type.rangeConstraints.toRangeStmt»
\r
742 private def dispatch toRange(UnsignedIntegerTypeDefinition type) '''
\r
743 «type.rangeConstraints.toRangeStmt»
\r
746 private def dispatch toRange(ExtendedType type) '''
\r
747 «type.rangeConstraints.toRangeStmt»
\r
750 def toLengthStmt(Collection<LengthConstraint> lengths) '''
\r
751 «IF lengths != null && !lengths.empty»
\r
752 «listItem("Length restrictions")»
\r
754 «FOR length : lengths»
\r
756 «IF length.min == length.max»
\r
759 <«length.min», «length.max»>
\r
767 def toRangeStmt(Collection<RangeConstraint> ranges) '''
\r
768 «IF ranges != null && !ranges.empty»
\r
769 «listItem("Range restrictions")»
\r
771 «FOR range : ranges»
\r
773 «IF range.min == range.max»
\r
776 <«range.min», «range.max»>
\r
786 /* #################### UTILITY #################### */
\r
787 private def String strong(CharSequence str) '''<strong>«str»</strong>'''
\r
788 private def italic(CharSequence str) '''<i>«str»</i>'''
\r
789 private def pre(CharSequence str) '''<pre>«str»</pre>'''
\r
791 def CharSequence descAndRefLi(SchemaNode node) '''
\r
792 «listItem(node.description)»
\r
793 «listItem("Reference", node.reference)»
\r
796 def CharSequence descAndRef(SchemaNode node) '''
\r
798 «IF node.reference !== null»
\r
799 Reference «node.reference»
\r
803 private def listItem(String value) '''
\r
804 «IF value !== null && !value.empty»
\r
811 private def listItem(String name, String value) '''
\r
812 «IF value !== null && !value.empty»
\r
819 private def String nodeSchemaPathToPath(DataSchemaNode node, Map<SchemaPath, DataSchemaNode> childNodes) {
\r
820 if (node instanceof ChoiceNode || node instanceof ChoiceCaseNode) {
\r
824 val path = node.path.path
\r
825 val absolute = node.path.absolute;
\r
826 var StringBuilder result = new StringBuilder
\r
830 if (path !== null && !path.empty) {
\r
831 val List<QName> actual = new ArrayList()
\r
833 for (pathElement : path) {
\r
834 actual.add(pathElement)
\r
835 val DataSchemaNode nodeByPath = childNodes.get(new SchemaPath(actual, absolute))
\r
836 if (!(nodeByPath instanceof ChoiceNode) && !(nodeByPath instanceof ChoiceCaseNode)) {
\r
837 result.append(pathElement.localName)
\r
838 if (i != path.size - 1) {
\r
845 return result.toString
\r
848 private def void collectChildNodes(Collection<DataSchemaNode> source, Map<SchemaPath, DataSchemaNode> destination) {
\r
849 for (node : source) {
\r
850 destination.put(node.path, node)
\r
851 if (node instanceof DataNodeContainer) {
\r
852 collectChildNodes((node as DataNodeContainer).childNodes, destination)
\r
854 if (node instanceof ChoiceNode) {
\r
855 val List<DataSchemaNode> choiceCases = new ArrayList()
\r
856 for (caseNode : (node as ChoiceNode).cases) {
\r
857 choiceCases.add(caseNode)
\r
859 collectChildNodes(choiceCases, destination)
\r
864 private def dispatch addedByInfo(SchemaNode node) '''
\r
867 private def dispatch addedByInfo(DataSchemaNode node) '''
\r
868 «IF node.augmenting»(A)«ENDIF»«IF node.addedByUses»(U)«ENDIF»
\r
871 private def dispatch isAddedBy(SchemaNode node) {
\r
875 private def dispatch isAddedBy(DataSchemaNode node) {
\r
876 if (node.augmenting || node.addedByUses) {
\r
883 private def dispatch nodeName(SchemaNode node) '''
\r
884 «IF node.isAddedBy»
\r
885 «italic(node.QName.localName)»«node.addedByInfo»
\r
887 «node.QName.localName»«node.addedByInfo»
\r
891 private def dispatch nodeName(ContainerSchemaNode node) '''
\r
892 «IF node.isAddedBy»
\r
893 «strong(italic(node.QName.localName))»«node.addedByInfo»
\r
895 «strong(node.QName.localName)»«node.addedByInfo»
\r
899 private def dispatch nodeName(ListSchemaNode node) '''
\r
900 «IF node.isAddedBy»
\r
901 «strong(italic(node.QName.localName))» «IF node.keyDefinition !== null && !node.keyDefinition.empty»«node.listKeys»«ENDIF»«node.addedByInfo»
\r
903 «strong(node.QName.localName)» «IF node.keyDefinition !== null && !node.keyDefinition.empty»«node.listKeys»«ENDIF»
\r