X-Git-Url: https://git.opendaylight.org/gerrit/gitweb?a=blobdiff_plain;f=binding2%2Fmdsal-binding2-generator-impl%2Fsrc%2Fmain%2Fjava%2Forg%2Fopendaylight%2Fmdsal%2Fbinding%2Fjavav2%2Fgenerator%2Fimpl%2FGenHelperUtil.java;h=11ac9465a138eead5950c6a9729e82432a176608;hb=refs%2Fchanges%2F58%2F61258%2F1;hp=9afe6650cb3118e9b6070b3b1a3ab7f78941327f;hpb=ad2fd7f3ac5de2d2b2e82f1b357331f5bc0a2603;p=mdsal.git diff --git a/binding2/mdsal-binding2-generator-impl/src/main/java/org/opendaylight/mdsal/binding/javav2/generator/impl/GenHelperUtil.java b/binding2/mdsal-binding2-generator-impl/src/main/java/org/opendaylight/mdsal/binding/javav2/generator/impl/GenHelperUtil.java index 9afe6650cb..11ac9465a1 100644 --- a/binding2/mdsal-binding2-generator-impl/src/main/java/org/opendaylight/mdsal/binding/javav2/generator/impl/GenHelperUtil.java +++ b/binding2/mdsal-binding2-generator-impl/src/main/java/org/opendaylight/mdsal/binding/javav2/generator/impl/GenHelperUtil.java @@ -11,7 +11,6 @@ package org.opendaylight.mdsal.binding.javav2.generator.impl; import static com.google.common.base.Preconditions.checkArgument; import static org.opendaylight.mdsal.binding.javav2.generator.impl.AuxiliaryGenUtils.addTOToTypeBuilder; import static org.opendaylight.mdsal.binding.javav2.generator.impl.AuxiliaryGenUtils.annotateDeprecatedIfNecessary; -import static org.opendaylight.mdsal.binding.javav2.generator.impl.AuxiliaryGenUtils.augGenTypeName; import static org.opendaylight.mdsal.binding.javav2.generator.impl.AuxiliaryGenUtils.constructGetter; import static org.opendaylight.mdsal.binding.javav2.generator.impl.AuxiliaryGenUtils.createDescription; import static org.opendaylight.mdsal.binding.javav2.generator.impl.AuxiliaryGenUtils.createReturnTypeForUnion; @@ -20,25 +19,31 @@ import static org.opendaylight.mdsal.binding.javav2.generator.impl.AuxiliaryGenU import static org.opendaylight.mdsal.binding.javav2.generator.impl.AuxiliaryGenUtils.qNameConstant; import static org.opendaylight.mdsal.binding.javav2.generator.impl.AuxiliaryGenUtils.resolveInnerEnumFromTypeDefinition; import static org.opendaylight.mdsal.binding.javav2.generator.impl.AuxiliaryGenUtils.resolveListKeyTOBuilder; +import static org.opendaylight.mdsal.binding.javav2.generator.impl.AuxiliaryGenUtils.resolveListKeyTypeBuilder; import static org.opendaylight.mdsal.binding.javav2.generator.util.BindingGeneratorUtil.computeDefaultSUID; import static org.opendaylight.mdsal.binding.javav2.generator.util.BindingGeneratorUtil.encodeAngleBrackets; import static org.opendaylight.mdsal.binding.javav2.generator.util.BindingGeneratorUtil.packageNameForGeneratedType; import static org.opendaylight.mdsal.binding.javav2.generator.util.BindingTypes.NOTIFICATION; import static org.opendaylight.mdsal.binding.javav2.generator.util.Types.parameterizedTypeFor; +import static org.opendaylight.mdsal.binding.javav2.generator.util.Types.wildcardTypeFor; +import static org.opendaylight.yangtools.yang.model.util.SchemaContextUtil.findDataSchemaNode; import static org.opendaylight.yangtools.yang.model.util.SchemaContextUtil.findParentModule; import com.google.common.annotations.Beta; import com.google.common.base.Preconditions; +import com.google.common.collect.Iterables; import java.util.Collection; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.Set; +import org.opendaylight.mdsal.binding.javav2.generator.context.ModuleContext; import org.opendaylight.mdsal.binding.javav2.generator.spi.TypeProvider; import org.opendaylight.mdsal.binding.javav2.generator.util.BindingGeneratorUtil; import org.opendaylight.mdsal.binding.javav2.generator.util.BindingTypes; import org.opendaylight.mdsal.binding.javav2.generator.util.JavaIdentifier; import org.opendaylight.mdsal.binding.javav2.generator.util.JavaIdentifierNormalizer; +import org.opendaylight.mdsal.binding.javav2.generator.util.ReferencedTypeImpl; import org.opendaylight.mdsal.binding.javav2.generator.util.Types; import org.opendaylight.mdsal.binding.javav2.generator.util.generated.type.builder.GeneratedPropertyBuilderImpl; import org.opendaylight.mdsal.binding.javav2.generator.util.generated.type.builder.GeneratedTOBuilderImpl; @@ -46,26 +51,33 @@ import org.opendaylight.mdsal.binding.javav2.generator.util.generated.type.build import org.opendaylight.mdsal.binding.javav2.generator.yang.types.GroupingDefinitionDependencySort; import org.opendaylight.mdsal.binding.javav2.generator.yang.types.TypeProviderImpl; import org.opendaylight.mdsal.binding.javav2.model.api.AccessModifier; -import org.opendaylight.mdsal.binding.javav2.model.api.GeneratedTransferObject; import org.opendaylight.mdsal.binding.javav2.model.api.GeneratedType; +import org.opendaylight.mdsal.binding.javav2.model.api.ParameterizedType; import org.opendaylight.mdsal.binding.javav2.model.api.Restrictions; import org.opendaylight.mdsal.binding.javav2.model.api.Type; import org.opendaylight.mdsal.binding.javav2.model.api.type.builder.EnumBuilder; import org.opendaylight.mdsal.binding.javav2.model.api.type.builder.GeneratedPropertyBuilder; import org.opendaylight.mdsal.binding.javav2.model.api.type.builder.GeneratedTOBuilder; import org.opendaylight.mdsal.binding.javav2.model.api.type.builder.GeneratedTypeBuilder; +import org.opendaylight.mdsal.binding.javav2.model.api.type.builder.MethodSignatureBuilder; import org.opendaylight.mdsal.binding.javav2.spec.base.BaseIdentity; import org.opendaylight.mdsal.binding.javav2.spec.base.TreeNode; import org.opendaylight.mdsal.binding.javav2.spec.runtime.BindingNamespaceType; import org.opendaylight.mdsal.binding.javav2.spec.structural.Augmentable; import org.opendaylight.mdsal.binding.javav2.util.BindingMapping; import org.opendaylight.yangtools.yang.common.QName; +import org.opendaylight.yangtools.yang.model.api.AnyDataSchemaNode; +import org.opendaylight.yangtools.yang.model.api.AnyXmlSchemaNode; import org.opendaylight.yangtools.yang.model.api.AugmentationSchema; +import org.opendaylight.yangtools.yang.model.api.ChoiceCaseNode; +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.DerivableSchemaNode; import org.opendaylight.yangtools.yang.model.api.GroupingDefinition; import org.opendaylight.yangtools.yang.model.api.IdentitySchemaNode; +import org.opendaylight.yangtools.yang.model.api.LeafListSchemaNode; import org.opendaylight.yangtools.yang.model.api.LeafSchemaNode; import org.opendaylight.yangtools.yang.model.api.ListSchemaNode; import org.opendaylight.yangtools.yang.model.api.Module; @@ -76,10 +88,12 @@ import org.opendaylight.yangtools.yang.model.api.SchemaPath; import org.opendaylight.yangtools.yang.model.api.Status; import org.opendaylight.yangtools.yang.model.api.TypeDefinition; import org.opendaylight.yangtools.yang.model.api.UsesNode; +import org.opendaylight.yangtools.yang.model.api.meta.ModelStatement; import org.opendaylight.yangtools.yang.model.api.type.BitsTypeDefinition; import org.opendaylight.yangtools.yang.model.api.type.EnumTypeDefinition; import org.opendaylight.yangtools.yang.model.api.type.UnionTypeDefinition; import org.opendaylight.yangtools.yang.model.util.SchemaContextUtil; +import org.opendaylight.yangtools.yang.model.util.SchemaNodeUtils; /** * Helper util class used for generation of types in Binding spec v2. @@ -96,8 +110,8 @@ final class GenHelperUtil { * * @param module * Module object from which builder will be created - * @param genCtx - * @param verboseClassComments + * @param genCtx generated context + * @param verboseClassComments verbosity switch * * @return GeneratedTypeBuilder which is internal * representation of the module @@ -107,7 +121,8 @@ final class GenHelperUtil { static GeneratedTypeBuilder moduleToDataType(final Module module, final Map genCtx, final boolean verboseClassComments) { Preconditions.checkArgument(module != null, "Module reference cannot be NULL."); - final GeneratedTypeBuilder moduleDataTypeBuilder = moduleTypeBuilder(module, "Data", verboseClassComments); + final GeneratedTypeBuilder moduleDataTypeBuilder = moduleTypeBuilder(module, "Data", verboseClassComments, + genCtx.get(module)); addImplementedInterfaceFromUses(module, moduleDataTypeBuilder, genCtx); moduleDataTypeBuilder.addImplementsType(BindingTypes.TREE_ROOT); moduleDataTypeBuilder.addComment(module.getDescription()); @@ -125,24 +140,23 @@ final class GenHelperUtil { * @param postfix * string which is added to the module class name representation * as suffix - * @param verboseClassComments + * @param verboseClassComments verbosity switch * @return instance of GeneratedTypeBuilder which represents * module. * @throws IllegalArgumentException * if module is null */ static GeneratedTypeBuilder moduleTypeBuilder(final Module module, final String postfix, final boolean - verboseClassComments) { + verboseClassComments, ModuleContext context) { Preconditions.checkArgument(module != null, "Module reference cannot be NULL."); final String packageName = BindingMapping.getRootPackageName(module); // underscore used as separator for distinction of module name parts final String moduleName = new StringBuilder(module.getName()).append('_').append(postfix).toString(); - final GeneratedTypeBuilderImpl moduleBuilder = new GeneratedTypeBuilderImpl(packageName, moduleName); + final GeneratedTypeBuilderImpl moduleBuilder = new GeneratedTypeBuilderImpl(packageName, moduleName, context); moduleBuilder.setDescription(createDescription(module, verboseClassComments)); moduleBuilder.setReference(module.getReference()); moduleBuilder.setModuleName(moduleName); - return moduleBuilder; } @@ -186,6 +200,16 @@ final class GenHelperUtil { return null; } + static GeneratedTOBuilder findIdentityByQname(final QName qname, final Map genCtx) { + for (final ModuleContext ctx : genCtx.values()) { + final GeneratedTOBuilder result = ctx.getIdentities().get(qname); + if (result != null) { + return result; + } + } + return null; + } + /** * Adds the methods to typeBuilder which represent subnodes of * node for which typeBuilder was created. @@ -216,38 +240,134 @@ final class GenHelperUtil { final Iterable schemaNodes, final Map genCtx, final SchemaContext schemaContext, final boolean verboseClassComments, final Map> genTypeBuilders, - final TypeProvider typeProvider) { + final TypeProvider typeProvider, final BindingNamespaceType namespaceType) { if (schemaNodes != null && parent != null) { for (final DataSchemaNode schemaNode : schemaNodes) { - if (!schemaNode.isAugmenting() && !schemaNode.isAddedByUses()) { + if (resolveDataSchemaNodesCheck(module, schemaContext, schemaNode)) { addSchemaNodeToBuilderAsMethod(basePackageName, schemaNode, parent, childOf, module, genCtx, - schemaContext, verboseClassComments, genTypeBuilders, typeProvider); + schemaContext, verboseClassComments, genTypeBuilders, typeProvider, namespaceType); } } } return parent; } - static GeneratedTypeBuilder addDefaultInterfaceDefinition(final String packageName, final SchemaNode + static boolean resolveDataSchemaNodesCheck(final Module module, final SchemaContext schemaContext, + final DataSchemaNode schemaNode) { + if (!schemaNode.isAugmenting()) { + return true; + } else if (schemaNode.isAugmenting()) { + QName qname = schemaNode.getPath().getLastComponent(); + final Module originalModule = schemaContext.findModuleByNamespaceAndRevision(qname.getNamespace(), + qname.getRevision()); + if (module.equals(originalModule)) { + return true; + } + } + + return false; + } + + static GeneratedTypeBuilder addDefaultInterfaceDefinition(final String basePackageName, final SchemaNode schemaNode, final Module module, final Map genCtx, final SchemaContext schemaContext, final boolean verboseClassComments, final Map> genTypeBuilders, - final TypeProvider typeProvider) { - return addDefaultInterfaceDefinition(packageName, schemaNode, null, module, genCtx, schemaContext, - verboseClassComments, genTypeBuilders, typeProvider); + final TypeProvider typeProvider, final BindingNamespaceType namespaceType) { + return addDefaultInterfaceDefinition(basePackageName, schemaNode, null, module, genCtx, schemaContext, + verboseClassComments, genTypeBuilders, typeProvider , namespaceType); } - static Map processUsesAugments(final SchemaContext schemaContext, final - DataNodeContainer node, final Module module, Map genCtx, - final Map> genTypeBuilders, - final boolean verboseClassComments, final TypeProvider typeProvider) { - final String basePackageName = BindingMapping.getRootPackageName(module); - for (final UsesNode usesNode : node.getUses()) { - for (final AugmentationSchema augment : usesNode.getAugmentations()) { - genCtx = AugmentToGenType.usesAugmentationToGenTypes(schemaContext, basePackageName, augment, module, - usesNode, node, genCtx, genTypeBuilders, verboseClassComments, typeProvider); - genCtx = processUsesAugments(schemaContext, augment, module, genCtx, genTypeBuilders, - verboseClassComments, typeProvider); + private static QName createQNameFromSuperNode(final Module module, final Object node, final SchemaNode superChildNode) { + QName childNodeQName = null; + if (node instanceof Module) { + childNodeQName = QName.create(((Module) node).getNamespace(), ((Module) node).getRevision(), + superChildNode.getQName().getLocalName()); + } else if (node instanceof SchemaNode) { + childNodeQName = QName.create(((SchemaNode) node).getQName(), superChildNode.getQName().getLocalName()); + } else if (node instanceof AugmentationSchema) { + childNodeQName = QName.create(module.getNamespace(), module.getRevision(), superChildNode.getQName().getLocalName()); + } else { + throw new IllegalArgumentException("Not support node type:" + node.toString()); + } + + return childNodeQName; + } + + private static void addUsesImplements(final SchemaNode superNode, final Module superModule, + final Object node, final Module module, final SchemaContext schemaContext, + Map genCtx, final BindingNamespaceType namespaceType) { + if (superNode instanceof DataNodeContainer) { + for (DataSchemaNode superChildNode : ((DataNodeContainer) superNode).getChildNodes()) { + if (superChildNode instanceof DataNodeContainer || superChildNode instanceof ChoiceSchemaNode) { + final QName childQName = createQNameFromSuperNode(module, node, superChildNode); + DataSchemaNode childNode = ((DataNodeContainer) node).getDataChildByName(childQName); + Preconditions.checkNotNull(childNode, node.toString() + "->" + childQName.toString()); + + final GeneratedTypeBuilder type = genCtx.get(module).getChildNode(childNode.getPath()); + final GeneratedTypeBuilder superType = genCtx.get(superModule).getChildNode(superChildNode.getPath()); + + Preconditions.checkNotNull(type, module.toString() + "->" + childNode.getPath().toString()); + Preconditions.checkNotNull(superType, superModule.toString() + "->" + superChildNode.getPath().toString()); + type.addImplementsType(superType); + if (superChildNode instanceof ListSchemaNode + && !((ListSchemaNode) superChildNode).getKeyDefinition().isEmpty()) { + if (namespaceType.equals(BindingNamespaceType.Grouping)) { + genCtx.get(module).getKeyType(childNode.getPath()) + .addImplementsType(genCtx.get(superModule).getKeyType(superChildNode.getPath())); + } else if (namespaceType.equals(BindingNamespaceType.Data)) { + genCtx.get(module).getKeyGenTO(childNode.getPath()) + .addImplementsType(genCtx.get(superModule).getKeyType(superChildNode.getPath())); + } + } + addUsesImplements(superChildNode, superModule, childNode, module, schemaContext, genCtx, namespaceType); + } + } + } else if (superNode instanceof ChoiceSchemaNode) { + for (ChoiceCaseNode superCaseNode : ((ChoiceSchemaNode) superNode).getCases()) { + final QName childQName = createQNameFromSuperNode(module, node, superCaseNode); + ChoiceCaseNode caseNode = ((ChoiceSchemaNode) node).getCaseNodeByName(childQName); + Preconditions.checkNotNull(caseNode, node.toString() + "->" + childQName.toString()); + + final GeneratedTypeBuilder type = genCtx.get(module).getCase(caseNode.getPath()); + final GeneratedTypeBuilder superType = genCtx.get(superModule).getCase(superCaseNode.getPath()); + Preconditions.checkNotNull(type, module.toString() + "->" + caseNode.getPath().toString()); + Preconditions.checkNotNull(superType, superModule.toString() + "->" + superCaseNode.getPath().toString()); + type.addImplementsType(superType); + addUsesImplements(superCaseNode, superModule, caseNode, module, schemaContext, genCtx, namespaceType); + } + } else { + throw new IllegalArgumentException("Not support super node :" + superNode.toString()); + } + } + + private static GroupingDefinition findGroupingNodeFromUses(final Module module, final SchemaContext schemaContext, + final Object parentNode, final UsesNode usesNode) { + SchemaNode groupingNode; + if (parentNode instanceof Module) { + final Module superModule = schemaContext.findModuleByNamespaceAndRevision( + usesNode.getGroupingPath().getLastComponent().getModule().getNamespace(), + usesNode.getGroupingPath().getLastComponent().getModule().getRevision()); + groupingNode = superModule.getGroupings() + .stream().filter(grouping -> grouping.getPath().equals(usesNode.getGroupingPath())) + .findFirst().orElse(null); + } else { + //FIXME: Schema path is not unique for Yang 1.1, findDataSchemaNode always does search from data node first. + groupingNode = SchemaContextUtil.findDataSchemaNode(schemaContext, usesNode.getGroupingPath()); + } + Preconditions.checkNotNull(groupingNode, module.toString() + "->" + + usesNode.getGroupingPath().toString()); + Preconditions.checkState(groupingNode instanceof GroupingDefinition, + module.toString() + "->" + usesNode.getGroupingPath().toString()); + return (GroupingDefinition) groupingNode; + } + + static Map processUsesImplements(final Object node, final Module module, + final SchemaContext schemaContext, Map genCtx, final BindingNamespaceType namespaceType) { + if (node instanceof DataNodeContainer) { + for (final UsesNode usesNode : ((DataNodeContainer) node).getUses()) { + final GroupingDefinition grouping = findGroupingNodeFromUses(module, schemaContext, node, usesNode); + final Module superModule = SchemaContextUtil.findParentModule(schemaContext, grouping); + addUsesImplements(grouping, superModule, node, module, schemaContext, genCtx, namespaceType); } } return genCtx; @@ -273,54 +393,53 @@ final class GenHelperUtil { return null; } - /** - * Returns a generated type builder for an augmentation. - * - * The name of the type builder is equal to the name of augmented node with - * serial number as suffix. - * - * @param module - * current module - * @param augmentPackageName - * string with contains the package name to which the augment - * belongs - * @param basePackageName - * string with the package name to which the augmented node - * belongs - * @param targetTypeRef - * target type - * @param augSchema - * augmentation schema which contains data about the child nodes - * and uses of augment - * @return generated type builder for augment in genCtx - */ static Map addRawAugmentGenTypeDefinition(final Module module, final String augmentPackageName, - final String basePackageName, final Type targetTypeRef, final AugmentationSchema augSchema, - final Map> genTypeBuilders, final Map genCtx, final SchemaContext schemaContext, final boolean verboseClassComments, final - TypeProvider typeProvider) { - - Map augmentBuilders = genTypeBuilders.computeIfAbsent(augmentPackageName, k -> new HashMap<>()); - String augIdentifier = getAugmentIdentifier(augSchema.getUnknownSchemaNodes()); + final Type targetTypeRef, final SchemaNode targetNode, final List schemaPathAugmentListEntry, + final Map> genTypeBuilders, final Map genCtx, + final SchemaContext schemaContext, final boolean verboseClassComments, final TypeProvider typeProvider, + final BindingNamespaceType namespaceType) { + + //pick augmentation grouped by augmentation target, there is always at least one + final AugmentationSchema augSchema = schemaPathAugmentListEntry.get(0); + + Map augmentBuilders = genTypeBuilders.computeIfAbsent( + augmentPackageName, k -> new HashMap<>()); + + //this requires valid semantics in YANG model + String augIdentifier = null; + for (AugmentationSchema aug : schemaPathAugmentListEntry) { + augIdentifier = getAugmentIdentifier(aug.getUnknownSchemaNodes()); + break; + } if (augIdentifier == null) { - augIdentifier = augGenTypeName(augmentBuilders, targetTypeRef.getName()); + augIdentifier = new StringBuilder(module.getName()) + .append('_').append(targetNode.getQName().getLocalName()).toString(); } - GeneratedTypeBuilder augTypeBuilder = new GeneratedTypeBuilderImpl(augmentPackageName, augIdentifier); + GeneratedTypeBuilderImpl augTypeBuilder = new GeneratedTypeBuilderImpl(augmentPackageName, augIdentifier, + true, false, genCtx.get(module)); augTypeBuilder.addImplementsType(BindingTypes.TREE_NODE); + augTypeBuilder.addImplementsType(parameterizedTypeFor(BindingTypes.INSTANTIABLE, augTypeBuilder)); augTypeBuilder.addImplementsType(Types.augmentationTypeFor(targetTypeRef)); + augTypeBuilder.setBasePackageName(BindingMapping.getRootPackageName(module)); + augTypeBuilder.setWithBuilder(true); annotateDeprecatedIfNecessary(augSchema.getStatus(), augTypeBuilder); - augTypeBuilder = addImplementedInterfaceFromUses(augSchema, augTypeBuilder, genCtx); - augTypeBuilder = augSchemaNodeToMethods(module, basePackageName, augTypeBuilder, augTypeBuilder, augSchema - .getChildNodes(), genCtx, schemaContext, verboseClassComments, typeProvider, genTypeBuilders); + //produces getters for augTypeBuilder eventually + for (AugmentationSchema aug : schemaPathAugmentListEntry) { + //apply all uses + addImplementedInterfaceFromUses(aug, augTypeBuilder, genCtx); + augSchemaNodeToMethods(module, BindingMapping.getRootPackageName(module), augTypeBuilder, augTypeBuilder, aug.getChildNodes(), + genCtx, schemaContext, verboseClassComments, typeProvider, genTypeBuilders, namespaceType); + } + augmentBuilders.put(augTypeBuilder.getName(), augTypeBuilder); if(!augSchema.getChildNodes().isEmpty()) { genCtx.get(module).addTypeToAugmentation(augTypeBuilder, augSchema); - + genCtx.get(module).addTargetToAugmentation(augTypeBuilder, augSchema.getTargetPath()); } genCtx.get(module).addAugmentType(augTypeBuilder); return genCtx; @@ -352,12 +471,12 @@ final class GenHelperUtil { final GeneratedTypeBuilder typeBuilder, final GeneratedTypeBuilder childOf, final Iterable schemaNodes, final Map genCtx, final SchemaContext schemaContext, final boolean verboseClassComments, final TypeProvider typeProvider, final Map> genTypeBuilders) { + GeneratedTypeBuilder>> genTypeBuilders, final BindingNamespaceType namespaceType) { if (schemaNodes != null && typeBuilder != null) { for (final DataSchemaNode schemaNode : schemaNodes) { if (!schemaNode.isAugmenting()) { addSchemaNodeToBuilderAsMethod(basePackageName, schemaNode, typeBuilder, childOf, module, genCtx, - schemaContext, verboseClassComments, genTypeBuilders, typeProvider); + schemaContext, verboseClassComments, genTypeBuilders, typeProvider, namespaceType); } } } @@ -378,9 +497,8 @@ final class GenHelperUtil { * DataNodeContainer} it can also implement nodes which are specified in * uses. * - * @param packageName - * string with the name of the package to which - * schemaNode belongs. + * @param basePackageName + * string contains the module package name * @param schemaNode * schema node for which is created generated type builder * @param parent @@ -388,28 +506,39 @@ final class GenHelperUtil { * @param schemaContext schema context * @return generated type builder schemaNode */ - static GeneratedTypeBuilder addDefaultInterfaceDefinition(final String packageName, final SchemaNode + private static GeneratedTypeBuilder addDefaultInterfaceDefinition(final String basePackageName, final SchemaNode schemaNode, final Type parent, final Module module, final Map genCtx, final SchemaContext schemaContext, final boolean verboseClassComments, final Map> genTypeBuilders, final TypeProvider typeProvider) { + GeneratedTypeBuilder>> genTypeBuilders, final TypeProvider typeProvider, final BindingNamespaceType namespaceType) { - GeneratedTypeBuilder it = addRawInterfaceDefinition(packageName, schemaNode, schemaContext, "", - verboseClassComments, genTypeBuilders); - if (parent == null) { - it.addImplementsType(BindingTypes.TREE_NODE); - } else { - if (parent instanceof ListSchemaNode) { - it.addImplementsType(parameterizedTypeFor(BindingTypes.TREE_CHILD_NODE, parent, parameterizedTypeFor - (BindingTypes.IDENTIFIABLE_ITEM, parent))); + String suffix = ""; + if (schemaNode instanceof GroupingDefinition) { + suffix = "grouping"; + } else if (namespaceType.equals(BindingNamespaceType.Grouping)) { + suffix = "data"; + } + + GeneratedTypeBuilder it = addRawInterfaceDefinition(basePackageName, schemaNode, schemaContext, "", suffix, + verboseClassComments, genTypeBuilders, namespaceType, genCtx.get(module)); + if (namespaceType.equals(BindingNamespaceType.Data)) { + if (parent == null) { + it.addImplementsType(BindingTypes.TREE_NODE); } else { - it.addImplementsType(parameterizedTypeFor(BindingTypes.TREE_CHILD_NODE, parent, parameterizedTypeFor - (BindingTypes.ITEM, parent))); - it.addImplementsType(parameterizedTypeFor(BindingTypes.INSTANTIABLE, it)); + if (parent instanceof ListSchemaNode) { + it.addImplementsType(parameterizedTypeFor(BindingTypes.TREE_CHILD_NODE, parent, parameterizedTypeFor + (BindingTypes.IDENTIFIABLE_ITEM, parent))); + } else { + it.addImplementsType(parameterizedTypeFor(BindingTypes.TREE_CHILD_NODE, parent, parameterizedTypeFor + (BindingTypes.ITEM, parent))); + it.addImplementsType(parameterizedTypeFor(BindingTypes.INSTANTIABLE, it)); + } } - } - if (!(schemaNode instanceof GroupingDefinition)) { - it.addImplementsType(BindingTypes.augmentable(it)); + if (!(schemaNode instanceof GroupingDefinition)) { + it.addImplementsType(BindingTypes.augmentable(it)); + } + } else { + it.addImplementsType(BindingTypes.TREE_NODE); } if (schemaNode instanceof DataNodeContainer) { @@ -425,13 +554,9 @@ final class GenHelperUtil { parentName, final String basePackageName, final NotificationDefinition notification, final Module module, final SchemaContext schemaContext, final boolean verboseClassComments, Map> genTypeBuilders, TypeProvider typeProvider, Map genCtx) { - - processUsesAugments(schemaContext, notification, module, genCtx, genTypeBuilders, - verboseClassComments, typeProvider); - final GeneratedTypeBuilder notificationInterface = addDefaultInterfaceDefinition (basePackageName, notification, null, module, genCtx, schemaContext, - verboseClassComments, genTypeBuilders, typeProvider); + verboseClassComments, genTypeBuilders, typeProvider, BindingNamespaceType.Data); annotateDeprecatedIfNecessary(notification.getStatus(), notificationInterface); notificationInterface.addImplementsType(NOTIFICATION); genCtx.get(module).addChildNodeType(notification, notificationInterface); @@ -439,7 +564,7 @@ final class GenHelperUtil { // Notification object resolveDataSchemaNodes(module, basePackageName, notificationInterface, notificationInterface, notification.getChildNodes(), genCtx, schemaContext, - verboseClassComments, genTypeBuilders, typeProvider); + verboseClassComments, genTypeBuilders, typeProvider, BindingNamespaceType.Data); //in case of tied notification, incorporate parent's localName final StringBuilder sb = new StringBuilder("on_"); @@ -462,9 +587,8 @@ final class GenHelperUtil { * {@link BindingGeneratorImpl#genTypeBuilders genTypeBuilders}. If it isn't * found it is created and added to genTypeBuilders. * - * @param packageName - * string with the package name to which returning generated type - * builder belongs + * @param basePackageName + * string contains the module package name * @param schemaNode * schema node which provide data about the schema node name * @param schemaContext schema context @@ -480,12 +604,13 @@ final class GenHelperUtil { * * */ - static GeneratedTypeBuilder addRawInterfaceDefinition(final String packageName, final SchemaNode schemaNode, - final SchemaContext schemaContext, final String prefix, final boolean verboseClassComments, - final Map> genTypeBuilders) { + static GeneratedTypeBuilder addRawInterfaceDefinition(final String basePackageName, final SchemaNode schemaNode, + final SchemaContext schemaContext, final String prefix, final String suffix, + final boolean verboseClassComments, final Map> genTypeBuilders, + final BindingNamespaceType namespaceType, ModuleContext context) { Preconditions.checkArgument(schemaNode != null, "Data Schema Node cannot be NULL."); - Preconditions.checkArgument(packageName != null, "Package Name for Generated Type cannot be NULL."); + Preconditions.checkArgument(basePackageName != null, "Base package Name for Generated Type cannot be NULL."); String schemaNodeName = schemaNode.getQName().getLocalName(); Preconditions.checkArgument(schemaNodeName != null, "Local Name of QName for Data Schema Node cannot be NULL."); @@ -494,14 +619,23 @@ final class GenHelperUtil { schemaNodeName = new StringBuilder(prefix).append('_').append(schemaNodeName).toString(); } - final GeneratedTypeBuilderImpl newType = new GeneratedTypeBuilderImpl(packageName, schemaNodeName); + if (suffix != null && !suffix.isEmpty()) { + // underscore used as separator for distinction of class name parts + schemaNodeName = new StringBuilder(schemaNodeName).append('_').append(suffix).toString(); + } + + final String packageName = packageNameForGeneratedType(basePackageName, schemaNode.getPath(), namespaceType); + final GeneratedTypeBuilderImpl newType = new GeneratedTypeBuilderImpl(packageName, schemaNodeName, context); final Module module = SchemaContextUtil.findParentModule(schemaContext, schemaNode); qNameConstant(newType, BindingMapping.QNAME_STATIC_FIELD_NAME, schemaNode.getQName()); newType.addComment(schemaNode.getDescription()); - newType.setDescription(createDescription(schemaNode, newType.getFullyQualifiedName(), schemaContext, verboseClassComments)); + newType.setDescription(createDescription(schemaNode, newType.getFullyQualifiedName(), schemaContext, + verboseClassComments, namespaceType)); newType.setReference(schemaNode.getReference()); newType.setSchemaPath((List) schemaNode.getPath().getPathFromRoot()); newType.setModuleName(module.getName()); + newType.setBasePackageName(BindingMapping.getRootPackageName(module)); + newType.setWithBuilder(AuxiliaryGenUtils.hasBuilderClass(schemaNode, namespaceType)); if (!genTypeBuilders.containsKey(packageName)) { final Map builders = new HashMap<>(); @@ -520,78 +654,159 @@ final class GenHelperUtil { private static void addSchemaNodeToBuilderAsMethod(final String basePackageName, final DataSchemaNode node, final GeneratedTypeBuilder typeBuilder, final GeneratedTypeBuilder childOf, final Module module, final Map genCtx, final SchemaContext schemaContext, final boolean verboseClassComments, - final Map> genTypeBuilders, final TypeProvider typeProvider) { - //TODO: implement rest of schema nodes GTO building + final Map> genTypeBuilders, final TypeProvider typeProvider, + final BindingNamespaceType namespaceType) { + if (node != null && typeBuilder != null) { if (node instanceof ContainerSchemaNode) { containerToGenType(module, basePackageName, typeBuilder, childOf, (ContainerSchemaNode) node, - schemaContext, verboseClassComments, genCtx, genTypeBuilders, typeProvider); + schemaContext, verboseClassComments, genCtx, genTypeBuilders, typeProvider, namespaceType); + } else if (node instanceof LeafListSchemaNode) { + resolveLeafListSchemaNode(schemaContext, typeBuilder, (LeafListSchemaNode) node, module, + typeProvider, genCtx); } else if (node instanceof LeafSchemaNode) { - resolveLeafSchemaNodeAsMethod(schemaContext, typeBuilder, genCtx, (LeafSchemaNode) node, module, + resolveLeafSchemaNodeAsMethod("", schemaContext, typeBuilder, genCtx, (LeafSchemaNode) node, module, typeProvider); } else if (node instanceof ListSchemaNode) { listToGenType(module, basePackageName, typeBuilder, childOf, (ListSchemaNode) node, schemaContext, - verboseClassComments, genCtx, genTypeBuilders, typeProvider); + verboseClassComments, genCtx, genTypeBuilders, typeProvider, namespaceType); + } else if (node instanceof ChoiceSchemaNode) { + choiceToGenType(module, schemaContext, verboseClassComments, basePackageName, childOf, + (ChoiceSchemaNode) node, genTypeBuilders, genCtx, typeProvider, namespaceType); + } else if (node instanceof AnyXmlSchemaNode || node instanceof AnyDataSchemaNode) { + resolveAnyNodeAsMethod(schemaContext, typeBuilder, genCtx, node, module, typeProvider); } } + } + /** + * Converts choiceNode to the list of generated types for + * choice and its cases. + * + * The package names for choice and for its cases are created as + * concatenation of the module package (basePackageName) and + * names of all parents node. + * + * @param module + * current module + * @param basePackageName + * string with the module package name + * @param parent + * parent type + * @param choiceNode + * choice node which is mapped to generated type. Also child + * nodes - cases are mapped to generated types. + * @throws IllegalArgumentException + *
    + *
  • if basePackageName is null
  • + *
  • if choiceNode is null
  • + *
