From: Tony Tkacik Date: Tue, 3 Sep 2013 17:16:49 +0000 (-0700) Subject: Fixed NPE regresion in augmentation handling. X-Git-Tag: yangtools-0.1.0~39 X-Git-Url: https://git.opendaylight.org/gerrit/gitweb?a=commitdiff_plain;h=ecb9e7e41f1098245f4d1f8137d8a337aa8f5cb0;p=yangtools.git Fixed NPE regresion in augmentation handling. Added rollback to original handling if the class of augmentation target is not already generated or registered in newly introduced mapping between yang types and generated java binding specs. Change-Id: I9d05e8ed0f6d6f2f3230a320e6eceb4463130ab0 Signed-off-by: Tony Tkacik --- 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 eb9346b72f..5b3bbb28e2 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 @@ -1,1942 +1,1940 @@ -/* - * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved. - * - * This program and the accompanying materials are made available under the - * terms of the Eclipse Public License v1.0 which accompanies this distribution, - * and is available at http://www.eclipse.org/legal/epl-v10.html - */ -package org.opendaylight.yangtools.sal.binding.generator.impl; +/* + * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License v1.0 which accompanies this distribution, + * and is available at http://www.eclipse.org/legal/epl-v10.html + */ +package org.opendaylight.yangtools.sal.binding.generator.impl; + +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 org.opendaylight.yangtools.binding.generator.util.BindingTypes; +import org.opendaylight.yangtools.binding.generator.util.ReferencedTypeImpl; +import org.opendaylight.yangtools.binding.generator.util.Types; +import org.opendaylight.yangtools.binding.generator.util.generated.type.builder.GeneratedTOBuilderImpl; +import org.opendaylight.yangtools.binding.generator.util.generated.type.builder.GeneratedTypeBuilderImpl; +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; +import org.opendaylight.yangtools.sal.binding.model.api.type.builder.GeneratedTypeBuilder; +import org.opendaylight.yangtools.sal.binding.model.api.type.builder.MethodSignatureBuilder; +import org.opendaylight.yangtools.sal.binding.yang.types.GroupingDefinitionDependencySort; +import org.opendaylight.yangtools.sal.binding.yang.types.TypeProviderImpl; +import org.opendaylight.yangtools.yang.binding.RpcService; +import org.opendaylight.yangtools.yang.common.RpcResult; +import org.opendaylight.yangtools.yang.model.api.AugmentationSchema; +import org.opendaylight.yangtools.yang.model.api.ChoiceCaseNode; +import org.opendaylight.yangtools.yang.model.api.ChoiceNode; +import org.opendaylight.yangtools.yang.model.api.ContainerSchemaNode; +import org.opendaylight.yangtools.yang.model.api.DataNodeContainer; +import org.opendaylight.yangtools.yang.model.api.DataSchemaNode; +import org.opendaylight.yangtools.yang.model.api.GroupingDefinition; +import org.opendaylight.yangtools.yang.model.api.IdentitySchemaNode; +import org.opendaylight.yangtools.yang.model.api.LeafListSchemaNode; +import org.opendaylight.yangtools.yang.model.api.LeafSchemaNode; +import org.opendaylight.yangtools.yang.model.api.ListSchemaNode; +import org.opendaylight.yangtools.yang.model.api.Module; +import org.opendaylight.yangtools.yang.model.api.RpcDefinition; +import org.opendaylight.yangtools.yang.model.api.SchemaContext; +import org.opendaylight.yangtools.yang.model.api.SchemaNode; +import org.opendaylight.yangtools.yang.model.api.SchemaPath; +import org.opendaylight.yangtools.yang.model.api.TypeDefinition; +import org.opendaylight.yangtools.yang.model.api.UnknownSchemaNode; +import org.opendaylight.yangtools.yang.model.api.type.BitsTypeDefinition; +import org.opendaylight.yangtools.yang.model.api.type.EnumTypeDefinition; +import org.opendaylight.yangtools.yang.model.api.type.UnionTypeDefinition; +import org.opendaylight.yangtools.yang.model.util.DataNodeIterator; +import org.opendaylight.yangtools.yang.model.util.ExtendedType; +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 java.util.ArrayList; -import java.util.Collections; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.Set; - -import org.opendaylight.yangtools.binding.generator.util.BindingTypes; -import org.opendaylight.yangtools.binding.generator.util.ReferencedTypeImpl; -import org.opendaylight.yangtools.binding.generator.util.Types; -import org.opendaylight.yangtools.binding.generator.util.generated.type.builder.GeneratedTOBuilderImpl; -import org.opendaylight.yangtools.binding.generator.util.generated.type.builder.GeneratedTypeBuilderImpl; -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; -import org.opendaylight.yangtools.sal.binding.model.api.type.builder.GeneratedTypeBuilder; -import org.opendaylight.yangtools.sal.binding.model.api.type.builder.MethodSignatureBuilder; -import org.opendaylight.yangtools.sal.binding.yang.types.GroupingDefinitionDependencySort; -import org.opendaylight.yangtools.sal.binding.yang.types.TypeProviderImpl; -import org.opendaylight.yangtools.yang.binding.RpcService; -import org.opendaylight.yangtools.yang.common.RpcResult; -import org.opendaylight.yangtools.yang.model.api.AugmentationSchema; -import org.opendaylight.yangtools.yang.model.api.ChoiceCaseNode; -import org.opendaylight.yangtools.yang.model.api.ChoiceNode; -import org.opendaylight.yangtools.yang.model.api.ContainerSchemaNode; -import org.opendaylight.yangtools.yang.model.api.DataNodeContainer; -import org.opendaylight.yangtools.yang.model.api.DataSchemaNode; -import org.opendaylight.yangtools.yang.model.api.GroupingDefinition; -import org.opendaylight.yangtools.yang.model.api.IdentitySchemaNode; -import org.opendaylight.yangtools.yang.model.api.LeafListSchemaNode; -import org.opendaylight.yangtools.yang.model.api.LeafSchemaNode; -import org.opendaylight.yangtools.yang.model.api.ListSchemaNode; -import org.opendaylight.yangtools.yang.model.api.Module; -import org.opendaylight.yangtools.yang.model.api.RpcDefinition; -import org.opendaylight.yangtools.yang.model.api.SchemaContext; -import org.opendaylight.yangtools.yang.model.api.SchemaNode; -import org.opendaylight.yangtools.yang.model.api.SchemaPath; -import org.opendaylight.yangtools.yang.model.api.TypeDefinition; -import org.opendaylight.yangtools.yang.model.api.UnknownSchemaNode; -import org.opendaylight.yangtools.yang.model.api.type.BitsTypeDefinition; -import org.opendaylight.yangtools.yang.model.api.type.EnumTypeDefinition; -import org.opendaylight.yangtools.yang.model.api.type.UnionTypeDefinition; -import org.opendaylight.yangtools.yang.model.util.DataNodeIterator; -import org.opendaylight.yangtools.yang.model.util.ExtendedType; -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.*; - -public class BindingGeneratorImpl implements BindingGenerator { - - /** - * Outter key represents the package name. Outter 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; - - /** - * Provide methods for converting YANG types to JAVA types. - */ - private var TypeProvider typeProvider; - - /** - * Holds reference to schema context to resolve data of augmented elemnt - * 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(); - - /** - * Constant with the concrete name of namespace. - */ - 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"; - - - /** - * Resolves generated types from context schema nodes of all - * modules. - * - * Generated types are created for modules, groupings, types, containers, - * lists, choices, augments, rpcs, notification, identities. - * - * @param context - * schema context which contains data about all schema nodes - * saved in modules - * @return list of types (usually GeneratedType - * GeneratedTransferObjectwhich are generated from - * context data. - * @throws IllegalArgumentException - * if param context is null - * @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; - genTypeBuilders = new HashMap(); - for (module : modules) { - - generatedTypes.addAll(allGroupingsToGenTypes(module)); - - if (false == module.childNodes.isEmpty()) { - generatedTypes.add(moduleToDataType(module)); - } - generatedTypes.addAll(allTypeDefinitionsToGenTypes(module)); - generatedTypes.addAll(allContainersToGenTypes(module)); - generatedTypes.addAll(allListsToGenTypes(module)); - generatedTypes.addAll(allChoicesToGenTypes(module)); - generatedTypes.addAll(allRPCMethodsToGenType(module)); - generatedTypes.addAll(allNotificationsToGenType(module)); - generatedTypes.addAll(allIdentitiesToGenTypes(module, context)); - } - for (module : modules) { - generatedTypes.addAll(allAugmentsToGenTypes(module)); - - } - return generatedTypes; - } - - /** - * Resolves generated types from context schema nodes only for - * modules specified in modules - * - * Generated types are created for modules, groupings, types, containers, - * lists, choices, augments, rpcs, notification, identities. - * - * @param context - * schema context which contains data about all schema nodes - * saved in modules - * @param modules - * set of modules for which schema nodes should be generated - * types - * @return list of types (usually GeneratedType or - * GeneratedTransferObject) which: - *
    - *
  • are generated from context schema nodes and
  • - *
  • are also part of some of the module in modules - * set
  • . - *
