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=94d4812cd039f3c5e72b6f46d85f503d51f761fb;hb=8a22fe9a9294bf02c4c2829a547dfae02b434aea;hp=8bc95f38a5ef49a40d65580855dee7f90ea0d46c;hpb=56301b40c4372ad9380081e95528c9f2fee3e6e5;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 8bc95f38a5..94d4812cd0 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 @@ -7,12 +7,20 @@ */ 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.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; @@ -21,7 +29,6 @@ import org.opendaylight.yangtools.binding.generator.util.generated.type.builder. import org.opendaylight.yangtools.sal.binding.generator.api.BindingGenerator; import org.opendaylight.yangtools.sal.binding.generator.spi.TypeProvider; import org.opendaylight.yangtools.sal.binding.model.api.AccessModifier; -import org.opendaylight.yangtools.sal.binding.model.api.GeneratedType; import org.opendaylight.yangtools.sal.binding.model.api.Type; import org.opendaylight.yangtools.sal.binding.model.api.type.builder.EnumBuilder; import org.opendaylight.yangtools.sal.binding.model.api.type.builder.GeneratedTOBuilder; @@ -55,57 +62,61 @@ 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 +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 org.opendaylight.yangtools.yang.model.api.AugmentationTarget +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.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 { - /** - * Outter key represents the package name. Outter value represents map of + + private final Map genCtx = new HashMap() + + /** + * 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. */ - private Map> genTypeBuilders; + private Map> genTypeBuilders; - /** + /** * Provide methods for converting YANG types to JAVA types. */ - private var TypeProvider typeProvider; + 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; - - /** - * Each grouping which is converted from schema node to generated type is - * added to this map with its Schema path as key to make it easier to get - * reference to it. In schema nodes in uses attribute there is - * only Schema Path but when building list of implemented interfaces for - * Schema node the object of type Type is required. So in this - * case is used this map. - */ - private val allGroupings = new HashMap(); - - private val yangToJavaMapping = new HashMap(); + private var SchemaContext schemaContext; - /** + /** * Constant with the concrete name of namespace. */ - private val static String YANG_EXT_NAMESPACE = "urn:opendaylight:yang:extension:yang-ext"; + private val static String YANG_EXT_NAMESPACE = "urn:opendaylight:yang:extension:yang-ext"; - /** + /** * Constant with the concrete name of identifier. */ - private val static String AUGMENT_IDENTIFIER_NAME = "augment-identifier"; + private val static String AUGMENT_IDENTIFIER_NAME = "augment-identifier"; - /** + /** * Resolves generated types from context schema nodes of all * modules. * @@ -123,17 +134,16 @@ public class BindingGeneratorImpl implements BindingGenerator { * @throws IllegalStateException * if context contain no modules */ - override generateTypes(SchemaContext context) { - checkArgument(context !== null, "Schema Context reference cannot be NULL."); - checkState(context.modules !== null, "Schema Context does not contain defined modules."); - val List generatedTypes = new ArrayList(); - schemaContext = context; - typeProvider = new TypeProviderImpl(context); - val Set modules = context.modules; - return generateTypes(context, modules); - } - - /** + override generateTypes(SchemaContext context) { + checkArgument(context !== null, "Schema Context reference cannot be NULL."); + checkState(context.modules !== null, "Schema Context does not contain defined modules."); + schemaContext = context; + typeProvider = new TypeProviderImpl(context); + val Set modules = context.modules; + return generateTypes(context, modules); + } + + /** * Resolves generated types from context schema nodes only for * modules specified in modules * @@ -161,54 +171,58 @@ public class BindingGeneratorImpl implements BindingGenerator { * @throws IllegalStateException * if context contain no modules */ - override generateTypes(SchemaContext context, Set modules) { - checkArgument(context !== null, "Schema Context reference cannot be NULL."); - checkState(context.modules !== null, "Schema Context does not contain defined modules."); - checkArgument(modules !== null, "Set of Modules cannot be NULL."); - - val List filteredGenTypes = new ArrayList(); - - schemaContext = context; - typeProvider = new TypeProviderImpl(context); - val contextModules = ModuleDependencySort.sort(context.modules); - genTypeBuilders = new HashMap(); - - for (contextModule : contextModules) { - val List generatedTypes = new ArrayList(); - generatedTypes.addAll(allTypeDefinitionsToGenTypes(contextModule)); - generatedTypes.addAll(allGroupingsToGenTypes(contextModule)); - if (false == contextModule.childNodes.isEmpty()) { - generatedTypes.add(moduleToDataType(contextModule)); - } - generatedTypes.addAll(allContainersToGenTypes(contextModule)); - generatedTypes.addAll(allListsToGenTypes(contextModule)); - generatedTypes.addAll(allChoicesToGenTypes(contextModule)); - generatedTypes.addAll(allRPCMethodsToGenType(contextModule)); - generatedTypes.addAll(allNotificationsToGenType(contextModule)); - generatedTypes.addAll(allIdentitiesToGenTypes(contextModule, context)); - - if (modules.contains(contextModule)) { - filteredGenTypes.addAll(generatedTypes); - } - } - for (contextModule : contextModules) { - val generatedTypes = (allAugmentsToGenTypes(contextModule)); - if (modules.contains(contextModule)) { - filteredGenTypes.addAll(generatedTypes); - } - - } - return filteredGenTypes; - } - - /** + override generateTypes(SchemaContext context, Set modules) { + checkArgument(context !== null, "Schema Context reference cannot be NULL."); + checkState(context.modules !== null, "Schema Context does not contain defined modules."); + checkArgument(modules !== null, "Set of Modules cannot be NULL."); + + schemaContext = context; + typeProvider = new TypeProviderImpl(context); + val contextModules = ModuleDependencySort.sort(context.modules); + genTypeBuilders = new HashMap(); + + for (contextModule : contextModules) { + moduleToGenTypes(contextModule, context); + } + for (contextModule : contextModules) { + allAugmentsToGenTypes(contextModule); + } + + val List filteredGenTypes = new ArrayList(); + for (Module m : modules) { + val ctx = checkNotNull(genCtx.get(m), "Module context not found for module %s", m) + filteredGenTypes.addAll(ctx.generatedTypes); + val Set additionalTypes = (typeProvider as TypeProviderImpl).additionalTypes.get(m) + if (additionalTypes != null) { + filteredGenTypes.addAll(additionalTypes) + } + } + + return filteredGenTypes; + } + + private def void moduleToGenTypes(Module m, SchemaContext context) { + genCtx.put(m, new ModuleContext) + allTypeDefinitionsToGenTypes(m) + groupingsToGenTypes(m, m.groupings) + rpcMethodsToGenType(m) + allIdentitiesToGenTypes(m, context) + notificationsToGenType(m) + + if (!m.childNodes.isEmpty()) { + val moduleType = moduleToDataType(m) + genCtx.get(m).addModuleNode(moduleType) + val basePackageName = moduleNamespaceToPackageName(m); + resolveDataSchemaNodes(m, basePackageName, moduleType, moduleType, m.childNodes) + } + } + + /** * Converts all extended type definitions of module to the list of * Type objects. * * @param module * module from which is obtained set of type definitions - * @return list of Type which are generated from extended - * definition types (object of type ExtendedType) * @throws IllegalArgumentException *
    *
  • if module equals null
  • @@ -217,145 +231,97 @@ public class BindingGeneratorImpl implements BindingGenerator { *
* */ - private def List allTypeDefinitionsToGenTypes(Module module) { - checkArgument(module !== null, "Module reference cannot be NULL."); - checkArgument(module.name !== null, "Module name cannot be NULL."); - val Set> typeDefinitions = module.typeDefinitions; - checkState(typeDefinitions !== null, '''Type Definitions for module «module.name» cannot be NULL.'''); - - val List generatedTypes = new ArrayList(); - for (TypeDefinition typedef : typeDefinitions) { - if (typedef !== null) { - val type = (typeProvider as TypeProviderImpl).generatedTypeForExtendedDefinitionType(typedef, typedef); - if ((type !== null) && !generatedTypes.contains(type)) { - generatedTypes.add(type); - } - } - } - return generatedTypes; - } - - /** - * Converts all containers of the module to the list of - * Type objects. - * - * @param module - * module from which is obtained DataNodeIterator to iterate over - * all containers - * @return list of Type which are generated from containers - * (objects of type ContainerSchemaNode) - * @throws IllegalArgumentException - *
    - *
  • if the module equals null
  • - *
  • if the name of module equals null
  • - *
  • if the set of child nodes equals null
  • - *
- * - */ - private def List allContainersToGenTypes(Module module) { - checkArgument(module !== null, "Module reference cannot be NULL."); - - checkArgument(module.name !== null, "Module name cannot be NULL."); - - if (module.childNodes === null) { - throw new IllegalArgumentException( - "Reference to Set of Child Nodes in module " + module.name + " cannot be NULL."); - } - - val List generatedTypes = new ArrayList(); - val it = new DataNodeIterator(module); - val List schemaContainers = it.allContainers(); - val basePackageName = moduleNamespaceToPackageName(module); - for (container : schemaContainers) { - if (!container.isAddedByUses()) { - generatedTypes.add(containerToGenType(basePackageName, container)); - } - } - return generatedTypes; - } - - /** - * Converts all lists of the module to the list of Type - * objects. - * - * @param module - * module from which is obtained DataNodeIterator to iterate over - * all lists - * @return list of Type which are generated from lists (objects - * of type ListSchemaNode) - * @throws IllegalArgumentException - *
    - *
  • if the module equals null
  • - *
  • if the name of module equals null
  • - *
  • if the set of child nodes equals null
  • - *
- * - */ - private def List allListsToGenTypes(Module module) { - checkArgument(module !== null, "Module reference cannot be NULL."); - checkArgument(module.name !== null, "Module name cannot be NULL."); - - if (module.childNodes === null) { - throw new IllegalArgumentException( - "Reference to Set of Child Nodes in module " + module.name + " cannot be NULL."); - } - - val List generatedTypes = new ArrayList(); - val it = new DataNodeIterator(module); - val List schemaLists = it.allLists(); - val basePackageName = moduleNamespaceToPackageName(module); - if (schemaLists !== null) { - for (list : schemaLists) { - if (!list.isAddedByUses()) { - generatedTypes.addAll(listToGenType(basePackageName, list)); - } - } - } - return generatedTypes; - } - - /** - * Converts all choices of the module to the list of - * Type objects. - * - * @param module - * module from which is obtained DataNodeIterator to iterate over - * all choices - * @return list of Type which are generated from choices - * (objects of type ChoiceNode) - * @throws IllegalArgumentException - *
    - *
  • if the module equals null
  • - *
  • if the name of module equals null
  • * - *
- * - */ - private def List allChoicesToGenTypes(Module module) { - checkArgument(module !== null, "Module reference cannot be NULL."); - checkArgument(module.name !== null, "Module name cannot be NULL."); - - val it = new DataNodeIterator(module); - val choiceNodes = it.allChoices(); - val basePackageName = moduleNamespaceToPackageName(module); - - val List generatedTypes = new ArrayList(); - for (choice : choiceNodes) { - if ((choice !== null) && !choice.isAddedByUses()) { - generatedTypes.addAll(choiceToGeneratedType(basePackageName, choice)); - } - } - return generatedTypes; - } - - /** + private def void allTypeDefinitionsToGenTypes(Module module) { + checkArgument(module !== null, "Module reference cannot be NULL."); + checkArgument(module.name !== null, "Module name cannot be NULL."); + val it = new DataNodeIterator(module); + val List> typeDefinitions = it.allTypedefs; + checkState(typeDefinitions !== null, '''Type Definitions for module «module.name» cannot be NULL.'''); + + for (TypeDefinition typedef : typeDefinitions) { + if (typedef !== null) { + val type = (typeProvider as TypeProviderImpl).generatedTypeForExtendedDefinitionType(typedef, typedef); + if (type !== null) { + genCtx.get(module).addTypedefType(typedef.path, type) + } + } + } + } + + private def GeneratedTypeBuilder processDataSchemaNode(Module module, String basePackageName, + GeneratedTypeBuilder parent, GeneratedTypeBuilder childOf, DataSchemaNode node) { + if (node.augmenting || node.addedByUses) { + return null + } + val packageName = packageNameForGeneratedType(basePackageName, node.path) + val genType = addDefaultInterfaceDefinition(packageName, node, childOf) + if (node instanceof DataNodeContainer) { + genCtx.get(module).addChildNodeType(node.path, genType) + groupingsToGenTypes(module, (node as DataNodeContainer).groupings) + processUsesAugments(node as DataNodeContainer, module) + } + return genType + } + + private def void containerToGenType(Module module, String basePackageName, GeneratedTypeBuilder parent, + GeneratedTypeBuilder childOf, ContainerSchemaNode node) { + val genType = processDataSchemaNode(module, basePackageName, parent, childOf, node) + if (genType != null) { + constructGetter(parent, node.QName.localName, node.description, genType) + resolveDataSchemaNodes(module, basePackageName, genType, genType, node.childNodes) + } + } + + private def void listToGenType(Module module, String basePackageName, GeneratedTypeBuilder parent, + GeneratedTypeBuilder childOf, ListSchemaNode node) { + val genType = processDataSchemaNode(module, basePackageName, parent, childOf, node) + if (genType != null) { + constructGetter(parent, node.QName.localName, node.description, Types.listTypeFor(genType)) + + val List listKeys = listKeys(node); + val packageName = packageNameForGeneratedType(basePackageName, (node).path) + val genTOBuilder = resolveListKeyTOBuilder(packageName, node); + if (genTOBuilder !== null) { + val identifierMarker = IDENTIFIER.parameterizedTypeFor(genType); + val identifiableMarker = IDENTIFIABLE.parameterizedTypeFor(genTOBuilder); + genTOBuilder.addImplementsType(identifierMarker); + genType.addImplementsType(identifiableMarker); + } + + for (schemaNode : node.childNodes) { + if (!schemaNode.augmenting) { + addSchemaNodeToListBuilders(basePackageName, schemaNode, genType, genTOBuilder, listKeys, module); + } + } + + // serialVersionUID + if (genTOBuilder !== null) { + val GeneratedPropertyBuilder prop = new GeneratedPropertyBuilderImpl("serialVersionUID"); + prop.setValue(Long.toString(computeDefaultSUID(genTOBuilder as GeneratedTOBuilderImpl))); + genTOBuilder.setSUID(prop); + } + + typeBuildersToGenTypes(module, genType, genTOBuilder); + } + } + + private def void processUsesAugments(DataNodeContainer node, Module module) { + val basePackageName = moduleNamespaceToPackageName(module); + for (usesNode : node.uses) { + for (augment : usesNode.augmentations) { + usesAugmentationToGenTypes(basePackageName, augment, module, usesNode, node); + processUsesAugments(augment, module); + } + } + } + + /** * Converts all augmentation of the module to the list * Type objects. * * @param module * module from which is obtained list of all augmentation objects * to iterate over them - * @return list of Type which are generated from augments - * (objects of type AugmentationSchema) * @throws IllegalArgumentException *
    *
  • if the module equals null
  • @@ -364,24 +330,22 @@ public class BindingGeneratorImpl implements BindingGenerator { *
* */ - private def List allAugmentsToGenTypes(Module module) { - checkArgument(module !== null, "Module reference cannot be NULL."); - checkArgument(module.name !== null, "Module name cannot be NULL."); - if (module.childNodes === null) { - throw new IllegalArgumentException( - "Reference to Set of Augmentation Definitions in module " + module.name + " cannot be NULL."); - } - - val List generatedTypes = new ArrayList(); - val basePackageName = moduleNamespaceToPackageName(module); - val List augmentations = resolveAugmentations(module); - for (augment : augmentations) { - generatedTypes.addAll(augmentationToGenTypes(basePackageName, augment)); - } - return generatedTypes; - } - - /** + private def void allAugmentsToGenTypes(Module module) { + checkArgument(module !== null, "Module reference cannot be NULL."); + checkArgument(module.name !== null, "Module name cannot be NULL."); + if (module.childNodes === null) { + throw new IllegalArgumentException( + "Reference to Set of Augmentation Definitions in module " + module.name + " cannot be NULL."); + } + + val basePackageName = moduleNamespaceToPackageName(module); + val List augmentations = resolveAugmentations(module); + for (augment : augmentations) { + augmentationToGenTypes(basePackageName, augment, module); + } + } + + /** * Returns list of AugmentationSchema objects. The objects are * sorted according to the length of their target path from the shortest to * the longest. @@ -397,25 +361,25 @@ public class BindingGeneratorImpl implements BindingGenerator { * * */ - private def List resolveAugmentations(Module module) { - checkArgument(module !== null, "Module reference cannot be NULL."); - checkState(module.augmentations !== null, "Augmentations Set cannot be NULL."); - - val Set augmentations = module.augmentations; - val List sortedAugmentations = new ArrayList(augmentations); - Collections.sort(sortedAugmentations, - [ augSchema1, augSchema2 | - if (augSchema1.targetPath.path.size() > augSchema2.targetPath.path.size()) { - return 1; - } else if (augSchema1.targetPath.path.size() < augSchema2.targetPath.path.size()) { - return -1; - } - return 0; - ]); - return sortedAugmentations; - } - - /** + private def List resolveAugmentations(Module module) { + checkArgument(module !== null, "Module reference cannot be NULL."); + checkState(module.augmentations !== null, "Augmentations Set cannot be NULL."); + + val Set augmentations = module.augmentations; + val List sortedAugmentations = new ArrayList(augmentations); + Collections.sort(sortedAugmentations, + [ augSchema1, augSchema2 | + if (augSchema1.targetPath.path.size() > augSchema2.targetPath.path.size()) { + return 1; + } else if (augSchema1.targetPath.path.size() < augSchema2.targetPath.path.size()) { + return -1; + } + return 0; + ]); + return sortedAugmentations; + } + + /** * Converts whole module to GeneratedType object. * Firstly is created the module builder object from which is vally * obtained reference to GeneratedType object. @@ -429,22 +393,16 @@ public class BindingGeneratorImpl implements BindingGenerator { * if the module equals null * */ - private def GeneratedType moduleToDataType(Module module) { - checkArgument(module !== null, "Module reference cannot be NULL."); - - val moduleDataTypeBuilder = moduleTypeBuilder(module, "Data"); - addImplementedInterfaceFromUses(module, moduleDataTypeBuilder); - moduleDataTypeBuilder.addImplementsType(DATA_ROOT); - - val basePackageName = moduleNamespaceToPackageName(module); - if (moduleDataTypeBuilder !== null) { - val Set dataNodes = module.childNodes; - resolveDataSchemaNodes(basePackageName, moduleDataTypeBuilder, dataNodes); - } - return moduleDataTypeBuilder.toInstance(); - } - - /** + private def GeneratedTypeBuilder moduleToDataType(Module module) { + checkArgument(module !== null, "Module reference cannot be NULL."); + + val moduleDataTypeBuilder = moduleTypeBuilder(module, "Data"); + addImplementedInterfaceFromUses(module, moduleDataTypeBuilder); + moduleDataTypeBuilder.addImplementsType(DATA_ROOT); + return moduleDataTypeBuilder; + } + + /** * Converts all rpcs inputs and outputs substatements of the module * to the list of Type objects. In addition are to containers * and lists which belong to input or output also part of returning list. @@ -452,8 +410,6 @@ public class BindingGeneratorImpl implements BindingGenerator { * @param module * module from which is obtained set of all rpc objects to * iterate over them - * @return list of Type which are generated from rpcs inputs, - * outputs + container and lists which are part of inputs or outputs * @throws IllegalArgumentException *
    *
  • if the module equals null
  • @@ -462,91 +418,59 @@ public class BindingGeneratorImpl implements BindingGenerator { *
* */ - private def List allRPCMethodsToGenType(Module module) { - checkArgument(module !== null, "Module reference cannot be NULL."); - - checkArgument(module.name !== null, "Module name cannot be NULL."); - - if (module.childNodes === null) { - throw new IllegalArgumentException( - "Reference to Set of RPC Method Definitions in module " + module.name + " cannot be NULL."); - } - - val basePackageName = moduleNamespaceToPackageName(module); - val Set rpcDefinitions = module.rpcs; - - if (rpcDefinitions.isEmpty()) { - return Collections.emptyList(); - } - - val List genRPCTypes = new ArrayList(); - val interfaceBuilder = moduleTypeBuilder(module, "Service"); - interfaceBuilder.addImplementsType(Types.typeForClass(RpcService)); - for (rpc : rpcDefinitions) { - if (rpc !== null) { - - val rpcName = parseToClassName(rpc.QName.localName); - val rpcMethodName = parseToValidParamName(rpcName); - val method = interfaceBuilder.addMethod(rpcMethodName); - - val rpcInOut = new ArrayList(); - - val input = rpc.input; - val output = rpc.output; - - if (input !== null) { - rpcInOut.add(new DataNodeIterator(input)); - val inType = addRawInterfaceDefinition(basePackageName, input, rpcName); - addImplementedInterfaceFromUses(input, inType); - inType.addImplementsType(DATA_OBJECT); - inType.addImplementsType(augmentable(inType)); - resolveDataSchemaNodes(basePackageName, inType, input.childNodes); - val inTypeInstance = inType.toInstance(); - genRPCTypes.add(inTypeInstance); - method.addParameter(inTypeInstance, "input"); - } - - var Type outTypeInstance = VOID; - if (output !== null) { - rpcInOut.add(new DataNodeIterator(output)); - val outType = addRawInterfaceDefinition(basePackageName, output, rpcName); - addImplementedInterfaceFromUses(output, outType); - outType.addImplementsType(DATA_OBJECT); - outType.addImplementsType(augmentable(outType)); - - resolveDataSchemaNodes(basePackageName, outType, output.childNodes); - outTypeInstance = outType.toInstance(); - genRPCTypes.add(outTypeInstance); - - } - - val rpcRes = Types.parameterizedTypeFor(Types.typeForClass(RpcResult), outTypeInstance); - method.setReturnType(Types.parameterizedTypeFor(FUTURE, rpcRes)); - for (iter : rpcInOut) { - val List nContainers = iter.allContainers(); - if ((nContainers !== null) && !nContainers.isEmpty()) { - for (container : nContainers) { - if (!container.isAddedByUses()) { - genRPCTypes.add(containerToGenType(basePackageName, container)); - } - } - } - val List nLists = iter.allLists(); - if ((nLists !== null) && !nLists.isEmpty()) { - for (list : nLists) { - if (!list.isAddedByUses()) { - genRPCTypes.addAll(listToGenType(basePackageName, list)); - } - } - } - } - } - } - genRPCTypes.add(interfaceBuilder.toInstance()); - return genRPCTypes; - } - - /** + private def void rpcMethodsToGenType(Module module) { + checkArgument(module !== null, "Module reference cannot be NULL."); + checkArgument(module.name !== null, "Module name cannot be NULL."); + checkArgument(module.childNodes !== null, + "Reference to Set of RPC Method Definitions in module " + module.name + " cannot be NULL."); + + val basePackageName = moduleNamespaceToPackageName(module); + val Set rpcDefinitions = module.rpcs; + if (rpcDefinitions.isEmpty()) { + return; + } + + val interfaceBuilder = moduleTypeBuilder(module, "Service"); + interfaceBuilder.addImplementsType(Types.typeForClass(RpcService)); + for (rpc : rpcDefinitions) { + if (rpc !== null) { + val rpcName = BindingMapping.getClassName(rpc.QName); + val rpcMethodName = parseToValidParamName(rpcName); + val method = interfaceBuilder.addMethod(rpcMethodName); + val input = rpc.input; + val output = rpc.output; + + if (input !== null) { + val inType = addRawInterfaceDefinition(basePackageName, input, rpcName); + addImplementedInterfaceFromUses(input, inType); + inType.addImplementsType(DATA_OBJECT); + inType.addImplementsType(augmentable(inType)); + resolveDataSchemaNodes(module, basePackageName, inType, inType, input.childNodes); + genCtx.get(module).addChildNodeType(input.path, inType) + val inTypeInstance = inType.toInstance(); + method.addParameter(inTypeInstance, "input"); + } + + var Type outTypeInstance = VOID; + if (output !== null) { + val outType = addRawInterfaceDefinition(basePackageName, output, rpcName); + addImplementedInterfaceFromUses(output, outType); + outType.addImplementsType(DATA_OBJECT); + outType.addImplementsType(augmentable(outType)); + resolveDataSchemaNodes(module, basePackageName, outType, outType, output.childNodes); + genCtx.get(module).addChildNodeType(output.path, outType) + outTypeInstance = outType.toInstance(); + } + + val rpcRes = Types.parameterizedTypeFor(Types.typeForClass(RpcResult), outTypeInstance); + method.setReturnType(Types.parameterizedTypeFor(FUTURE, rpcRes)); + } + } + + genCtx.get(module).addTopLevelNodeType(interfaceBuilder) + } + + /** * Converts all notifications of the module to the list of * Type objects. In addition are to this list added containers * and lists which are part of this notification. @@ -554,8 +478,6 @@ public class BindingGeneratorImpl implements BindingGenerator { * @param module * module from which is obtained set of all notification objects * to iterate over them - * @return list of Type which are generated from notification - * (object of type NotificationDefinition * @throws IllegalArgumentException *
    *
  • if the module equals null
  • @@ -564,59 +486,44 @@ public class BindingGeneratorImpl implements BindingGenerator { *
* */ - private def List allNotificationsToGenType(Module module) { - checkArgument(module !== null, "Module reference cannot be NULL."); - - checkArgument(module.name !== null, "Module name cannot be NULL."); - - if (module.childNodes === null) { - throw new IllegalArgumentException( - "Reference to Set of Notification Definitions in module " + module.name + " cannot be NULL."); - } - val notifications = module.notifications; - if(notifications.isEmpty()) return Collections.emptyList(); - - val listenerInterface = moduleTypeBuilder(module, "Listener"); - listenerInterface.addImplementsType(BindingTypes.NOTIFICATION_LISTENER); - - val basePackageName = moduleNamespaceToPackageName(module); - val List generatedTypes = new ArrayList(); - - for (notification : notifications) { - if (notification !== null) { - val iter = new DataNodeIterator(notification); - - // Containers - for (node : iter.allContainers()) { - if (!node.isAddedByUses()) { - generatedTypes.add(containerToGenType(basePackageName, node)); - } - } - - // Lists - for (node : iter.allLists()) { - if (!node.isAddedByUses()) { - generatedTypes.addAll(listToGenType(basePackageName, node)); - } - } - val notificationInterface = addDefaultInterfaceDefinition(basePackageName, notification); - notificationInterface.addImplementsType(NOTIFICATION); - - // Notification object - resolveDataSchemaNodes(basePackageName, notificationInterface, notification.childNodes); - - listenerInterface.addMethod("on" + notificationInterface.name) // - .setAccessModifier(AccessModifier.PUBLIC).addParameter(notificationInterface, "notification"). - setReturnType(Types.VOID); - - generatedTypes.add(notificationInterface.toInstance()); - } - } - generatedTypes.add(listenerInterface.toInstance()); - return generatedTypes; - } - - /** + private def void notificationsToGenType(Module module) { + checkArgument(module !== null, "Module reference cannot be NULL."); + checkArgument(module.name !== null, "Module name cannot be NULL."); + + if (module.childNodes === null) { + throw new IllegalArgumentException( + "Reference to Set of Notification Definitions in module " + module.name + " cannot be NULL."); + } + val notifications = module.notifications; + if(notifications.empty) return; + + val listenerInterface = moduleTypeBuilder(module, "Listener"); + listenerInterface.addImplementsType(BindingTypes.NOTIFICATION_LISTENER); + val basePackageName = moduleNamespaceToPackageName(module); + + for (notification : notifications) { + if (notification !== null) { + processUsesAugments(notification, module); + + val notificationInterface = addDefaultInterfaceDefinition(basePackageName, notification, + BindingTypes.DATA_OBJECT); + notificationInterface.addImplementsType(NOTIFICATION); + genCtx.get(module).addChildNodeType(notification.path, notificationInterface) + + // Notification object + resolveDataSchemaNodes(module, basePackageName, notificationInterface, notificationInterface, + notification.childNodes); + + listenerInterface.addMethod("on" + notificationInterface.name) // + .setAccessModifier(AccessModifier.PUBLIC).addParameter(notificationInterface, "notification"). + setReturnType(Types.VOID); + } + } + + genCtx.get(module).addTopLevelNodeType(listenerInterface) + } + + /** * Converts all identities of the module to the list of * Type objects. * @@ -626,26 +533,20 @@ public class BindingGeneratorImpl implements BindingGenerator { * @param context * schema context only used as input parameter for method * {@link identityToGenType} - * @return list of Type which are generated from identities - * (object of type IdentitySchemaNode * */ - private def List allIdentitiesToGenTypes(Module module, SchemaContext context) { - val List genTypes = new ArrayList(); - - val Set schemaIdentities = module.identities; - - val basePackageName = moduleNamespaceToPackageName(module); - - if (schemaIdentities !== null && !schemaIdentities.isEmpty()) { - for (identity : schemaIdentities) { - genTypes.add(identityToGenType(basePackageName, identity, context)); - } - } - return genTypes; - } - - /** + private def void allIdentitiesToGenTypes(Module module, SchemaContext context) { + val Set schemaIdentities = module.identities; + val basePackageName = moduleNamespaceToPackageName(module); + + if (schemaIdentities !== null && !schemaIdentities.isEmpty()) { + for (identity : schemaIdentities) { + identityToGenType(module, basePackageName, identity, context); + } + } + } + + /** * Converts the identity object to GeneratedType. Firstly it is * created transport object builder. If identity contains base identity then * reference to base identity is added to superior identity as its extend. @@ -653,6 +554,7 @@ public class BindingGeneratorImpl implements BindingGenerator { * class {@link org.opendaylight.yangtools.yang.model.api.BaseIdentity * BaseIdentity} is added * + * @param module current module * @param basePackageName * string contains the module package name * @param identity @@ -661,68 +563,61 @@ public class BindingGeneratorImpl implements BindingGenerator { * SchemaContext which is used to get package and name * information about base of identity * - * @return GeneratedType which is generated from identity (object of type - * IdentitySchemaNode - * */ - private def GeneratedType identityToGenType(String basePackageName, IdentitySchemaNode identity, - SchemaContext context) { - if (identity === null) { - return null; - } - - val packageName = packageNameForGeneratedType(basePackageName, identity.path); - val genTypeName = parseToClassName(identity.QName.localName); - val newType = new GeneratedTOBuilderImpl(packageName, genTypeName); - - val baseIdentity = identity.baseIdentity; - if (baseIdentity !== null) { - val baseIdentityParentModule = SchemaContextUtil.findParentModule(context, baseIdentity); - - val returnTypePkgName = moduleNamespaceToPackageName(baseIdentityParentModule); - val returnTypeName = parseToClassName(baseIdentity.QName.localName); - - val gto = new GeneratedTOBuilderImpl(returnTypePkgName, returnTypeName).toInstance(); - newType.setExtendsType(gto); - } else { - newType.setExtendsType(Types.baseIdentityTO); - } - newType.setAbstract(true); - return newType.toInstance(); - } - - /** + private def void identityToGenType(Module module, String basePackageName, IdentitySchemaNode identity, + SchemaContext context) { + if (identity === null) { + return; + } + val packageName = packageNameForGeneratedType(basePackageName, identity.path); + val genTypeName = BindingMapping.getClassName(identity.QName); + val newType = new GeneratedTOBuilderImpl(packageName, genTypeName); + val baseIdentity = identity.baseIdentity; + if (baseIdentity === null) { + newType.setExtendsType(Types.baseIdentityTO); + } else { + val baseIdentityParentModule = SchemaContextUtil.findParentModule(context, baseIdentity); + val returnTypePkgName = moduleNamespaceToPackageName(baseIdentityParentModule); + val returnTypeName = BindingMapping.getClassName(baseIdentity.QName); + val gto = new GeneratedTOBuilderImpl(returnTypePkgName, returnTypeName).toInstance(); + newType.setExtendsType(gto); + } + 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} * * @param module - * module from which is obtained set of all grouping objects to - * iterate over them - * @return list of Type which are generated from groupings - * (object of type GroupingDefinition) + * current module + * @param collection of groupings from which types will be generated * */ - private def List allGroupingsToGenTypes(Module module) { - checkArgument(module !== null, "Module parameter can not be null"); - val List genTypes = new ArrayList(); - val basePackageName = moduleNamespaceToPackageName(module); - val Set groupings = module.groupings; - val List groupingsSortedByDependencies = new GroupingDefinitionDependencySort().sort( - groupings); - - for (grouping : groupingsSortedByDependencies) { - val genType = groupingToGenType(basePackageName, grouping); - genTypes.add(genType); - val schemaPath = grouping.path; - allGroupings.put(schemaPath, genType); - } - return genTypes; - } - - /** + private def void groupingsToGenTypes(Module module, Collection groupings) { + val basePackageName = moduleNamespaceToPackageName(module); + val List groupingsSortedByDependencies = new GroupingDefinitionDependencySort().sort( + groupings); + for (grouping : groupingsSortedByDependencies) { + groupingToGenType(basePackageName, grouping, module); + } + } + + /** * Converts individual grouping to GeneratedType. Firstly generated type * builder is created and every child node of grouping is resolved to the * method. @@ -731,26 +626,23 @@ public class BindingGeneratorImpl implements BindingGenerator { * string contains the module package name * @param grouping * GroupingDefinition which contains data about grouping + * @param module current module * @return GeneratedType which is generated from grouping (object of type * GroupingDefinition) */ - private def GeneratedType groupingToGenType(String basePackageName, GroupingDefinition grouping) { - if (grouping === null) { - return null; - } - - val packageName = packageNameForGeneratedType(basePackageName, grouping.path); - val Set schemaNodes = grouping.childNodes; - val typeBuilder = addDefaultInterfaceDefinition(packageName, grouping); - - resolveDataSchemaNodes(basePackageName, typeBuilder, schemaNodes); - return typeBuilder.toInstance(); - } - - /** + private def void groupingToGenType(String basePackageName, GroupingDefinition grouping, Module module) { + val packageName = packageNameForGeneratedType(basePackageName, grouping.path); + val genType = addDefaultInterfaceDefinition(packageName, grouping); + genCtx.get(module).addGroupingType(grouping.path, genType) + resolveDataSchemaNodes(module, basePackageName, genType, genType, grouping.childNodes); + groupingsToGenTypes(module, grouping.groupings); + processUsesAugments(grouping, module); + } + + /** * 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 @@ -758,18 +650,18 @@ public class BindingGeneratorImpl implements BindingGenerator { * @return EnumTypeDefinition if it is found inside * typeDefinition or null in other case */ - private def EnumTypeDefinition enumTypeDefFromExtendedType(TypeDefinition typeDefinition) { - if (typeDefinition !== null) { - if (typeDefinition.baseType instanceof EnumTypeDefinition) { - return typeDefinition.baseType as EnumTypeDefinition; - } else if (typeDefinition.baseType instanceof ExtendedType) { - return enumTypeDefFromExtendedType(typeDefinition.baseType); - } - } - return null; - } - - /** + private def EnumTypeDefinition enumTypeDefFromExtendedType(TypeDefinition typeDefinition) { + if (typeDefinition !== null) { + if (typeDefinition.baseType instanceof EnumTypeDefinition) { + return typeDefinition.baseType as EnumTypeDefinition; + } else if (typeDefinition.baseType instanceof ExtendedType) { + return enumTypeDefFromExtendedType(typeDefinition.baseType); + } + } + return null; + } + + /** * Adds enumeration builder created from enumTypeDef to * typeBuilder. * @@ -783,24 +675,22 @@ 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, - GeneratedTypeBuilder typeBuilder) { - if ((enumTypeDef !== null) && (typeBuilder !== null) && (enumTypeDef.QName !== null) && - (enumTypeDef.QName.localName !== null)) { - - val enumerationName = parseToClassName(enumName); - val enumBuilder = typeBuilder.addEnumeration(enumerationName); - enumBuilder.updateEnumPairsFromEnumTypeDef(enumTypeDef); - - return enumBuilder; - } - return null; - } - - /** + private def EnumBuilder resolveInnerEnumFromTypeDefinition(EnumTypeDefinition enumTypeDef, QName enumName, + GeneratedTypeBuilder typeBuilder) { + if ((enumTypeDef !== null) && (typeBuilder !== null) && (enumTypeDef.QName !== null) && + (enumTypeDef.QName.localName !== null)) { + val enumerationName = BindingMapping.getClassName(enumName); + val enumBuilder = typeBuilder.addEnumeration(enumerationName); + enumBuilder.updateEnumPairsFromEnumTypeDef(enumTypeDef); + return enumBuilder; + } + return null; + } + + /** * Generates type builder for module. * * @param module @@ -814,16 +704,14 @@ public class BindingGeneratorImpl implements BindingGenerator { * @throws IllegalArgumentException * if module equals null */ - 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; - - return new GeneratedTypeBuilderImpl(packageName, moduleName); - - } - - /** + private def GeneratedTypeBuilder moduleTypeBuilder(Module module, String postfix) { + checkArgument(module !== null, "Module reference cannot be NULL."); + val packageName = moduleNamespaceToPackageName(module); + val moduleName = BindingMapping.getClassName(module.name) + postfix; + return new GeneratedTypeBuilderImpl(packageName, moduleName); + } + + /** * Converts augSchema to list of Type which * contains generated type for augmentation. In addition there are also * generated types for all containers, list and choices which are child of @@ -834,10 +722,10 @@ 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...) - * @return list of Type objects which contains generated type - * for augmentation and for container, list and choice child nodes + * @param module current module + * @param parentUsesNode parent uses node of this augment (can be null if this augment is not defined under uses statement) * @throws IllegalArgumentException *
    *
  • if augmentPackageName equals null
  • @@ -845,167 +733,412 @@ public class BindingGeneratorImpl implements BindingGenerator { *
  • if target path of augSchema equals null
  • *
*/ - private def List augmentationToGenTypes(String augmentPackageName, AugmentationSchema augSchema) { - checkArgument(augmentPackageName !== null, "Package Name cannot be NULL."); - checkArgument(augSchema !== null, "Augmentation Schema cannot be NULL."); - checkState(augSchema.targetPath !== null, - "Augmentation Schema does not contain Target Path (Target Path is NULL)."); - val List genTypes = new ArrayList(); - - // EVERY augmented interface will extends Augmentation interface - // and DataObject interface!!! - val targetPath = augSchema.targetPath; - val targetSchemaNode = findDataSchemaNode(schemaContext, targetPath); - if (targetSchemaNode !== null) { - var targetType = yangToJavaMapping.get(targetSchemaNode.path); - if (targetType == null) { - - // FIXME: augmentation should be added as last, all types should already be generated - // and have assigned Java Types, - val targetModule = findParentModule(schemaContext, targetSchemaNode); - val targetBasePackage = moduleNamespaceToPackageName(targetModule); - val typePackage = packageNameForGeneratedType(targetBasePackage, targetSchemaNode.getPath()); - val targetSchemaNodeName = targetSchemaNode.getQName().getLocalName(); - val typeName = parseToClassName(targetSchemaNodeName); - targetType = new ReferencedTypeImpl(typePackage, typeName); - } - val augChildNodes = augSchema.childNodes; - if (!(targetSchemaNode instanceof ChoiceNode)) { - val augTypeBuilder = addRawAugmentGenTypeDefinition(augmentPackageName, targetType, augSchema); - val augType = augTypeBuilder.toInstance(); - genTypes.add(augType); - } else { - val choiceTarget = targetSchemaNode as ChoiceNode; - val choiceCaseNodes = choiceTarget.cases; - genTypes.addAll( - generateTypesFromAugmentedChoiceCases(augmentPackageName, targetType, choiceCaseNodes)); - } - genTypes.addAll(augmentationBodyToGenTypes(augmentPackageName, augChildNodes)); - } - return genTypes; - } - - /** + private def void augmentationToGenTypes(String augmentPackageName, AugmentationSchema augSchema, Module module) { + checkArgument(augmentPackageName !== null, "Package Name cannot be NULL."); + checkArgument(augSchema !== null, "Augmentation Schema cannot be NULL."); + checkState(augSchema.targetPath !== null, + "Augmentation Schema does not contain Target Path (Target Path is NULL)."); + + processUsesAugments(augSchema, module); + val targetPath = augSchema.targetPath; + var SchemaNode targetSchemaNode = null + + targetSchemaNode = findDataSchemaNode(schemaContext, targetPath); + if (targetSchemaNode instanceof DataSchemaNode && (targetSchemaNode as DataSchemaNode).isAddedByUses()) { + targetSchemaNode = findOriginal(targetSchemaNode as DataSchemaNode); + if (targetSchemaNode == null) { + throw new NullPointerException( + "Failed to find target node from grouping in augmentation " + augSchema + " in module " + + module.name); + } + } + if (targetSchemaNode == null) { + throw new IllegalArgumentException("augment target not found: " + targetPath) + } + + var targetTypeBuilder = findChildNodeByPath(targetSchemaNode.path) + if (targetTypeBuilder === null) { + targetTypeBuilder = findCaseByPath(targetSchemaNode.path) + } + if (targetTypeBuilder === null) { + throw new NullPointerException("Target type not yet generated: " + targetSchemaNode); + } + + if (!(targetSchemaNode instanceof ChoiceNode)) { + var packageName = augmentPackageName; + val augTypeBuilder = addRawAugmentGenTypeDefinition(module, packageName, augmentPackageName, + targetTypeBuilder.toInstance, augSchema); + genCtx.get(module).addAugmentType(augTypeBuilder) + genCtx.get(module).addTypeToAugmentation(augTypeBuilder, augSchema); + } else { + generateTypesFromAugmentedChoiceCases(module, augmentPackageName, targetTypeBuilder.toInstance, + targetSchemaNode as ChoiceNode, augSchema.childNodes); + } + } + + private def void usesAugmentationToGenTypes(String augmentPackageName, AugmentationSchema augSchema, Module module, + UsesNode usesNode, DataNodeContainer usesNodeParent) { + checkArgument(augmentPackageName !== null, "Package Name cannot be NULL."); + checkArgument(augSchema !== null, "Augmentation Schema cannot be NULL."); + checkState(augSchema.targetPath !== null, + "Augmentation Schema does not contain Target Path (Target Path is NULL)."); + + processUsesAugments(augSchema, module); + val targetPath = augSchema.targetPath; + var SchemaNode targetSchemaNode = null + targetSchemaNode = findOriginalTargetFromGrouping(targetPath, usesNode); + if (targetSchemaNode == null) { + throw new IllegalArgumentException("augment target not found: " + targetPath) + } + + var targetTypeBuilder = findChildNodeByPath(targetSchemaNode.path) + if (targetTypeBuilder === null) { + targetTypeBuilder = findCaseByPath(targetSchemaNode.path) + } + if (targetTypeBuilder === null) { + throw new NullPointerException("Target type not yet generated: " + targetSchemaNode); + } + + if (!(targetSchemaNode instanceof ChoiceNode)) { + var packageName = augmentPackageName; + if (usesNodeParent instanceof SchemaNode) { + packageName = packageNameForGeneratedType(augmentPackageName, (usesNodeParent as SchemaNode).path, true) + } + val augTypeBuilder = addRawAugmentGenTypeDefinition(module, packageName, augmentPackageName, + targetTypeBuilder.toInstance, augSchema); + genCtx.get(module).addAugmentType(augTypeBuilder) + genCtx.get(module).addTypeToAugmentation(augTypeBuilder, augSchema); + } else { + generateTypesFromAugmentedChoiceCases(module, augmentPackageName, targetTypeBuilder.toInstance, + targetSchemaNode as ChoiceNode, augSchema.childNodes); + } + } + + /** + * Utility method which search for original node defined in grouping. + */ + private def DataSchemaNode findOriginal(DataSchemaNode node) { + var DataSchemaNode result = findCorrectTargetFromGrouping(node); + if (result == null) { + result = findCorrectTargetFromAugment(node); + if (result != null) { + if (result.addedByUses) { + result = findOriginal(result); + } + } + } + return result; + } + + private def DataSchemaNode findCorrectTargetFromAugment(DataSchemaNode node) { + if (!node.augmenting) { + return null + } + + 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 { + 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); + tmpTree.add(currentNode as SchemaNode) + augment = findNodeInAugment((parent as AugmentationTarget).availableAugmentations, currentName); + if (augment == null) { + currentName = (parent as DataSchemaNode).QName + currentNode = parent + } + } + } while ((parent as DataSchemaNode).augmenting && augment == null); + + if (augment == null) { + return null; + } else { + 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.localName); + actualParent = (actualParent as DataNodeContainer).getDataChildByName(name.localName); + } else { + if (actualParent instanceof ChoiceNode) { + result = (actualParent as ChoiceNode).getCaseNodeByName(name.localName); + actualParent = (actualParent as ChoiceNode).getCaseNodeByName(name.localName); + } + } + } + + if (result.addedByUses) { + result = findCorrectTargetFromAugmentGrouping(result, augment, tmpTree); + } + + return result; + } + } + + 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) { + // 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); + } + 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); + if (parent instanceof DataNodeContainer) { + 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) + } + } + if (result == null) { + 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 newParent = result; + Collections.reverse(tmpPath); + + tmpPath.remove(0); + for (name : tmpPath) { + // searching by local name is must, because node has different namespace in its original location + if (newParent instanceof DataNodeContainer) { + newParent = (newParent as DataNodeContainer).getDataChildByName(name.localName); + } else { + newParent = (newParent as ChoiceNode).getCaseNodeByName(name.localName); + } + } + if (newParent != null && newParent.addedByUses) { + newParent = findOriginal(newParent); + } + return newParent; + } + } + + + /** + * Convenient method to find node added by uses statement. + */ + private def DataSchemaNode findOriginalTargetFromGrouping(SchemaPath targetPath, UsesNode parentUsesNode) { + var SchemaNode targetGrouping = findNodeInSchemaContext(schemaContext, parentUsesNode.groupingPath.path); + if (!(targetGrouping instanceof GroupingDefinition)) { + throw new IllegalArgumentException("Failed to generate code for augment in " + parentUsesNode); + } + + var grouping = targetGrouping as GroupingDefinition; + var SchemaNode result = grouping; + val List path = targetPath.path + for (node : path) { + // finding by local name is valid, grouping cannot contain nodes with same name and different namespace + if (result instanceof DataNodeContainer) { + result = (result as DataNodeContainer).getDataChildByName(node.localName) + } else if (result instanceof ChoiceNode) { + result = (result as ChoiceNode).getCaseNodeByName(node.localName) + } + } + if (result == null) { + return null; + } + + val String targetSchemaNodeName = result.QName.localName; + var boolean fromUses = (result as DataSchemaNode).addedByUses + var Iterator groupingUses = grouping.uses.iterator; + while (fromUses) { + if (groupingUses.hasNext()) { + grouping = findNodeInSchemaContext(schemaContext, groupingUses.next().groupingPath.path) as GroupingDefinition; + result = grouping.getDataChildByName(targetSchemaNodeName); + fromUses = (result as DataSchemaNode).addedByUses; + } else { + throw new NullPointerException("Failed to generate code for augment in " + parentUsesNode); + } + } + + return result as DataSchemaNode + } + + /** * 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 targetPackageName + * @param basePackageName * string with the package name to which the augmented node * belongs - * @param targetSchemaNodeName - * string with the name of the augmented node + * @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 */ - private def GeneratedTypeBuilder addRawAugmentGenTypeDefinition(String augmentPackageName, Type targetTypeRef, - AugmentationSchema augSchema) { - var Map augmentBuilders = genTypeBuilders.get(augmentPackageName); - if (augmentBuilders === null) { - augmentBuilders = new HashMap(); - genTypeBuilders.put(augmentPackageName, augmentBuilders); - } - val augIdentifier = getAugmentIdentifier(augSchema.unknownSchemaNodes); - - val augTypeName = if (augIdentifier !== null) { - parseToClassName(augIdentifier) - } else { - augGenTypeName(augmentBuilders, targetTypeRef.name); - } - val Set augChildNodes = augSchema.childNodes; - - val augTypeBuilder = new GeneratedTypeBuilderImpl(augmentPackageName, augTypeName); - - augTypeBuilder.addImplementsType(DATA_OBJECT); - augTypeBuilder.addImplementsType(Types.augmentationTypeFor(targetTypeRef)); - addImplementedInterfaceFromUses(augSchema, augTypeBuilder); - - augSchemaNodeToMethods(augmentPackageName, augTypeBuilder, augChildNodes); - augmentBuilders.put(augTypeName, augTypeBuilder); - return augTypeBuilder; - } - - /** + private def GeneratedTypeBuilder addRawAugmentGenTypeDefinition(Module module, String augmentPackageName, + String basePackageName, Type targetTypeRef, AugmentationSchema augSchema) { + var Map augmentBuilders = genTypeBuilders.get(augmentPackageName); + if (augmentBuilders === null) { + augmentBuilders = new HashMap(); + genTypeBuilders.put(augmentPackageName, augmentBuilders); + } + val augIdentifier = getAugmentIdentifier(augSchema.unknownSchemaNodes); + + val augTypeName = if (augIdentifier !== null) { + BindingMapping.getClassName(augIdentifier) + } else { + augGenTypeName(augmentBuilders, targetTypeRef.name); + } + + val augTypeBuilder = new GeneratedTypeBuilderImpl(augmentPackageName, augTypeName); + + augTypeBuilder.addImplementsType(DATA_OBJECT); + augTypeBuilder.addImplementsType(Types.augmentationTypeFor(targetTypeRef)); + addImplementedInterfaceFromUses(augSchema, augTypeBuilder); + + augSchemaNodeToMethods(module, basePackageName, augTypeBuilder, augTypeBuilder, augSchema.childNodes); + augmentBuilders.put(augTypeName, augTypeBuilder); + return augTypeBuilder; + } + + /** * * @param unknownSchemaNodes - * @return + * @return nodeParameter of UnknownSchemaNode */ - private def String getAugmentIdentifier(List unknownSchemaNodes) { - for (unknownSchemaNode : unknownSchemaNodes) { - val nodeType = unknownSchemaNode.nodeType; - if (AUGMENT_IDENTIFIER_NAME.equals(nodeType.localName) && - YANG_EXT_NAMESPACE.equals(nodeType.namespace.toString())) { - return unknownSchemaNode.nodeParameter; - } - } - return null; - } - - /** - * Convert a container, list and choice subnodes (and recursivelly their - * subnodes) of augment to generated types - * - * @param augBasePackageName - * string with the augment package name - * @param augChildNodes - * set of data schema nodes which represents child nodes of the - * augment - * - * @return list of Type which represents container, list and - * choice subnodes of augment - */ - private def List augmentationBodyToGenTypes(String augBasePackageName, Set augChildNodes) { - val List genTypes = new ArrayList(); - val List augSchemaIts = new ArrayList(); - for (childNode : augChildNodes) { - if (childNode instanceof DataNodeContainer) { - augSchemaIts.add(new DataNodeIterator(childNode as DataNodeContainer)); - - if (childNode instanceof ContainerSchemaNode) { - genTypes.add(containerToGenType(augBasePackageName, childNode as ContainerSchemaNode)); - } else if (childNode instanceof ListSchemaNode) { - genTypes.addAll(listToGenType(augBasePackageName, childNode as ListSchemaNode)); - } - } else if (childNode instanceof ChoiceNode) { - val choice = childNode as ChoiceNode; - for (caseNode : choice.cases) { - augSchemaIts.add(new DataNodeIterator(caseNode)); - } - genTypes.addAll(choiceToGeneratedType(augBasePackageName, childNode as ChoiceNode)); - } - } - - for (it : augSchemaIts) { - val List augContainers = it.allContainers(); - val List augLists = it.allLists(); - val List augChoices = it.allChoices(); - - if (augContainers !== null) { - for (container : augContainers) { - genTypes.add(containerToGenType(augBasePackageName, container)); - } - } - if (augLists !== null) { - for (list : augLists) { - genTypes.addAll(listToGenType(augBasePackageName, list)); - } - } - if (augChoices !== null) { - for (choice : augChoices) { - genTypes.addAll(choiceToGeneratedType(augBasePackageName, choice)); - } - } - } - return genTypes; - } - - /** + private def String getAugmentIdentifier(List unknownSchemaNodes) { + for (unknownSchemaNode : unknownSchemaNodes) { + val nodeType = unknownSchemaNode.nodeType; + if (AUGMENT_IDENTIFIER_NAME.equals(nodeType.localName) && + YANG_EXT_NAMESPACE.equals(nodeType.namespace.toString())) { + return unknownSchemaNode.nodeParameter; + } + } + return null; + } + + /** * Returns first unique name for the augment generated type builder. The * generated type builder name for augment consists from name of augmented * node and serial number of its augmentation. @@ -1017,54 +1150,30 @@ public class BindingGeneratorImpl implements BindingGenerator { * string with name of augmented node * @return string with unique name for augmentation builder */ - private def String augGenTypeName(Map builders, String genTypeName) { - var index = 1; - while ((builders !== null) && builders.containsKey(genTypeName + index)) { - index = index + 1; - } - return genTypeName + index; - } - - /** - * Converts containerNode to generated type. Firstly the - * generated type builder is created. The subnodes of - * containerNode are added as methods and the instance of - * GeneratedType is returned. - * - * @param basePackageName - * string contains the module package name - * @param containerNode - * container schema node with the data about childs nodes and - * schema paths - * @return generated type for containerNode - */ - private def GeneratedType containerToGenType(String basePackageName, ContainerSchemaNode containerNode) { - if (containerNode === null) { - return null; - } - - val packageName = packageNameForGeneratedType(basePackageName, containerNode.path); - val schemaNodes = containerNode.childNodes; - val typeBuilder = addDefaultInterfaceDefinition(packageName, containerNode); - - resolveDataSchemaNodes(basePackageName, typeBuilder, schemaNodes); - return typeBuilder.toInstance(); - } - - /** + private def String augGenTypeName(Map builders, String genTypeName) { + var index = 1; + while ((builders !== null) && builders.containsKey(genTypeName + index)) { + index = index + 1; + } + return genTypeName + index; + } + + /** * Adds the methods to typeBuilder which represent subnodes of * node for which typeBuilder was created. * * The subnodes aren't mapped to the methods if they are part of grouping or * augment (in this case are already part of them). * + * @param module current module * @param basePackageName * string contains the module package name - * @param typeBuilder + * @param parent * generated type builder which represents any node. The subnodes * of this node are added to the typeBuilder as * methods. The subnode can be of type leaf, leaf-list, list, * container, choice. + * @param childOf parent type * @param schemaNodes * set of data schema nodes which are the children of the node * for which typeBuilder was created @@ -1072,23 +1181,23 @@ public class BindingGeneratorImpl implements BindingGenerator { * parameter. The getter methods (representing child nodes) could be * added to it. */ - private def GeneratedTypeBuilder resolveDataSchemaNodes(String basePackageName, GeneratedTypeBuilder typeBuilder, - Set schemaNodes) { - if ((schemaNodes !== null) && (typeBuilder !== null)) { - for (schemaNode : schemaNodes) { - if (!schemaNode.isAugmenting() && !schemaNode.isAddedByUses()) { - addSchemaNodeToBuilderAsMethod(basePackageName, schemaNode, typeBuilder); - } - - } - } - return typeBuilder; - } - - /** + private def GeneratedTypeBuilder resolveDataSchemaNodes(Module module, String basePackageName, + GeneratedTypeBuilder parent, GeneratedTypeBuilder childOf, Set schemaNodes) { + if ((schemaNodes !== null) && (parent !== null)) { + for (schemaNode : schemaNodes) { + if (!schemaNode.augmenting && !schemaNode.addedByUses) { + addSchemaNodeToBuilderAsMethod(basePackageName, schemaNode, parent, childOf, module); + } + } + } + return parent; + } + + /** * Adds the methods to typeBuilder what represents subnodes of * node for which typeBuilder was created. * + * @param module current module * @param basePackageName * string contains the module package name * @param typeBuilder @@ -1096,6 +1205,7 @@ public class BindingGeneratorImpl implements BindingGenerator { * of this node are added to the typeBuilder as * methods. The subnode can be of type leaf, leaf-list, list, * container, choice. + * @param childOf parent type * @param schemaNodes * set of data schema nodes which are the children of the node * for which typeBuilder was created @@ -1103,89 +1213,52 @@ public class BindingGeneratorImpl implements BindingGenerator { * parameter typeBuilder. The getter method could be * added to it. */ - private def GeneratedTypeBuilder augSchemaNodeToMethods(String basePackageName, GeneratedTypeBuilder typeBuilder, - Set schemaNodes) { - if ((schemaNodes !== null) && (typeBuilder !== null)) { - for (schemaNode : schemaNodes) { - if (schemaNode.isAugmenting()) { - addSchemaNodeToBuilderAsMethod(basePackageName, schemaNode, typeBuilder); - } - } - } - return typeBuilder; - } - - /** + private def GeneratedTypeBuilder augSchemaNodeToMethods(Module module, String basePackageName, + GeneratedTypeBuilder typeBuilder, GeneratedTypeBuilder childOf, Set schemaNodes) { + if ((schemaNodes !== null) && (typeBuilder !== null)) { + for (schemaNode : schemaNodes) { + if (!schemaNode.isAugmenting()) { + addSchemaNodeToBuilderAsMethod(basePackageName, schemaNode, typeBuilder, childOf, module); + } + } + } + return typeBuilder; + } + + /** * Adds to typeBuilder a method which is derived from * schemaNode. * * @param basePackageName * string with the module package name - * @param schemaNode + * @param node * data schema node which is added to typeBuilder as * a method * @param typeBuilder * generated type builder to which is schemaNode * added as a method. + * @param childOf parent type + * @param module current module */ - private def void addSchemaNodeToBuilderAsMethod(String basePackageName, DataSchemaNode node, - GeneratedTypeBuilder typeBuilder) { - if (node !== null && typeBuilder !== null) { - switch (node) { - case node instanceof LeafSchemaNode: - resolveLeafSchemaNodeAsMethod(typeBuilder, node as LeafSchemaNode) - case node instanceof LeafListSchemaNode: - resolveLeafListSchemaNode(typeBuilder, node as LeafListSchemaNode) - case node instanceof ContainerSchemaNode: - resolveContainerSchemaNode(basePackageName, typeBuilder, node as ContainerSchemaNode) - case node instanceof ListSchemaNode: - resolveListSchemaNode(basePackageName, typeBuilder, node as ListSchemaNode) - case node instanceof ChoiceNode: - resolveChoiceSchemaNode(basePackageName, typeBuilder, node as ChoiceNode) - } - } - } - - /** - * Creates a getter method for a choice node. - * - * Firstly generated type builder for choice is created or found in - * {@link BindingGeneratorImpl#allGroupings allGroupings}. The package name - * in the builder is created as concatenation of module package name and - * names of all parent nodes. In the end the getter method for choice is - * added to typeBuilder and return type is set to choice - * builder. - * - * @param basePackageName - * string with the module package name - * @param typeBuilder - * generated type builder to which is choiceNode - * added as getter method - * @param choiceNode - * choice node which is mapped as a getter method - * @throws IllegalArgumentException - *
    - *
  • if basePackageName equals null
  • - *
  • if typeBuilder equals null
  • - *
  • if choiceNode equals null
  • - *
- * - */ - private def void resolveChoiceSchemaNode(String basePackageName, GeneratedTypeBuilder typeBuilder, - ChoiceNode choiceNode) { - checkArgument(basePackageName !== null, "Base Package Name cannot be NULL."); - checkArgument(typeBuilder !== null, "Generated Type Builder cannot be NULL."); - checkArgument(choiceNode !== null, "Choice Schema Node cannot be NULL."); - - val choiceName = choiceNode.QName.localName; - if (choiceName !== null && !choiceNode.isAddedByUses()) { - val packageName = packageNameForGeneratedType(basePackageName, choiceNode.path); - val choiceType = addDefaultInterfaceDefinition(packageName, choiceNode); - constructGetter(typeBuilder, choiceName, choiceNode.description, choiceType); - } - } - - /** + private def void addSchemaNodeToBuilderAsMethod(String basePackageName, DataSchemaNode node, + GeneratedTypeBuilder typeBuilder, GeneratedTypeBuilder childOf, Module module) { + if (node !== null && typeBuilder !== null) { + switch (node) { + case node instanceof LeafSchemaNode: + resolveLeafSchemaNodeAsMethod(typeBuilder, node as LeafSchemaNode) + case node instanceof LeafListSchemaNode: + resolveLeafListSchemaNode(typeBuilder, node as LeafListSchemaNode) + case node instanceof ContainerSchemaNode: + containerToGenType(module, basePackageName, typeBuilder, childOf, node as ContainerSchemaNode) + case node instanceof ListSchemaNode: + listToGenType(module, basePackageName, typeBuilder, childOf, node as ListSchemaNode) + case node instanceof ChoiceNode: + choiceToGeneratedType(module, basePackageName, typeBuilder, node as ChoiceNode) + } + } + } + + /** * Converts choiceNode to the list of generated types for * choice and its cases. * @@ -1193,14 +1266,14 @@ public class BindingGeneratorImpl implements BindingGenerator { * 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 childOf concrete parent for case child nodes * @param choiceNode * choice node which is mapped to generated type. Also child * nodes - cases are mapped to generated types. - * @return list of generated types which contains generated type for choice - * and generated types for all cases which aren't added do choice - * through uses. * @throws IllegalArgumentException *
    *
  • if basePackageName equals null
  • @@ -1208,26 +1281,22 @@ public class BindingGeneratorImpl implements BindingGenerator { *
* */ - private def List choiceToGeneratedType(String basePackageName, ChoiceNode choiceNode) { - checkArgument(basePackageName !== null, "Base Package Name cannot be NULL."); - checkArgument(choiceNode !== null, "Choice Schema Node cannot be NULL."); - - val List generatedTypes = new ArrayList(); - val packageName = packageNameForGeneratedType(basePackageName, choiceNode.path); - val choiceTypeBuilder = addRawInterfaceDefinition(packageName, choiceNode); - - //choiceTypeBuilder.addImplementsType(DATA_OBJECT); - val choiceType = choiceTypeBuilder.toInstance(); - - generatedTypes.add(choiceType); - val Set caseNodes = choiceNode.cases; - if ((caseNodes !== null) && !caseNodes.isEmpty()) { - generatedTypes.addAll(generateTypesFromChoiceCases(basePackageName, choiceType, caseNodes)); - } - return generatedTypes; - } - - /** + private def void choiceToGeneratedType(Module module, String basePackageName, GeneratedTypeBuilder parent, + ChoiceNode choiceNode) { + checkArgument(basePackageName !== null, "Base Package Name cannot be NULL."); + checkArgument(choiceNode !== null, "Choice Schema Node cannot be NULL."); + + 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); + } + } + + /** * Converts caseNodes set to list of corresponding generated * types. * @@ -1253,31 +1322,66 @@ public class BindingGeneratorImpl implements BindingGenerator { * * * */ - private def List generateTypesFromChoiceCases(String basePackageName, Type refChoiceType, - Set caseNodes) { - checkArgument(basePackageName !== null, "Base Package Name cannot be NULL."); - checkArgument(refChoiceType !== null, "Referenced Choice Type cannot be NULL."); - checkArgument(caseNodes !== null, "Set of Choice Case Nodes cannot be NULL."); - - val List generatedTypes = new ArrayList(); - for (caseNode : caseNodes) { - if (caseNode !== null && !caseNode.isAddedByUses() && !caseNode.isAugmenting()) { - val packageName = packageNameForGeneratedType(basePackageName, caseNode.path); - val caseTypeBuilder = addDefaultInterfaceDefinition(packageName, caseNode); - caseTypeBuilder.addImplementsType(refChoiceType); - - val Set childNodes = caseNode.childNodes; - if (childNodes !== null) { - resolveDataSchemaNodes(basePackageName, caseTypeBuilder, childNodes); - } - generatedTypes.add(caseTypeBuilder.toInstance()); - } - } - - return generatedTypes; - } - - /** + private def void generateTypesFromChoiceCases(Module module, String basePackageName, + GeneratedTypeBuilder choiceParent, Type refChoiceType, ChoiceNode choiceNode) { + 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."); + + val Set caseNodes = choiceNode.cases; + if (caseNodes == null) { + return + } + + for (caseNode : caseNodes) { + if (caseNode !== null && !caseNode.isAddedByUses() && !caseNode.isAugmenting()) { + val packageName = packageNameForGeneratedType(basePackageName, caseNode.path) + val caseTypeBuilder = addDefaultInterfaceDefinition(packageName, caseNode) + caseTypeBuilder.addImplementsType(refChoiceType) + genCtx.get(module).addCaseType(caseNode.path, caseTypeBuilder) + val Set caseChildNodes = caseNode.childNodes + if (caseChildNodes !== null) { + 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; + val targetPath = augSchema.targetPath; + var targetSchemaNode = findDataSchemaNode(schemaContext, targetPath) + if (targetSchemaNode instanceof DataSchemaNode && + (targetSchemaNode as DataSchemaNode).isAddedByUses()) { + targetSchemaNode = findOriginal(targetSchemaNode as DataSchemaNode); + if (targetSchemaNode == null) { + throw new NullPointerException( + "Failed to find target node from grouping for augmentation " + augSchema + + " in module " + module.name); + } + } + parent = targetSchemaNode + } else { + 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) + } + } + + processUsesAugments(caseNode, module); + } + } + + /** * Generates list of generated types for all the cases of a choice which are * added to the choice through the augment. * @@ -1302,31 +1406,62 @@ public class BindingGeneratorImpl implements BindingGenerator { *
  • if caseNodes equals null
  • * */ - private def List generateTypesFromAugmentedChoiceCases(String basePackageName, Type refChoiceType, - Set caseNodes) { - checkArgument(basePackageName !== null, "Base Package Name cannot be NULL."); - checkArgument(refChoiceType !== null, "Referenced Choice Type cannot be NULL."); - checkArgument(caseNodes !== null, "Set of Choice Case Nodes cannot be NULL."); - - val List generatedTypes = new ArrayList(); - for (caseNode : caseNodes) { - if (caseNode !== null && caseNode.isAugmenting()) { - val packageName = packageNameForGeneratedType(basePackageName, caseNode.path); - val caseTypeBuilder = addDefaultInterfaceDefinition(packageName, caseNode); - caseTypeBuilder.addImplementsType(refChoiceType); - - val Set childNodes = caseNode.childNodes; - if (childNodes !== null) { - resolveDataSchemaNodes(basePackageName, caseTypeBuilder, childNodes); - } - generatedTypes.add(caseTypeBuilder.toInstance()); - } - } - - return generatedTypes; - } - - /** + private def void generateTypesFromAugmentedChoiceCases(Module module, String basePackageName, Type targetType, + ChoiceNode targetNode, Set augmentedNodes) { + checkArgument(basePackageName !== null, "Base Package Name cannot be NULL."); + checkArgument(targetType !== null, "Referenced Choice Type cannot be NULL."); + checkArgument(augmentedNodes !== null, "Set of Choice Case Nodes cannot be NULL."); + + for (caseNode : augmentedNodes) { + if (caseNode !== null) { + val packageName = packageNameForGeneratedType(basePackageName, caseNode.path); + val caseTypeBuilder = addDefaultInterfaceDefinition(packageName, caseNode); + caseTypeBuilder.addImplementsType(targetType); + + 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 + } else if (parent instanceof ChoiceCaseNode) { + childOfType = findCaseByPath(parent.path) + } else if (parent instanceof DataSchemaNode || parent instanceof NotificationDefinition) { + childOfType = findChildNodeByPath(parent.path) + } else if (parent instanceof GroupingDefinition) { + childOfType = findGroupingByPath(parent.path); + } + + if (childOfType == null) { + throw new IllegalArgumentException("Failed to find parent type of choice " + targetNode); + } + + if (caseNode instanceof DataNodeContainer) { + val DataNodeContainer dataNodeCase = caseNode as DataNodeContainer; + val Set childNodes = dataNodeCase.childNodes; + if (childNodes !== null) { + resolveDataSchemaNodes(module, basePackageName, caseTypeBuilder, childOfType, childNodes); + } + } else { + val ChoiceCaseNode node = targetNode.getCaseNodeByName(caseNode.getQName().getLocalName()); + val Set childNodes = node.childNodes; + if (childNodes !== null) { + resolveDataSchemaNodes(module, basePackageName, caseTypeBuilder, childOfType, childNodes); + } + } + + genCtx.get(module).addCaseType(caseNode.path, caseTypeBuilder) + } + } + + } + + /** * Converts leaf to the getter method which is added to * typeBuilder. * @@ -1343,51 +1478,110 @@ public class BindingGeneratorImpl implements BindingGenerator { *
  • true - in other cases
  • * */ - private def boolean resolveLeafSchemaNodeAsMethod(GeneratedTypeBuilder typeBuilder, LeafSchemaNode leaf) { - if ((leaf !== null) && (typeBuilder !== null)) { - val leafName = leaf.QName.localName; - var String leafDesc = leaf.description; - if (leafDesc === null) { - leafDesc = ""; - } - - val parentModule = findParentModule(schemaContext, leaf); - if (leafName !== null && !leaf.isAddedByUses()) { - val TypeDefinition typeDef = leaf.type; - - var Type returnType = null; - if (typeDef instanceof EnumTypeDefinition) { - returnType = typeProvider.javaTypeForSchemaDefinitionType(typeDef, leaf); - val enumTypeDef = typeDef as EnumTypeDefinition; - val enumBuilder = resolveInnerEnumFromTypeDefinition(enumTypeDef, leafName, 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); - } - } else if (typeDef instanceof BitsTypeDefinition) { - val genTOBuilder = addTOToTypeBuilder(typeDef, typeBuilder, leafName, leaf, parentModule); - if (genTOBuilder !== null) { - returnType = new ReferencedTypeImpl(genTOBuilder.packageName, genTOBuilder.name); - } - } else { - returnType = typeProvider.javaTypeForSchemaDefinitionType(typeDef, leaf); - } - if (returnType !== null) { - constructGetter(typeBuilder, leafName, leafDesc, returnType); - return true; - } - } - } - return false; - } - - /** + private def boolean resolveLeafSchemaNodeAsMethod(GeneratedTypeBuilder typeBuilder, LeafSchemaNode leaf) { + if ((leaf !== null) && (typeBuilder !== null)) { + val leafName = leaf.QName.localName; + var String leafDesc = leaf.description; + if (leafDesc === null) { + leafDesc = ""; + } + + val parentModule = findParentModule(schemaContext, leaf); + if (leafName !== null && !leaf.isAddedByUses()) { + 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, 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) { + genTOBuilder = addTOToTypeBuilder(typeDef, typeBuilder, leaf, parentModule); + if (genTOBuilder !== null) { + returnType = createReturnTypeForUnion(genTOBuilder, typeDef, typeBuilder, parentModule) + } + } else if (typeDef instanceof BitsTypeDefinition) { + genTOBuilder = addTOToTypeBuilder(typeDef, typeBuilder, leaf, parentModule); + if (genTOBuilder !== null) { + returnType = new ReferencedTypeImpl(genTOBuilder.packageName, genTOBuilder.name); + } + } else { + val Restrictions restrictions = BindingGeneratorUtil.getRestrictions(typeDef); + returnType = typeProvider.javaTypeForSchemaDefinitionType(typeDef, leaf, restrictions); + } + if (returnType !== null) { + val MethodSignatureBuilder getter = constructGetter(typeBuilder, leafName, leafDesc, returnType); + processContextRefExtension(leaf, getter, parentModule); + return true; + } + } + } + return false; + } + + private def void processContextRefExtension(LeafSchemaNode leaf, MethodSignatureBuilder getter, Module module) { + for (node : leaf.unknownSchemaNodes) { + val nodeType = node.nodeType; + if ("context-reference".equals(nodeType.localName)) { + val nodeParam = node.nodeParameter; + var IdentitySchemaNode identity = null; + var String basePackageName = null; + val String[] splittedElement = nodeParam.split(":"); + if (splittedElement.length == 1) { + identity = findIdentityByName(module.identities, splittedElement.get(0)); + basePackageName = moduleNamespaceToPackageName(module); + } else if (splittedElement.length == 2) { + var prefix = splittedElement.get(0); + val Module dependentModule = findModuleFromImports(module.imports, prefix) + if (dependentModule == null) { + throw new IllegalArgumentException( + "Failed to process context-reference: unknown prefix " + prefix); + } + identity = findIdentityByName(dependentModule.identities, splittedElement.get(1)); + basePackageName = moduleNamespaceToPackageName(dependentModule); + } else { + throw new IllegalArgumentException( + "Failed to process context-reference: unknown identity " + nodeParam); + } + if (identity == null) { + throw new IllegalArgumentException( + "Failed to process context-reference: unknown identity " + nodeParam); + } + + val Class clazz = typeof(RoutingContext); + val AnnotationTypeBuilder rc = getter.addAnnotation(clazz.package.name, clazz.simpleName); + val packageName = packageNameForGeneratedType(basePackageName, identity.path); + val genTypeName = BindingMapping.getClassName(identity.QName.localName); + rc.addParameter("value", packageName + "." + genTypeName + ".class"); + } + } + } + + private def IdentitySchemaNode findIdentityByName(Set identities, String name) { + for (id : identities) { + if (id.QName.localName.equals(name)) { + return id; + } + } + return null; + } + + private def Module findModuleFromImports(Set imports, String prefix) { + for (imp : imports) { + if (imp.prefix.equals(prefix)) { + return schemaContext.findModuleByName(imp.moduleName, imp.revision); + } + } + return null; + } + + /** * Converts leaf schema node to property of generated TO * builder. * @@ -1406,40 +1600,49 @@ public class BindingGeneratorImpl implements BindingGenerator { *
  • true - other cases
  • * */ - private def boolean resolveLeafSchemaNodeAsProperty(GeneratedTOBuilder toBuilder, LeafSchemaNode leaf, - boolean isReadOnly) { - if ((leaf !== null) && (toBuilder !== null)) { - val leafName = leaf.QName.localName; - var String leafDesc = leaf.description; - if (leafDesc === null) { - leafDesc = ""; - } - - if (leafName !== null && !leaf.isAddedByUses()) { - val TypeDefinition typeDef = leaf.type; - - // TODO: properly resolve enum types - val returnType = typeProvider.javaTypeForSchemaDefinitionType(typeDef, leaf); - - if (returnType !== null) { - val propBuilder = toBuilder.addProperty(parseToClassName(leafName)); - - propBuilder.setReadOnly(isReadOnly); - propBuilder.setReturnType(returnType); - propBuilder.setComment(leafDesc); - - toBuilder.addEqualsIdentity(propBuilder); - toBuilder.addHashIdentity(propBuilder); - toBuilder.addToStringProperty(propBuilder); - - return true; - } - } - } - return false; - } - - /** + private def boolean resolveLeafSchemaNodeAsProperty(GeneratedTOBuilder toBuilder, LeafSchemaNode leaf, + boolean isReadOnly, Module module) { + if ((leaf !== null) && (toBuilder !== null)) { + val leafName = leaf.QName.localName; + var String leafDesc = leaf.description; + if (leafDesc === null) { + leafDesc = ""; + } + + 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); + } + + if (returnType !== null) { + val propBuilder = toBuilder.addProperty(parseToValidParamName(leafName)); + propBuilder.setReadOnly(isReadOnly); + propBuilder.setReturnType(returnType); + propBuilder.setComment(leafDesc); + toBuilder.addEqualsIdentity(propBuilder); + toBuilder.addHashIdentity(propBuilder); + toBuilder.addToStringProperty(propBuilder); + return true; + } + } + } + return false; + } + + /** * Converts node leaf list schema node to getter method of * typeBuilder. * @@ -1456,109 +1659,77 @@ public class BindingGeneratorImpl implements BindingGenerator { *
  • false - other cases
  • * */ - private def boolean resolveLeafListSchemaNode(GeneratedTypeBuilder typeBuilder, LeafListSchemaNode node) { - if ((node !== null) && (typeBuilder !== null)) { - val nodeName = node.QName.localName; - var String nodeDesc = node.description; - if (nodeDesc === null) { - nodeDesc = ""; - } - - if (nodeName !== null && !node.isAddedByUses()) { - val TypeDefinition type = node.type; - val listType = Types.listTypeFor(typeProvider.javaTypeForSchemaDefinitionType(type, node)); - - constructGetter(typeBuilder, nodeName, nodeDesc, listType); - return true; - } - } - return false; - } - - /** - * Creates a getter method for a container node. - * - * Firstly generated type builder for container is created or found in - * {@link BindingGeneratorImpl#allGroupings allGroupings}. The package name - * in the builder is created as concatenation of module package name and - * names of all parent nodes. In the end the getter method for container is - * added to typeBuilder and return type is set to container - * type builder. - * - * @param basePackageName - * string with the module package name - * @param typeBuilder - * generated type builder to which is containerNode - * added as getter method - * @param containerNode - * container schema node which is mapped as getter method to - * typeBuilder - * @return boolean value - *
      - *
    • false - if containerNode, - * typeBuilder, container node name equal null or - * containerNode is added by uses
    • - *
    • true - other cases
    • - *
    - */ - private def boolean resolveContainerSchemaNode(String basePackageName, GeneratedTypeBuilder typeBuilder, - ContainerSchemaNode containerNode) { - if ((containerNode !== null) && (typeBuilder !== null)) { - val nodeName = containerNode.QName.localName; - - if (nodeName !== null && !containerNode.isAddedByUses()) { - val packageName = packageNameForGeneratedType(basePackageName, containerNode.path); - - val rawGenType = addDefaultInterfaceDefinition(packageName, containerNode); - constructGetter(typeBuilder, nodeName, containerNode.description, rawGenType); - - return true; - } - } - return false; - } - - /** - * Creates a getter method for a list node. - * - * Firstly generated type builder for list is created or found in - * {@link BindingGeneratorImpl#allGroupings allGroupings}. The package name - * in the builder is created as concatenation of module package name and - * names of all parent nodes. In the end the getter method for list is added - * to typeBuilder and return type is set to list type builder. - * - * @param basePackageName - * string with the module package name - * @param typeBuilder - * generated type builder to which is added as - * getter method - * @param listNode - * list schema node which is mapped as getter method to - * typeBuilder - * @return boolean value - *
      - *
    • false - if listNode, typeBuilder, - * list node name equal null or listNode is added by - * uses
    • - *
    • true - other cases
    • - *
    - */ - private def boolean resolveListSchemaNode(String basePackageName, GeneratedTypeBuilder typeBuilder, - ListSchemaNode listNode) { - if ((listNode !== null) && (typeBuilder !== null)) { - val listName = listNode.QName.localName; - - if (listName !== null && !listNode.isAddedByUses()) { - val packageName = packageNameForGeneratedType(basePackageName, listNode.path); - val rawGenType = addDefaultInterfaceDefinition(packageName, listNode); - constructGetter(typeBuilder, listName, listNode.description, Types.listTypeFor(rawGenType)); - return true; - } - } - return false; - } - - /** + private def boolean resolveLeafListSchemaNode(GeneratedTypeBuilder typeBuilder, LeafListSchemaNode node) { + if ((node !== null) && (typeBuilder !== null)) { + val nodeName = node.QName; + var String nodeDesc = node.description; + if (nodeDesc === null) { + nodeDesc = ""; + } + if (nodeName !== null && !node.isAddedByUses()) { + val TypeDefinition typeDef = node.type; + val parentModule = findParentModule(schemaContext, node); + + var Type returnType = null; + if (typeDef instanceof EnumTypeDefinition) { + returnType = typeProvider.javaTypeForSchemaDefinitionType(typeDef, node); + val enumTypeDef = typeDef as EnumTypeDefinition; + val enumBuilder = resolveInnerEnumFromTypeDefinition(enumTypeDef, nodeName, typeBuilder); + returnType = new ReferencedTypeImpl(enumBuilder.packageName, enumBuilder.name); + (typeProvider as TypeProviderImpl).putReferencedType(node.path, returnType); + } else if (typeDef instanceof UnionType) { + 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, node, parentModule); + returnType = new ReferencedTypeImpl(genTOBuilder.packageName, genTOBuilder.name); + } else { + val Restrictions restrictions = BindingGeneratorUtil.getRestrictions(typeDef); + returnType = typeProvider.javaTypeForSchemaDefinitionType(typeDef, node, restrictions); + } + + val listType = Types.listTypeFor(returnType); + 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); + } + + /** * Instantiates generated type builder with packageName and * schemaNode. * @@ -1577,23 +1748,30 @@ public class BindingGeneratorImpl implements BindingGenerator { * schemaNode belongs. * @param schemaNode * schema node for which is created generated type builder + * @param parent parent type (can be null) * @return generated type builder schemaNode */ - private def GeneratedTypeBuilder addDefaultInterfaceDefinition(String packageName, SchemaNode schemaNode) { - val builder = addRawInterfaceDefinition(packageName, schemaNode, ""); - builder.addImplementsType(DATA_OBJECT); - if (!(schemaNode instanceof GroupingDefinition)) { - builder.addImplementsType(augmentable(builder)); - } - - if (schemaNode instanceof DataNodeContainer) { - addImplementedInterfaceFromUses(schemaNode as DataNodeContainer, builder); - } - - return builder; - } - - /** + private def GeneratedTypeBuilder addDefaultInterfaceDefinition(String packageName, SchemaNode schemaNode, + Type parent) { + val it = addRawInterfaceDefinition(packageName, schemaNode, ""); + qnameConstant(BindingMapping.QNAME_STATIC_FIELD_NAME,schemaNode.QName); + if (parent === null) { + addImplementsType(DATA_OBJECT); + } else { + addImplementsType(BindingTypes.childOf(parent)); + } + if (!(schemaNode instanceof GroupingDefinition)) { + addImplementsType(augmentable(it)); + } + + if (schemaNode instanceof DataNodeContainer) { + addImplementedInterfaceFromUses(schemaNode as DataNodeContainer, it); + } + + return it; + } + + /** * Wraps the calling of the same overloaded method. * * @param packageName @@ -1603,11 +1781,11 @@ public class BindingGeneratorImpl implements BindingGenerator { * schema node which provide data about the schema node name * @return generated type builder for schemaNode */ - private def GeneratedTypeBuilder addRawInterfaceDefinition(String packageName, SchemaNode schemaNode) { - return addRawInterfaceDefinition(packageName, schemaNode, ""); - } + private def GeneratedTypeBuilder addRawInterfaceDefinition(String packageName, SchemaNode schemaNode) { + return addRawInterfaceDefinition(packageName, schemaNode, ""); + } - /** + /** * Returns reference to generated type builder for specified * schemaNode with packageName. * @@ -1620,67 +1798,68 @@ public class BindingGeneratorImpl implements BindingGenerator { * builder belongs * @param schemaNode * schema node which provide data about the schema node name + * @param prefix return type name prefix * @return generated type builder for schemaNode * @throws IllegalArgumentException *
      *
    • 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
    • *
    * */ - private def GeneratedTypeBuilder addRawInterfaceDefinition(String packageName, SchemaNode schemaNode, - String prefix) { - checkArgument(schemaNode !== null, "Data Schema Node cannot be NULL."); - checkArgument(packageName !== null, "Package Name for Generated Type cannot be NULL."); - checkArgument(schemaNode.QName !== null, "QName for Data Schema Node cannot be NULL."); - val schemaNodeName = schemaNode.QName.localName; - checkArgument(schemaNodeName !== null, "Local Name of QName for Data Schema Node cannot be NULL."); - - var String genTypeName; - if (prefix === null) { - genTypeName = parseToClassName(schemaNodeName); - } else { - genTypeName = prefix + parseToClassName(schemaNodeName); - } - - //FIXME: Validation of name conflict - val newType = new GeneratedTypeBuilderImpl(packageName, genTypeName); - yangToJavaMapping.put(schemaNode.path, newType); - if (!genTypeBuilders.containsKey(packageName)) { - val Map builders = new HashMap(); - builders.put(genTypeName, newType); - genTypeBuilders.put(packageName, builders); - } else { - val Map builders = genTypeBuilders.get(packageName); - if (!builders.containsKey(genTypeName)) { - builders.put(genTypeName, newType); - } - } - return newType; - } - - /** + private def GeneratedTypeBuilder addRawInterfaceDefinition(String packageName, SchemaNode schemaNode, + String prefix) { + checkArgument(schemaNode !== null, "Data Schema Node cannot be NULL."); + checkArgument(packageName !== null, "Package Name for Generated Type cannot be NULL."); + checkArgument(schemaNode.QName !== null, "QName for Data Schema Node cannot be NULL."); + val schemaNodeName = schemaNode.QName.localName; + checkArgument(schemaNodeName !== null, "Local Name of QName for Data Schema Node cannot be NULL."); + + var String genTypeName; + if (prefix === null) { + genTypeName = BindingMapping.getClassName(schemaNodeName); + } else { + genTypeName = prefix + BindingMapping.getClassName(schemaNodeName); + } + + //FIXME: Validation of name conflict + val newType = new GeneratedTypeBuilderImpl(packageName, genTypeName); + if (!genTypeBuilders.containsKey(packageName)) { + val Map builders = new HashMap(); + builders.put(genTypeName, newType); + genTypeBuilders.put(packageName, builders); + } else { + val Map builders = genTypeBuilders.get(packageName); + if (!builders.containsKey(genTypeName)) { + builders.put(genTypeName, newType); + } + } + return newType; + } + + /** * Creates the name of the getter method from methodName. * * @param methodName * string with the name of the getter method + * @param returnType return type * @return string with the name of the getter method for * methodName in JAVA method format */ - private def String getterMethodName(String methodName, Type returnType) { - val method = new StringBuilder(); - if (BOOLEAN.equals(returnType)) { - method.append("is"); - } else { - method.append("get"); - } - method.append(parseToClassName(methodName)); - return method.toString(); - } - - /** + public static def String getterMethodName(String localName, Type returnType) { + val method = new StringBuilder(); + if (BOOLEAN.equals(returnType)) { + method.append("is"); + } else { + method.append("get"); + } + method.append(BindingMapping.getPropertyName(localName).toFirstUpper); + return method.toString(); + } + + /** * Created a method signature builder as part of * interfaceBuilder. * @@ -1701,47 +1880,15 @@ public class BindingGeneratorImpl implements BindingGenerator { * @return method signature builder which represents the getter method of * interfaceBuilder */ - private def MethodSignatureBuilder constructGetter(GeneratedTypeBuilder interfaceBuilder, String schemaNodeName, - String comment, Type returnType) { - - val getMethod = interfaceBuilder.addMethod(getterMethodName(schemaNodeName, returnType)); - - getMethod.setComment(comment); - getMethod.setReturnType(returnType); - - return getMethod; - } - - private def listToGenType(String basePackageName, ListSchemaNode list) { - checkArgument(basePackageName !== null, "Package Name for Generated Type cannot be NULL."); - checkArgument(list !== null, "List Schema Node cannot be NULL."); - - val packageName = packageNameForGeneratedType(basePackageName, list.path); - - // val typeBuilder = - // resolveListTypeBuilder(packageName, list); - val typeBuilder = addDefaultInterfaceDefinition(packageName, list); - - val List listKeys = listKeys(list); - val genTOBuilder = resolveListKeyTOBuilder(packageName, list); - - if (genTOBuilder !== null) { - val identifierMarker = IDENTIFIER.parameterizedTypeFor(typeBuilder); - val identifiableMarker = IDENTIFIABLE.parameterizedTypeFor(genTOBuilder); - genTOBuilder.addImplementsType(identifierMarker); - typeBuilder.addImplementsType(identifiableMarker); - } - val schemaNodes = list.childNodes; - - for (schemaNode : schemaNodes) { - if (!schemaNode.isAugmenting()) { - addSchemaNodeToListBuilders(basePackageName, schemaNode, typeBuilder, genTOBuilder, listKeys); - } - } - return typeBuildersToGenTypes(typeBuilder, genTOBuilder); - } - - /** + private def MethodSignatureBuilder constructGetter(GeneratedTypeBuilder interfaceBuilder, String schemaNodeName, + String comment, Type returnType) { + val getMethod = interfaceBuilder.addMethod(getterMethodName(schemaNodeName, returnType)); + getMethod.setComment(comment); + getMethod.setReturnType(returnType); + return getMethod; + } + + /** * Adds schemaNode to typeBuilder as getter method * or to genTOBuilder as property. * @@ -1757,49 +1904,49 @@ public class BindingGeneratorImpl implements BindingGenerator { * generated TO builder for the list keys * @param listKeys * list of string which contains names of the list keys + * @param module current module * @throws IllegalArgumentException *
      *
    • if schemaNode equals null
    • *
    • if typeBuilder equals null
    • *
    */ - private def void addSchemaNodeToListBuilders(String basePackageName, DataSchemaNode schemaNode, - GeneratedTypeBuilder typeBuilder, GeneratedTOBuilder genTOBuilder, List listKeys) { - checkArgument(schemaNode !== null, "Data Schema Node cannot be NULL."); - - checkArgument(typeBuilder !== null, "Generated Type Builder cannot be NULL."); - - if (schemaNode instanceof LeafSchemaNode) { - val leaf = schemaNode as LeafSchemaNode; - val leafName = leaf.QName.localName; - if (!listKeys.contains(leafName)) { - resolveLeafSchemaNodeAsMethod(typeBuilder, leaf); - } else { - resolveLeafSchemaNodeAsProperty(genTOBuilder, leaf, true); - } - } else if (schemaNode instanceof LeafListSchemaNode) { - resolveLeafListSchemaNode(typeBuilder, schemaNode as LeafListSchemaNode); - } else if (schemaNode instanceof ContainerSchemaNode) { - resolveContainerSchemaNode(basePackageName, typeBuilder, schemaNode as ContainerSchemaNode); - } else if (schemaNode instanceof ListSchemaNode) { - resolveListSchemaNode(basePackageName, typeBuilder, schemaNode as ListSchemaNode); - } - } - - private def typeBuildersToGenTypes(GeneratedTypeBuilder typeBuilder, GeneratedTOBuilder genTOBuilder) { - val List genTypes = new ArrayList(); - checkArgument(typeBuilder !== null, "Generated Type Builder cannot be NULL."); - - if (genTOBuilder !== null) { - val genTO = genTOBuilder.toInstance(); - constructGetter(typeBuilder, "key", "Returns Primary Key of Yang List Type", genTO); - genTypes.add(genTO); - } - genTypes.add(typeBuilder.toInstance()); - return genTypes; - } - - /** + private def void addSchemaNodeToListBuilders(String basePackageName, DataSchemaNode schemaNode, + GeneratedTypeBuilder typeBuilder, GeneratedTOBuilder genTOBuilder, List listKeys, Module module) { + checkArgument(schemaNode !== null, "Data Schema Node cannot be NULL."); + checkArgument(typeBuilder !== null, "Generated Type Builder cannot be NULL."); + + if (schemaNode instanceof LeafSchemaNode) { + val leaf = schemaNode as LeafSchemaNode; + val leafName = leaf.QName.localName; + resolveLeafSchemaNodeAsMethod(typeBuilder, leaf); + if (listKeys.contains(leafName)) { + resolveLeafSchemaNodeAsProperty(genTOBuilder, leaf, true, module) + } + } else if (!schemaNode.addedByUses) { + if (schemaNode instanceof LeafListSchemaNode) { + resolveLeafListSchemaNode(typeBuilder, schemaNode as LeafListSchemaNode); + } else if (schemaNode instanceof ContainerSchemaNode) { + containerToGenType(module, basePackageName, typeBuilder, typeBuilder, schemaNode as ContainerSchemaNode); + } else if (schemaNode instanceof ChoiceNode) { + choiceToGeneratedType(module, basePackageName, typeBuilder, schemaNode as ChoiceNode); + } else if (schemaNode instanceof ListSchemaNode) { + listToGenType(module, basePackageName, typeBuilder, typeBuilder, schemaNode as ListSchemaNode); + } + } + } + + private def typeBuildersToGenTypes(Module module, GeneratedTypeBuilder typeBuilder, GeneratedTOBuilder genTOBuilder) { + checkArgument(typeBuilder !== null, "Generated Type Builder cannot be NULL."); + + if (genTOBuilder !== null) { + val genTO = genTOBuilder.toInstance(); + constructGetter(typeBuilder, "key", "Returns Primary Key of Yang List Type", genTO); + genCtx.get(module).addGeneratedTOBuilder(genTOBuilder) + } + } + + /** * Selects the names of the list keys from list and returns * them as the list of the strings * @@ -1809,19 +1956,19 @@ public class BindingGeneratorImpl implements BindingGenerator { * list contains no keys then the empty list is * returned. */ - private def listKeys(ListSchemaNode list) { - val List listKeys = new ArrayList(); - - if (list.keyDefinition !== null) { - val keyDefinitions = list.keyDefinition; - for (keyDefinition : keyDefinitions) { - listKeys.add(keyDefinition.localName); - } - } - return listKeys; - } - - /** + private def listKeys(ListSchemaNode list) { + val List listKeys = new ArrayList(); + + if (list.keyDefinition !== null) { + val keyDefinitions = list.keyDefinition; + for (keyDefinition : keyDefinitions) { + listKeys.add(keyDefinition.localName); + } + } + return listKeys; + } + + /** * Generates for the list which contains any list keys special * generated TO builder. * @@ -1833,20 +1980,17 @@ public class BindingGeneratorImpl implements BindingGenerator { * list or null if list is null or list of * key definitions is null or empty. */ - private def GeneratedTOBuilder resolveListKeyTOBuilder(String packageName, ListSchemaNode list) { - var GeneratedTOBuilder genTOBuilder = null; - if ((list.keyDefinition !== null) && (!list.keyDefinition.isEmpty())) { - if (list !== null) { - val listName = list.QName.localName + "Key"; - val String genTOName = parseToClassName(listName); - genTOBuilder = new GeneratedTOBuilderImpl(packageName, genTOName); - } - } - return genTOBuilder; - - } - - /** + private def GeneratedTOBuilder resolveListKeyTOBuilder(String packageName, ListSchemaNode list) { + var GeneratedTOBuilder genTOBuilder = null; + if ((list.keyDefinition !== null) && (!list.keyDefinition.isEmpty())) { + val listName = list.QName.localName + "Key"; + val String genTOName = BindingMapping.getClassName(listName); + genTOBuilder = new GeneratedTOBuilderImpl(packageName, genTOName); + } + return genTOBuilder; + } + + /** * Builds generated TO builders for typeDef of type * {@link org.opendaylight.yangtools.yang.model.util.UnionType UnionType} or * {@link org.opendaylight.yangtools.yang.model.api.type.BitsTypeDefinition @@ -1865,37 +2009,56 @@ public class BindingGeneratorImpl implements BindingGenerator { * from typeDef * @param leafName * string with name for generated TO builder + * @param leaf + * @param parentModule * @return generated TO builder for typeDef */ - private def GeneratedTOBuilder addTOToTypeBuilder(TypeDefinition typeDef, GeneratedTypeBuilder typeBuilder, - String leafName, LeafSchemaNode leaf, Module parentModule) { - val classNameFromLeaf = parseToClassName(leafName); - 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)); - } else if (typeDef instanceof BitsTypeDefinition) { - genTOBuilders.add( - ((typeProvider as TypeProviderImpl) ). - provideGeneratedTOBuilderForBitsTypeDefinition(packageName, typeDef, classNameFromLeaf)); - } - if (genTOBuilders !== null && !genTOBuilders.isEmpty()) { - for (genTOBuilder : genTOBuilders) { - typeBuilder.addEnclosingTransferObject(genTOBuilder); - } - return genTOBuilders.get(0); - } - return null; - - } - - /** + private def GeneratedTOBuilder addTOToTypeBuilder(TypeDefinition typeDef, GeneratedTypeBuilder typeBuilder, + DataSchemaNode leaf, Module parentModule) { + val classNameFromLeaf = BindingMapping.getClassName(leaf.QName); + val List genTOBuilders = new ArrayList(); + val packageName = typeBuilder.fullyQualifiedName; + 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) ). + provideGeneratedTOBuilderForBitsTypeDefinition(packageName, typeDef, classNameFromLeaf)); + } + if (genTOBuilders !== null && !genTOBuilders.isEmpty()) { + for (genTOBuilder : genTOBuilders) { + typeBuilder.addEnclosingTransferObject(genTOBuilder); + } + return genTOBuilders.get(0); + } + return null; + + } + + /** * 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 @@ -1907,17 +2070,59 @@ public class BindingGeneratorImpl implements BindingGenerator { * dataNodeContainer * @return generated type builder with all implemented types */ - private def addImplementedInterfaceFromUses(DataNodeContainer dataNodeContainer, GeneratedTypeBuilder builder) { - for (usesNode : dataNodeContainer.uses) { - if (usesNode.groupingPath !== null) { - val genType = allGroupings.get(usesNode.groupingPath); - if (genType === null) { - throw new IllegalStateException( - "Grouping " + usesNode.groupingPath + "is not resolved for " + builder.name); - } - builder.addImplementsType(genType); - } - } - return builder; - } + private def addImplementedInterfaceFromUses(DataNodeContainer dataNodeContainer, GeneratedTypeBuilder builder) { + for (usesNode : dataNodeContainer.uses) { + if (usesNode.groupingPath !== null) { + val genType = findGroupingByPath(usesNode.groupingPath).toInstance + if (genType === null) { + throw new IllegalStateException( + "Grouping " + usesNode.groupingPath + "is not resolved for " + builder.name); + } + builder.addImplementsType(genType); + } + } + return builder; + } + + private def GeneratedTypeBuilder findChildNodeByPath(SchemaPath path) { + for (ctx : genCtx.values) { + var result = ctx.getChildNode(path) + if (result !== null) { + return result + } + } + return null + } + + private def GeneratedTypeBuilder findGroupingByPath(SchemaPath path) { + for (ctx : genCtx.values) { + var result = ctx.getGrouping(path) + if (result !== null) { + return result + } + } + return null + } + + private def GeneratedTypeBuilder findCaseByPath(SchemaPath path) { + for (ctx : genCtx.values) { + var result = ctx.getCase(path) + if (result !== null) { + return result + } + } + 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; + } + }