+ */ + private static void choiceToGenType(final Module module, final SchemaContext schemaContext, final boolean + verboseClasssComments, final String basePackageName, final GeneratedTypeBuilder parent, final + ChoiceSchemaNode choiceNode, final Map> genTypeBuilders, + final Map genCtx, final TypeProvider typeProvider, final BindingNamespaceType namespaceType) { + checkArgument(basePackageName != null, "Base Package Name cannot be NULL."); + checkArgument(choiceNode != null, "Choice Schema Node cannot be NULL."); + + final GeneratedTypeBuilder choiceTypeBuilder = addRawInterfaceDefinition(basePackageName, choiceNode, + schemaContext, "", "", verboseClasssComments, genTypeBuilders, namespaceType, genCtx.get(module)); + constructGetter(parent, choiceNode.getQName().getLocalName(), + choiceNode.getDescription(), choiceTypeBuilder, choiceNode.getStatus()); + if (namespaceType.equals(BindingNamespaceType.Data)) { + choiceTypeBuilder.addImplementsType(parameterizedTypeFor(BindingTypes.INSTANTIABLE, choiceTypeBuilder)); + } + annotateDeprecatedIfNecessary(choiceNode.getStatus(), choiceTypeBuilder); + genCtx.get(module).addChildNodeType(choiceNode, choiceTypeBuilder); + generateTypesFromChoiceCases(module, schemaContext, genCtx, basePackageName, choiceTypeBuilder.toInstance(), + choiceNode, verboseClasssComments, typeProvider, genTypeBuilders, namespaceType); } private static void containerToGenType(final Module module, final String basePackageName, final GeneratedTypeBuilder parent, final GeneratedTypeBuilder childOf, final ContainerSchemaNode node, final SchemaContext schemaContext, final boolean verboseClassComments, final Map genCtx, - final Map> genTypeBuilders, final TypeProvider typeProvider) { + final Map> genTypeBuilders, final TypeProvider typeProvider, + final BindingNamespaceType namespaceType) { final GeneratedTypeBuilder genType = processDataSchemaNode(module, basePackageName, childOf, node, - schemaContext, verboseClassComments, genCtx, genTypeBuilders, typeProvider); + schemaContext, verboseClassComments, genCtx, genTypeBuilders, typeProvider, namespaceType); if (genType != null) { - constructGetter(parent, node.getQName().getLocalName(), node.getDescription(), genType, node.getStatus()); + StringBuilder getterName = new StringBuilder(node.getQName().getLocalName()); + final MethodSignatureBuilder getter = constructGetter(parent, getterName.toString(), node.getDescription(), genType, node.getStatus()); resolveDataSchemaNodes(module, basePackageName, genType, genType, node.getChildNodes(), genCtx, - schemaContext, verboseClassComments, genTypeBuilders, typeProvider); + schemaContext, verboseClassComments, genTypeBuilders, typeProvider, namespaceType); + processUsesImplements(node, module, schemaContext, genCtx, namespaceType); } } private static void listToGenType(final Module module, final String basePackageName, final GeneratedTypeBuilder parent, final GeneratedTypeBuilder childOf, final ListSchemaNode node, final SchemaContext schemaContext, final boolean verboseClassComments, final Map genCtx, - final Map> genTypeBuilders, final TypeProvider typeProvider) { + final Map> genTypeBuilders, final TypeProvider typeProvider, + final BindingNamespaceType namespaceType) { + final GeneratedTypeBuilder genType = processDataSchemaNode(module, basePackageName, childOf, node, - schemaContext, verboseClassComments, genCtx, genTypeBuilders, typeProvider); + schemaContext, verboseClassComments, genCtx, genTypeBuilders, typeProvider, namespaceType); if (genType != null) { final String nodeName = node.getQName().getLocalName(); - constructGetter(parent, nodeName, node.getDescription(), - Types.listTypeFor(genType), node.getStatus()); + + Type getterReturnType = Types.listTypeFor(genType); + if (namespaceType.equals(BindingNamespaceType.Grouping)) { + getterReturnType = Types.listTypeFor(wildcardTypeFor(genType.getPackageName(), genType.getName(), + true, true, null)); + } + constructGetter(parent, nodeName, node.getDescription(), getterReturnType, node.getStatus()); + final List listKeys = node.getKeyDefinition(); final String packageName = new StringBuilder(packageNameForGeneratedType(basePackageName, node.getPath(), BindingNamespaceType.Key)).append('.').append(nodeName).toString(); + //FIXME: Is it neccessary to generate interface of key and implemented by class? + if (namespaceType.equals(BindingNamespaceType.Grouping)) { + final GeneratedTypeBuilder genTypeBuilder = resolveListKeyTypeBuilder(packageName, node, genCtx.get(module)); + for (final DataSchemaNode schemaNode : node.getChildNodes()) { + if (resolveDataSchemaNodesCheck(module, schemaContext, schemaNode)) { + addSchemaNodeToListTypeBuilders(nodeName, basePackageName, schemaNode, genType, genTypeBuilder, listKeys, + module, typeProvider, schemaContext, genCtx, genTypeBuilders, verboseClassComments, namespaceType); + } + } + if (genTypeBuilder != null) { + typeBuildersToGenTypes(module, genType, genTypeBuilder.toInstance(), genCtx, namespaceType); + genCtx.get(module).addKeyType(node.getPath(), genTypeBuilder); + } + } else { + final GeneratedTOBuilder genTOBuilder = resolveListKeyTOBuilder(packageName, node, genCtx.get(module)); + for (final DataSchemaNode schemaNode : node.getChildNodes()) { + if (resolveDataSchemaNodesCheck(module, schemaContext, schemaNode)) { + addSchemaNodeToListBuilders(nodeName, basePackageName, schemaNode, genType, genTOBuilder, listKeys, + module, typeProvider, schemaContext, genCtx, genTypeBuilders, verboseClassComments, namespaceType); + } + } - final GeneratedTOBuilder genTOBuilder = resolveListKeyTOBuilder(packageName, node); + // serialVersionUID + if (genTOBuilder != null) { + final GeneratedPropertyBuilder prop = new GeneratedPropertyBuilderImpl("serialVersionUID"); + prop.setValue(Long.toString(computeDefaultSUID(genTOBuilder))); + genTOBuilder.setSUID(prop); - for (final DataSchemaNode schemaNode : node.getChildNodes()) { - if (!schemaNode.isAugmenting()) { - addSchemaNodeToListBuilders(nodeName, basePackageName, schemaNode, genType, genTOBuilder, listKeys, - module, typeProvider, schemaContext, genCtx, genTypeBuilders, verboseClassComments); + typeBuildersToGenTypes(module, genType, genTOBuilder.toInstance(), genCtx, namespaceType); + genCtx.get(module).addGeneratedTOBuilder(node.getPath(), genTOBuilder); } } - - // serialVersionUID - if (genTOBuilder != null) { - final GeneratedPropertyBuilder prop = new GeneratedPropertyBuilderImpl("serialVersionUID"); - prop.setValue(Long.toString(computeDefaultSUID(genTOBuilder))); - genTOBuilder.setSUID(prop); - } - - typeBuildersToGenTypes(module, genType, genTOBuilder, genCtx); } } private static void typeBuildersToGenTypes(final Module module, final GeneratedTypeBuilder typeBuilder, - final GeneratedTOBuilder genTOBuilder, final Map genCtx) { + final Type keyType, final Map genCtx, + final BindingNamespaceType namespaceType) { checkArgument(typeBuilder != null, "Generated Type Builder cannot be NULL."); - if (genTOBuilder != null) { - final GeneratedTransferObject genTO = genTOBuilder.toInstance(); - constructGetter(typeBuilder, "key", "Returns Primary Key of Yang List Type", genTO, Status.CURRENT); - genCtx.get(module).addGeneratedTOBuilder(genTOBuilder); + if (keyType != null) { + Type returnKeyType = keyType; + if (namespaceType.equals(BindingNamespaceType.Grouping)) { + returnKeyType = wildcardTypeFor(keyType.getPackageName(), keyType.getName(), + true, true, null); + } + constructGetter(typeBuilder, "key", "Returns Primary Key of Yang List Type", returnKeyType, Status.CURRENT); + } } @@ -614,10 +829,10 @@ final class GenHelperUtil { *
  • true - in other cases
  • * */ - private static Type resolveLeafSchemaNodeAsMethod(final SchemaContext schemaContext, final GeneratedTypeBuilder - typeBuilder, final Map genCtx, final LeafSchemaNode leaf, final Module module, - final TypeProvider typeProvider) { - if (leaf == null || typeBuilder == null || leaf.isAddedByUses()) { + private static Type resolveLeafSchemaNodeAsMethod(final String nodeName, final SchemaContext schemaContext, + final GeneratedTypeBuilder typeBuilder, final Map genCtx, final LeafSchemaNode leaf, + final Module module, final TypeProvider typeProvider) { + if (leaf == null || typeBuilder == null) { return null; } @@ -632,7 +847,7 @@ final class GenHelperUtil { final TypeDefinition typeDef = leaf.getType(); if (isInnerType(leaf, typeDef)) { if (typeDef instanceof EnumTypeDefinition) { - returnType = typeProvider.javaTypeForSchemaDefinitionType(typeDef, leaf); + returnType = typeProvider.javaTypeForSchemaDefinitionType(typeDef, leaf, genCtx.get(module)); final EnumTypeDefinition enumTypeDef = (EnumTypeDefinition) typeDef; final EnumBuilder enumBuilder = resolveInnerEnumFromTypeDefinition(enumTypeDef, leaf.getQName(), genCtx, typeBuilder, module); @@ -642,14 +857,14 @@ final class GenHelperUtil { ((TypeProviderImpl) typeProvider).putReferencedType(leaf.getPath(), returnType); } else if (typeDef instanceof UnionTypeDefinition) { final GeneratedTOBuilder genTOBuilder = addTOToTypeBuilder(typeDef, typeBuilder, leaf, parentModule, - typeProvider, schemaContext); + typeProvider, schemaContext, genCtx.get(module)); if (genTOBuilder != null) { //TODO: https://bugs.opendaylight.org/show_bug.cgi?id=2289 returnType = createReturnTypeForUnion(genTOBuilder, typeDef, typeBuilder, parentModule, typeProvider); } } else if (typeDef instanceof BitsTypeDefinition) { final GeneratedTOBuilder genTOBuilder = addTOToTypeBuilder(typeDef, typeBuilder, leaf, parentModule, - typeProvider, schemaContext); + typeProvider, schemaContext, genCtx.get(module)); if (genTOBuilder != null) { returnType = genTOBuilder.toInstance(); } @@ -660,11 +875,11 @@ final class GenHelperUtil { // and apply restrictions from leaf type final Restrictions restrictions = BindingGeneratorUtil.getRestrictions(typeDef); returnType = typeProvider.javaTypeForSchemaDefinitionType(getBaseOrDeclaredType(typeDef), leaf, - restrictions); + restrictions, genCtx.get(module)); } } else { final Restrictions restrictions = BindingGeneratorUtil.getRestrictions(typeDef); - returnType = typeProvider.javaTypeForSchemaDefinitionType(typeDef, leaf, restrictions); + returnType = typeProvider.javaTypeForSchemaDefinitionType(typeDef, leaf, restrictions, genCtx.get(module)); } if (returnType == null) { @@ -680,7 +895,198 @@ final class GenHelperUtil { leafDesc = ""; } - constructGetter(typeBuilder, leafName, leafDesc, returnType, leaf.getStatus()); + final String leafGetterName; + if ("key".equals(leafName.toLowerCase())) { + StringBuilder sb = new StringBuilder(leafName) + .append('_').append("RESERVED_WORD"); + leafGetterName = sb.toString(); + } else { + leafGetterName = leafName; + } + constructGetter(typeBuilder, leafGetterName, leafDesc, returnType, leaf.getStatus()); + return returnType; + } + + /** + * Converts node leaf list schema node to getter method of + * typeBuilder. + * + * @param typeBuilder + * generated type builder to which is node added as + * getter method + * @param node + * leaf list schema node which is added to + * typeBuilder as getter method + * @param module module + * @param typeProvider type provider instance + * @param genCtx actual generated context + * @return boolean value + *
      + *
    • true - if node, typeBuilder, + * nodeName equal null or node is added by uses
    • + *
    • false - other cases
    • + *
    + */ + private static boolean resolveLeafListSchemaNode(final SchemaContext schemaContext, final GeneratedTypeBuilder + typeBuilder, final LeafListSchemaNode node, final Module module, final TypeProvider typeProvider, + final Map genCtx) { + if (node == null || typeBuilder == null) { + return false; + } + + final QName nodeName = node.getQName(); + + final TypeDefinition typeDef = node.getType(); + final Module parentModule = findParentModule(schemaContext, node); + + Type returnType = null; + if (typeDef.getBaseType() == null) { + if (typeDef instanceof EnumTypeDefinition) { + returnType = typeProvider.javaTypeForSchemaDefinitionType(typeDef, node, genCtx.get(module)); + final EnumTypeDefinition enumTypeDef = (EnumTypeDefinition) typeDef; + final EnumBuilder enumBuilder = resolveInnerEnumFromTypeDefinition(enumTypeDef, nodeName, + genCtx, typeBuilder, module); + returnType = new ReferencedTypeImpl(enumBuilder.getPackageName(), enumBuilder.getName(), + genCtx.get(module)); + ((TypeProviderImpl) typeProvider).putReferencedType(node.getPath(), returnType); + } else if (typeDef instanceof UnionTypeDefinition) { + final GeneratedTOBuilder genTOBuilder = addTOToTypeBuilder(typeDef, typeBuilder, node, parentModule, + typeProvider, schemaContext, genCtx.get(module)); + if (genTOBuilder != null) { + returnType = createReturnTypeForUnion(genTOBuilder, typeDef, typeBuilder, parentModule, typeProvider); + } + } else if (typeDef instanceof BitsTypeDefinition) { + final GeneratedTOBuilder genTOBuilder = addTOToTypeBuilder(typeDef, typeBuilder, node, parentModule, + typeProvider, schemaContext, genCtx.get(module)); + returnType = genTOBuilder.toInstance(); + } else { + final Restrictions restrictions = BindingGeneratorUtil.getRestrictions(typeDef); + returnType = typeProvider.javaTypeForSchemaDefinitionType(typeDef, node, restrictions, genCtx.get(module)); + } + } else { + final Restrictions restrictions = BindingGeneratorUtil.getRestrictions(typeDef); + returnType = typeProvider.javaTypeForSchemaDefinitionType(typeDef, node, restrictions, genCtx.get(module)); + } + + final ParameterizedType listType = Types.listTypeFor(returnType); + constructGetter(typeBuilder, nodeName.getLocalName(), node.getDescription(), listType, node.getStatus()); + return true; + } + + /** + * Converts caseNodes set to list of corresponding generated + * types. + * + * For every case which isn't added through augment or uses is + * created generated type builder. The package names for the builder is + * created as concatenation of the module package ( + * basePackageName) and names of all parents nodes of the + * concrete case. There is also relation "implements type" + * between every case builder and choice type + * + * @param module + * current module + * @param schemaContext + * current schema context + * @param genCtx + * actual generated context + * @param basePackageName + * string with the module package name + * @param refChoiceType + * type which represents superior case + * @param choiceNode + * choice case node which is mapped to generated type + * @param verboseClassComments + * Javadoc verbosity switch + * @throws IllegalArgumentException + *
      + *
    • if basePackageName equals null
    • + *
    • if refChoiceType equals null
    • + *
    • if caseNodes equals null
    • + *
    + */ + private static void generateTypesFromChoiceCases(final Module module, final SchemaContext schemaContext, + final Map genCtx, final String basePackageName, final Type refChoiceType, + final ChoiceSchemaNode choiceNode, final boolean verboseClassComments, final TypeProvider typeProvider, + final Map> genTypeBuilders, final BindingNamespaceType namespaceType) { + checkArgument(basePackageName != null, "Base Package Name cannot be NULL."); + checkArgument(refChoiceType != null, "Referenced Choice Type cannot be NULL."); + checkArgument(choiceNode != null, "ChoiceNode cannot be NULL."); + + final Set caseNodes = choiceNode.getCases(); + if (caseNodes == null) { + return; + } + + for (final ChoiceCaseNode caseNode : caseNodes) { + if (caseNode != null && resolveDataSchemaNodesCheck(module, schemaContext, caseNode)) { + final GeneratedTypeBuilder caseTypeBuilder = addDefaultInterfaceDefinition(basePackageName, caseNode, + module, genCtx, schemaContext, verboseClassComments, genTypeBuilders, typeProvider, namespaceType); + caseTypeBuilder.addImplementsType(refChoiceType); + caseTypeBuilder.setParentTypeForBuilder(refChoiceType); + annotateDeprecatedIfNecessary(caseNode.getStatus(), caseTypeBuilder); + genCtx.get(module).addCaseType(caseNode.getPath(), caseTypeBuilder); + genCtx.get(module).addChoiceToCaseMapping(refChoiceType, caseTypeBuilder, caseNode); + final Iterable caseChildNodes = caseNode.getChildNodes(); + if (caseChildNodes != null) { + final SchemaPath choiceNodeParentPath = choiceNode.getPath().getParent(); + + if (!Iterables.isEmpty(choiceNodeParentPath.getPathFromRoot())) { + SchemaNode parent = findDataSchemaNode(schemaContext, choiceNodeParentPath); + + if (parent instanceof AugmentationSchema) { + final AugmentationSchema augSchema = (AugmentationSchema) parent; + final SchemaPath targetPath = augSchema.getTargetPath(); + SchemaNode targetSchemaNode = findDataSchemaNode(schemaContext, targetPath); + if (targetSchemaNode instanceof DataSchemaNode + && ((DataSchemaNode) targetSchemaNode).isAddedByUses()) { + if (targetSchemaNode instanceof DerivableSchemaNode) { + targetSchemaNode = ((DerivableSchemaNode) targetSchemaNode).getOriginal().orNull(); + } + if (targetSchemaNode == null) { + throw new IllegalStateException( + "Failed to find target node from grouping for augmentation " + augSchema + + " in module " + module.getName()); + } + } + parent = targetSchemaNode; + } + + Preconditions.checkState(parent != null, "Could not find Choice node parent %s", + choiceNodeParentPath); + GeneratedTypeBuilder childOfType = findChildNodeByPath(parent.getPath(), genCtx); + if (childOfType == null) { + childOfType = findGroupingByPath(parent.getPath(), genCtx); + } + resolveDataSchemaNodes(module, basePackageName, caseTypeBuilder, childOfType, caseChildNodes, + genCtx, schemaContext, verboseClassComments, genTypeBuilders, typeProvider, namespaceType); + } else { + resolveDataSchemaNodes(module, basePackageName, caseTypeBuilder, moduleToDataType(module, + genCtx, verboseClassComments), caseChildNodes, genCtx, schemaContext, + verboseClassComments, genTypeBuilders, typeProvider, namespaceType); + } + } + } + } + } + + private static Type resolveAnyNodeAsMethod(final SchemaContext schemaContext, final GeneratedTypeBuilder + typeBuilder, final Map genCtx, final DataSchemaNode node, final Module module, + final TypeProvider typeProvider) { + + final String anyName = node.getQName().getLocalName(); + if (anyName == null) { + return null; + } + + String anyDesc = node.getDescription(); + if (anyDesc == null) { + anyDesc = ""; + } + + Type returnType = Types.DOCUMENT; + + constructGetter(typeBuilder, anyName, anyDesc, returnType, node.getStatus()); return returnType; } @@ -724,48 +1130,107 @@ final class GenHelperUtil { final DataSchemaNode schemaNode, final GeneratedTypeBuilder typeBuilder, final GeneratedTOBuilder genTOBuilder, final List listKeys, final Module module, final TypeProvider typeProvider, final SchemaContext schemaContext, final Map genCtx, - final Map> genTypeBuilders, final boolean verboseClassComments) { + final Map> genTypeBuilders, final boolean verboseClassComments, + final BindingNamespaceType namespaceType) { checkArgument(schemaNode != null, "Data Schema Node cannot be NULL."); checkArgument(typeBuilder != null, "Generated Type Builder cannot be NULL."); if (schemaNode instanceof LeafSchemaNode) { final LeafSchemaNode leaf = (LeafSchemaNode) schemaNode; final QName leafQName = leaf.getQName(); - final String leafName = leafQName.getLocalName(); - String leafPckgName = basePackageName; - boolean isKeyPart = false; - if (listKeys.contains(leafQName)) { - leafPckgName = new StringBuilder(leafPckgName).append('.').append(BindingNamespaceType.Key).append('.') - .append(nodeName).toString(); - isKeyPart = true; - } else { - leafPckgName = new StringBuilder(leafPckgName).append('.').append(BindingNamespaceType.Data).append('.') - .append(nodeName).toString(); - } - final String leafGTOName = new StringBuilder(nodeName).append('_').append(leafName).toString(); - final GeneratedTypeBuilder leafGTp = new GeneratedTypeBuilderImpl(leafPckgName, leafGTOName); - resolveLeafSchemaNodeAsMethod(schemaContext, leafGTp, genCtx, leaf, module, + final Type type = resolveLeafSchemaNodeAsMethod(nodeName, schemaContext, typeBuilder, genCtx, leaf, module, typeProvider); + if (listKeys.contains(leafQName)) { + if (type == null) { + resolveLeafSchemaNodeAsProperty(nodeName, schemaContext, typeProvider, genCtx, genTOBuilder, leaf, true, + module); + } else { + AuxiliaryGenUtils.resolveLeafSchemaNodeAsProperty(nodeName, genTOBuilder, leaf, type, true); + } + } + } else { + if (schemaNode instanceof LeafListSchemaNode) { + resolveLeafListSchemaNode(schemaContext, typeBuilder, (LeafListSchemaNode) schemaNode, module, + typeProvider, genCtx); + } else if (schemaNode instanceof ContainerSchemaNode) { + containerToGenType(module, basePackageName, typeBuilder, typeBuilder, (ContainerSchemaNode) schemaNode, + schemaContext, verboseClassComments, genCtx, genTypeBuilders, typeProvider, namespaceType); + } else if (schemaNode instanceof ListSchemaNode) { + listToGenType(module, basePackageName, typeBuilder, typeBuilder, (ListSchemaNode) schemaNode, + schemaContext, verboseClassComments, genCtx, genTypeBuilders, typeProvider, namespaceType); + } else if (schemaNode instanceof ChoiceSchemaNode) { + choiceToGenType(module, schemaContext, verboseClassComments, basePackageName, typeBuilder, + (ChoiceSchemaNode) schemaNode, genTypeBuilders, genCtx, typeProvider, namespaceType); + } + } + } - constructGetter(typeBuilder, leafGTOName, schemaNode.getDescription(), leafGTp, Status.CURRENT); + private static void addSchemaNodeToListTypeBuilders(final String nodeName, final String basePackageName, + final DataSchemaNode schemaNode, final GeneratedTypeBuilder typeBuilder, + final GeneratedTypeBuilder genTypeBuilder, final List listKeys, final Module module, + final TypeProvider typeProvider, final SchemaContext schemaContext, final Map genCtx, + final Map> genTypeBuilders, final boolean verboseClassComments, + final BindingNamespaceType namespaceType) { + checkArgument(schemaNode != null, "Data Schema Node cannot be NULL."); + checkArgument(typeBuilder != null, "Generated Type Builder cannot be NULL."); - if (isKeyPart) { - AuxiliaryGenUtils.resolveLeafSchemaNodeAsProperty(genTOBuilder, leaf, leafGTp, true); + if (schemaNode instanceof LeafSchemaNode) { + final LeafSchemaNode leaf = (LeafSchemaNode) schemaNode; + final QName leafQName = leaf.getQName(); + final Type type = resolveLeafSchemaNodeAsMethod(nodeName, schemaContext, typeBuilder, genCtx, leaf, module, + typeProvider); + if (listKeys.contains(leafQName)) { + resolveLeafSchemaNodeAsMethod(nodeName, schemaContext, genTypeBuilder, genCtx, leaf, module, + typeProvider); } - } else if (!schemaNode.isAddedByUses()) { - //TODO: implement leaf list to generated type - //TODO: implement choice to generated type - if (schemaNode instanceof ContainerSchemaNode) { + } else { + if (schemaNode instanceof LeafListSchemaNode) { + resolveLeafListSchemaNode(schemaContext, typeBuilder, (LeafListSchemaNode) schemaNode, module, + typeProvider, genCtx); + } else if (schemaNode instanceof ContainerSchemaNode) { containerToGenType(module, basePackageName, typeBuilder, typeBuilder, (ContainerSchemaNode) schemaNode, - schemaContext, verboseClassComments, genCtx, genTypeBuilders, typeProvider); + schemaContext, verboseClassComments, genCtx, genTypeBuilders, typeProvider, namespaceType); } else if (schemaNode instanceof ListSchemaNode) { listToGenType(module, basePackageName, typeBuilder, typeBuilder, (ListSchemaNode) schemaNode, - schemaContext, verboseClassComments, genCtx, genTypeBuilders, typeProvider); + schemaContext, verboseClassComments, genCtx, genTypeBuilders, typeProvider, namespaceType); + } else if (schemaNode instanceof ChoiceSchemaNode) { + choiceToGenType(module, schemaContext, verboseClassComments, basePackageName, typeBuilder, + (ChoiceSchemaNode) schemaNode, genTypeBuilders, genCtx, typeProvider, namespaceType); } } } + private static boolean resolveLeafSchemaNodeAsProperty(final String nodeName, final SchemaContext schemaContext, final TypeProvider + typeProvider, final Map genCtx, final GeneratedTOBuilder + toBuilder, final LeafSchemaNode leaf, final boolean isReadOnly, final Module module) { + + if (leaf != null && toBuilder != null) { + Type returnType; + final TypeDefinition typeDef = leaf.getType(); + if (typeDef instanceof UnionTypeDefinition) { + // GeneratedType for this type definition should be already + // created + final QName qname = typeDef.getQName(); + final Module unionModule = schemaContext.findModuleByNamespaceAndRevision(qname.getNamespace(), + qname.getRevision()); + final ModuleContext mc = genCtx.get(unionModule); + returnType = mc.getTypedefs().get(typeDef.getPath()); + } else if (typeDef instanceof EnumTypeDefinition && typeDef.getBaseType() == null) { + // Annonymous enumeration (already generated, since it is inherited via uses). + LeafSchemaNode originalLeaf = (LeafSchemaNode) SchemaNodeUtils.getRootOriginalIfPossible(leaf); + QName qname = originalLeaf.getQName(); + final Module enumModule = schemaContext.findModuleByNamespaceAndRevision(qname.getNamespace(), + qname.getRevision()); + returnType = genCtx.get(enumModule).getInnerType(originalLeaf.getType().getPath()); + } else { + returnType = typeProvider.javaTypeForSchemaDefinitionType(typeDef, leaf, genCtx.get(module)); + } + return AuxiliaryGenUtils.resolveLeafSchemaNodeAsProperty(nodeName, toBuilder, leaf, returnType, isReadOnly); + } + return false; + } + private static TypeDefinition getBaseOrDeclaredType(final TypeDefinition typeDef) { final TypeDefinition baseType = typeDef.getBaseType(); return (baseType != null && baseType.getBaseType() != null) ? baseType : typeDef; @@ -775,27 +1240,20 @@ final class GenHelperUtil { private static GeneratedTypeBuilder processDataSchemaNode(final Module module, final String basePackageName, final GeneratedTypeBuilder childOf, final DataSchemaNode node, final SchemaContext schemaContext, final boolean verboseClassComments, Map genCtx, final Map> genTypeBuilders, final TypeProvider typeProvider) { + GeneratedTypeBuilder>> genTypeBuilders, final TypeProvider typeProvider, final BindingNamespaceType namespaceType) { - if (node.isAugmenting() || node.isAddedByUses()) { - return null; - } - final String packageName = packageNameForGeneratedType(basePackageName, node.getPath(), BindingNamespaceType.Data); - final GeneratedTypeBuilder genType = addDefaultInterfaceDefinition(packageName, node, childOf, module, - genCtx, schemaContext, verboseClassComments, genTypeBuilders, typeProvider); + final GeneratedTypeBuilder genType = addDefaultInterfaceDefinition(basePackageName, node, childOf, module, + genCtx, schemaContext, verboseClassComments, genTypeBuilders, typeProvider, namespaceType); genType.addComment(node.getDescription()); annotateDeprecatedIfNecessary(node.getStatus(), genType); - genType.setDescription(createDescription(node, genType.getFullyQualifiedName(), schemaContext, verboseClassComments)); + genType.setDescription(createDescription(node, genType.getFullyQualifiedName(), schemaContext, + verboseClassComments, namespaceType)); genType.setModuleName(module.getName()); genType.setReference(node.getReference()); genType.setSchemaPath((List) node.getPath().getPathFromRoot()); genType.setParentTypeForBuilder(childOf); if (node instanceof DataNodeContainer) { genCtx.get(module).addChildNodeType(node, genType); - genCtx = groupingsToGenTypes(module, ((DataNodeContainer) node).getGroupings(), genCtx, schemaContext, - verboseClassComments, genTypeBuilders, typeProvider); - processUsesAugments(schemaContext, (DataNodeContainer) node, module, genCtx, genTypeBuilders, - verboseClassComments, typeProvider); } return genType; } @@ -864,17 +1322,13 @@ final class GenHelperUtil { private static Map groupingToGenType(final String basePackageName, final GroupingDefinition grouping, final Module module, Map genCtx, final SchemaContext schemaContext, final boolean verboseClassComments, Map> genTypeBuilders, final TypeProvider typeProvider) { - final String packageName = packageNameForGeneratedType(basePackageName, grouping.getPath(), BindingNamespaceType.Grouping); - final GeneratedTypeBuilder genType = addDefaultInterfaceDefinition(packageName, grouping, module, genCtx, - schemaContext, verboseClassComments, genTypeBuilders, typeProvider); + final GeneratedTypeBuilder genType = addDefaultInterfaceDefinition(basePackageName, grouping, module, genCtx, + schemaContext, verboseClassComments, genTypeBuilders, typeProvider, BindingNamespaceType.Grouping); annotateDeprecatedIfNecessary(grouping.getStatus(), genType); - genCtx.get(module).addGroupingType(grouping.getPath(), genType); + genCtx.get(module).addGroupingType(grouping, genType); resolveDataSchemaNodes(module, basePackageName, genType, genType, grouping.getChildNodes(), genCtx, - schemaContext, verboseClassComments, genTypeBuilders, typeProvider); - genCtx = groupingsToGenTypes(module, grouping.getGroupings(), genCtx, schemaContext, verboseClassComments, - genTypeBuilders, typeProvider); - genCtx = processUsesAugments(schemaContext, grouping, module, genCtx, genTypeBuilders, verboseClassComments, - typeProvider); + schemaContext, verboseClassComments, genTypeBuilders, typeProvider, BindingNamespaceType.Grouping); + genCtx = processUsesImplements(grouping, module, schemaContext, genCtx, BindingNamespaceType.Grouping); return genCtx; } @@ -901,56 +1355,56 @@ final class GenHelperUtil { */ static Map identityToGenType(final Module module, final String basePackageName, final IdentitySchemaNode identity, final SchemaContext schemaContext, Map genCtx, - boolean verboseClassComments, final Map> genTypeBuilders, - final TypeProvider typeProvider, Map generatedIdentities) { - - final String packageName = BindingGeneratorUtil.packageNameForGeneratedType(basePackageName, identity.getPath(), - BindingNamespaceType.Identity); - final GeneratedTOBuilderImpl newType = new GeneratedTOBuilderImpl(packageName, - identity.getQName().getLocalName()); - - final Set baseIdentities = identity.getBaseIdentities(); - if (baseIdentities.size() == 0) { - //no base - abstract - final GeneratedTOBuilderImpl gto = new GeneratedTOBuilderImpl(BaseIdentity.class.getPackage().getName(), - BaseIdentity.class.getSimpleName()); - newType.setExtendsType(gto.toInstance()); - generatedIdentities.put(identity.getQName(), newType); - } else { - //one base - inheritance - final IdentitySchemaNode baseIdentity = baseIdentities.iterator().next(); - final Module baseIdentityParentModule = SchemaContextUtil.findParentModule(schemaContext, baseIdentity); - final String returnTypePkgName = new StringBuilder(BindingMapping.getRootPackageName - (baseIdentityParentModule)) - .append('.') - .append(BindingNamespaceType.Identity.getPackagePrefix()) - .toString(); - - final GeneratedTOBuilderImpl existingIdentityGto = generatedIdentities.get(baseIdentity.getQName()); - if (existingIdentityGto != null) { - newType.setExtendsType(existingIdentityGto.toInstance()); - } else { - final GeneratedTOBuilderImpl gto = new GeneratedTOBuilderImpl(returnTypePkgName, - baseIdentity.getQName().getLocalName()); + boolean verboseClassComments) { + + resolveIdentitySchemaNode(basePackageName, schemaContext, identity, module, verboseClassComments, genCtx); + return genCtx; + } + + private static GeneratedTOBuilder resolveIdentitySchemaNode(final String basePackageName, final SchemaContext schemaContext, + final IdentitySchemaNode identity, final Module module, final boolean verboseClassComments, + final Map genCtx) { + Preconditions.checkNotNull(identity,"Identity can not be null!"); + + //check first if identity has been resolved as base identity of some other one + GeneratedTOBuilder newType = findIdentityByQname(identity.getQName(), genCtx); + if (newType == null) { + final Module parentModule = SchemaContextUtil.findParentModule(schemaContext, identity); + Preconditions.checkState(module.equals(parentModule), + "If the type is null ,it must be in the same module, otherwise it must has been" + + "resolved by an imported module."); + + final String packageName = BindingGeneratorUtil.packageNameForGeneratedType(basePackageName, identity.getPath(), + BindingNamespaceType.Identity); + newType = new GeneratedTOBuilderImpl(packageName, identity.getQName().getLocalName(), true, false, + genCtx.get(module)); + + final Set baseIdentities = identity.getBaseIdentities(); + if (baseIdentities.size() == 0) { + //no base - abstract + final GeneratedTOBuilderImpl gto = new GeneratedTOBuilderImpl(BaseIdentity.class.getPackage().getName(), + BaseIdentity.class.getSimpleName(), genCtx.get(module)); newType.setExtendsType(gto.toInstance()); - generatedIdentities.put(baseIdentity.getQName(), gto); + } else { + //one base - inheritance + final IdentitySchemaNode baseIdentity = baseIdentities.iterator().next(); + GeneratedTOBuilder baseType = resolveIdentitySchemaNode(basePackageName, schemaContext, + baseIdentity, module, verboseClassComments, genCtx); + newType.setExtendsType(baseType.toInstance()); } - //FIXME: more bases - possible composition, multiple inheritance not possible - } - generatedIdentities.put(identity.getQName(), newType); - - newType.setAbstract(true); - newType.addComment(identity.getDescription()); - newType.setDescription(createDescription(identity, newType.getFullyQualifiedName(), schemaContext, - verboseClassComments)); - newType.setReference(identity.getReference()); - newType.setModuleName(module.getName()); - newType.setSchemaPath((List) identity.getPath().getPathFromRoot()); + newType.setAbstract(true); + newType.addComment(identity.getDescription()); + newType.setDescription(createDescription(identity, newType.getFullyQualifiedName(), schemaContext, + verboseClassComments, BindingNamespaceType.Identity)); + newType.setReference(identity.getReference()); + newType.setModuleName(module.getName()); + newType.setSchemaPath((List) identity.getPath().getPathFromRoot()); - qNameConstant(newType, BindingMapping.QNAME_STATIC_FIELD_NAME, identity.getQName()); + qNameConstant(newType, BindingMapping.QNAME_STATIC_FIELD_NAME, identity.getQName()); - genCtx.get(module).addIdentityType(identity.getQName(), newType); - return genCtx; + genCtx.get(module).addIdentityType(identity.getQName(), newType); + } + return newType; } }