- * @throws IllegalArgumentException - *
    - *
  • if param context is null or
  • - *
  • if param modules is null
  • - *
- * @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 Set contextModules = context.modules; - genTypeBuilders = new HashMap(); - - for (contextModule : contextModules) { - val List generatedTypes = new ArrayList(); - - generatedTypes.addAll(allGroupingsToGenTypes(contextModule)); - if (false == contextModule.childNodes.isEmpty()) { - generatedTypes.add(moduleToDataType(contextModule)); - } - generatedTypes.addAll(allTypeDefinitionsToGenTypes(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; - } - - /** - * 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
  • - *
  • if name of module equals null
  • - *
  • if type definitions of module equal null
  • - *
- * - */ - 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; - } - - /** - * 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
  • - *
  • if the name of module equals null
  • - *
  • if the set of child nodes equals null
  • - *
- * - */ - 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; - } - - /** - * Returns list of AugmentationSchema objects. The objects are - * sorted according to the length of their target path from the shortest to - * the longest. - * - * @param module - * module from which is obtained list of all augmentation objects - * @return list of sorted AugmentationSchema objects obtained - * from module - * @throws IllegalArgumentException - *
    - *
  • if the module equals null
  • - *
  • if the set of augmentation equals null
  • - *
- * - */ - 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. - * - * @param module - * module from which are obtained the module name, child nodes, - * uses and is derived package name - * @return GeneratedType which is internal representation of - * the module - * @throws IllegalArgumentException - * 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(); - } - - /** - * 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. - * - * @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
  • - *
  • if the name of module equals null
  • - *
  • if the set of child nodes equals null
  • - *
- * - */ - 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; - } - - /** - * 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. - * - * @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
  • - *
  • if the name of module equals null
  • - *
  • if the set of child nodes equals null
  • - *
- * - */ - 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; - } - - /** - * Converts all identities of the module to the list of - * Type objects. - * - * @param module - * module from which is obtained set of all identity objects to - * iterate over them - * @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; - } - - /** - * 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. - * If identity doesn't contain base identity then only reference to abstract - * class {@link org.opendaylight.yangtools.yang.model.api.BaseIdentity - * BaseIdentity} is added - * - * @param basePackageName - * string contains the module package name - * @param identity - * IdentitySchemaNode which contains data about identity - * @param context - * 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(); - } - - /** - * 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 - * 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) - * - */ - 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 GroupingDefinitionDependencySort groupingSort = new GroupingDefinitionDependencySort(); - val List groupingsSortedByDependencies = groupingSort.sort(groupings); - - for (grouping : groupingsSortedByDependencies) { - val genType = groupingToGenType(basePackageName, grouping); - genTypes.add(genType); - val schemaPath = grouping.path; - allGroupings.put(schemaPath, genType); - } - return genTypes; - } - - /** - * Converts individual grouping to GeneratedType. Firstly generated type - * builder is created and every child node of grouping is resolved to the - * method. - * - * @param basePackageName - * string contains the module package name - * @param grouping - * GroupingDefinition which contains data about grouping - * @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(); - } - - /** - * 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. - * - * @param typeDefinition - * TypeDefinition in which should be EnumTypeDefinition found as - * base type - * @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; - } - - /** - * Adds enumeration builder created from enumTypeDef to - * typeBuilder. - * - * Each enumTypeDef item is added to builder with its name and - * value. - * - * @param enumTypeDef - * EnumTypeDefinition contains enum data - * @param enumName - * string contains name which will be assigned to enumeration - * builder - * @param typeBuilder - * GeneratedTypeBuilder to which will be enum builder assigned - * @return enumeration builder which contais 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; - } - - /** - * Generates type builder for module. - * - * @param module - * Module which is source of package name for generated type - * builder - * @param postfix - * string which is added to the module class name representation - * as suffix - * @return instance of GeneratedTypeBuilder which represents - * module. - * @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); - - } - - /** - * 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 - * augSchema node or a generated types for cases are added if - * augmented node is choice. - * - * @param augmentPackageName - * string with the name of the package to which the augmentation - * belongs - * @param augSchema - * AugmentationSchema which is contains data about agumentation - * (target path, childs...) - * @return list of Type objects which contains generated type - * for augmentation and for container, list and choice child nodes - * @throws IllegalArgumentException - *
    - *
  • if augmentPackageName equals null
  • - *
  • if augSchema equals null
  • - *
  • 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); - val targetType = yangToJavaMapping.get(targetSchemaNode.path); - if ((targetSchemaNode !== null) && (targetSchemaNode.QName !== null) - && (targetSchemaNode.QName.localName !== null)) { - - val targetPackageName = targetType.packageName; - val targetSchemaNodeName = targetType.name; - - - val augChildNodes = augSchema.childNodes; - - if (!(targetSchemaNode instanceof ChoiceNode)) { - val augTypeBuilder = addRawAugmentGenTypeDefinition(augmentPackageName, - targetType, augSchema); - val augType = augTypeBuilder.toInstance(); - genTypes.add(augType); - } else { - val refChoiceType = new ReferencedTypeImpl(targetPackageName, - parseToClassName(targetSchemaNodeName)); - val choiceTarget = targetSchemaNode as ChoiceNode; - val choiceCaseNodes = choiceTarget.cases; - genTypes.addAll(generateTypesFromAugmentedChoiceCases(augmentPackageName, refChoiceType, - choiceCaseNodes)); - } - genTypes.addAll(augmentationBodyToGenTypes(augmentPackageName, augChildNodes)); - } - return genTypes; - } - - /** - * 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 augmentPackageName - * string with contains the package name to which the augment - * belongs - * @param targetPackageName - * string with the package name to which the augmented node - * belongs - * @param targetSchemaNodeName - * string with the name of the augmented node - * @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; - } - - /** - * - * @param unknownSchemaNodes - * @return - */ - 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; - } - - /** - * 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. - * - * @param builders - * map of builders which were created in the package to which the - * augmentation belongs - * @param genTypeName - * 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(); - } - - /** - * 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 basePackageName - * string contains the module package name - * @param typeBuilder - * 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 schemaNodes - * set of data schema nodes which are the children of the node - * for which typeBuilder was created - * @return generated type builder which is the same builder as input - * 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; - } - - /** - * Adds the methods to typeBuilder what represents subnodes of - * node for which typeBuilder was created. - * - * @param basePackageName - * string contains the module package name - * @param typeBuilder - * 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 schemaNodes - * set of data schema nodes which are the children of the node - * for which typeBuilder was created - * @return generated type builder which is the same object as the input - * 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; - } - - /** - * Adds to typeBuilder a method which is derived from - * schemaNode. - * - * @param basePackageName - * string with the module package name - * @param schemaNode - * data schema node which is added to typeBuilder as - * a method - * @param typeBuilder - * generated type builder to which is schemaNode - * added as a method. - */ - 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); - } - } - - /** - * Converts choiceNode to the list of generated types for - * choice and its cases. - * - * The package names for choice and for its cases are created as - * concatenation of the module package (basePackageName) and - * names of all parents node. - * - * @param basePackageName - * string with the module package name - * @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
  • - *
  • if choiceNode equals null
  • - *
- * - */ - 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; - } - - /** - * Converts caseNodes set to list of corresponding generated - * types. - * - * For every case which isn't added through augment or uses is - * created generated type builder. The package names for the builder is - * created as concatenation of the module package ( - * basePackageName) and names of all parents nodes of the - * concrete case. There is also relation "implements type" - * between every case builder and choice type - * - * @param basePackageName - * string with the module package name - * @param refChoiceType - * type which represents superior case - * @param caseNodes - * set of choice case nodes which are mapped to generated types - * @return list of generated types for caseNodes. - * @throws IllegalArgumentException - *
    - *
  • if basePackageName equals null
  • - *
  • if refChoiceType equals null
  • - *
  • if caseNodes equals null
  • - *
- * * - */ - 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; - } - - /** - * Generates list of generated types for all the cases of a choice which are - * added to the choice through the augment. - * - * - * @param basePackageName - * string contains name of package to which augment belongs. If - * an augmented choice is from an other package (pcg1) than an - * augmenting choice (pcg2) then case's of the augmenting choice - * will belong to pcg2. - * @param refChoiceType - * Type which represents the choice to which case belongs. Every - * case has to contain its choice in extend part. - * @param caseNodes - * set of choice case nodes for which is checked if are/aren't - * added to choice through augmentation - * @return list of generated types which represents augmented cases of - * choice refChoiceType - * @throws IllegalArgumentException - *
    - *
  • if basePackageName equals null
  • - *
  • if refChoiceType equals null
  • - *
  • 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; - } - - /** - * Converts leaf to the getter method which is added to - * typeBuilder. - * - * @param typeBuilder - * generated type builder to which is added getter method as - * leaf mapping - * @param leaf - * leaf schema node which is mapped as getter method which is - * added to typeBuilder - * @return boolean value - *
    - *
  • false - if leaf or typeBuilder are - * null
  • - *
  • 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 = enumTypeDefFromExtendedType(typeDef); - 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; - } - - /** - * Converts leaf schema node to property of generated TO - * builder. - * - * @param toBuilder - * generated TO builder to which is leaf added as - * property - * @param leaf - * leaf schema node which is added to toBuilder as - * property - * @param isReadOnly - * boolean value which says if leaf property is|isn't read only - * @return boolean value - *
    - *
  • false - if leaf, toBuilder or leaf - * name equals null or if leaf is added by uses.
  • - *
  • 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; - } - - /** - * Converts node leaf list schema node to getter method of - * typeBuilder. - * - * @param typeBuilder - * generated type builder to which is node added as - * getter method - * @param node - * leaf list schema node which is added to - * typeBuilder as getter method - * @return boolean value - *
    - *
  • true - if node, typeBuilder, - * nodeName equal null or node is added by uses
  • - *
  • 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; - } - - /** - * Instantiates generated type builder with packageName and - * schemaNode. - * - * The new builder always implements - * {@link org.opendaylight.yangtools.yang.binding.DataObject DataObject}.
- * If schemaNode is instance of GroupingDefinition it also - * implements {@link org.opendaylight.yangtools.yang.binding.Augmentable - * Augmentable}.
- * If schemaNode is instance of - * {@link org.opendaylight.yangtools.yang.model.api.DataNodeContainer - * DataNodeContainer} it can also implement nodes which are specified in - * uses. - * - * @param packageName - * string with the name of the package to which - * schemaNode belongs. - * @param schemaNode - * schema node for which is created generated type builder - * @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; - } - - /** - * Wraps the calling of the same overloaded method. - * - * @param packageName - * string with the package name to which returning generated type - * builder belongs - * @param schemaNode - * 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, ""); - } - - /** - * Returns reference to generated type builder for specified - * schemaNode with packageName. - * - * Firstly the generated type builder is searched in - * {@link BindingGeneratorImpl#genTypeBuilders genTypeBuilders}. If it isn't - * found it is created and added to genTypeBuilders. - * - * @param packageName - * string with the package name to which returning generated type - * builder belongs - * @param schemaNode - * schema node which provide data about the schema node name - * @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
  • - *
- * - */ - 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; - } - - /** - * Creates the name of the getter method from methodName. - * - * @param methodName - * string with the name of the getter method - * @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(); - } - - /** - * Created a method signature builder as part of - * interfaceBuilder. - * - * The method signature builder is created for the getter method of - * schemaNodeName. Also comment and - * returnType information are added to the builder. - * - * @param interfaceBuilder - * generated type builder for which the getter method should be - * created - * @param schemaNodeName - * string with schema node name. The name will be the part of the - * getter method name. - * @param comment - * string with comment for the getter method - * @param returnType - * type which represents the return type of the getter method - * @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); - } - - /** - * Adds schemaNode to typeBuilder as getter method - * or to genTOBuilder as property. - * - * @param basePackageName - * string contains the module package name - * @param schemaNode - * data schema node which should be added as getter method to - * typeBuilder or as a property to - * genTOBuilder if is part of the list key - * @param typeBuilder - * generated type builder for the list schema node - * @param genTOBuilder - * generated TO builder for the list keys - * @param listKeys - * list of string which contains names of the list keys - * @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; - } - - /** - * Selects the names of the list keys from list and returns - * them as the list of the strings - * - * @param list - * of string with names of the list keys - * @return list of string which represents names of the list keys. If the - * 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; - } - - /** - * Generates for the list which contains any list keys special - * generated TO builder. - * - * @param packageName - * string with package name to which the list belongs - * @param list - * list schema node which is source of data about the list name - * @return generated TO builder which represents the keys of the - * 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"; - genTOBuilder = schemaNodeToTransferObjectBuilder(packageName, listName); - } - } - 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 - * BitsTypeDefinition} which are also added to typeBuilder as - * enclosing transfer object. - * - * If more then one generated TO builder is created for enclosing then all - * of the generated TO builders are added to typeBuilder as - * enclosing transfer objects. - * - * @param typeDef - * type definition which can be of type UnionType or - * BitsTypeDefinition - * @param typeBuilder - * generated type builder to which is added generated TO created - * from typeDef - * @param leafName - * string with name for generated TO builder - * @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, 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; - - } - - /** - * Adds the implemented types to type builder. - * - * The method passes through the list of uses in - * {@code dataNodeContainer}. For every use is obtained coresponding - * generated type from {@link BindingGeneratorImpl#allGroupings - * allGroupings} which is added as implements type to - * builder - * - * @param dataNodeContainer - * element which contains the list of used YANG groupings - * @param builder - * builder to which are added implemented types according to - * 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; - } + +public class BindingGeneratorImpl implements BindingGenerator { + + /** + * Outter key represents the package name. Outter 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; + + /** + * Provide methods for converting YANG types to JAVA types. + */ + private var TypeProvider typeProvider; + + /** + * Holds reference to schema context to resolve data of augmented elemnt + * 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(); + + /** + * Constant with the concrete name of namespace. + */ + 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"; + + + /** + * Resolves generated types from context schema nodes of all + * modules. + * + * Generated types are created for modules, groupings, types, containers, + * lists, choices, augments, rpcs, notification, identities. + * + * @param context + * schema context which contains data about all schema nodes + * saved in modules + * @return list of types (usually GeneratedType + * GeneratedTransferObjectwhich are generated from + * context data. + * @throws IllegalArgumentException + * if param context is null + * @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; + genTypeBuilders = new HashMap(); + for (module : modules) { + + generatedTypes.addAll(allGroupingsToGenTypes(module)); + + if (false == module.childNodes.isEmpty()) { + generatedTypes.add(moduleToDataType(module)); + } + generatedTypes.addAll(allTypeDefinitionsToGenTypes(module)); + generatedTypes.addAll(allContainersToGenTypes(module)); + generatedTypes.addAll(allListsToGenTypes(module)); + generatedTypes.addAll(allChoicesToGenTypes(module)); + generatedTypes.addAll(allRPCMethodsToGenType(module)); + generatedTypes.addAll(allNotificationsToGenType(module)); + generatedTypes.addAll(allIdentitiesToGenTypes(module, context)); + } + for (module : modules) { + generatedTypes.addAll(allAugmentsToGenTypes(module)); + + } + return generatedTypes; + } + + /** + * Resolves generated types from context schema nodes only for + * modules specified in modules + * + * Generated types are created for modules, groupings, types, containers, + * lists, choices, augments, rpcs, notification, identities. + * + * @param context + * schema context which contains data about all schema nodes + * saved in modules + * @param modules + * set of modules for which schema nodes should be generated + * types + * @return list of types (usually GeneratedType or + * GeneratedTransferObject) which: + *
    + *
  • are generated from context schema nodes and
  • + *
  • are also part of some of the module in modules + * set
  • . + *
