package org.opendaylight.mdsal.binding.yang.unified.doc.generator
import com.google.common.collect.Iterables
+import com.google.common.collect.Lists
import java.io.BufferedWriter
import java.io.File
import java.io.IOException
import java.io.OutputStreamWriter
import java.nio.charset.StandardCharsets
-import java.text.SimpleDateFormat
import java.util.ArrayList
import java.util.Collection
import java.util.HashMap
import java.util.LinkedHashMap
import java.util.List
import java.util.Map
+import java.util.Optional
import java.util.Set
import org.opendaylight.yangtools.yang.common.QName
import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier
import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeIdentifierWithPredicates
import org.opendaylight.yangtools.yang.model.api.AnyXmlSchemaNode
import org.opendaylight.yangtools.yang.model.api.AugmentationTarget
-import org.opendaylight.yangtools.yang.model.api.ChoiceCaseNode
+import org.opendaylight.yangtools.yang.model.api.CaseSchemaNode
import org.opendaylight.yangtools.yang.model.api.ChoiceSchemaNode
import org.opendaylight.yangtools.yang.model.api.ContainerSchemaNode
import org.opendaylight.yangtools.yang.model.api.DataNodeContainer
import org.opendaylight.yangtools.yang.model.api.DataSchemaNode
+import org.opendaylight.yangtools.yang.model.api.ElementCountConstraintAware
import org.opendaylight.yangtools.yang.model.api.ExtensionDefinition
import org.opendaylight.yangtools.yang.model.api.GroupingDefinition
import org.opendaylight.yangtools.yang.model.api.LeafListSchemaNode
import org.opendaylight.yangtools.yang.model.api.UsesNode
import org.opendaylight.yangtools.yang.model.api.type.BinaryTypeDefinition
import org.opendaylight.yangtools.yang.model.api.type.DecimalTypeDefinition
-import org.opendaylight.yangtools.yang.model.api.type.IntegerTypeDefinition
+import org.opendaylight.yangtools.yang.model.api.type.Int8TypeDefinition
+import org.opendaylight.yangtools.yang.model.api.type.Int16TypeDefinition
+import org.opendaylight.yangtools.yang.model.api.type.Int32TypeDefinition
+import org.opendaylight.yangtools.yang.model.api.type.Int64TypeDefinition
import org.opendaylight.yangtools.yang.model.api.type.LengthConstraint
import org.opendaylight.yangtools.yang.model.api.type.RangeConstraint
import org.opendaylight.yangtools.yang.model.api.type.StringTypeDefinition
-import org.opendaylight.yangtools.yang.model.api.type.UnsignedIntegerTypeDefinition
+import org.opendaylight.yangtools.yang.model.api.type.Uint8TypeDefinition
+import org.opendaylight.yangtools.yang.model.api.type.Uint16TypeDefinition
+import org.opendaylight.yangtools.yang.model.api.type.Uint32TypeDefinition
+import org.opendaylight.yangtools.yang.model.api.type.Uint64TypeDefinition
import org.slf4j.Logger
import org.slf4j.LoggerFactory
import org.sonatype.plexus.build.incremental.BuildContext
import org.sonatype.plexus.build.incremental.DefaultBuildContext
-import com.google.common.collect.Lists
class GeneratorImpl {
File path
- static val REVISION_FORMAT = new SimpleDateFormat("yyyy-MM-dd")
static val Logger LOG = LoggerFactory.getLogger(GeneratorImpl)
static val BuildContext CTX = new DefaultBuildContext();
var Module currentModule;
private def parseTargetPath(SchemaPath path) {
val List<DataSchemaNode> nodes = new ArrayList<DataSchemaNode>();
for (QName pathElement : path.pathFromRoot) {
- val module = ctx.findModuleByNamespaceAndRevision(pathElement.namespace, pathElement.revision);
- if (module !== null) {
- var foundNode = module.getDataChildByName(pathElement)
+ val module = ctx.findModule(pathElement.module)
+ if (module.isPresent) {
+ var foundNode = module.get.getDataChildByName(pathElement)
if (foundNode === null) {
val child = nodes.last
if (child instanceof DataNodeContainer) {
private def CharSequence printAugmentedNode(DataSchemaNode child) {
- if(child instanceof ChoiceCaseNode)
+ if(child instanceof CaseSchemaNode)
return ''
return
}
private def printChoiceNode(ChoiceSchemaNode child) {
- val List<ChoiceCaseNode> cases = new ArrayList(child.cases);
+ val List<CaseSchemaNode> cases = new ArrayList(child.cases.values);
if(!cases.empty) {
- val ChoiceCaseNode aCase = cases.get(0)
+ val CaseSchemaNode aCase = cases.get(0)
for(caseChildNode : aCase.childNodes)
printAugmentedNode(caseChildNode)
}
<td>«module.namespace»</td>
</tr>
<tr>
+ «IF module.revision.isPresent»
<td>«strong("revision")»</td>
- <td>«REVISION_FORMAT.format(module.revision)»</td>
+ <td>«module.revision.get.toString»</td>
+ «ENDIF»
</tr>
<tr>
<td>«strong("description")»</td>
</tr>
<tr>
«FOR imp : module.imports BEFORE '''<td>«strong("imports")»</td><td>''' AFTER '''</td>'''»
- «imp.prefix»:«imp.moduleName»«IF imp.revision !== null» «REVISION_FORMAT.format(imp.revision)»«ENDIF»;
+ «imp.prefix»:«imp.moduleName»«IF imp.revision.isPresent» «imp.revision.get.toString»«ENDIF»;
«ENDFOR»
</tr>
</table>
private def dispatch CharSequence tree(ChoiceSchemaNode node,YangInstanceIdentifier path) '''
«node.nodeName» (choice)
- «casesTree(node.cases,path)»
+ «casesTree(node.cases.values, path)»
'''
- def casesTree(Set<ChoiceCaseNode> nodes,YangInstanceIdentifier path) '''
+ def casesTree(Collection<CaseSchemaNode> nodes, YangInstanceIdentifier path) '''
<ul>
«FOR node : nodes»
<li>
return '''
«printInfo(node, "leaf")»
«listItem("type", typeAnchorLink(node.type?.path, node.type.QName.localName))»
- «listItem("units", node.units)»
- «listItem("default", node.^default)»
+ «listItem("units", node.type.units.orElse(null))»
+ «listItem("default", node.type.defaultValue.map([ Object o | o.toString]).orElse(null))»
</ul>
'''
} else if(node instanceof LeafListSchemaNode) {
} else if(node instanceof ChoiceSchemaNode) {
return '''
«printInfo(node, "choice")»
- «listItem("default case", node.defaultCase)»
- «FOR caseNode : node.cases»
+ «listItem("default case", node.defaultCase.map([ CaseSchemaNode n | n.getQName.localName]).orElse(null))»
+ «FOR caseNode : node.cases.values»
«caseNode.printSchemaNodeInfo»
«ENDFOR»
</ul>
'''
- } else if(node instanceof ChoiceCaseNode) {
+ } else if(node instanceof CaseSchemaNode) {
return '''
«printInfo(node, "case")»
</ul>
«strong(listItem(nodeType, node.QName.localName))»
«ENDIF»
<ul>
- «listItem("description", node.description)»
- «listItem("reference", node.reference)»
+ «listItem("description", node.description.orElse(null))»
+ «listItem("reference", node.reference.orElse(null))»
«IF node instanceof DataSchemaNode»
- «listItem("when condition", node.constraints.whenCondition?.toString)»
- «listItem("min elements", node.constraints.minElements?.toString)»
- «listItem("max elements", node.constraints.maxElements?.toString)»
+ «IF node.whenCondition.present»
+ «listItem("when condition", node.whenCondition.get.toString)»
+ «ENDIF»
+ «ENDIF»
+ «IF node instanceof ElementCountConstraintAware»
+ «IF node.elementCountConstraint.present»
+ «val constraint = node.elementCountConstraint.get»
+ «listItem("min elements", constraint.minElements?.toString)»
+ «listItem("max elements", constraint.maxElements?.toString)»
+ «ENDIF»
«ENDIF»
'''
}
val leafNodes = nodes.filter(LeafSchemaNode)
val leafListNodes = nodes.filter(LeafListSchemaNode)
val choices = nodes.filter(ChoiceSchemaNode)
- val cases = nodes.filter(ChoiceCaseNode)
+ val cases = nodes.filter(CaseSchemaNode)
val containers = nodes.filter(ContainerSchemaNode)
val lists = nodes.filter(ListSchemaNode)
return '''
'''
private def dispatch CharSequence printInfo(ChoiceSchemaNode node, int level, YangInstanceIdentifier path) '''
- «val Set<DataSchemaNode> choiceCases = new HashSet(node.cases)»
- «choiceCases.printChildren(level,path)»
+ «val Set<DataSchemaNode> choiceCases = new HashSet(node.cases.values)»
+ «choiceCases.printChildren(level, path)»
'''
- private def dispatch CharSequence printInfo(ChoiceCaseNode node, int level, YangInstanceIdentifier path) '''
- «node.childNodes.printChildren(level,path)»
+ private def dispatch CharSequence printInfo(CaseSchemaNode node, int level, YangInstanceIdentifier path) '''
+ «node.childNodes.printChildren(level, path)»
'''
<li>«strong((node.QName.localName))» (anyxml)
<ul>
<li>configuration data: «strong(String.valueOf(node.configuration))»</li>
- <li>mandatory: «strong(String.valueOf(node.constraints.mandatory))»</li>
+ <li>mandatory: «strong(String.valueOf(node.mandatory))»</li>
</ul>
</li>
'''
<li>«strong((node.QName.localName))» (leaf)
<ul>
<li>configuration data: «strong(String.valueOf(node.configuration))»</li>
- <li>mandatory: «strong(String.valueOf(node.constraints.mandatory))»</li>
+ <li>mandatory: «strong(String.valueOf(node.mandatory))»</li>
</ul>
</li>
'''
}
val QName qname = path.get(0)
- var Object parent = ctx.findModuleByNamespaceAndRevision(qname.namespace, qname.revision)
+ var Object parent = ctx.findModule(qname.module).orElse(null)
for (name : path) {
if (parent instanceof DataNodeContainer) {
}
}
- val pathElementModule = ctx.findModuleByNamespaceAndRevision(name.namespace, name.revision)
+ val pathElementModule = ctx.findModule(name.module).get
val String moduleName = pathElementModule.name
pathString.append(moduleName)
pathString.append(':')
pathString.append(name.localName)
pathString.append('/')
if(node instanceof ChoiceSchemaNode && dataNode !== null) {
- val DataSchemaNode caseNode = dataNode.childNodes.findFirst[DataSchemaNode e | e instanceof ChoiceCaseNode];
+ val DataSchemaNode caseNode = dataNode.childNodes.findFirst[DataSchemaNode e | e instanceof CaseSchemaNode];
if(caseNode !== null) {
pathString.append("(case)");
pathString.append(caseNode.QName.localName);
}
private def dispatch toLength(BinaryTypeDefinition type) '''
- «type.lengthConstraints.toLengthStmt»
+ «type.lengthConstraint.toLengthStmt»
'''
private def dispatch toLength(StringTypeDefinition type) '''
- «type.lengthConstraints.toLengthStmt»
+ «type.lengthConstraint.toLengthStmt»
'''
private def dispatch toRange(TypeDefinition<?> type) {
}
private def dispatch toRange(DecimalTypeDefinition type) '''
- «type.rangeConstraints.toRangeStmt»
+ «type.rangeConstraint.toRangeStmt»
+ '''
+
+ private def dispatch toRange(Int8TypeDefinition type) '''
+ «type.rangeConstraint.toRangeStmt»
+ '''
+
+ private def dispatch toRange(Int16TypeDefinition type) '''
+ «type.rangeConstraint.toRangeStmt»
+ '''
+
+ private def dispatch toRange(Int32TypeDefinition type) '''
+ «type.rangeConstraint.toRangeStmt»
+ '''
+
+ private def dispatch toRange(Int64TypeDefinition type) '''
+ «type.rangeConstraint.toRangeStmt»
+ '''
+
+ private def dispatch toRange(Uint8TypeDefinition type) '''
+ «type.rangeConstraint.toRangeStmt»
+ '''
+
+ private def dispatch toRange(Uint16TypeDefinition type) '''
+ «type.rangeConstraint.toRangeStmt»
'''
- private def dispatch toRange(IntegerTypeDefinition type) '''
- «type.rangeConstraints.toRangeStmt»
+ private def dispatch toRange(Uint32TypeDefinition type) '''
+ «type.rangeConstraint.toRangeStmt»
'''
- private def dispatch toRange(UnsignedIntegerTypeDefinition type) '''
- «type.rangeConstraints.toRangeStmt»
+ private def dispatch toRange(Uint64TypeDefinition type) '''
+ «type.rangeConstraint.toRangeStmt»
'''
- def toLengthStmt(Collection<LengthConstraint> lengths) '''
- «IF lengths !== null && !lengths.empty»
+ def toLengthStmt(Optional<LengthConstraint> lengths) '''
+ «IF lengths.isPresent»
«listItem("Length restrictions:")»
<ul>
- «FOR length : lengths»
+ «FOR length : lengths.get.allowedRanges.asRanges»
<li>
- «IF length.min == length.max»
- «length.min»
+ «IF length.lowerEndpoint == length.upperEndpoint»
+ «length.lowerEndpoint»
«ELSE»
- <«length.min», «length.max»>
+ <«length.lowerEndpoint», «length.upperEndpoint»>
«ENDIF»
</li>
«ENDFOR»
«ENDIF»
'''
- def toRangeStmt(Collection<RangeConstraint> ranges) '''
- «IF ranges !== null && !ranges.empty»
+ def toRangeStmt(Optional<? extends RangeConstraint<?>> constraint) '''
+ «IF constraint.present»
«listItem("Range restrictions:")»
<ul>
- «FOR range : ranges»
+ «FOR range : constraint.get.allowedRanges.asRanges»
<li>
- «IF range.min == range.max»
- «range.min»
+ «IF range.lowerEndpoint == range.upperEndpoint»
+ «range.lowerEndpoint»
«ELSE»
- <«range.min», «range.max»>
+ <«range.lowerEndpoint», «range.upperEndpoint»>
«ENDIF»
</li>
«ENDFOR»
private def italic(CharSequence str) '''<i>«str»</i>'''
def CharSequence descAndRefLi(SchemaNode node) '''
- «listItem("Description", node.description)»
- «listItem("Reference", node.reference)»
+ «listItem("Description", node.description.orElse(null))»
+ «listItem("Reference", node.reference.orElse(null))»
'''
def CharSequence descAndRef(SchemaNode node) '''
'''
private def String nodeSchemaPathToPath(DataSchemaNode node, Map<SchemaPath, DataSchemaNode> childNodes) {
- if (node instanceof ChoiceSchemaNode || node instanceof ChoiceCaseNode) {
+ if (node instanceof ChoiceSchemaNode || node instanceof CaseSchemaNode) {
return null
}
for (pathElement : path) {
actual.add(pathElement)
val DataSchemaNode nodeByPath = childNodes.get(SchemaPath.create(actual, absolute))
- if (!(nodeByPath instanceof ChoiceSchemaNode) && !(nodeByPath instanceof ChoiceCaseNode)) {
+ if (!(nodeByPath instanceof ChoiceSchemaNode) && !(nodeByPath instanceof CaseSchemaNode)) {
result.append(pathElement.localName)
if (i != path.size - 1) {
result.append('/')