X-Git-Url: https://git.opendaylight.org/gerrit/gitweb?a=blobdiff_plain;f=code-generator%2Fbinding-generator-impl%2Fsrc%2Fmain%2Fjava%2Forg%2Fopendaylight%2Fyangtools%2Fsal%2Fbinding%2Fgenerator%2Fimpl%2FBindingGeneratorImpl.xtend;h=e5aa5c4c2286f9660fcfa58319cce5060f79e66c;hb=37b13418f43e8c78e585f7495c2cd3b65d7c085e;hp=4d694bba9270a351159ba1aa7f7a9bfaaa22727f;hpb=dea46b20bfec80fe9d84dd1768219b497d57cc15;p=yangtools.git diff --git a/code-generator/binding-generator-impl/src/main/java/org/opendaylight/yangtools/sal/binding/generator/impl/BindingGeneratorImpl.xtend b/code-generator/binding-generator-impl/src/main/java/org/opendaylight/yangtools/sal/binding/generator/impl/BindingGeneratorImpl.xtend index 4d694bba92..e5aa5c4c22 100644 --- a/code-generator/binding-generator-impl/src/main/java/org/opendaylight/yangtools/sal/binding/generator/impl/BindingGeneratorImpl.xtend +++ b/code-generator/binding-generator-impl/src/main/java/org/opendaylight/yangtools/sal/binding/generator/impl/BindingGeneratorImpl.xtend @@ -6,13 +6,21 @@ * and is available at http://www.eclipse.org/legal/epl-v10.html */ package org.opendaylight.yangtools.sal.binding.generator.impl; + +import static com.google.common.base.Preconditions.*; +import static extension org.opendaylight.yangtools.binding.generator.util.Types.*; +import static org.opendaylight.yangtools.binding.generator.util.BindingGeneratorUtil.*; +import static org.opendaylight.yangtools.binding.generator.util.BindingTypes.*; +import static org.opendaylight.yangtools.yang.model.util.SchemaContextUtil.*; import java.util.ArrayList; import java.util.Collections; import java.util.HashMap; import java.util.List; import java.util.Map; -import java.util.Set; +import java.util.Set; +import java.util.Iterator +import java.util.Collection import org.opendaylight.yangtools.binding.generator.util.BindingTypes; import org.opendaylight.yangtools.binding.generator.util.ReferencedTypeImpl; import org.opendaylight.yangtools.binding.generator.util.Types; @@ -54,11 +62,6 @@ import org.opendaylight.yangtools.yang.model.api.type.UnionTypeDefinition; import org.opendaylight.yangtools.yang.model.util.DataNodeIterator; import org.opendaylight.yangtools.yang.model.util.SchemaContextUtil; import org.opendaylight.yangtools.yang.model.util.UnionType; -import static com.google.common.base.Preconditions.*; -import static extension org.opendaylight.yangtools.binding.generator.util.Types.*; -import static org.opendaylight.yangtools.binding.generator.util.BindingGeneratorUtil.*; -import static org.opendaylight.yangtools.binding.generator.util.BindingTypes.*; -import static org.opendaylight.yangtools.yang.model.util.SchemaContextUtil.*; import org.opendaylight.yangtools.yang.parser.util.ModuleDependencySort import org.opendaylight.yangtools.yang.model.util.ExtendedType; import org.opendaylight.yangtools.yang.model.api.UsesNode @@ -66,23 +69,25 @@ import org.opendaylight.yangtools.yang.binding.annotations.RoutingContext import org.opendaylight.yangtools.sal.binding.model.api.type.builder.AnnotationTypeBuilder import org.opendaylight.yangtools.yang.model.api.ModuleImport import org.opendaylight.yangtools.yang.binding.DataContainer -import java.util.Iterator import org.opendaylight.yangtools.yang.model.api.AugmentationTarget -import java.util.Collection -import org.opendaylight.yangtools.yang.model.api.YangNode import org.opendaylight.yangtools.yang.model.api.NotificationDefinition import org.opendaylight.yangtools.binding.generator.util.BindingGeneratorUtil import org.opendaylight.yangtools.sal.binding.model.api.Restrictions import org.opendaylight.yangtools.sal.binding.model.api.type.builder.GeneratedPropertyBuilder import org.opendaylight.yangtools.binding.generator.util.generated.type.builder.GeneratedPropertyBuilderImpl -import org.opendaylight.yangtools.yang.common.QName - +import org.opendaylight.yangtools.yang.common.QName import org.opendaylight.yangtools.yang.binding.BindingMapping +import org.opendaylight.yangtools.sal.binding.model.api.type.builder.GeneratedTypeBuilderBase + +import com.google.common.collect.Sets +import java.net.URI +import java.util.Date + public class BindingGeneratorImpl implements BindingGenerator { private final Map genCtx = new HashMap() /** - * Outter key represents the package name. Outter value represents map of + * Outer key represents the package name. Outer value represents map of * all builders in the same package. Inner key represents the schema node * name (in JAVA class/interface name format). Inner value represents * instance of builder for schema node specified in key part. @@ -95,7 +100,7 @@ public class BindingGeneratorImpl implements BindingGenerator { private var TypeProvider typeProvider; /** - * Holds reference to schema context to resolve data of augmented elemnt + * Holds reference to schema context to resolve data of augmented element * when creating augmentation builder */ private var SchemaContext schemaContext; @@ -184,10 +189,12 @@ public class BindingGeneratorImpl implements BindingGenerator { val List filteredGenTypes = new ArrayList(); for (Module m : modules) { - filteredGenTypes.addAll(genCtx.get(m).generatedTypes); - - } - //genCtx.clear; + filteredGenTypes.addAll(genCtx.get(m).generatedTypes); + val Set additionalTypes = (typeProvider as TypeProviderImpl).additionalTypes.get(m) + if (additionalTypes != null) { + filteredGenTypes.addAll(additionalTypes) + } + } return filteredGenTypes; } @@ -237,7 +244,7 @@ public class BindingGeneratorImpl implements BindingGenerator { } } } - } + } private def GeneratedTypeBuilder processDataSchemaNode(Module module, String basePackageName, GeneratedTypeBuilder parent, GeneratedTypeBuilder childOf, DataSchemaNode node) { @@ -425,7 +432,7 @@ public class BindingGeneratorImpl implements BindingGenerator { interfaceBuilder.addImplementsType(Types.typeForClass(RpcService)); for (rpc : rpcDefinitions) { if (rpc !== null) { - val rpcName = parseToClassName(rpc.QName.localName); + val rpcName = BindingMapping.getClassName(rpc.QName); val rpcMethodName = parseToValidParamName(rpcName); val method = interfaceBuilder.addMethod(rpcMethodName); val input = rpc.input; @@ -561,7 +568,7 @@ public class BindingGeneratorImpl implements BindingGenerator { return; } val packageName = packageNameForGeneratedType(basePackageName, identity.path); - val genTypeName = parseToClassName(identity.QName.localName); + val genTypeName = BindingMapping.getClassName(identity.QName); val newType = new GeneratedTOBuilderImpl(packageName, genTypeName); val baseIdentity = identity.baseIdentity; if (baseIdentity === null) { @@ -569,18 +576,28 @@ public class BindingGeneratorImpl implements BindingGenerator { } else { val baseIdentityParentModule = SchemaContextUtil.findParentModule(context, baseIdentity); val returnTypePkgName = moduleNamespaceToPackageName(baseIdentityParentModule); - val returnTypeName = parseToClassName(baseIdentity.QName.localName); + val returnTypeName = BindingMapping.getClassName(baseIdentity.QName); val gto = new GeneratedTOBuilderImpl(returnTypePkgName, returnTypeName).toInstance(); newType.setExtendsType(gto); } - newType.setAbstract(true); - genCtx.get(module).addIdentityType(newType) + newType.setAbstract(true); + val qname = identity.QName; + + newType.qnameConstant(BindingMapping.QNAME_STATIC_FIELD_NAME,qname); + + genCtx.get(module).addIdentityType(identity.QName,newType) + } + + private static def qnameConstant(GeneratedTypeBuilderBase toBuilder, String constantName, QName name) { + toBuilder.addConstant(QName.typeForClass,constantName,''' + org.opendaylight.yangtools.yang.common.QName.create("«name.namespace»","«name.formattedRevision»","«name.localName»") + '''); } /** * Converts all groupings of the module to the list of * Type objects. Firstly are groupings sorted according mutual - * dependencies. At least dependend (indepedent) groupings are in the list + * dependencies. At least dependent (independent) groupings are in the list * saved at first positions. For every grouping the record is added to map * {@link BindingGeneratorImpl#allGroupings allGroupings} * @@ -623,7 +640,7 @@ public class BindingGeneratorImpl implements BindingGenerator { /** * Tries to find EnumTypeDefinition in typeDefinition. If base * type of typeDefinition is of the type ExtendedType then this - * method is recursivelly called with this base type. + * method is recursively called with this base type. * * @param typeDefinition * TypeDefinition in which should be EnumTypeDefinition found as @@ -656,14 +673,14 @@ public class BindingGeneratorImpl implements BindingGenerator { * builder * @param typeBuilder * GeneratedTypeBuilder to which will be enum builder assigned - * @return enumeration builder which contais data from + * @return enumeration builder which contains data from * enumTypeDef */ - private def EnumBuilder resolveInnerEnumFromTypeDefinition(EnumTypeDefinition enumTypeDef, String enumName, + private def EnumBuilder resolveInnerEnumFromTypeDefinition(EnumTypeDefinition enumTypeDef, QName enumName, GeneratedTypeBuilder typeBuilder) { if ((enumTypeDef !== null) && (typeBuilder !== null) && (enumTypeDef.QName !== null) && (enumTypeDef.QName.localName !== null)) { - val enumerationName = parseToClassName(enumName); + val enumerationName = BindingMapping.getClassName(enumName); val enumBuilder = typeBuilder.addEnumeration(enumerationName); enumBuilder.updateEnumPairsFromEnumTypeDef(enumTypeDef); return enumBuilder; @@ -688,7 +705,7 @@ public class BindingGeneratorImpl implements BindingGenerator { private def GeneratedTypeBuilder moduleTypeBuilder(Module module, String postfix) { checkArgument(module !== null, "Module reference cannot be NULL."); val packageName = moduleNamespaceToPackageName(module); - val moduleName = parseToClassName(module.name) + postfix; + val moduleName = BindingMapping.getClassName(module.name) + postfix; return new GeneratedTypeBuilderImpl(packageName, moduleName); } @@ -703,7 +720,7 @@ public class BindingGeneratorImpl implements BindingGenerator { * string with the name of the package to which the augmentation * belongs * @param augSchema - * AugmentationSchema which is contains data about agumentation + * AugmentationSchema which is contains data about augmentation * (target path, childs...) * @param module current module * @param parentUsesNode parent uses node of this augment (can be null if this augment is not defined under uses statement) @@ -721,12 +738,9 @@ public class BindingGeneratorImpl implements BindingGenerator { checkState(augSchema.targetPath !== null, "Augmentation Schema does not contain Target Path (Target Path is NULL)."); - processUsesAugments(augSchema, module); - - // EVERY augmented interface will extends Augmentation interface - // and DataObject interface + processUsesAugments(augSchema, module); val targetPath = augSchema.targetPath; - var targetSchemaNode = findDataSchemaNode(schemaContext, targetPath); + var targetSchemaNode = findDataSchemaNode(schemaContext, targetPath); if (targetSchemaNode instanceof DataSchemaNode && (targetSchemaNode as DataSchemaNode).isAddedByUses()) { if (parentUsesNode == null) { targetSchemaNode = findOriginal(targetSchemaNode as DataSchemaNode); @@ -738,7 +752,11 @@ public class BindingGeneratorImpl implements BindingGenerator { "Failed to find target node from grouping for augmentation " + augSchema + " in module " + module.name); } - } + } + + if (targetSchemaNode == null) { + throw new IllegalArgumentException("augment target not found: " + targetPath) + } if (targetSchemaNode !== null) { var targetTypeBuilder = findChildNodeByPath(targetSchemaNode.path) @@ -782,20 +800,30 @@ public class BindingGeneratorImpl implements BindingGenerator { private def DataSchemaNode findCorrectTargetFromAugment(DataSchemaNode node) { if (!node.augmenting) { - return null; + return null } - var String currentName = node.QName.localName; - var tmpPath = new ArrayList(); - var YangNode parent = node; + var QName currentName = node.QName + var Object currentNode = node + var Object parent = node; + val tmpPath = new ArrayList() + val tmpTree = new ArrayList() + var AugmentationSchema augment = null; - do { - parent = (parent as DataSchemaNode).parent; + do { + val SchemaPath sp = (parent as SchemaNode).path + val List names = sp.path + val List newNames = new ArrayList(names) + newNames.remove(newNames.size - 1) + val SchemaPath newSp = new SchemaPath(newNames, sp.absolute) + parent = findDataSchemaNode(schemaContext, newSp) if (parent instanceof AugmentationTarget) { - tmpPath.add(currentName); + tmpPath.add(currentName); + tmpTree.add(currentNode as SchemaNode) augment = findNodeInAugment((parent as AugmentationTarget).availableAugmentations, currentName); if (augment == null) { - currentName = (parent as DataSchemaNode).QName.localName; + currentName = (parent as DataSchemaNode).QName + currentNode = parent } } } while ((parent as DataSchemaNode).augmenting && augment == null); @@ -803,107 +831,172 @@ public class BindingGeneratorImpl implements BindingGenerator { if (augment == null) { return null; } else { - Collections.reverse(tmpPath); + Collections.reverse(tmpPath); + Collections.reverse(tmpTree); var Object actualParent = augment; var DataSchemaNode result = null; for (name : tmpPath) { if (actualParent instanceof DataNodeContainer) { - result = (actualParent as DataNodeContainer).getDataChildByName(name); - actualParent = (actualParent as DataNodeContainer).getDataChildByName(name); + result = (actualParent as DataNodeContainer).getDataChildByName(name.localName); + actualParent = (actualParent as DataNodeContainer).getDataChildByName(name.localName); } else { if (actualParent instanceof ChoiceNode) { - result = (actualParent as ChoiceNode).getCaseNodeByName(name); - actualParent = (actualParent as ChoiceNode).getCaseNodeByName(name); + result = (actualParent as ChoiceNode).getCaseNodeByName(name.localName); + actualParent = (actualParent as ChoiceNode).getCaseNodeByName(name.localName); } } } - if (result.addedByUses) { - result = findCorrectTargetFromGrouping(result); + if (result.addedByUses) { + result = findCorrectTargetFromAugmentGrouping(result, augment, tmpTree); } return result; } } - private def AugmentationSchema findNodeInAugment(Collection augments, String name) { - for (augment : augments) { - if (augment.getDataChildByName(name) != null) { + private def AugmentationSchema findNodeInAugment(Collection augments, QName name) { + for (augment : augments) { + val DataSchemaNode node = augment.getDataChildByName(name); + if (node != null) { return augment; } } return null; } - - private def DataSchemaNode findCorrectTargetFromGrouping(DataSchemaNode node) { - if (node.path.path.size == 1) { - + + private def DataSchemaNode findCorrectTargetFromGrouping(DataSchemaNode node) { + if (node.path.path.size == 1) { // uses is under module statement - val Module m = findParentModule(schemaContext, node); - var DataSchemaNode result = null; - for (u : m.uses) { - var SchemaNode targetGrouping = findNodeInSchemaContext(schemaContext, u.groupingPath.path); - if (!(targetGrouping instanceof GroupingDefinition)) { - throw new IllegalArgumentException("Failed to generate code for augment in " + u); + val Module m = findParentModule(schemaContext, node); + var DataSchemaNode result = null; + for (u : m.uses) { + var SchemaNode targetGrouping = findNodeInSchemaContext(schemaContext, u.groupingPath.path); + if (!(targetGrouping instanceof GroupingDefinition)) { + throw new IllegalArgumentException("Failed to generate code for augment in " + u); + } + var gr = targetGrouping as GroupingDefinition; + result = gr.getDataChildByName(node.QName.localName); + } + if (result == null) { + throw new IllegalArgumentException("Failed to generate code for augment") + } + return result + } else { + var DataSchemaNode result = null; + var QName currentName = node.QName + var tmpPath = new ArrayList() + var Object parent = null + + val SchemaPath sp = node.path + val List names = sp.path + val List newNames = new ArrayList(names) + newNames.remove(newNames.size - 1) + val SchemaPath newSp = new SchemaPath(newNames, sp.absolute) + parent = findDataSchemaNode(schemaContext, newSp) + + do { + tmpPath.add(currentName); + val dataNodeParent = parent as DataNodeContainer; + for (u : dataNodeParent.uses) { + if (result == null) { + result = getResultFromUses(u, currentName.localName) + } + } + if (result == null) { + currentName = (parent as SchemaNode).QName + if (parent instanceof SchemaNode) { + val SchemaPath nodeSp = (parent as SchemaNode).path + val List nodeNames = nodeSp.path + val List nodeNewNames = new ArrayList(nodeNames) + nodeNewNames.remove(nodeNewNames.size - 1) + if (nodeNewNames.empty) { + parent = getParentModule(parent as SchemaNode) + } else { + val SchemaPath nodeNewSp = new SchemaPath(nodeNewNames, nodeSp.absolute) + parent = findDataSchemaNode(schemaContext, nodeNewSp) + } + } else { + throw new IllegalArgumentException("Failed to generate code for augment") + } + } + } while (result == null && !(parent instanceof Module)); + + if (result != null) { + result = getTargetNode(tmpPath, result) + } + return result; + } + } + + private def DataSchemaNode findCorrectTargetFromAugmentGrouping(DataSchemaNode node, AugmentationSchema parentNode, + List dataTree) { + + var DataSchemaNode result = null; + var QName currentName = node.QName + var tmpPath = new ArrayList() + tmpPath.add(currentName) + var int i = 1; + var Object parent = null + + do { + if (dataTree.size < 2 || dataTree.size == i) { + parent = parentNode + } else { + parent = dataTree.get(dataTree.size - (i+1)) + tmpPath.add((parent as SchemaNode).QName) + } + + val dataNodeParent = parent as DataNodeContainer; + for (u : dataNodeParent.uses) { + if (result == null) { + result = getResultFromUses(u, currentName.localName) } - var gr = targetGrouping as GroupingDefinition; - result = gr.getDataChildByName(node.QName.localName); } if (result == null) { - throw new IllegalArgumentException("Failed to generate code for augment"); + i = i + 1 + currentName = (parent as SchemaNode).QName + } + } while (result == null); + + if (result != null) { + result = getTargetNode(tmpPath, result) + } + return result; + } + + private def getResultFromUses(UsesNode u, String currentName) { + var SchemaNode targetGrouping = findNodeInSchemaContext(schemaContext, u.groupingPath.path) + if (!(targetGrouping instanceof GroupingDefinition)) { + throw new IllegalArgumentException("Failed to generate code for augment in " + u) + } + var gr = targetGrouping as GroupingDefinition + return gr.getDataChildByName(currentName) + } + + private def getTargetNode(List tmpPath, DataSchemaNode node) { + var DataSchemaNode result = node + if (tmpPath.size == 1) { + if (result != null && result.addedByUses) { + result = findOriginal(result); } return result; } else { - var DataSchemaNode result = null; - var String currentName = node.QName.localName; - var tmpPath = new ArrayList(); - var YangNode parent = node.parent; - do { - tmpPath.add(currentName); - val dataNodeParent = parent as DataNodeContainer; - for (u : dataNodeParent.uses) { - if (result == null) { - var SchemaNode targetGrouping = findNodeInSchemaContext(schemaContext, u.groupingPath.path); - if (!(targetGrouping instanceof GroupingDefinition)) { - throw new IllegalArgumentException("Failed to generate code for augment in " + u); - } - var gr = targetGrouping as GroupingDefinition; - result = gr.getDataChildByName(currentName); - } - } - if (result == null) { - currentName = (parent as SchemaNode).QName.localName; - if (parent instanceof DataSchemaNode) { - parent = (parent as DataSchemaNode).parent; - } else { - parent = (parent as DataNodeContainer).parent; - } - } - } while (result == null && !(parent instanceof Module)); + var DataSchemaNode newParent = result; + Collections.reverse(tmpPath); - if (result != null) { - if (tmpPath.size == 1) { - if (result != null && result.addedByUses) { - result = findOriginal(result); - } - return result; - } else { - var DataSchemaNode newParent = result; - Collections.reverse(tmpPath); - tmpPath.remove(0); - for (name : tmpPath) { - newParent = (newParent as DataNodeContainer).getDataChildByName(name); - } - if (newParent != null && newParent.addedByUses) { - newParent = findOriginal(newParent); - } - return newParent; - } + tmpPath.remove(0); + for (name : tmpPath) { + // searching by local name is must, because node has different namespace in its original location + newParent = (newParent as DataNodeContainer).getDataChildByName(name.localName); } - - return result; + if (newParent != null && newParent.addedByUses) { + newParent = findOriginal(newParent); + } + return newParent; } - } + } + /** * Convenient method to find node added by uses statement. @@ -965,7 +1058,7 @@ public class BindingGeneratorImpl implements BindingGenerator { val augIdentifier = getAugmentIdentifier(augSchema.unknownSchemaNodes); val augTypeName = if (augIdentifier !== null) { - parseToClassName(augIdentifier) + BindingMapping.getClassName(augIdentifier) } else { augGenTypeName(augmentBuilders, targetTypeRef.name); } @@ -1145,12 +1238,14 @@ public class BindingGeneratorImpl implements BindingGenerator { checkArgument(basePackageName !== null, "Base Package Name cannot be NULL."); checkArgument(choiceNode !== null, "Choice Schema Node cannot be NULL."); - val packageName = packageNameForGeneratedType(basePackageName, choiceNode.path); - val choiceTypeBuilder = addRawInterfaceDefinition(packageName, choiceNode); - constructGetter(parent, choiceNode.QName.localName, choiceNode.description, choiceTypeBuilder); - choiceTypeBuilder.addImplementsType(DataContainer.typeForClass); - genCtx.get(module).addChildNodeType(choiceNode.path, choiceTypeBuilder) - generateTypesFromChoiceCases(module, basePackageName, parent, choiceTypeBuilder.toInstance, choiceNode); + if (!choiceNode.addedByUses) { + val packageName = packageNameForGeneratedType(basePackageName, choiceNode.path); + val choiceTypeBuilder = addRawInterfaceDefinition(packageName, choiceNode); + constructGetter(parent, choiceNode.QName.localName, choiceNode.description, choiceTypeBuilder); + choiceTypeBuilder.addImplementsType(DataContainer.typeForClass); + genCtx.get(module).addChildNodeType(choiceNode.path, choiceTypeBuilder) + generateTypesFromChoiceCases(module, basePackageName, parent, choiceTypeBuilder.toInstance, choiceNode); + } } /** @@ -1198,7 +1293,14 @@ public class BindingGeneratorImpl implements BindingGenerator { genCtx.get(module).addCaseType(caseNode.path, caseTypeBuilder) val Set caseChildNodes = caseNode.childNodes if (caseChildNodes !== null) { - val parentNode = choiceNode.parent + var Object parentNode = null + val SchemaPath nodeSp = choiceNode.path + val List nodeNames = nodeSp.path + val List nodeNewNames = new ArrayList(nodeNames) + nodeNewNames.remove(nodeNewNames.size - 1) + val SchemaPath nodeNewSp = new SchemaPath(nodeNewNames, nodeSp.absolute) + parentNode = findDataSchemaNode(schemaContext, nodeNewSp) + var SchemaNode parent if (parentNode instanceof AugmentationSchema) { val augSchema = parentNode as AugmentationSchema; @@ -1215,7 +1317,12 @@ public class BindingGeneratorImpl implements BindingGenerator { } parent = targetSchemaNode } else { - parent = choiceNode.parent as SchemaNode + val SchemaPath sp = choiceNode.path + val List names = sp.path + val List newNames = new ArrayList(names) + newNames.remove(newNames.size - 1) + val SchemaPath newSp = new SchemaPath(newNames, sp.absolute) + parent = findDataSchemaNode(schemaContext, newSp) } var GeneratedTypeBuilder childOfType = findChildNodeByPath(parent.path) resolveDataSchemaNodes(module, basePackageName, caseTypeBuilder, childOfType, caseChildNodes) @@ -1263,7 +1370,14 @@ public class BindingGeneratorImpl implements BindingGenerator { val caseTypeBuilder = addDefaultInterfaceDefinition(packageName, caseNode); caseTypeBuilder.addImplementsType(targetType); - val SchemaNode parent = targetNode.parent as SchemaNode; + var SchemaNode parent = null + val SchemaPath nodeSp = targetNode.path + val List nodeNames = nodeSp.path + val List nodeNewNames = new ArrayList(nodeNames) + nodeNewNames.remove(nodeNewNames.size - 1) + val SchemaPath nodeNewSp = new SchemaPath(nodeNewNames, nodeSp.absolute) + parent = findDataSchemaNode(schemaContext, nodeNewSp) + var GeneratedTypeBuilder childOfType = null; if (parent instanceof Module) { childOfType = genCtx.get(parent as Module).moduleNode @@ -1329,27 +1443,28 @@ public class BindingGeneratorImpl implements BindingGenerator { val TypeDefinition typeDef = leaf.type; var Type returnType = null; + var GeneratedTOBuilder genTOBuilder; if (typeDef instanceof EnumTypeDefinition) { returnType = typeProvider.javaTypeForSchemaDefinitionType(typeDef, leaf); val enumTypeDef = typeDef as EnumTypeDefinition; - val enumBuilder = resolveInnerEnumFromTypeDefinition(enumTypeDef, leafName, typeBuilder); + val enumBuilder = resolveInnerEnumFromTypeDefinition(enumTypeDef, leaf.QName, typeBuilder); if (enumBuilder !== null) { returnType = new ReferencedTypeImpl(enumBuilder.packageName, enumBuilder.name); } (typeProvider as TypeProviderImpl).putReferencedType(leaf.path, returnType); } else if (typeDef instanceof UnionType) { - val genTOBuilder = addTOToTypeBuilder(typeDef, typeBuilder, leafName, leaf, parentModule); - if (genTOBuilder !== null) { - returnType = new ReferencedTypeImpl(genTOBuilder.packageName, genTOBuilder.name); + genTOBuilder = addTOToTypeBuilder(typeDef, typeBuilder, leaf, parentModule); + if (genTOBuilder !== null) { + returnType = createReturnTypeForUnion(genTOBuilder, typeDef, typeBuilder, parentModule) } } else if (typeDef instanceof BitsTypeDefinition) { - val genTOBuilder = addTOToTypeBuilder(typeDef, typeBuilder, leafName, leaf, parentModule); - if (genTOBuilder !== null) { - returnType = new ReferencedTypeImpl(genTOBuilder.packageName, genTOBuilder.name); + genTOBuilder = addTOToTypeBuilder(typeDef, typeBuilder, leaf, parentModule); + if (genTOBuilder !== null) { + returnType = new ReferencedTypeImpl(genTOBuilder.packageName, genTOBuilder.name); } - } else { - val Restrictions restrictions = BindingGeneratorUtil.getRestrictions(typeDef); + } else { + val Restrictions restrictions = BindingGeneratorUtil.getRestrictions(typeDef); returnType = typeProvider.javaTypeForSchemaDefinitionType(typeDef, leaf, restrictions); } if (returnType !== null) { @@ -1394,7 +1509,7 @@ public class BindingGeneratorImpl implements BindingGenerator { val Class clazz = typeof(RoutingContext); val AnnotationTypeBuilder rc = getter.addAnnotation(clazz.package.name, clazz.simpleName); val packageName = packageNameForGeneratedType(basePackageName, identity.path); - val genTypeName = parseToClassName(identity.QName.localName); + val genTypeName = BindingMapping.getClassName(identity.QName.localName); rc.addParameter("value", packageName + "." + genTypeName + ".class"); } } @@ -1438,7 +1553,7 @@ public class BindingGeneratorImpl implements BindingGenerator { * */ private def boolean resolveLeafSchemaNodeAsProperty(GeneratedTOBuilder toBuilder, LeafSchemaNode leaf, - boolean isReadOnly) { + boolean isReadOnly, Module module) { if ((leaf !== null) && (toBuilder !== null)) { val leafName = leaf.QName.localName; var String leafDesc = leaf.description; @@ -1446,11 +1561,24 @@ public class BindingGeneratorImpl implements BindingGenerator { leafDesc = ""; } - if (leafName !== null) { - val TypeDefinition typeDef = leaf.type; + if (leafName !== null) { + var Type returnType = null; + val TypeDefinition typeDef = leaf.type; + if (typeDef instanceof UnionTypeDefinition) { + // GeneratedType for this type definition should be already created + var qname = typeDef.QName + var Module unionModule = null + if (qname.prefix == null || qname.prefix.empty) { + unionModule = module + } else { + unionModule = findModuleFromImports(module.imports, qname.prefix) + } + val ModuleContext mc = genCtx.get(unionModule) + returnType = mc.typedefs.get(typeDef.path) + } else { + returnType = typeProvider.javaTypeForSchemaDefinitionType(typeDef, leaf); + } - // TODO: properly resolve enum types - val returnType = typeProvider.javaTypeForSchemaDefinitionType(typeDef, leaf); if (returnType !== null) { val propBuilder = toBuilder.addProperty(parseToValidParamName(leafName)); propBuilder.setReadOnly(isReadOnly); @@ -1485,7 +1613,7 @@ public class BindingGeneratorImpl implements BindingGenerator { */ private def boolean resolveLeafListSchemaNode(GeneratedTypeBuilder typeBuilder, LeafListSchemaNode node) { if ((node !== null) && (typeBuilder !== null)) { - val nodeName = node.QName.localName; + val nodeName = node.QName; var String nodeDesc = node.description; if (nodeDesc === null) { nodeDesc = ""; @@ -1502,10 +1630,12 @@ public class BindingGeneratorImpl implements BindingGenerator { returnType = new ReferencedTypeImpl(enumBuilder.packageName, enumBuilder.name); (typeProvider as TypeProviderImpl).putReferencedType(node.path, returnType); } else if (typeDef instanceof UnionType) { - val genTOBuilder = addTOToTypeBuilder(typeDef, typeBuilder, nodeName, node, parentModule); - returnType = new ReferencedTypeImpl(genTOBuilder.packageName, genTOBuilder.name); + val genTOBuilder = addTOToTypeBuilder(typeDef, typeBuilder, node, parentModule); + if (genTOBuilder !== null) { + returnType = createReturnTypeForUnion(genTOBuilder, typeDef, typeBuilder, parentModule) + } } else if (typeDef instanceof BitsTypeDefinition) { - val genTOBuilder = addTOToTypeBuilder(typeDef, typeBuilder, nodeName, node, parentModule); + val genTOBuilder = addTOToTypeBuilder(typeDef, typeBuilder, node, parentModule); returnType = new ReferencedTypeImpl(genTOBuilder.packageName, genTOBuilder.name); } else { val Restrictions restrictions = BindingGeneratorUtil.getRestrictions(typeDef); @@ -1513,12 +1643,39 @@ public class BindingGeneratorImpl implements BindingGenerator { } val listType = Types.listTypeFor(returnType); - constructGetter(typeBuilder, nodeName, nodeDesc, listType); + constructGetter(typeBuilder, nodeName.localName, nodeDesc, listType); return true; } } return false; } + + private def Type createReturnTypeForUnion(GeneratedTOBuilder genTOBuilder, TypeDefinition typeDef, + GeneratedTypeBuilder typeBuilder, Module parentModule) { + val Type returnType = new ReferencedTypeImpl(genTOBuilder.packageName, genTOBuilder.name); + genTOBuilder.setTypedef(true); + genTOBuilder.setIsUnion(true); + (typeProvider as TypeProviderImpl).addUnitsToGenTO(genTOBuilder, typeDef.getUnits()); + + // union builder + val GeneratedTOBuilder unionBuilder = new GeneratedTOBuilderImpl(typeBuilder.getPackageName(), + genTOBuilder.getName() + "Builder"); + unionBuilder.setIsUnionBuilder(true); + val MethodSignatureBuilder method = unionBuilder.addMethod("getDefaultInstance"); + method.setReturnType(returnType); + method.addParameter(Types.STRING, "defaultValue"); + method.setAccessModifier(AccessModifier.PUBLIC); + method.setStatic(true); + + val Set types = (typeProvider as TypeProviderImpl).additionalTypes.get(parentModule); + if (types == null) { + (typeProvider as TypeProviderImpl).additionalTypes.put(parentModule, + Sets.newHashSet(unionBuilder.toInstance)) + } else { + types.add(unionBuilder.toInstance) + } + return returnType + } private def GeneratedTypeBuilder addDefaultInterfaceDefinition(String packageName, SchemaNode schemaNode) { return addDefaultInterfaceDefinition(packageName, schemaNode, null); @@ -1549,10 +1706,7 @@ public class BindingGeneratorImpl implements BindingGenerator { private def GeneratedTypeBuilder addDefaultInterfaceDefinition(String packageName, SchemaNode schemaNode, Type parent) { val it = addRawInterfaceDefinition(packageName, schemaNode, ""); - val qname = schemaNode.QName; - addConstant(QName.typeForClass,"QNAME",''' - org.opendaylight.yangtools.yang.common.QName.create("«qname.namespace»","«qname.formattedRevision»","«qname.localName»") - '''); + qnameConstant(BindingMapping.QNAME_STATIC_FIELD_NAME,schemaNode.QName); if (parent === null) { addImplementsType(DATA_OBJECT); } else { @@ -1603,7 +1757,7 @@ public class BindingGeneratorImpl implements BindingGenerator { *
  • if schemaNode equals null
  • *
  • if packageName equals null
  • *
  • if Q name of schema node is null
  • - *
  • if schema node name is nul
  • + *
  • if schema node name is null
  • * * */ @@ -1617,9 +1771,9 @@ public class BindingGeneratorImpl implements BindingGenerator { var String genTypeName; if (prefix === null) { - genTypeName = parseToClassName(schemaNodeName); + genTypeName = BindingMapping.getClassName(schemaNodeName); } else { - genTypeName = prefix + parseToClassName(schemaNodeName); + genTypeName = prefix + BindingMapping.getClassName(schemaNodeName); } //FIXME: Validation of name conflict @@ -1653,7 +1807,7 @@ public class BindingGeneratorImpl implements BindingGenerator { } else { method.append("get"); } - method.append(parseToClassName(localName)); + method.append(BindingMapping.getPropertyName(localName).toFirstUpper); return method.toString(); } @@ -1719,7 +1873,7 @@ public class BindingGeneratorImpl implements BindingGenerator { val leafName = leaf.QName.localName; resolveLeafSchemaNodeAsMethod(typeBuilder, leaf); if (listKeys.contains(leafName)) { - resolveLeafSchemaNodeAsProperty(genTOBuilder, leaf, true); + resolveLeafSchemaNodeAsProperty(genTOBuilder, leaf, true, module) } } else if (!schemaNode.addedByUses) { if (schemaNode instanceof LeafListSchemaNode) { @@ -1782,7 +1936,7 @@ public class BindingGeneratorImpl implements BindingGenerator { var GeneratedTOBuilder genTOBuilder = null; if ((list.keyDefinition !== null) && (!list.keyDefinition.isEmpty())) { val listName = list.QName.localName + "Key"; - val String genTOName = parseToClassName(listName); + val String genTOName = BindingMapping.getClassName(listName); genTOBuilder = new GeneratedTOBuilderImpl(packageName, genTOName); } return genTOBuilder; @@ -1812,15 +1966,31 @@ public class BindingGeneratorImpl implements BindingGenerator { * @return generated TO builder for typeDef */ private def GeneratedTOBuilder addTOToTypeBuilder(TypeDefinition typeDef, GeneratedTypeBuilder typeBuilder, - String leafName, DataSchemaNode leaf, Module parentModule) { - val classNameFromLeaf = parseToClassName(leafName); + DataSchemaNode leaf, Module parentModule) { + val classNameFromLeaf = BindingMapping.getClassName(leaf.QName); val List genTOBuilders = new ArrayList(); val packageName = typeBuilder.fullyQualifiedName; - if (typeDef instanceof UnionTypeDefinition) { - genTOBuilders.addAll( - (typeProvider as TypeProviderImpl). - provideGeneratedTOBuildersForUnionTypeDef(packageName, (typeDef as UnionTypeDefinition), - classNameFromLeaf, leaf)); + if (typeDef instanceof UnionTypeDefinition) { + val List types = (typeProvider as TypeProviderImpl). + provideGeneratedTOBuildersForUnionTypeDef(packageName, (typeDef as UnionTypeDefinition), + classNameFromLeaf, leaf); + genTOBuilders.addAll(types); + + + var GeneratedTOBuilder resultTOBuilder = null; + if (!types.isEmpty()) { + resultTOBuilder = types.remove(0); + for (GeneratedTOBuilder genTOBuilder : types) { + resultTOBuilder.addEnclosingTransferObject(genTOBuilder); + } + } + + val GeneratedPropertyBuilder genPropBuilder = resultTOBuilder.addProperty("value"); + genPropBuilder.setReturnType(Types.primitiveType("char[]", null)); + resultTOBuilder.addEqualsIdentity(genPropBuilder); + resultTOBuilder.addHashIdentity(genPropBuilder); + resultTOBuilder.addToStringProperty(genPropBuilder); + } else if (typeDef instanceof BitsTypeDefinition) { genTOBuilders.add( ((typeProvider as TypeProviderImpl) ). @@ -1840,7 +2010,7 @@ public class BindingGeneratorImpl implements BindingGenerator { * Adds the implemented types to type builder. * * The method passes through the list of uses in - * {@code dataNodeContainer}. For every use is obtained coresponding + * {@code dataNodeContainer}. For every use is obtained corresponding * generated type from {@link BindingGeneratorImpl#allGroupings * allGroupings} which is added as implements type to * builder @@ -1896,8 +2066,15 @@ public class BindingGeneratorImpl implements BindingGenerator { return null } + private def Module getParentModule(SchemaNode node) { + val QName qname = node.getPath().getPath().get(0); + val URI namespace = qname.getNamespace(); + val Date revision = qname.getRevision(); + return schemaContext.findModuleByNamespaceAndRevision(namespace, revision); + } public def getModuleContexts() { genCtx; - } + } + }