+ * @throws IllegalArgumentException + *
    + *
  • if param context is null or
  • + *
  • if param modules is null
  • + *
+ * @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 Set contextModules = context.modules; + genTypeBuilders = new HashMap(); + + for (contextModule : contextModules) { + val List generatedTypes = new ArrayList(); + + generatedTypes.addAll(allGroupingsToGenTypes(contextModule)); + if (false == contextModule.childNodes.isEmpty()) { + generatedTypes.add(moduleToDataType(contextModule)); + } + generatedTypes.addAll(allTypeDefinitionsToGenTypes(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; + } + + /** + * 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
  • + *
  • if name of module equals null
  • + *
  • if type definitions of module equal null
  • + *
+ * + */ + 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; + } + + /** + * 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
  • + *
  • if the name of module equals null
  • + *
  • if the set of child nodes equals null
  • + *
+ * + */ + 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; + } + + /** + * Returns list of AugmentationSchema objects. The objects are + * sorted according to the length of their target path from the shortest to + * the longest. + * + * @param module + * module from which is obtained list of all augmentation objects + * @return list of sorted AugmentationSchema objects obtained + * from module + * @throws IllegalArgumentException + *
    + *
  • if the module equals null
  • + *
  • if the set of augmentation equals null
  • + *
+ * + */ + 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. + * + * @param module + * module from which are obtained the module name, child nodes, + * uses and is derived package name + * @return GeneratedType which is internal representation of + * the module + * @throws IllegalArgumentException + * 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(); + } + + /** + * 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. + * + * @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
  • + *
  • if the name of module equals null
  • + *
  • if the set of child nodes equals null
  • + *
+ * + */ + 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; + } + + /** + * 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. + * + * @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
  • + *
  • if the name of module equals null
  • + *
  • if the set of child nodes equals null
  • + *
+ * + */ + 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; + } + + /** + * Converts all identities of the module to the list of + * Type objects. + * + * @param module + * module from which is obtained set of all identity objects to + * iterate over them + * @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; + } + + /** + * 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. + * If identity doesn't contain base identity then only reference to abstract + * class {@link org.opendaylight.yangtools.yang.model.api.BaseIdentity + * BaseIdentity} is added + * + * @param basePackageName + * string contains the module package name + * @param identity + * IdentitySchemaNode which contains data about identity + * @param context + * 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(); + } + + /** + * 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 + * 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) + * + */ + 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; + } + + /** + * Converts individual grouping to GeneratedType. Firstly generated type + * builder is created and every child node of grouping is resolved to the + * method. + * + * @param basePackageName + * string contains the module package name + * @param grouping + * GroupingDefinition which contains data about grouping + * @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(); + } + + /** + * 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. + * + * @param typeDefinition + * TypeDefinition in which should be EnumTypeDefinition found as + * base type + * @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; + } + + /** + * Adds enumeration builder created from enumTypeDef to + * typeBuilder. + * + * Each enumTypeDef item is added to builder with its name and + * value. + * + * @param enumTypeDef + * EnumTypeDefinition contains enum data + * @param enumName + * string contains name which will be assigned to enumeration + * builder + * @param typeBuilder + * GeneratedTypeBuilder to which will be enum builder assigned + * @return enumeration builder which contais 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; + } + + /** + * Generates type builder for module. + * + * @param module + * Module which is source of package name for generated type + * builder + * @param postfix + * string which is added to the module class name representation + * as suffix + * @return instance of GeneratedTypeBuilder which represents + * module. + * @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); + + } + + /** + * 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 + * augSchema node or a generated types for cases are added if + * augmented node is choice. + * + * @param augmentPackageName + * string with the name of the package to which the augmentation + * belongs + * @param augSchema + * AugmentationSchema which is contains data about agumentation + * (target path, childs...) + * @return list of Type objects which contains generated type + * for augmentation and for container, list and choice child nodes + * @throws IllegalArgumentException + *
    + *
  • if augmentPackageName equals null
  • + *
  • if augSchema equals null
  • + *
  • 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); + 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); + } + if (targetSchemaNode !== null) { + 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; + } + + /** + * 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 augmentPackageName + * string with contains the package name to which the augment + * belongs + * @param targetPackageName + * string with the package name to which the augmented node + * belongs + * @param targetSchemaNodeName + * string with the name of the augmented node + * @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; + } + + /** + * + * @param unknownSchemaNodes + * @return + */ + 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; + } + + /** + * 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. + * + * @param builders + * map of builders which were created in the package to which the + * augmentation belongs + * @param genTypeName + * 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(); + } + + /** + * 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 basePackageName + * string contains the module package name + * @param typeBuilder + * 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 schemaNodes + * set of data schema nodes which are the children of the node + * for which typeBuilder was created + * @return generated type builder which is the same builder as input + * 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; + } + + /** + * Adds the methods to typeBuilder what represents subnodes of + * node for which typeBuilder was created. + * + * @param basePackageName + * string contains the module package name + * @param typeBuilder + * 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 schemaNodes + * set of data schema nodes which are the children of the node + * for which typeBuilder was created + * @return generated type builder which is the same object as the input + * 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; + } + + /** + * Adds to typeBuilder a method which is derived from + * schemaNode. + * + * @param basePackageName + * string with the module package name + * @param schemaNode + * data schema node which is added to typeBuilder as + * a method + * @param typeBuilder + * generated type builder to which is schemaNode + * added as a method. + */ + 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); + } + } + + /** + * Converts choiceNode to the list of generated types for + * choice and its cases. + * + * The package names for choice and for its cases are created as + * concatenation of the module package (basePackageName) and + * names of all parents node. + * + * @param basePackageName + * string with the module package name + * @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
  • + *
  • if choiceNode equals null
  • + *
+ * + */ + 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; + } + + /** + * Converts caseNodes set to list of corresponding generated + * types. + * + * For every case which isn't added through augment or uses is + * created generated type builder. The package names for the builder is + * created as concatenation of the module package ( + * basePackageName) and names of all parents nodes of the + * concrete case. There is also relation "implements type" + * between every case builder and choice type + * + * @param basePackageName + * string with the module package name + * @param refChoiceType + * type which represents superior case + * @param caseNodes + * set of choice case nodes which are mapped to generated types + * @return list of generated types for caseNodes. + * @throws IllegalArgumentException + *
    + *
  • if basePackageName equals null
  • + *
  • if refChoiceType equals null
  • + *
  • if caseNodes equals null
  • + *
+ * * + */ + 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; + } + + /** + * Generates list of generated types for all the cases of a choice which are + * added to the choice through the augment. + * + * + * @param basePackageName + * string contains name of package to which augment belongs. If + * an augmented choice is from an other package (pcg1) than an + * augmenting choice (pcg2) then case's of the augmenting choice + * will belong to pcg2. + * @param refChoiceType + * Type which represents the choice to which case belongs. Every + * case has to contain its choice in extend part. + * @param caseNodes + * set of choice case nodes for which is checked if are/aren't + * added to choice through augmentation + * @return list of generated types which represents augmented cases of + * choice refChoiceType + * @throws IllegalArgumentException + *
    + *
  • if basePackageName equals null
  • + *
  • if refChoiceType equals null
  • + *
  • 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; + } + + /** + * Converts leaf to the getter method which is added to + * typeBuilder. + * + * @param typeBuilder + * generated type builder to which is added getter method as + * leaf mapping + * @param leaf + * leaf schema node which is mapped as getter method which is + * added to typeBuilder + * @return boolean value + *
    + *
  • false - if leaf or typeBuilder are + * null
  • + *
  • 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 = enumTypeDefFromExtendedType(typeDef); + 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; + } + + /** + * Converts leaf schema node to property of generated TO + * builder. + * + * @param toBuilder + * generated TO builder to which is leaf added as + * property + * @param leaf + * leaf schema node which is added to toBuilder as + * property + * @param isReadOnly + * boolean value which says if leaf property is|isn't read only + * @return boolean value + *
    + *
  • false - if leaf, toBuilder or leaf + * name equals null or if leaf is added by uses.
  • + *
  • 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; + } + + /** + * Converts node leaf list schema node to getter method of + * typeBuilder. + * + * @param typeBuilder + * generated type builder to which is node added as + * getter method + * @param node + * leaf list schema node which is added to + * typeBuilder as getter method + * @return boolean value + *
    + *
  • true - if node, typeBuilder, + * nodeName equal null or node is added by uses
  • + *
  • 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; + } + + /** + * Instantiates generated type builder with packageName and + * schemaNode. + * + * The new builder always implements + * {@link org.opendaylight.yangtools.yang.binding.DataObject DataObject}.
+ * If schemaNode is instance of GroupingDefinition it also + * implements {@link org.opendaylight.yangtools.yang.binding.Augmentable + * Augmentable}.
+ * If schemaNode is instance of + * {@link org.opendaylight.yangtools.yang.model.api.DataNodeContainer + * DataNodeContainer} it can also implement nodes which are specified in + * uses. + * + * @param packageName + * string with the name of the package to which + * schemaNode belongs. + * @param schemaNode + * schema node for which is created generated type builder + * @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; + } + + /** + * Wraps the calling of the same overloaded method. + * + * @param packageName + * string with the package name to which returning generated type + * builder belongs + * @param schemaNode + * 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, ""); + } + + /** + * Returns reference to generated type builder for specified + * schemaNode with packageName. + * + * Firstly the generated type builder is searched in + * {@link BindingGeneratorImpl#genTypeBuilders genTypeBuilders}. If it isn't + * found it is created and added to genTypeBuilders. + * + * @param packageName + * string with the package name to which returning generated type + * builder belongs + * @param schemaNode + * schema node which provide data about the schema node name + * @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
  • + *
+ * + */ + 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; + } + + /** + * Creates the name of the getter method from methodName. + * + * @param methodName + * string with the name of the getter method + * @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(); + } + + /** + * Created a method signature builder as part of + * interfaceBuilder. + * + * The method signature builder is created for the getter method of + * schemaNodeName. Also comment and + * returnType information are added to the builder. + * + * @param interfaceBuilder + * generated type builder for which the getter method should be + * created + * @param schemaNodeName + * string with schema node name. The name will be the part of the + * getter method name. + * @param comment + * string with comment for the getter method + * @param returnType + * type which represents the return type of the getter method + * @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); + } + + /** + * Adds schemaNode to typeBuilder as getter method + * or to genTOBuilder as property. + * + * @param basePackageName + * string contains the module package name + * @param schemaNode + * data schema node which should be added as getter method to + * typeBuilder or as a property to + * genTOBuilder if is part of the list key + * @param typeBuilder + * generated type builder for the list schema node + * @param genTOBuilder + * generated TO builder for the list keys + * @param listKeys + * list of string which contains names of the list keys + * @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; + } + + /** + * Selects the names of the list keys from list and returns + * them as the list of the strings + * + * @param list + * of string with names of the list keys + * @return list of string which represents names of the list keys. If the + * 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; + } + + /** + * Generates for the list which contains any list keys special + * generated TO builder. + * + * @param packageName + * string with package name to which the list belongs + * @param list + * list schema node which is source of data about the list name + * @return generated TO builder which represents the keys of the + * 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"; + genTOBuilder = schemaNodeToTransferObjectBuilder(packageName, listName); + } + } + 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 + * BitsTypeDefinition} which are also added to typeBuilder as + * enclosing transfer object. + * + * If more then one generated TO builder is created for enclosing then all + * of the generated TO builders are added to typeBuilder as + * enclosing transfer objects. + * + * @param typeDef + * type definition which can be of type UnionType or + * BitsTypeDefinition + * @param typeBuilder + * generated type builder to which is added generated TO created + * from typeDef + * @param leafName + * string with name for generated TO builder + * @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, 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; + + } + + /** + * Adds the implemented types to type builder. + * + * The method passes through the list of uses in + * {@code dataNodeContainer}. For every use is obtained coresponding + * generated type from {@link BindingGeneratorImpl#allGroupings + * allGroupings} which is added as implements type to + * builder + * + * @param dataNodeContainer + * element which contains the list of used YANG groupings + * @param builder + * builder to which are added implemented types according to + * 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; + } }