From 1f5f42569eeadaa202813396c1198e7bebd74b25 Mon Sep 17 00:00:00 2001 From: Martin Vitez Date: Thu, 31 Oct 2013 12:43:00 +0100 Subject: [PATCH] Implemented use of ChildOf interface in generated classes. Change-Id: I4795dde99f562258e7bc9670fe418c432aeccc5c Signed-off-by: Martin Vitez --- .../generator/impl/BindingGeneratorImpl.xtend | 2793 +++++++---------- .../binding/generator/impl/ModuleContext.java | 122 + .../generator/impl/GeneratedTypesTest.java | 32 +- .../binding/generator/util/BindingTypes.java | 31 +- .../java/api/generator/GeneratorJavaFile.java | 22 +- ...AugmentToUsesInAugmentCompilationTest.java | 1 + .../generator/test/BaseCompilationTest.java | 170 +- .../test/CascadeUsesCompilationTest.java | 1 + .../api/generator/test/CompilationTest.java | 61 +- .../generator/test/CompilationTestUtils.java | 185 ++ .../compilation/augment-of-augment/baz.yang | 5 + model/pom.xml | 2 +- 12 files changed, 1635 insertions(+), 1790 deletions(-) create mode 100644 code-generator/binding-generator-impl/src/main/java/org/opendaylight/yangtools/sal/binding/generator/impl/ModuleContext.java create mode 100644 code-generator/binding-java-api-generator/src/test/java/org/opendaylight/yangtools/sal/java/api/generator/test/CompilationTestUtils.java 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 0a228da330..257a5c4c76 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 @@ -4,116 +4,107 @@ * 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.SchemaContextUtil; -import org.opendaylight.yangtools.yang.model.util.UnionType; -import static com.google.common.base.Preconditions.*; -import static extension org.opendaylight.yangtools.binding.generator.util.Types.*; -import static org.opendaylight.yangtools.binding.generator.util.BindingGeneratorUtil.*; -import static org.opendaylight.yangtools.binding.generator.util.BindingTypes.*; -import static org.opendaylight.yangtools.yang.model.util.SchemaContextUtil.*; -import org.opendaylight.yangtools.yang.parser.util.ModuleDependencySort -import org.opendaylight.yangtools.yang.model.util.ExtendedType; -import org.opendaylight.yangtools.yang.model.api.UsesNode -import org.opendaylight.yangtools.yang.binding.annotations.RoutingContext -import org.opendaylight.yangtools.sal.binding.model.api.type.builder.AnnotationTypeBuilder -import org.opendaylight.yangtools.yang.model.api.ModuleImport -import org.opendaylight.yangtools.yang.binding.DataContainer import java.util.Iterator + */ +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.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.SchemaContextUtil; +import org.opendaylight.yangtools.yang.model.util.UnionType; +import static com.google.common.base.Preconditions.*; +import static extension org.opendaylight.yangtools.binding.generator.util.Types.*; +import static org.opendaylight.yangtools.binding.generator.util.BindingGeneratorUtil.*; +import static org.opendaylight.yangtools.binding.generator.util.BindingTypes.*; +import static org.opendaylight.yangtools.yang.model.util.SchemaContextUtil.*; +import org.opendaylight.yangtools.yang.parser.util.ModuleDependencySort +import org.opendaylight.yangtools.yang.model.util.ExtendedType; +import org.opendaylight.yangtools.yang.model.api.UsesNode +import org.opendaylight.yangtools.yang.binding.annotations.RoutingContext +import org.opendaylight.yangtools.sal.binding.model.api.type.builder.AnnotationTypeBuilder +import org.opendaylight.yangtools.yang.model.api.ModuleImport +import org.opendaylight.yangtools.yang.binding.DataContainer +import java.util.Iterator import org.opendaylight.yangtools.yang.model.api.AugmentationTarget import java.util.Collection import org.opendaylight.yangtools.yang.model.api.YangNode -import java.util.LinkedHashMap +import org.opendaylight.yangtools.yang.model.api.NotificationDefinition + +public class BindingGeneratorImpl implements BindingGenerator { + + private final Map genCtx = new HashMap() -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; - + */ + private Map> genTypeBuilders; + /** * Provide methods for converting YANG types to JAVA types. - */ - private var TypeProvider typeProvider; - + */ + private var TypeProvider typeProvider; + /** * Holds reference to schema context to resolve data of augmented elemnt * 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 LinkedHashMap(); - - private val yangToJavaMapping = new HashMap(); - + */ + private var SchemaContext schemaContext; + /** * Constant with the concrete name of namespace. - */ - private val static String YANG_EXT_NAMESPACE = "urn:opendaylight:yang:extension:yang-ext"; - + */ + private val static String YANG_EXT_NAMESPACE = "urn:opendaylight:yang:extension:yang-ext"; + /** * Constant with the concrete name of identifier. - */ - private val static String AUGMENT_IDENTIFIER_NAME = "augment-identifier"; - + */ + private val static String AUGMENT_IDENTIFIER_NAME = "augment-identifier"; + /** * Resolves generated types from context schema nodes of all * modules. @@ -131,16 +122,16 @@ public class BindingGeneratorImpl implements BindingGenerator { * 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."); - schemaContext = context; - typeProvider = new TypeProviderImpl(context); - val Set modules = context.modules; - return generateTypes(context, modules); - } - + */ + override generateTypes(SchemaContext context) { + checkArgument(context !== null, "Schema Context reference cannot be NULL."); + checkState(context.modules !== null, "Schema Context does not contain defined modules."); + schemaContext = context; + typeProvider = new TypeProviderImpl(context); + val Set modules = context.modules; + return generateTypes(context, modules); + } + /** * Resolves generated types from context schema nodes only for * modules specified in modules @@ -168,55 +159,56 @@ public class BindingGeneratorImpl implements BindingGenerator { * * @throws IllegalStateException * if context contain no modules - */ - override generateTypes(SchemaContext context, Set modules) { - checkArgument(context !== null, "Schema Context reference cannot be NULL."); - checkState(context.modules !== null, "Schema Context does not contain defined modules."); - checkArgument(modules !== null, "Set of Modules cannot be NULL."); - - val List filteredGenTypes = new ArrayList(); - - schemaContext = context; - typeProvider = new TypeProviderImpl(context); - val contextModules = ModuleDependencySort.sort(context.modules); - genTypeBuilders = new HashMap(); - - for (contextModule : contextModules) { - val List generatedTypes = new ArrayList(); - generatedTypes.addAll(allTypeDefinitionsToGenTypes(contextModule)); - generatedTypes.addAll(allGroupingsToGenTypes(contextModule)); - if(false == contextModule.childNodes.isEmpty()) { - generatedTypes.add(moduleToDataType(contextModule)); - } - generatedTypes.addAll(allContainersToGenTypes(contextModule)); - generatedTypes.addAll(allListsToGenTypes(contextModule)); - generatedTypes.addAll(allChoicesToGenTypes(contextModule)); - generatedTypes.addAll(allRPCMethodsToGenType(contextModule)); - generatedTypes.addAll(allNotificationsToGenType(contextModule)); - generatedTypes.addAll(allIdentitiesToGenTypes(contextModule, context)); - - if(modules.contains(contextModule)) { - filteredGenTypes.addAll(generatedTypes); - } - } - for (contextModule : contextModules) { - val generatedTypes = (allAugmentsToGenTypes(contextModule)); - if(modules.contains(contextModule)) { - filteredGenTypes.addAll(generatedTypes); - } - - } - return filteredGenTypes; - } - + */ + override generateTypes(SchemaContext context, Set modules) { + checkArgument(context !== null, "Schema Context reference cannot be NULL."); + checkState(context.modules !== null, "Schema Context does not contain defined modules."); + checkArgument(modules !== null, "Set of Modules cannot be NULL."); + + schemaContext = context; + typeProvider = new TypeProviderImpl(context); + val contextModules = ModuleDependencySort.sort(context.modules); + genTypeBuilders = new HashMap(); + + for (contextModule : contextModules) { + moduleToGenTypes(contextModule, context); + } + for (contextModule : contextModules) { + allAugmentsToGenTypes(contextModule); + } + + val List filteredGenTypes = new ArrayList(); + for (Module m : modules) { + filteredGenTypes.addAll(genCtx.get(m).generatedTypes); + + } + genCtx.clear; + + return filteredGenTypes; + } + + private def void moduleToGenTypes(Module m, SchemaContext context) { + genCtx.put(m, new ModuleContext) + allTypeDefinitionsToGenTypes(m) + groupingsToGenTypes(m, m.groupings) + rpcMethodsToGenType(m) + allIdentitiesToGenTypes(m, context) + notificationsToGenType(m) + + if (!m.childNodes.isEmpty()) { + val moduleType = moduleToDataType(m) + genCtx.get(m).addModuleNode(moduleType) + val basePackageName = moduleNamespaceToPackageName(m); + resolveDataSchemaNodes(m, basePackageName, moduleType, moduleType, m.childNodes) + } + } + /** * Converts all extended type definitions of module to the list of * Type objects. * * @param module * module from which is obtained set of type definitions - * @return list of Type which are generated from extended - * definition types (object of type ExtendedType) * @throws IllegalArgumentException *
    *
  • if module equals null
  • @@ -224,190 +216,79 @@ public class BindingGeneratorImpl implements BindingGenerator { *
  • 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 it = new DataNodeIterator(module); - val List> typeDefinitions = it.allTypedefs; - 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; - } - - private def List dataNodeContainerToGenType(String basePackageName, DataNodeContainer node, Module module) { - if (node === null) { - return null; - } - if (!(node instanceof SchemaNode)) { - throw new IllegalArgumentException("node to generate must be instance of SchemaNode"); - } - val List result = new ArrayList(); - - result.addAll(processUsesAugments(node, module)); - - val packageName = packageNameForGeneratedType(basePackageName, (node as SchemaNode).path); - val typeBuilder = addDefaultInterfaceDefinition(packageName, node as SchemaNode); - val schemaNodes = node.childNodes; - if (node instanceof ContainerSchemaNode) { - resolveDataSchemaNodes(basePackageName, typeBuilder, schemaNodes); - result.add(typeBuilder.toInstance()); - } else if (node instanceof ListSchemaNode) { - val List listKeys = listKeys(node as ListSchemaNode); - val genTOBuilder = resolveListKeyTOBuilder(packageName, node as ListSchemaNode); - - if(genTOBuilder !== null) { - val identifierMarker = IDENTIFIER.parameterizedTypeFor(typeBuilder); - val identifiableMarker = IDENTIFIABLE.parameterizedTypeFor(genTOBuilder); - genTOBuilder.addImplementsType(identifierMarker); - typeBuilder.addImplementsType(identifiableMarker); - } - for (schemaNode : schemaNodes) { - if (!schemaNode.isAugmenting()) { - addSchemaNodeToListBuilders(basePackageName, schemaNode, typeBuilder, genTOBuilder, listKeys); - } - } - result.addAll(typeBuildersToGenTypes(typeBuilder, genTOBuilder)); - } - - return result; - } - - private def List processUsesAugments(DataNodeContainer node, Module module) { - val List result = new ArrayList(); - val basePackageName = moduleNamespaceToPackageName(module); - - for (usesNode : node.uses) { - for (augment : usesNode.augmentations) { - result.addAll(augmentationToGenTypes(basePackageName, augment, module, usesNode)); - result.addAll(processUsesAugments(augment, module)); - } - } - - return result; - } - - /** - * 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.addAll(dataNodeContainerToGenType(basePackageName, container, module)); - } - } - 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(dataNodeContainerToGenType(basePackageName, list, module)); - } - } - } - 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, module)); - } - } - return generatedTypes; - } - + */ + private def void allTypeDefinitionsToGenTypes(Module module) { + checkArgument(module !== null, "Module reference cannot be NULL."); + checkArgument(module.name !== null, "Module name cannot be NULL."); + val it = new DataNodeIterator(module); + val List> typeDefinitions = it.allTypedefs; + checkState(typeDefinitions !== null, '''Type Definitions for module «module.name» cannot be NULL.'''); + + for (TypeDefinition typedef : typeDefinitions) { + if (typedef !== null) { + val type = (typeProvider as TypeProviderImpl).generatedTypeForExtendedDefinitionType(typedef, typedef); + if (type !== null) { + genCtx.get(module).addTypedefType(typedef.path, type) + } + } + } + } + + private def void containerToGenType(Module module, String basePackageName, GeneratedTypeBuilder parent, + GeneratedTypeBuilder childOf, ContainerSchemaNode node) { + if (node.augmenting || node.addedByUses) { + return + } + val packageName = packageNameForGeneratedType(basePackageName, node.path) + val genType = addDefaultInterfaceDefinition(packageName, node, childOf) + constructGetter(parent, node.QName.localName, node.description, genType) + genCtx.get(module).addChildNodeType(node.path, genType) + resolveDataSchemaNodes(module, basePackageName, genType, genType, node.childNodes) + groupingsToGenTypes(module, node.groupings) + processUsesAugments(node, module) + } + + private def void listToGenType(Module module, String basePackageName, GeneratedTypeBuilder parent, + GeneratedTypeBuilder childOf, ListSchemaNode node) { + if (node.augmenting || node.addedByUses) { + return + } + val packageName = packageNameForGeneratedType(basePackageName, (node).path) + val genType = addDefaultInterfaceDefinition(packageName, node, childOf) + constructGetter(parent, node.QName.localName, node.description, Types.listTypeFor(genType)) + genCtx.get(module).addChildNodeType(node.path, genType) + groupingsToGenTypes(module, node.groupings) + processUsesAugments(node, module) + + val List listKeys = listKeys(node); + val genTOBuilder = resolveListKeyTOBuilder(packageName, node); + + if (genTOBuilder !== null) { + val identifierMarker = IDENTIFIER.parameterizedTypeFor(genType); + val identifiableMarker = IDENTIFIABLE.parameterizedTypeFor(genTOBuilder); + genTOBuilder.addImplementsType(identifierMarker); + genType.addImplementsType(identifiableMarker); + } + + for (schemaNode : node.childNodes) { + if (!schemaNode.augmenting) { + addSchemaNodeToListBuilders(basePackageName, schemaNode, genType, genTOBuilder, listKeys, module); + } + } + + typeBuildersToGenTypes(module, genType, genTOBuilder); + } + + private def void processUsesAugments(DataNodeContainer node, Module module) { + val basePackageName = moduleNamespaceToPackageName(module); + for (usesNode : node.uses) { + for (augment : usesNode.augmentations) { + augmentationToGenTypes(basePackageName, augment, module, usesNode); + processUsesAugments(augment, module); + } + } + } + /** * Converts all augmentation of the module to the list * Type objects. @@ -415,8 +296,6 @@ public class BindingGeneratorImpl implements BindingGenerator { * @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
  • @@ -424,24 +303,22 @@ public class BindingGeneratorImpl implements BindingGenerator { *
  • 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, module, null)); - } - return generatedTypes; - } - + */ + private def void allAugmentsToGenTypes(Module module) { + checkArgument(module !== null, "Module reference cannot be NULL."); + checkArgument(module.name !== null, "Module name cannot be NULL."); + if (module.childNodes === null) { + throw new IllegalArgumentException( + "Reference to Set of Augmentation Definitions in module " + module.name + " cannot be NULL."); + } + + val basePackageName = moduleNamespaceToPackageName(module); + val List augmentations = resolveAugmentations(module); + for (augment : augmentations) { + augmentationToGenTypes(basePackageName, augment, module, null); + } + } + /** * Returns list of AugmentationSchema objects. The objects are * sorted according to the length of their target path from the shortest to @@ -457,25 +334,25 @@ public class BindingGeneratorImpl implements BindingGenerator { *
  • 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; - } - + */ + 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 @@ -489,22 +366,16 @@ public class BindingGeneratorImpl implements BindingGenerator { * @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(); - } - + */ + private def GeneratedTypeBuilder moduleToDataType(Module module) { + checkArgument(module !== null, "Module reference cannot be NULL."); + + val moduleDataTypeBuilder = moduleTypeBuilder(module, "Data"); + addImplementedInterfaceFromUses(module, moduleDataTypeBuilder); + moduleDataTypeBuilder.addImplementsType(DATA_ROOT); + return moduleDataTypeBuilder; + } + /** * Converts all rpcs inputs and outputs substatements of the module * to the list of Type objects. In addition are to containers @@ -513,8 +384,6 @@ public class BindingGeneratorImpl implements BindingGenerator { * @param module * module from which is obtained set of all rpc objects to * iterate over them - * @return list of Type which are generated from rpcs inputs, - * outputs + container and lists which are part of inputs or outputs * @throws IllegalArgumentException *
      *
    • if the module equals null
    • @@ -522,99 +391,59 @@ public class BindingGeneratorImpl implements BindingGenerator { *
    • 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.addAll(dataNodeContainerToGenType(basePackageName, container, module)); - } - } - } - val List nLists = iter.allLists(); - if((nLists !== null) && !nLists.isEmpty()) { - for (list : nLists) { - if(!list.isAddedByUses()) { - genRPCTypes.addAll(dataNodeContainerToGenType(basePackageName, list, module)); - } - } - } - val List nChoices = iter.allChoices(); - if((nChoices !== null) && !nChoices.isEmpty()) { - for (choice : nChoices) { - if(!choice.isAddedByUses()) { - genRPCTypes.addAll(choiceToGeneratedType(basePackageName, choice, module)); - } - } - } - } - } - } - genRPCTypes.add(interfaceBuilder.toInstance()); - return genRPCTypes; - } - + */ + private def void rpcMethodsToGenType(Module module) { + checkArgument(module !== null, "Module reference cannot be NULL."); + checkArgument(module.name !== null, "Module name cannot be NULL."); + checkArgument(module.childNodes !== null, + "Reference to Set of RPC Method Definitions in module " + module.name + " cannot be NULL."); + + val basePackageName = moduleNamespaceToPackageName(module); + val Set rpcDefinitions = module.rpcs; + if (rpcDefinitions.isEmpty()) { + return; + } + + val interfaceBuilder = moduleTypeBuilder(module, "Service"); + interfaceBuilder.addImplementsType(Types.typeForClass(RpcService)); + for (rpc : rpcDefinitions) { + if (rpc !== null) { + val rpcName = parseToClassName(rpc.QName.localName); + val rpcMethodName = parseToValidParamName(rpcName); + val method = interfaceBuilder.addMethod(rpcMethodName); + val input = rpc.input; + val output = rpc.output; + + if (input !== null) { + val inType = addRawInterfaceDefinition(basePackageName, input, rpcName); + addImplementedInterfaceFromUses(input, inType); + inType.addImplementsType(DATA_OBJECT); + inType.addImplementsType(augmentable(inType)); + resolveDataSchemaNodes(module, basePackageName, inType, inType, input.childNodes); + genCtx.get(module).addChildNodeType(input.path, inType) + val inTypeInstance = inType.toInstance(); + method.addParameter(inTypeInstance, "input"); + } + + var Type outTypeInstance = VOID; + if (output !== null) { + val outType = addRawInterfaceDefinition(basePackageName, output, rpcName); + addImplementedInterfaceFromUses(output, outType); + outType.addImplementsType(DATA_OBJECT); + outType.addImplementsType(augmentable(outType)); + resolveDataSchemaNodes(module, basePackageName, outType, outType, output.childNodes); + genCtx.get(module).addChildNodeType(output.path, outType) + outTypeInstance = outType.toInstance(); + } + + val rpcRes = Types.parameterizedTypeFor(Types.typeForClass(RpcResult), outTypeInstance); + method.setReturnType(Types.parameterizedTypeFor(FUTURE, rpcRes)); + } + } + + genCtx.get(module).addTopLevelNodeType(interfaceBuilder) + } + /** * Converts all notifications of the module to the list of * Type objects. In addition are to this list added containers @@ -623,8 +452,6 @@ public class BindingGeneratorImpl implements BindingGenerator { * @param module * module from which is obtained set of all notification objects * to iterate over them - * @return list of Type which are generated from notification - * (object of type NotificationDefinition * @throws IllegalArgumentException *
      *
    • if the module equals null
    • @@ -632,63 +459,44 @@ public class BindingGeneratorImpl implements BindingGenerator { *
    • 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) { - generatedTypes.addAll(processUsesAugments(notification, module)); - - val iter = new DataNodeIterator(notification); - - // Containers - for (node : iter.allContainers()) { - if(!node.isAddedByUses()) { - generatedTypes.addAll(dataNodeContainerToGenType(basePackageName, node, module)); - } - } - - // Lists - for (node : iter.allLists()) { - if(!node.isAddedByUses()) { - generatedTypes.addAll(dataNodeContainerToGenType(basePackageName, node, module)); - } - } - val notificationInterface = addDefaultInterfaceDefinition(basePackageName, notification); - notificationInterface.addImplementsType(NOTIFICATION); - + */ + private def void notificationsToGenType(Module module) { + checkArgument(module !== null, "Module reference cannot be NULL."); + checkArgument(module.name !== null, "Module name cannot be NULL."); + + if (module.childNodes === null) { + throw new IllegalArgumentException( + "Reference to Set of Notification Definitions in module " + module.name + " cannot be NULL."); + } + val notifications = module.notifications; + if(notifications.empty) return; + + val listenerInterface = moduleTypeBuilder(module, "Listener"); + listenerInterface.addImplementsType(BindingTypes.NOTIFICATION_LISTENER); + val basePackageName = moduleNamespaceToPackageName(module); + + for (notification : notifications) { + if (notification !== null) { + processUsesAugments(notification, module); + + val notificationInterface = addDefaultInterfaceDefinition(basePackageName, notification, + BindingTypes.DATA_OBJECT); + notificationInterface.addImplementsType(NOTIFICATION); + genCtx.get(module).addChildNodeType(notification.path, notificationInterface) + // Notification object - resolveDataSchemaNodes(basePackageName, notificationInterface, notification.childNodes); - + resolveDataSchemaNodes(module, basePackageName, notificationInterface, 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; - } - + .setAccessModifier(AccessModifier.PUBLIC).addParameter(notificationInterface, "notification"). + setReturnType(Types.VOID); + } + } + + genCtx.get(module).addTopLevelNodeType(listenerInterface) + } + /** * Converts all identities of the module to the list of * Type objects. @@ -699,25 +507,19 @@ public class BindingGeneratorImpl implements BindingGenerator { * @param context * schema context only used as input parameter for method * {@link identityToGenType} - * @return list of Type which are generated from identities - * (object of type IdentitySchemaNode * - */ - private def List allIdentitiesToGenTypes(Module module, SchemaContext context) { - val List genTypes = new ArrayList(); - - val Set schemaIdentities = module.identities; - - val basePackageName = moduleNamespaceToPackageName(module); - - if(schemaIdentities !== null && !schemaIdentities.isEmpty()) { - for (identity : schemaIdentities) { - genTypes.add(identityToGenType(basePackageName, identity, context)); - } - } - return genTypes; - } - + */ + private def void allIdentitiesToGenTypes(Module module, SchemaContext context) { + val Set schemaIdentities = module.identities; + val basePackageName = moduleNamespaceToPackageName(module); + + if (schemaIdentities !== null && !schemaIdentities.isEmpty()) { + for (identity : schemaIdentities) { + identityToGenType(module, basePackageName, identity, context); + } + } + } + /** * Converts the identity object to GeneratedType. Firstly it is * created transport object builder. If identity contains base identity then @@ -726,6 +528,7 @@ public class BindingGeneratorImpl implements BindingGenerator { * class {@link org.opendaylight.yangtools.yang.model.api.BaseIdentity * BaseIdentity} is added * + * @param module current module * @param basePackageName * string contains the module package name * @param identity @@ -734,36 +537,29 @@ public class BindingGeneratorImpl implements BindingGenerator { * SchemaContext which is used to get package and name * information about base of identity * - * @return GeneratedType which is generated from identity (object of type - * IdentitySchemaNode - * - */ - private def GeneratedType identityToGenType(String basePackageName, IdentitySchemaNode identity, - SchemaContext context) { - if(identity === null) { - return null; - } - - val packageName = packageNameForGeneratedType(basePackageName, identity.path); - val genTypeName = parseToClassName(identity.QName.localName); - val newType = new GeneratedTOBuilderImpl(packageName, genTypeName); - - val baseIdentity = identity.baseIdentity; - if(baseIdentity !== null) { - val baseIdentityParentModule = SchemaContextUtil.findParentModule(context, baseIdentity); - - val returnTypePkgName = moduleNamespaceToPackageName(baseIdentityParentModule); - val returnTypeName = parseToClassName(baseIdentity.QName.localName); - - val gto = new GeneratedTOBuilderImpl(returnTypePkgName, returnTypeName).toInstance(); - newType.setExtendsType(gto); - } else { - newType.setExtendsType(Types.baseIdentityTO); - } - newType.setAbstract(true); - return newType.toInstance(); - } - + */ + private def void identityToGenType(Module module, String basePackageName, IdentitySchemaNode identity, + SchemaContext context) { + if (identity === null) { + return; + } + val packageName = packageNameForGeneratedType(basePackageName, identity.path); + val genTypeName = parseToClassName(identity.QName.localName); + val newType = new GeneratedTOBuilderImpl(packageName, genTypeName); + val baseIdentity = identity.baseIdentity; + if (baseIdentity === null) { + newType.setExtendsType(Types.baseIdentityTO); + } else { + val baseIdentityParentModule = SchemaContextUtil.findParentModule(context, baseIdentity); + val returnTypePkgName = moduleNamespaceToPackageName(baseIdentityParentModule); + val returnTypeName = parseToClassName(baseIdentity.QName.localName); + val gto = new GeneratedTOBuilderImpl(returnTypePkgName, returnTypeName).toInstance(); + newType.setExtendsType(gto); + } + newType.setAbstract(true); + genCtx.get(module).addIdentityType(newType) + } + /** * Converts all groupings of the module to the list of * Type objects. Firstly are groupings sorted according mutual @@ -772,31 +568,19 @@ public class BindingGeneratorImpl implements BindingGenerator { * {@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 it = new DataNodeIterator(module); - val List groupings = it.allGroupings(); - val List groupingsSortedByDependencies = new GroupingDefinitionDependencySort().sort( - groupings); - - for (grouping : groupingsSortedByDependencies) { - val genType = groupingToGenType(basePackageName, grouping, module); - genTypes.add(genType); - genTypes.addAll(processUsesAugments(grouping, module)); - val schemaPath = grouping.path; - allGroupings.put(schemaPath, genType); - } - return genTypes; - } - + * current module + * @param collection of groupings from which types will be generated + * + */ + private def void groupingsToGenTypes(Module module, Collection groupings) { + val basePackageName = moduleNamespaceToPackageName(module); + val List groupingsSortedByDependencies = new GroupingDefinitionDependencySort().sort( + groupings); + for (grouping : groupingsSortedByDependencies) { + groupingToGenType(basePackageName, grouping, module); + } + } + /** * Converts individual grouping to GeneratedType. Firstly generated type * builder is created and every child node of grouping is resolved to the @@ -806,23 +590,19 @@ public class BindingGeneratorImpl implements BindingGenerator { * string contains the module package name * @param grouping * GroupingDefinition which contains data about grouping + * @param module current module * @return GeneratedType which is generated from grouping (object of type * GroupingDefinition) - */ - private def GeneratedType groupingToGenType(String basePackageName, GroupingDefinition grouping, Module module) { - if(grouping === null) { - return null; - } - - val packageName = packageNameForGeneratedType(basePackageName, grouping.path); - val Set schemaNodes = grouping.childNodes; - val typeBuilder = addDefaultInterfaceDefinition(packageName, grouping); - - resolveDataSchemaNodes(basePackageName, typeBuilder, schemaNodes); - - return typeBuilder.toInstance(); - } - + */ + private def void groupingToGenType(String basePackageName, GroupingDefinition grouping, Module module) { + val packageName = packageNameForGeneratedType(basePackageName, grouping.path); + val genType = addDefaultInterfaceDefinition(packageName, grouping); + genCtx.get(module).addGroupingType(grouping.path, genType) + resolveDataSchemaNodes(module, basePackageName, genType, genType, grouping.childNodes); + groupingsToGenTypes(module, grouping.groupings); + processUsesAugments(grouping, module); + } + /** * Tries to find EnumTypeDefinition in typeDefinition. If base * type of typeDefinition is of the type ExtendedType then this @@ -833,18 +613,18 @@ public class BindingGeneratorImpl implements BindingGenerator { * 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; - } - + */ + 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. @@ -861,21 +641,19 @@ public class BindingGeneratorImpl implements BindingGenerator { * 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; - } - + */ + 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. * @@ -889,15 +667,14 @@ public class BindingGeneratorImpl implements BindingGenerator { * 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); - } - + */ + 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 @@ -911,361 +688,289 @@ public class BindingGeneratorImpl implements BindingGenerator { * @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 + * @param module current module + * @param parentUsesNode parent uses node of this augment (can be null if this augment is not defined under uses statement) * @throws IllegalArgumentException *
      *
    • if augmentPackageName equals null
    • *
    • if augSchema equals null
    • *
    • if target path of augSchema equals null
    • *
    - */ - private def List augmentationToGenTypes(String augmentPackageName, AugmentationSchema augSchema, Module module, + */ + private def void augmentationToGenTypes(String augmentPackageName, AugmentationSchema augSchema, Module module, UsesNode parentUsesNode) { 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(); - genTypes.addAll(processUsesAugments(augSchema, module)); + + processUsesAugments(augSchema, module); // EVERY augmented interface will extends Augmentation interface - // and DataObject interface!!! + // and DataObject interface val targetPath = augSchema.targetPath; var targetSchemaNode = findDataSchemaNode(schemaContext, targetPath); - if (targetSchemaNode instanceof DataSchemaNode && (targetSchemaNode as DataSchemaNode).isAddedByUses()) { - if (parentUsesNode == null) { - targetSchemaNode = findOriginal(targetSchemaNode as DataSchemaNode); - } else { - targetSchemaNode = findOriginalTargetFromGrouping(targetSchemaNode.QName.localName, parentUsesNode); - } - if (targetSchemaNode == null) { - throw new NullPointerException( - "Failed to find target node from grouping for augmentation " + augSchema + " in module " + module.name); + if (targetSchemaNode instanceof DataSchemaNode && (targetSchemaNode as DataSchemaNode).isAddedByUses()) { + if (parentUsesNode == null) { + targetSchemaNode = findOriginal(targetSchemaNode as DataSchemaNode); + } else { + targetSchemaNode = findOriginalTargetFromGrouping(targetSchemaNode.QName.localName, parentUsesNode); + } + if (targetSchemaNode == null) { + throw new NullPointerException( + "Failed to find target node from grouping for augmentation " + augSchema + " in module " + + module.name); } } - + if (targetSchemaNode !== null) { - var targetType = yangToJavaMapping.get(targetSchemaNode.path); - if (targetType == null) { - // FIXME: augmentation should be added as last, all types should already be generated - // and have assigned Java Types, - val targetModule = findParentModule(schemaContext, targetSchemaNode); - val targetBasePackage = moduleNamespaceToPackageName(targetModule); - val typePackage = packageNameForGeneratedType(targetBasePackage, targetSchemaNode.getPath()); - val targetSchemaNodeName = targetSchemaNode.getQName().getLocalName(); - val typeName = parseToClassName(targetSchemaNodeName); - targetType = new ReferencedTypeImpl(typePackage, typeName); + var targetTypeBuilder = findChildNodeByPath(targetSchemaNode.path) + if (targetTypeBuilder === null) { + targetTypeBuilder = findCaseByPath(targetSchemaNode.path) + } + if (targetTypeBuilder === null) { + throw new NullPointerException("Target type not yet generated: " + targetSchemaNode); } - val augChildNodes = augSchema.childNodes; - if (!(targetSchemaNode instanceof ChoiceNode)) { var packageName = augmentPackageName; if (parentUsesNode != null) { packageName = packageNameForGeneratedType(augmentPackageName, augSchema.targetPath); } - val augTypeBuilder = addRawAugmentGenTypeDefinition(packageName, augmentPackageName, targetType, - augSchema); - val augType = augTypeBuilder.toInstance(); - genTypes.add(augType); + val augTypeBuilder = addRawAugmentGenTypeDefinition(module, packageName, augmentPackageName, + targetTypeBuilder.toInstance, augSchema); + genCtx.get(module).addAugmentType(augTypeBuilder) } else { - genTypes.addAll( - generateTypesFromAugmentedChoiceCases(augmentPackageName, targetType, augChildNodes, - targetSchemaNode as ChoiceNode)); + generateTypesFromAugmentedChoiceCases(module, augmentPackageName, targetTypeBuilder.toInstance, + targetSchemaNode as ChoiceNode, augSchema.childNodes); } - genTypes.addAll(augmentationBodyToGenTypes(augmentPackageName, augChildNodes, module)); } + } - return genTypes; - } - /** * Utility method which search for original node defined in grouping. - */ - private def DataSchemaNode findOriginal(DataSchemaNode node) { - var DataSchemaNode result = findCorrectTargetFromGrouping(node); - if (result == null) { - result = findCorrectTargetFromAugment(node); - if (result != null) { - if (result.addedByUses) { - result = findOriginal(result); - } - } - } - return result; - } - - private def DataSchemaNode findCorrectTargetFromAugment(DataSchemaNode node) { - if (!node.augmenting) { - return null; - } - - var String currentName = node.QName.localName; - var tmpPath = new ArrayList(); - var YangNode parent = node; - var AugmentationSchema augment = null; - do { - parent = (parent as DataSchemaNode).parent; - if (parent instanceof AugmentationTarget) { - tmpPath.add(currentName); - augment = findNodeInAugment((parent as AugmentationTarget).availableAugmentations, currentName); - if (augment == null) { - currentName = (parent as DataSchemaNode).QName.localName; - } - } - } while ((parent as DataSchemaNode).augmenting && augment == null); - - if (augment == null) { - return null; - } else { - Collections.reverse(tmpPath); - var Object actualParent = augment; - var DataSchemaNode result = null; - for (name : tmpPath) { - if (actualParent instanceof DataNodeContainer) { - result = (actualParent as DataNodeContainer).getDataChildByName(name); - actualParent = (actualParent as DataNodeContainer).getDataChildByName(name); - } else { - if (actualParent instanceof ChoiceNode) { - result = (actualParent as ChoiceNode).getCaseNodeByName(name); - actualParent = (actualParent as ChoiceNode).getCaseNodeByName(name); - } - } - } - - if (result.addedByUses) { - result = findCorrectTargetFromGrouping(result); - } - - return result; - } - } - - private def AugmentationSchema findNodeInAugment(Collection augments, String name) { - for (augment : augments) { - if (augment.getDataChildByName(name) != null) { - return augment; - } - } - return null; - } - - private def DataSchemaNode findCorrectTargetFromGrouping(DataSchemaNode node) { - if (node.path.path.size == 1) { + */ + private def DataSchemaNode findOriginal(DataSchemaNode node) { + var DataSchemaNode result = findCorrectTargetFromGrouping(node); + if (result == null) { + result = findCorrectTargetFromAugment(node); + if (result != null) { + if (result.addedByUses) { + result = findOriginal(result); + } + } + } + return result; + } + + private def DataSchemaNode findCorrectTargetFromAugment(DataSchemaNode node) { + if (!node.augmenting) { + return null; + } + + var String currentName = node.QName.localName; + var tmpPath = new ArrayList(); + var YangNode parent = node; + var AugmentationSchema augment = null; + do { + parent = (parent as DataSchemaNode).parent; + if (parent instanceof AugmentationTarget) { + tmpPath.add(currentName); + augment = findNodeInAugment((parent as AugmentationTarget).availableAugmentations, currentName); + if (augment == null) { + currentName = (parent as DataSchemaNode).QName.localName; + } + } + } while ((parent as DataSchemaNode).augmenting && augment == null); + + if (augment == null) { + return null; + } else { + Collections.reverse(tmpPath); + var Object actualParent = augment; + var DataSchemaNode result = null; + for (name : tmpPath) { + if (actualParent instanceof DataNodeContainer) { + result = (actualParent as DataNodeContainer).getDataChildByName(name); + actualParent = (actualParent as DataNodeContainer).getDataChildByName(name); + } else { + if (actualParent instanceof ChoiceNode) { + result = (actualParent as ChoiceNode).getCaseNodeByName(name); + actualParent = (actualParent as ChoiceNode).getCaseNodeByName(name); + } + } + } + + if (result.addedByUses) { + result = findCorrectTargetFromGrouping(result); + } + + return result; + } + } + + private def AugmentationSchema findNodeInAugment(Collection augments, String name) { + for (augment : augments) { + if (augment.getDataChildByName(name) != null) { + return augment; + } + } + return null; + } + + private def DataSchemaNode findCorrectTargetFromGrouping(DataSchemaNode node) { + if (node.path.path.size == 1) { + // uses is under module statement - val Module m = findParentModule(schemaContext, node); - var DataSchemaNode result = null; - for (u : m.uses) { - var SchemaNode targetGrouping = findNodeInSchemaContext(schemaContext, u.groupingPath.path); - if (!(targetGrouping instanceof GroupingDefinition)) { - throw new IllegalArgumentException("Failed to generate code for augment in " + u); - } - var gr = targetGrouping as GroupingDefinition; - result = gr.getDataChildByName(node.QName.localName); - } - if (result == null) { - throw new IllegalArgumentException("Failed to generate code for augment"); - } - return result; - } else { - var DataSchemaNode result = null; - var String currentName = node.QName.localName; - var tmpPath = new ArrayList(); - var YangNode parent = node.parent; - do { - tmpPath.add(currentName); - val dataNodeParent = parent as DataNodeContainer; - for (u : dataNodeParent.uses) { - var SchemaNode targetGrouping = findNodeInSchemaContext(schemaContext, u.groupingPath.path); - if (!(targetGrouping instanceof GroupingDefinition)) { - throw new IllegalArgumentException("Failed to generate code for augment in " + u); - } - var gr = targetGrouping as GroupingDefinition; - result = gr.getDataChildByName(currentName); - } - if (result == null) { - currentName = (parent as SchemaNode).QName.localName; - if (parent instanceof DataSchemaNode) { - parent = (parent as DataSchemaNode).parent; - } else { - parent = (parent as DataNodeContainer).parent; - } - } - } while (result == null && !(parent instanceof Module)); - - if (result != null) { - if (tmpPath.size == 1) { - return result; - } else { - var DataSchemaNode newParent = result; - Collections.reverse(tmpPath); - tmpPath.remove(0); - for (name : tmpPath) { - newParent = (newParent as DataNodeContainer).getDataChildByName(name); - } - return newParent; - } - } - - return result; - } - } - + val Module m = findParentModule(schemaContext, node); + var DataSchemaNode result = null; + for (u : m.uses) { + var SchemaNode targetGrouping = findNodeInSchemaContext(schemaContext, u.groupingPath.path); + if (!(targetGrouping instanceof GroupingDefinition)) { + throw new IllegalArgumentException("Failed to generate code for augment in " + u); + } + var gr = targetGrouping as GroupingDefinition; + result = gr.getDataChildByName(node.QName.localName); + } + if (result == null) { + throw new IllegalArgumentException("Failed to generate code for augment"); + } + return result; + } else { + var DataSchemaNode result = null; + var String currentName = node.QName.localName; + var tmpPath = new ArrayList(); + var YangNode parent = node.parent; + do { + tmpPath.add(currentName); + val dataNodeParent = parent as DataNodeContainer; + for (u : dataNodeParent.uses) { + var SchemaNode targetGrouping = findNodeInSchemaContext(schemaContext, u.groupingPath.path); + if (!(targetGrouping instanceof GroupingDefinition)) { + throw new IllegalArgumentException("Failed to generate code for augment in " + u); + } + var gr = targetGrouping as GroupingDefinition; + result = gr.getDataChildByName(currentName); + } + if (result == null) { + currentName = (parent as SchemaNode).QName.localName; + if (parent instanceof DataSchemaNode) { + parent = (parent as DataSchemaNode).parent; + } else { + parent = (parent as DataNodeContainer).parent; + } + } + } while (result == null && !(parent instanceof Module)); + + if (result != null) { + if (tmpPath.size == 1) { + return result; + } else { + var DataSchemaNode newParent = result; + Collections.reverse(tmpPath); + tmpPath.remove(0); + for (name : tmpPath) { + newParent = (newParent as DataNodeContainer).getDataChildByName(name); + } + return newParent; + } + } + + return result; + } + } + /** * Convenient method to find node added by uses statement. - */ - private def DataSchemaNode findOriginalTargetFromGrouping(String targetSchemaNodeName, UsesNode parentUsesNode) { - var SchemaNode targetGrouping = findNodeInSchemaContext(schemaContext, parentUsesNode.groupingPath.path); - if (!(targetGrouping instanceof GroupingDefinition)) { - throw new IllegalArgumentException("Failed to generate code for augment in " + parentUsesNode); - } - - var grouping = targetGrouping as GroupingDefinition; - var result = grouping.getDataChildByName(targetSchemaNodeName); - if (result == null) { - return null; - } - var boolean fromUses = result.addedByUses; - - var Iterator groupingUses = grouping.uses.iterator; - while (fromUses) { - if (groupingUses.hasNext()) { - grouping = findNodeInSchemaContext(schemaContext, groupingUses.next().groupingPath.path) as GroupingDefinition; - result = grouping.getDataChildByName(targetSchemaNodeName); - fromUses = result.addedByUses; - } else { - throw new NullPointerException("Failed to generate code for augment in " + parentUsesNode); - } - } - - return result; - } - + */ + private def DataSchemaNode findOriginalTargetFromGrouping(String targetSchemaNodeName, UsesNode parentUsesNode) { + var SchemaNode targetGrouping = findNodeInSchemaContext(schemaContext, parentUsesNode.groupingPath.path); + if (!(targetGrouping instanceof GroupingDefinition)) { + throw new IllegalArgumentException("Failed to generate code for augment in " + parentUsesNode); + } + + var grouping = targetGrouping as GroupingDefinition; + var result = grouping.getDataChildByName(targetSchemaNodeName); + if (result == null) { + return null; + } + var boolean fromUses = result.addedByUses; + + var Iterator groupingUses = grouping.uses.iterator; + while (fromUses) { + if (groupingUses.hasNext()) { + grouping = findNodeInSchemaContext(schemaContext, groupingUses.next().groupingPath.path) as GroupingDefinition; + result = grouping.getDataChildByName(targetSchemaNodeName); + fromUses = result.addedByUses; + } else { + throw new NullPointerException("Failed to generate code for augment in " + parentUsesNode); + } + } + + return result; + } + /** * Returns a generated type builder for an augmentation. * * The name of the type builder is equal to the name of augmented node with * serial number as suffix. * + * @param module current module * @param augmentPackageName * string with contains the package name to which the augment * belongs - * @param targetPackageName + * @param basePackageName * string with the package name to which the augmented node * belongs - * @param targetSchemaNodeName - * string with the name of the augmented node + * @param targetTypeRef + * target type * @param augSchema * augmentation schema which contains data about the child nodes * and uses of augment * @return generated type builder for augment - */ - private def GeneratedTypeBuilder addRawAugmentGenTypeDefinition(String augmentPackageName, String basePackageName, - Type targetTypeRef, AugmentationSchema augSchema) { - var Map augmentBuilders = genTypeBuilders.get(augmentPackageName); - if (augmentBuilders === null) { - augmentBuilders = new HashMap(); - genTypeBuilders.put(augmentPackageName, augmentBuilders); - } - val augIdentifier = getAugmentIdentifier(augSchema.unknownSchemaNodes); - - val augTypeName = if (augIdentifier !== null) { - parseToClassName(augIdentifier) - } else { - augGenTypeName(augmentBuilders, targetTypeRef.name); - } - - val augTypeBuilder = new GeneratedTypeBuilderImpl(augmentPackageName, augTypeName); - - augTypeBuilder.addImplementsType(DATA_OBJECT); - augTypeBuilder.addImplementsType(Types.augmentationTypeFor(targetTypeRef)); - addImplementedInterfaceFromUses(augSchema, augTypeBuilder); - - augSchemaNodeToMethods(basePackageName, augTypeBuilder, augSchema.childNodes); - augmentBuilders.put(augTypeName, augTypeBuilder); - return augTypeBuilder; - } - + */ + private def GeneratedTypeBuilder addRawAugmentGenTypeDefinition(Module module, String augmentPackageName, + String basePackageName, Type targetTypeRef, AugmentationSchema augSchema) { + var Map augmentBuilders = genTypeBuilders.get(augmentPackageName); + if (augmentBuilders === null) { + augmentBuilders = new HashMap(); + genTypeBuilders.put(augmentPackageName, augmentBuilders); + } + val augIdentifier = getAugmentIdentifier(augSchema.unknownSchemaNodes); + + val augTypeName = if (augIdentifier !== null) { + parseToClassName(augIdentifier) + } else { + augGenTypeName(augmentBuilders, targetTypeRef.name); + } + + val augTypeBuilder = new GeneratedTypeBuilderImpl(augmentPackageName, augTypeName); + + augTypeBuilder.addImplementsType(DATA_OBJECT); + augTypeBuilder.addImplementsType(Types.augmentationTypeFor(targetTypeRef)); + addImplementedInterfaceFromUses(augSchema, augTypeBuilder); + + augSchemaNodeToMethods(module, basePackageName, augTypeBuilder, augTypeBuilder, augSchema.childNodes); + augmentBuilders.put(augTypeName, augTypeBuilder); + return augTypeBuilder; + } + /** * * @param unknownSchemaNodes * @return nodeParameter of UnknownSchemaNode - */ - private def String getAugmentIdentifier(List unknownSchemaNodes) { - for (unknownSchemaNode : unknownSchemaNodes) { - val nodeType = unknownSchemaNode.nodeType; - if(AUGMENT_IDENTIFIER_NAME.equals(nodeType.localName) && - YANG_EXT_NAMESPACE.equals(nodeType.namespace.toString())) { - return unknownSchemaNode.nodeParameter; - } - } - return null; - } - - /** - * Convert a container, list and choice subnodes (and recursivelly their - * subnodes) of augment to generated types - * - * @param augBasePackageName - * string with the augment package name - * @param augChildNodes - * set of data schema nodes which represents child nodes of the - * augment - * - * @return list of Type which represents container, list and - * choice subnodes of augment - */ - private def List augmentationBodyToGenTypes(String augBasePackageName, Set augChildNodes, Module module) { - val List genTypes = new ArrayList(); - val List augSchemaIts = new ArrayList(); - for (childNode : augChildNodes) { - if (!childNode.addedByUses) { - - - if(childNode instanceof DataNodeContainer) { - augSchemaIts.add(new DataNodeIterator(childNode as DataNodeContainer)); - - if(childNode instanceof ContainerSchemaNode) { - genTypes.addAll(dataNodeContainerToGenType(augBasePackageName, childNode as ContainerSchemaNode, module)); - } else if(childNode instanceof ListSchemaNode) { - genTypes.addAll(dataNodeContainerToGenType(augBasePackageName, childNode as ListSchemaNode, module)); - } - } 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, module)); - } - - - } - } - - 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.addAll(dataNodeContainerToGenType(augBasePackageName, container, module)); - } - } - if(augLists !== null) { - for (list : augLists) { - genTypes.addAll(dataNodeContainerToGenType(augBasePackageName, list, module)); - } - } - if(augChoices !== null) { - for (choice : augChoices) { - genTypes.addAll(choiceToGeneratedType(augBasePackageName, choice, module)); - } - } - } - return genTypes; - } - + */ + private def String getAugmentIdentifier(List unknownSchemaNodes) { + for (unknownSchemaNode : unknownSchemaNodes) { + val nodeType = unknownSchemaNode.nodeType; + if (AUGMENT_IDENTIFIER_NAME.equals(nodeType.localName) && + YANG_EXT_NAMESPACE.equals(nodeType.namespace.toString())) { + return unknownSchemaNode.nodeParameter; + } + } + return null; + } + /** * Returns first unique name for the augment generated type builder. The * generated type builder name for augment consists from name of augmented @@ -1277,15 +982,15 @@ public class BindingGeneratorImpl implements BindingGenerator { * @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; - } - + */ + private def String augGenTypeName(Map builders, String genTypeName) { + var index = 1; + while ((builders !== null) && builders.containsKey(genTypeName + index)) { + index = index + 1; + } + return genTypeName + index; + } + /** * Adds the methods to typeBuilder which represent subnodes of * node for which typeBuilder was created. @@ -1293,49 +998,39 @@ public class BindingGeneratorImpl implements BindingGenerator { * The subnodes aren't mapped to the methods if they are part of grouping or * augment (in this case are already part of them). * + * @param module current module * @param basePackageName * string contains the module package name - * @param typeBuilder + * @param parent * generated type builder which represents any node. The subnodes * of this node are added to the typeBuilder as * methods. The subnode can be of type leaf, leaf-list, list, * container, choice. + * @param childOf parent type * @param schemaNodes * set of data schema nodes which are the children of the node * for which typeBuilder was created * @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; - } - - private def GeneratedTypeBuilder resolveDataSchemaNodesAugmented(String basePackageName, GeneratedTypeBuilder typeBuilder, - Set schemaNodes) { - if ((schemaNodes !== null) && (typeBuilder !== null)) { - for (schemaNode : schemaNodes) { - if (!schemaNode.isAddedByUses()) { - addSchemaNodeToBuilderAsMethod(basePackageName, schemaNode, typeBuilder); - } - } - } - return typeBuilder; - } - + */ + private def GeneratedTypeBuilder resolveDataSchemaNodes(Module module, String basePackageName, + GeneratedTypeBuilder parent, GeneratedTypeBuilder childOf, Set schemaNodes) { + if ((schemaNodes !== null) && (parent !== null)) { + for (schemaNode : schemaNodes) { + if (!schemaNode.augmenting && !schemaNode.addedByUses) { + addSchemaNodeToBuilderAsMethod(basePackageName, schemaNode, parent, childOf, module); + } + } + } + return parent; + } + /** * Adds the methods to typeBuilder what represents subnodes of * node for which typeBuilder was created. * + * @param module current module * @param basePackageName * string contains the module package name * @param typeBuilder @@ -1343,95 +1038,59 @@ public class BindingGeneratorImpl implements BindingGenerator { * of this node are added to the typeBuilder as * methods. The subnode can be of type leaf, leaf-list, list, * container, choice. + * @param childOf parent type * @param schemaNodes * set of data schema nodes which are the children of the node * for which typeBuilder was created * @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; - } - + */ + private def GeneratedTypeBuilder augSchemaNodeToMethods(Module module, String basePackageName, + GeneratedTypeBuilder typeBuilder, GeneratedTypeBuilder childOf, Set schemaNodes) { + if ((schemaNodes !== null) && (typeBuilder !== null)) { + for (schemaNode : schemaNodes) { + if (!schemaNode.isAugmenting()) { + addSchemaNodeToBuilderAsMethod(basePackageName, schemaNode, typeBuilder, childOf, module); + } + } + } + return typeBuilder; + } + /** * Adds to typeBuilder a method which is derived from * schemaNode. * * @param basePackageName * string with the module package name - * @param schemaNode + * @param node * data schema node which is added to typeBuilder as * a method * @param typeBuilder * generated type builder to which is schemaNode * added as a method. - */ - 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); - } - } - + * @param childOf parent type + * @param module current module + */ + private def void addSchemaNodeToBuilderAsMethod(String basePackageName, DataSchemaNode node, + GeneratedTypeBuilder typeBuilder, GeneratedTypeBuilder childOf, Module module) { + if (node !== null && typeBuilder !== null) { + switch (node) { + case node instanceof LeafSchemaNode: + resolveLeafSchemaNodeAsMethod(typeBuilder, node as LeafSchemaNode) + case node instanceof LeafListSchemaNode: + resolveLeafListSchemaNode(typeBuilder, node as LeafListSchemaNode) + case node instanceof ContainerSchemaNode: + containerToGenType(module, basePackageName, typeBuilder, childOf, node as ContainerSchemaNode) + case node instanceof ListSchemaNode: + listToGenType(module, basePackageName, typeBuilder, childOf, node as ListSchemaNode) + case node instanceof ChoiceNode: + choiceToGeneratedType(module, basePackageName, typeBuilder, node as ChoiceNode) + } + } + } + /** * Converts choiceNode to the list of generated types for * choice and its cases. @@ -1440,40 +1099,34 @@ public class BindingGeneratorImpl implements BindingGenerator { * concatenation of the module package (basePackageName) and * names of all parents node. * + * @param module current module * @param basePackageName * string with the module package name + * @param parent parent type + * @param childOf concrete parent for case child nodes * @param choiceNode * choice node which is mapped to generated type. Also child * nodes - cases are mapped to generated types. - * @return list of generated types which contains generated type for choice - * and generated types for all cases which aren't added do choice - * through uses. * @throws IllegalArgumentException *
      *
    • if basePackageName equals null
    • *
    • if choiceNode equals null
    • *
    * - */ - private def List choiceToGeneratedType(String basePackageName, ChoiceNode choiceNode, Module module) { - 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(DataContainer.typeForClass); - val choiceType = choiceTypeBuilder.toInstance(); - - generatedTypes.add(choiceType); - val Set caseNodes = choiceNode.cases; - if((caseNodes !== null) && !caseNodes.isEmpty()) { - generatedTypes.addAll(generateTypesFromChoiceCases(basePackageName, choiceType, caseNodes, module)); - } - return generatedTypes; - } - + */ + private def void choiceToGeneratedType(Module module, String basePackageName, GeneratedTypeBuilder parent, + ChoiceNode choiceNode) { + checkArgument(basePackageName !== null, "Base Package Name cannot be NULL."); + checkArgument(choiceNode !== null, "Choice Schema Node cannot be NULL."); + + val packageName = packageNameForGeneratedType(basePackageName, choiceNode.path); + val choiceTypeBuilder = addRawInterfaceDefinition(packageName, choiceNode); + constructGetter(parent, choiceNode.QName.localName, choiceNode.description, choiceTypeBuilder); + choiceTypeBuilder.addImplementsType(DataContainer.typeForClass); + genCtx.get(module).addChildNodeType(choiceNode.path, choiceTypeBuilder) + generateTypesFromChoiceCases(module, basePackageName, parent, choiceTypeBuilder.toInstance, choiceNode); + } + /** * Converts caseNodes set to list of corresponding generated * types. @@ -1499,33 +1152,54 @@ public class BindingGeneratorImpl implements BindingGenerator { *
  • if caseNodes equals null
  • * * * - */ - private def List generateTypesFromChoiceCases(String basePackageName, Type refChoiceType, - Set caseNodes, Module module) { - 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()); - } - - generatedTypes.addAll(processUsesAugments(caseNode, module)); - } - - return generatedTypes; - } - + */ + private def void generateTypesFromChoiceCases(Module module, String basePackageName, + GeneratedTypeBuilder choiceParent, Type refChoiceType, ChoiceNode choiceNode) { + checkArgument(basePackageName !== null, "Base Package Name cannot be NULL."); + checkArgument(refChoiceType !== null, "Referenced Choice Type cannot be NULL."); + checkArgument(choiceNode !== null, "ChoiceNode cannot be NULL."); + + val Set caseNodes = choiceNode.cases; + if (caseNodes == null) { + return + } + + for (caseNode : caseNodes) { + if (caseNode !== null && !caseNode.isAddedByUses() && !caseNode.isAugmenting()) { + val packageName = packageNameForGeneratedType(basePackageName, caseNode.path); + val caseTypeBuilder = addDefaultInterfaceDefinition(packageName, caseNode); + caseTypeBuilder.addImplementsType(refChoiceType); + genCtx.get(module).addCaseType(caseNode.path, caseTypeBuilder) + val Set caseChildNodes = caseNode.childNodes; + if (caseChildNodes !== null) { + val parentNode = choiceNode.parent; + var SchemaNode parent; + if (parentNode instanceof AugmentationSchema) { + val augSchema = parentNode as AugmentationSchema; + val targetPath = augSchema.targetPath; + var targetSchemaNode = findDataSchemaNode(schemaContext, targetPath); + if (targetSchemaNode instanceof DataSchemaNode && + (targetSchemaNode as DataSchemaNode).isAddedByUses()) { + targetSchemaNode = findOriginal(targetSchemaNode as DataSchemaNode); + if (targetSchemaNode == null) { + throw new NullPointerException( + "Failed to find target node from grouping for augmentation " + augSchema + + " in module " + module.name); + } + } + parent = targetSchemaNode as SchemaNode + } else { + parent = choiceNode.parent as SchemaNode; + } + var GeneratedTypeBuilder childOfType = findChildNodeByPath(parent.path) + resolveDataSchemaNodes(module, basePackageName, caseTypeBuilder, childOfType, caseChildNodes); + } + } + + processUsesAugments(caseNode, module); + } + } + /** * Generates list of generated types for all the cases of a choice which are * added to the choice through the augment. @@ -1550,41 +1224,55 @@ public class BindingGeneratorImpl implements BindingGenerator { *
  • if refChoiceType equals null
  • *
  • if caseNodes equals null
  • * - */ - private def List generateTypesFromAugmentedChoiceCases(String basePackageName, Type refChoiceType, - Set caseNodes, ChoiceNode targetNode) { - 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) { - val packageName = packageNameForGeneratedType(basePackageName, caseNode.path); - val caseTypeBuilder = addDefaultInterfaceDefinition(packageName, caseNode); - caseTypeBuilder.addImplementsType(refChoiceType); - - if (caseNode instanceof DataNodeContainer) { - val DataNodeContainer dataNodeCase = caseNode as DataNodeContainer; - val Set childNodes = dataNodeCase.childNodes; - if(childNodes !== null) { - resolveDataSchemaNodesAugmented(basePackageName, caseTypeBuilder, childNodes); - } - } else { - val ChoiceCaseNode node = targetNode.getCaseNodeByName(caseNode.getQName().getLocalName()); - val Set childNodes = node.childNodes; - if(childNodes !== null) { - resolveDataSchemaNodesAugmented(basePackageName, caseTypeBuilder, childNodes); - } - } - - generatedTypes.add(caseTypeBuilder.toInstance()); - } - } - - return generatedTypes; - } - + */ + private def void generateTypesFromAugmentedChoiceCases(Module module, String basePackageName, Type targetType, + ChoiceNode targetNode, Set augmentedNodes) { + checkArgument(basePackageName !== null, "Base Package Name cannot be NULL."); + checkArgument(targetType !== null, "Referenced Choice Type cannot be NULL."); + checkArgument(augmentedNodes !== null, "Set of Choice Case Nodes cannot be NULL."); + + for (caseNode : augmentedNodes) { + if (caseNode !== null) { + val packageName = packageNameForGeneratedType(basePackageName, caseNode.path); + val caseTypeBuilder = addDefaultInterfaceDefinition(packageName, caseNode); + caseTypeBuilder.addImplementsType(targetType); + + val SchemaNode parent = targetNode.parent as SchemaNode; + var GeneratedTypeBuilder childOfType = null; + if (parent instanceof Module) { + childOfType = genCtx.get(parent as Module).moduleNode + } else if (parent instanceof ChoiceCaseNode) { + childOfType = findCaseByPath(parent.path) + } else if (parent instanceof DataSchemaNode || parent instanceof NotificationDefinition) { + childOfType = findChildNodeByPath(parent.path) + } else if (parent instanceof GroupingDefinition) { + childOfType = findGroupingByPath(parent.path); + } + + if (childOfType == null) { + throw new IllegalArgumentException("Failed to find parent type of choice " + targetNode); + } + + if (caseNode instanceof DataNodeContainer) { + val DataNodeContainer dataNodeCase = caseNode as DataNodeContainer; + val Set childNodes = dataNodeCase.childNodes; + if (childNodes !== null) { + resolveDataSchemaNodes(module, basePackageName, caseTypeBuilder, childOfType, childNodes); + } + } else { + val ChoiceCaseNode node = targetNode.getCaseNodeByName(caseNode.getQName().getLocalName()); + val Set childNodes = node.childNodes; + if (childNodes !== null) { + resolveDataSchemaNodes(module, basePackageName, caseTypeBuilder, childOfType, childNodes); + } + } + + genCtx.get(module).addCaseType(caseNode.path, caseTypeBuilder) + } + } + + } + /** * Converts leaf to the getter method which is added to * typeBuilder. @@ -1601,105 +1289,108 @@ public class BindingGeneratorImpl implements BindingGenerator { * 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 = typeDef as EnumTypeDefinition; - val enumBuilder = resolveInnerEnumFromTypeDefinition(enumTypeDef, leafName, typeBuilder); - - if(enumBuilder !== null) { - returnType = new ReferencedTypeImpl(enumBuilder.packageName, enumBuilder.name); - } - (typeProvider as TypeProviderImpl).putReferencedType(leaf.path, returnType); - } else if(typeDef instanceof UnionType) { - val genTOBuilder = addTOToTypeBuilder(typeDef, typeBuilder, leafName, leaf, parentModule); - if(genTOBuilder !== null) { - returnType = new ReferencedTypeImpl(genTOBuilder.packageName, genTOBuilder.name); - } - } else if(typeDef instanceof BitsTypeDefinition) { - val genTOBuilder = addTOToTypeBuilder(typeDef, typeBuilder, leafName, leaf, parentModule); - if(genTOBuilder !== null) { - returnType = new ReferencedTypeImpl(genTOBuilder.packageName, genTOBuilder.name); - } - } else { - returnType = typeProvider.javaTypeForSchemaDefinitionType(typeDef, leaf); - } - if(returnType !== null) { - val MethodSignatureBuilder getter = constructGetter(typeBuilder, leafName, leafDesc, returnType); - processContextRefExtension(leaf, getter, parentModule); - return true; - } - } - } - return false; - } - - private def void processContextRefExtension(LeafSchemaNode leaf, MethodSignatureBuilder getter, Module module) { - for (node : leaf.unknownSchemaNodes) { - val nodeType = node.nodeType; - if ("context-reference".equals(nodeType.localName)) { - val nodeParam = node.nodeParameter; - var IdentitySchemaNode identity = null; - var String basePackageName = null; - val String[] splittedElement = nodeParam.split(":"); - if (splittedElement.length == 1) { - identity = findIdentityByName(module.identities, splittedElement.get(0)); - basePackageName = moduleNamespaceToPackageName(module); - } else if (splittedElement.length == 2) { - var prefix = splittedElement.get(0); - val Module dependentModule = findModuleFromImports(module.imports, prefix) - if (dependentModule == null) { - throw new IllegalArgumentException("Failed to process context-reference: unknown prefix " + prefix); - } - identity = findIdentityByName(dependentModule.identities, splittedElement.get(1)); - basePackageName = moduleNamespaceToPackageName(dependentModule); - } else { - throw new IllegalArgumentException("Failed to process context-reference: unknown identity " + nodeParam); - } - if (identity == null) { - throw new IllegalArgumentException("Failed to process context-reference: unknown identity " + nodeParam); - } - - val Class clazz = typeof(RoutingContext); - val AnnotationTypeBuilder rc = getter.addAnnotation(clazz.package.name, clazz.simpleName); - val packageName = packageNameForGeneratedType(basePackageName, identity.path); - val genTypeName = parseToClassName(identity.QName.localName); - rc.addParameter("value", packageName + "." + genTypeName + ".class"); - } - } - } - - private def IdentitySchemaNode findIdentityByName(Set identities, String name) { - for (id : identities) { - if (id.QName.localName.equals(name)) { - return id; - } - } - return null; - } - - private def Module findModuleFromImports(Set imports, String prefix) { - for (imp : imports) { - if (imp.prefix.equals(prefix)) { - return schemaContext.findModuleByName(imp.moduleName, imp.revision); - } - } - return null; - } - + */ + private def boolean resolveLeafSchemaNodeAsMethod(GeneratedTypeBuilder typeBuilder, LeafSchemaNode leaf) { + if ((leaf !== null) && (typeBuilder !== null)) { + val leafName = leaf.QName.localName; + var String leafDesc = leaf.description; + if (leafDesc === null) { + leafDesc = ""; + } + + val parentModule = findParentModule(schemaContext, leaf); + if (leafName !== null && !leaf.isAddedByUses()) { + val TypeDefinition typeDef = leaf.type; + + var Type returnType = null; + if (typeDef instanceof EnumTypeDefinition) { + returnType = typeProvider.javaTypeForSchemaDefinitionType(typeDef, leaf); + val enumTypeDef = typeDef as EnumTypeDefinition; + val enumBuilder = resolveInnerEnumFromTypeDefinition(enumTypeDef, leafName, typeBuilder); + + if (enumBuilder !== null) { + returnType = new ReferencedTypeImpl(enumBuilder.packageName, enumBuilder.name); + } + (typeProvider as TypeProviderImpl).putReferencedType(leaf.path, returnType); + } else if (typeDef instanceof UnionType) { + val genTOBuilder = addTOToTypeBuilder(typeDef, typeBuilder, leafName, leaf, parentModule); + if (genTOBuilder !== null) { + returnType = new ReferencedTypeImpl(genTOBuilder.packageName, genTOBuilder.name); + } + } else if (typeDef instanceof BitsTypeDefinition) { + val genTOBuilder = addTOToTypeBuilder(typeDef, typeBuilder, leafName, leaf, parentModule); + if (genTOBuilder !== null) { + returnType = new ReferencedTypeImpl(genTOBuilder.packageName, genTOBuilder.name); + } + } else { + returnType = typeProvider.javaTypeForSchemaDefinitionType(typeDef, leaf); + } + if (returnType !== null) { + val MethodSignatureBuilder getter = constructGetter(typeBuilder, leafName, leafDesc, returnType); + processContextRefExtension(leaf, getter, parentModule); + return true; + } + } + } + return false; + } + + private def void processContextRefExtension(LeafSchemaNode leaf, MethodSignatureBuilder getter, Module module) { + for (node : leaf.unknownSchemaNodes) { + val nodeType = node.nodeType; + if ("context-reference".equals(nodeType.localName)) { + val nodeParam = node.nodeParameter; + var IdentitySchemaNode identity = null; + var String basePackageName = null; + val String[] splittedElement = nodeParam.split(":"); + if (splittedElement.length == 1) { + identity = findIdentityByName(module.identities, splittedElement.get(0)); + basePackageName = moduleNamespaceToPackageName(module); + } else if (splittedElement.length == 2) { + var prefix = splittedElement.get(0); + val Module dependentModule = findModuleFromImports(module.imports, prefix) + if (dependentModule == null) { + throw new IllegalArgumentException( + "Failed to process context-reference: unknown prefix " + prefix); + } + identity = findIdentityByName(dependentModule.identities, splittedElement.get(1)); + basePackageName = moduleNamespaceToPackageName(dependentModule); + } else { + throw new IllegalArgumentException( + "Failed to process context-reference: unknown identity " + nodeParam); + } + if (identity == null) { + throw new IllegalArgumentException( + "Failed to process context-reference: unknown identity " + nodeParam); + } + + val Class clazz = typeof(RoutingContext); + val AnnotationTypeBuilder rc = getter.addAnnotation(clazz.package.name, clazz.simpleName); + val packageName = packageNameForGeneratedType(basePackageName, identity.path); + val genTypeName = parseToClassName(identity.QName.localName); + rc.addParameter("value", packageName + "." + genTypeName + ".class"); + } + } + } + + private def IdentitySchemaNode findIdentityByName(Set identities, String name) { + for (id : identities) { + if (id.QName.localName.equals(name)) { + return id; + } + } + return null; + } + + private def Module findModuleFromImports(Set imports, String prefix) { + for (imp : imports) { + if (imp.prefix.equals(prefix)) { + return schemaContext.findModuleByName(imp.moduleName, imp.revision); + } + } + return null; + } + /** * Converts leaf schema node to property of generated TO * builder. @@ -1718,40 +1409,40 @@ public class BindingGeneratorImpl implements BindingGenerator { * 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) { - val TypeDefinition typeDef = leaf.type; - + */ + 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) { + 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; - } - + 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. @@ -1768,109 +1459,28 @@ public class BindingGeneratorImpl implements BindingGenerator { * 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; - } - + */ + 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; + } + + private def GeneratedTypeBuilder addDefaultInterfaceDefinition(String packageName, SchemaNode schemaNode) { + return addDefaultInterfaceDefinition(packageName, schemaNode, null); + } + /** * Instantiates generated type builder with packageName and * schemaNode. @@ -1890,22 +1500,28 @@ public class BindingGeneratorImpl implements BindingGenerator { * schemaNode belongs. * @param schemaNode * schema node for which is created generated type builder + * @param parent parent type (can be null) * @return generated type builder schemaNode - */ - private def GeneratedTypeBuilder addDefaultInterfaceDefinition(String packageName, SchemaNode schemaNode) { - val builder = addRawInterfaceDefinition(packageName, schemaNode, ""); - builder.addImplementsType(DATA_OBJECT); - if(!(schemaNode instanceof GroupingDefinition)) { - builder.addImplementsType(augmentable(builder)); - } - - if(schemaNode instanceof DataNodeContainer) { - addImplementedInterfaceFromUses(schemaNode as DataNodeContainer, builder); - } - - return builder; - } - + */ + private def GeneratedTypeBuilder addDefaultInterfaceDefinition(String packageName, SchemaNode schemaNode, + Type parent) { + val builder = addRawInterfaceDefinition(packageName, schemaNode, ""); + if (parent === null) { + builder.addImplementsType(DATA_OBJECT); + } else { + builder.addImplementsType(BindingTypes.childOf(parent)); + } + 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. * @@ -1915,11 +1531,11 @@ public class BindingGeneratorImpl implements BindingGenerator { * @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, ""); - } - + */ + private def GeneratedTypeBuilder addRawInterfaceDefinition(String packageName, SchemaNode schemaNode) { + return addRawInterfaceDefinition(packageName, schemaNode, ""); + } + /** * Returns reference to generated type builder for specified * schemaNode with packageName. @@ -1933,6 +1549,7 @@ public class BindingGeneratorImpl implements BindingGenerator { * builder belongs * @param schemaNode * schema node which provide data about the schema node name + * @param prefix return type name prefix * @return generated type builder for schemaNode * @throws IllegalArgumentException *
      @@ -1942,57 +1559,57 @@ public class BindingGeneratorImpl implements BindingGenerator { *
    • 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); - } - + */ + 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; - } - + val newType = new GeneratedTypeBuilderImpl(packageName, genTypeName); + if (!genTypeBuilders.containsKey(packageName)) { + val Map builders = new HashMap(); + builders.put(genTypeName, newType); + genTypeBuilders.put(packageName, builders); + } else { + val Map builders = genTypeBuilders.get(packageName); + if (!builders.containsKey(genTypeName)) { + builders.put(genTypeName, newType); + } + } + return newType; + } + /** * Creates the name of the getter method from methodName. * * @param methodName * string with the name of the getter method + * @param returnType return type * @return string with the name of the getter method for * methodName in JAVA method format - */ - private def String getterMethodName(String methodName, Type returnType) { - val method = new StringBuilder(); - if(BOOLEAN.equals(returnType)) { - method.append("is"); - } else { - method.append("get"); - } - method.append(parseToClassName(methodName)); - return method.toString(); - } - + */ + 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. @@ -2013,18 +1630,15 @@ public class BindingGeneratorImpl implements BindingGenerator { * 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 MethodSignatureBuilder constructGetter(GeneratedTypeBuilder interfaceBuilder, String schemaNodeName, + String comment, Type returnType) { + val getMethod = interfaceBuilder.addMethod(getterMethodName(schemaNodeName, returnType)); + getMethod.setComment(comment); + getMethod.setReturnType(returnType); + return getMethod; + } + /** * Adds schemaNode to typeBuilder as getter method * or to genTOBuilder as property. @@ -2041,52 +1655,49 @@ public class BindingGeneratorImpl implements BindingGenerator { * generated TO builder for the list keys * @param listKeys * list of string which contains names of the list keys + * @param module current module * @throws IllegalArgumentException *
      *
    • if schemaNode equals null
    • *
    • if typeBuilder equals null
    • *
    - */ - private def void addSchemaNodeToListBuilders(String basePackageName, DataSchemaNode schemaNode, - GeneratedTypeBuilder typeBuilder, GeneratedTOBuilder genTOBuilder, List listKeys) { - checkArgument(schemaNode !== null, "Data Schema Node cannot be NULL."); - - checkArgument(typeBuilder !== null, "Generated Type Builder cannot be NULL."); - - if(schemaNode instanceof LeafSchemaNode) { - val leaf = schemaNode as LeafSchemaNode; - val leafName = leaf.QName.localName; - if(!listKeys.contains(leafName)) { - resolveLeafSchemaNodeAsMethod(typeBuilder, leaf); - } else { - resolveLeafSchemaNodeAsProperty(genTOBuilder, leaf, true); - } - } else if (!schemaNode.addedByUses) { - if (schemaNode instanceof LeafListSchemaNode) { - resolveLeafListSchemaNode(typeBuilder, schemaNode as LeafListSchemaNode); - } else if(schemaNode instanceof ContainerSchemaNode) { - resolveContainerSchemaNode(basePackageName, typeBuilder, schemaNode as ContainerSchemaNode); - } else if(schemaNode instanceof ChoiceNode) { - resolveChoiceSchemaNode(basePackageName,typeBuilder,schemaNode as ChoiceNode); - } else if(schemaNode instanceof ListSchemaNode) { - resolveListSchemaNode(basePackageName, typeBuilder, schemaNode as ListSchemaNode); - } - } - } - - private def typeBuildersToGenTypes(GeneratedTypeBuilder typeBuilder, GeneratedTOBuilder genTOBuilder) { - val List genTypes = new ArrayList(); - checkArgument(typeBuilder !== null, "Generated Type Builder cannot be NULL."); - - if(genTOBuilder !== null) { - val genTO = genTOBuilder.toInstance(); - constructGetter(typeBuilder, "key", "Returns Primary Key of Yang List Type", genTO); - genTypes.add(genTO); - } - genTypes.add(typeBuilder.toInstance()); - return genTypes; - } - + */ + private def void addSchemaNodeToListBuilders(String basePackageName, DataSchemaNode schemaNode, + GeneratedTypeBuilder typeBuilder, GeneratedTOBuilder genTOBuilder, List listKeys, Module module) { + checkArgument(schemaNode !== null, "Data Schema Node cannot be NULL."); + checkArgument(typeBuilder !== null, "Generated Type Builder cannot be NULL."); + + if (schemaNode instanceof LeafSchemaNode) { + val leaf = schemaNode as LeafSchemaNode; + val leafName = leaf.QName.localName; + if (!listKeys.contains(leafName)) { + resolveLeafSchemaNodeAsMethod(typeBuilder, leaf); + } else { + resolveLeafSchemaNodeAsProperty(genTOBuilder, leaf, true); + } + } else if (!schemaNode.addedByUses) { + if (schemaNode instanceof LeafListSchemaNode) { + resolveLeafListSchemaNode(typeBuilder, schemaNode as LeafListSchemaNode); + } else if (schemaNode instanceof ContainerSchemaNode) { + containerToGenType(module, basePackageName, typeBuilder, typeBuilder, schemaNode as ContainerSchemaNode); + } else if (schemaNode instanceof ChoiceNode) { + choiceToGeneratedType(module, basePackageName, typeBuilder, schemaNode as ChoiceNode); + } else if (schemaNode instanceof ListSchemaNode) { + listToGenType(module, basePackageName, typeBuilder, typeBuilder, schemaNode as ListSchemaNode); + } + } + } + + private def typeBuildersToGenTypes(Module module, GeneratedTypeBuilder typeBuilder, GeneratedTOBuilder genTOBuilder) { + checkArgument(typeBuilder !== null, "Generated Type Builder cannot be NULL."); + + if (genTOBuilder !== null) { + val genTO = genTOBuilder.toInstance(); + constructGetter(typeBuilder, "key", "Returns Primary Key of Yang List Type", genTO); + genCtx.get(module).addGeneratedTOBuilder(genTOBuilder) + } + } + /** * Selects the names of the list keys from list and returns * them as the list of the strings @@ -2096,19 +1707,19 @@ public class BindingGeneratorImpl implements BindingGenerator { * @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; - } - + */ + 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. @@ -2120,20 +1731,19 @@ public class BindingGeneratorImpl implements BindingGenerator { * @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"; - val String genTOName = parseToClassName(listName); - genTOBuilder = new GeneratedTOBuilderImpl(packageName, genTOName); - } - } - return genTOBuilder; - - } - + */ + private def GeneratedTOBuilder resolveListKeyTOBuilder(String packageName, ListSchemaNode list) { + var GeneratedTOBuilder genTOBuilder = null; + if ((list.keyDefinition !== null) && (!list.keyDefinition.isEmpty())) { + if (list !== null) { + val listName = list.QName.localName + "Key"; + val String genTOName = parseToClassName(listName); + genTOBuilder = new GeneratedTOBuilderImpl(packageName, genTOName); + } + } + return genTOBuilder; + } + /** * Builds generated TO builders for typeDef of type * {@link org.opendaylight.yangtools.yang.model.util.UnionType UnionType} or @@ -2153,33 +1763,35 @@ public class BindingGeneratorImpl implements BindingGenerator { * from typeDef * @param leafName * string with name for generated TO builder + * @param leaf + * @param parentModule * @return generated TO builder for typeDef - */ - private def GeneratedTOBuilder addTOToTypeBuilder(TypeDefinition typeDef, GeneratedTypeBuilder typeBuilder, - String leafName, LeafSchemaNode leaf, Module parentModule) { - val classNameFromLeaf = parseToClassName(leafName); - val List genTOBuilders = new ArrayList(); - val packageName = typeBuilder.fullyQualifiedName; - if(typeDef instanceof UnionTypeDefinition) { - genTOBuilders.addAll( - (typeProvider as TypeProviderImpl). - provideGeneratedTOBuildersForUnionTypeDef(packageName, (typeDef as UnionTypeDefinition), - classNameFromLeaf, leaf)); - } else if(typeDef instanceof BitsTypeDefinition) { - genTOBuilders.add( - ((typeProvider as TypeProviderImpl) ). - provideGeneratedTOBuilderForBitsTypeDefinition(packageName, typeDef, classNameFromLeaf)); - } - if(genTOBuilders !== null && !genTOBuilders.isEmpty()) { - for (genTOBuilder : genTOBuilders) { - typeBuilder.addEnclosingTransferObject(genTOBuilder); - } - return genTOBuilders.get(0); - } - return null; - - } - + */ + private def GeneratedTOBuilder addTOToTypeBuilder(TypeDefinition typeDef, GeneratedTypeBuilder typeBuilder, + String leafName, LeafSchemaNode leaf, Module parentModule) { + val classNameFromLeaf = parseToClassName(leafName); + val List genTOBuilders = new ArrayList(); + val packageName = typeBuilder.fullyQualifiedName; + if (typeDef instanceof UnionTypeDefinition) { + genTOBuilders.addAll( + (typeProvider as TypeProviderImpl). + provideGeneratedTOBuildersForUnionTypeDef(packageName, (typeDef as UnionTypeDefinition), + classNameFromLeaf, leaf)); + } else if (typeDef instanceof BitsTypeDefinition) { + genTOBuilders.add( + ((typeProvider as TypeProviderImpl) ). + provideGeneratedTOBuilderForBitsTypeDefinition(packageName, typeDef, classNameFromLeaf)); + } + if (genTOBuilders !== null && !genTOBuilders.isEmpty()) { + for (genTOBuilder : genTOBuilders) { + typeBuilder.addEnclosingTransferObject(genTOBuilder); + } + return genTOBuilders.get(0); + } + return null; + + } + /** * Adds the implemented types to type builder. * @@ -2195,18 +1807,49 @@ public class BindingGeneratorImpl implements BindingGenerator { * 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; - } -} + */ + private def addImplementedInterfaceFromUses(DataNodeContainer dataNodeContainer, GeneratedTypeBuilder builder) { + for (usesNode : dataNodeContainer.uses) { + if (usesNode.groupingPath !== null) { + val genType = findGroupingByPath(usesNode.groupingPath).toInstance + if (genType === null) { + throw new IllegalStateException( + "Grouping " + usesNode.groupingPath + "is not resolved for " + builder.name); + } + builder.addImplementsType(genType); + } + } + return builder; + } + + private def GeneratedTypeBuilder findChildNodeByPath(SchemaPath path) { + for (ctx : genCtx.values) { + var result = ctx.getChildNode(path) + if (result !== null) { + return result + } + } + return null + } + + private def GeneratedTypeBuilder findGroupingByPath(SchemaPath path) { + for (ctx : genCtx.values) { + var result = ctx.getGrouping(path) + if (result !== null) { + return result + } + } + return null + } + + private def GeneratedTypeBuilder findCaseByPath(SchemaPath path) { + for (ctx : genCtx.values) { + var result = ctx.getCase(path) + if (result !== null) { + return result + } + } + return null + } + +} diff --git a/code-generator/binding-generator-impl/src/main/java/org/opendaylight/yangtools/sal/binding/generator/impl/ModuleContext.java b/code-generator/binding-generator-impl/src/main/java/org/opendaylight/yangtools/sal/binding/generator/impl/ModuleContext.java new file mode 100644 index 0000000000..592b98e908 --- /dev/null +++ b/code-generator/binding-generator-impl/src/main/java/org/opendaylight/yangtools/sal/binding/generator/impl/ModuleContext.java @@ -0,0 +1,122 @@ +/* + * 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.HashMap; +import java.util.HashSet; +import java.util.List; +import java.util.Map; +import java.util.Set; + +import org.opendaylight.yangtools.sal.binding.model.api.Type; +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.yang.model.api.SchemaPath; + +final class ModuleContext { + private GeneratedTypeBuilder moduleNode; + private final List genTOs = new ArrayList(); + private final Map typedefs = new HashMap(); + private final Map childNodes = new HashMap(); + private final Map groupings = new HashMap(); + private final Map cases = new HashMap(); + private final Set identities = new HashSet(); + private final Set topLevelNodes = new HashSet(); + private final List augmentations = new ArrayList(); + + + List getGeneratedTypes() { + List result = new ArrayList<>(); + + if (moduleNode != null) { + result.add(moduleNode.toInstance()); + } + + for (GeneratedTOBuilder b : genTOs) { + result.add(b.toInstance()); + } + for (Type b : typedefs.values()) { + if (b != null) { + result.add(b); + } + } + for (GeneratedTypeBuilder b : childNodes.values()) { + result.add(b.toInstance()); + } + for (GeneratedTypeBuilder b : groupings.values()) { + result.add(b.toInstance()); + } + for (GeneratedTypeBuilder b : cases.values()) { + result.add(b.toInstance()); + } + for (GeneratedTOBuilder b : identities) { + result.add(b.toInstance()); + } + for (GeneratedTypeBuilder b : topLevelNodes) { + result.add(b.toInstance()); + } + for (GeneratedTypeBuilder b : augmentations) { + result.add(b.toInstance()); + } + return result; + } + + public GeneratedTypeBuilder getModuleNode() { + return moduleNode; + } + + public GeneratedTypeBuilder getChildNode(SchemaPath p) { + return childNodes.get(p); + } + + public GeneratedTypeBuilder getGrouping(SchemaPath p) { + return groupings.get(p); + } + + public GeneratedTypeBuilder getCase(SchemaPath p) { + return cases.get(p); + } + + public void addModuleNode(GeneratedTypeBuilder moduleNode) { + this.moduleNode = moduleNode; + } + + public void addGeneratedTOBuilder(GeneratedTOBuilder b) { + genTOs.add(b); + } + + public void addChildNodeType(SchemaPath p, GeneratedTypeBuilder b) { + childNodes.put(p, b); + } + + public void addGroupingType(SchemaPath p, GeneratedTypeBuilder b) { + groupings.put(p, b); + } + + public void addTypedefType(SchemaPath p, Type t) { + typedefs.put(p, t); + } + + public void addCaseType(SchemaPath p, GeneratedTypeBuilder b) { + cases.put(p, b); + } + + public void addIdentityType(GeneratedTOBuilder b) { + identities.add(b); + } + + public void addTopLevelNodeType(GeneratedTypeBuilder b) { + topLevelNodes.add(b); + } + + public void addAugmentType(GeneratedTypeBuilder b) { + augmentations.add(b); + } + +} diff --git a/code-generator/binding-generator-impl/src/test/java/org/opendaylight/yangtools/sal/binding/generator/impl/GeneratedTypesTest.java b/code-generator/binding-generator-impl/src/test/java/org/opendaylight/yangtools/sal/binding/generator/impl/GeneratedTypesTest.java index 0658adaec3..2e10a4a1be 100644 --- a/code-generator/binding-generator-impl/src/test/java/org/opendaylight/yangtools/sal/binding/generator/impl/GeneratedTypesTest.java +++ b/code-generator/binding-generator-impl/src/test/java/org/opendaylight/yangtools/sal/binding/generator/impl/GeneratedTypesTest.java @@ -264,11 +264,17 @@ public class GeneratedTypesTest { assertNotNull(genTypes); assertEquals(3, genTypes.size()); - final GeneratedType simpleContainer = (GeneratedType) genTypes.get(1); - final GeneratedType nestedContainer = (GeneratedType) genTypes.get(2); - - assertEquals("SimpleContainer", simpleContainer.getName()); - assertEquals("NestedContainer", nestedContainer.getName()); + GeneratedType simpleContainer = (GeneratedType) genTypes.get(1); + GeneratedType nestedContainer = (GeneratedType) genTypes.get(2); + for (Type t : genTypes) { + if ("SimpleContainer".equals(t.getName())) { + simpleContainer = (GeneratedType)t; + } else if ("NestedContainer".equals(t.getName())) { + nestedContainer = (GeneratedType)t; + } + } + assertNotNull(simpleContainer); + assertNotNull(nestedContainer); assertEquals(3, simpleContainer.getMethodDefinitions().size()); assertEquals(2, nestedContainer.getMethodDefinitions().size()); @@ -343,11 +349,17 @@ public class GeneratedTypesTest { assertNotNull(genTypes); assertEquals(3, genTypes.size()); - final GeneratedType simpleContainer = (GeneratedType) genTypes.get(1); - final GeneratedType nestedContainer = (GeneratedType) genTypes.get(2); - - assertEquals("SimpleContainer", simpleContainer.getName()); - assertEquals("NestedContainer", nestedContainer.getName()); + GeneratedType simpleContainer = (GeneratedType) genTypes.get(1); + GeneratedType nestedContainer = (GeneratedType) genTypes.get(2); + for (Type t : genTypes) { + if ("SimpleContainer".equals(t.getName())) { + simpleContainer = (GeneratedType)t; + } else if ("NestedContainer".equals(t.getName())) { + nestedContainer = (GeneratedType)t; + } + } + assertNotNull(simpleContainer); + assertNotNull(nestedContainer); assertEquals(3, simpleContainer.getMethodDefinitions().size()); assertEquals(2, nestedContainer.getMethodDefinitions().size()); diff --git a/code-generator/binding-generator-util/src/main/java/org/opendaylight/yangtools/binding/generator/util/BindingTypes.java b/code-generator/binding-generator-util/src/main/java/org/opendaylight/yangtools/binding/generator/util/BindingTypes.java index eb5ff850db..eb310b627f 100644 --- a/code-generator/binding-generator-util/src/main/java/org/opendaylight/yangtools/binding/generator/util/BindingTypes.java +++ b/code-generator/binding-generator-util/src/main/java/org/opendaylight/yangtools/binding/generator/util/BindingTypes.java @@ -1,10 +1,30 @@ +/* + * 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.binding.generator.util; +import static org.opendaylight.yangtools.binding.generator.util.Types.parameterizedTypeFor; +import static org.opendaylight.yangtools.binding.generator.util.Types.typeForClass; + import org.opendaylight.yangtools.sal.binding.model.api.ConcreteType; import org.opendaylight.yangtools.sal.binding.model.api.ParameterizedType; import org.opendaylight.yangtools.sal.binding.model.api.Type; -import org.opendaylight.yangtools.yang.binding.*; -import static org.opendaylight.yangtools.binding.generator.util.Types.*; +import org.opendaylight.yangtools.yang.binding.Augmentable; +import org.opendaylight.yangtools.yang.binding.Augmentation; +import org.opendaylight.yangtools.yang.binding.BaseIdentity; +import org.opendaylight.yangtools.yang.binding.ChildOf; +import org.opendaylight.yangtools.yang.binding.DataObject; +import org.opendaylight.yangtools.yang.binding.DataRoot; +import org.opendaylight.yangtools.yang.binding.Identifiable; +import org.opendaylight.yangtools.yang.binding.Identifier; +import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; +import org.opendaylight.yangtools.yang.binding.Notification; +import org.opendaylight.yangtools.yang.binding.NotificationListener; +import org.opendaylight.yangtools.yang.binding.RpcService; public final class BindingTypes { @@ -20,6 +40,8 @@ public final class BindingTypes { public static final ConcreteType NOTIFICATION_LISTENER = typeForClass(NotificationListener.class); public static final ConcreteType RPC_SERVICE = typeForClass(RpcService.class); + private static final ConcreteType CHILD_OF = typeForClass(ChildOf.class); + private BindingTypes() { } @@ -27,4 +49,9 @@ public final class BindingTypes { public static ParameterizedType augmentable(Type t) { return parameterizedTypeFor(AUGMENTABLE, t); } + + public static ParameterizedType childOf(Type t) { + return parameterizedTypeFor(CHILD_OF, t); + } + } diff --git a/code-generator/binding-java-api-generator/src/main/java/org/opendaylight/yangtools/sal/java/api/generator/GeneratorJavaFile.java b/code-generator/binding-java-api-generator/src/main/java/org/opendaylight/yangtools/sal/java/api/generator/GeneratorJavaFile.java index 6ff6252ce5..085fd1b018 100644 --- a/code-generator/binding-java-api-generator/src/main/java/org/opendaylight/yangtools/sal/java/api/generator/GeneratorJavaFile.java +++ b/code-generator/binding-java-api-generator/src/main/java/org/opendaylight/yangtools/sal/java/api/generator/GeneratorJavaFile.java @@ -22,7 +22,7 @@ import org.slf4j.LoggerFactory; /** * Generates files with JAVA source codes for every specified type. - * + * */ public final class GeneratorJavaFile { @@ -41,9 +41,9 @@ public final class GeneratorJavaFile { /** * Creates instance of this class with the set of types for * which the JAVA code is generated. - * + * * The instances of concrete JAVA code generator are created. - * + * * @param types * set of types for which JAVA code should be generated */ @@ -58,7 +58,7 @@ public final class GeneratorJavaFile { /** * Generates list of files with JAVA source code. Only the suitable code * generator is used to generate the source code for the concrete type. - * + * * @param parentDirectory * directory to which the output source codes should be generated * @return list of output files @@ -68,10 +68,12 @@ public final class GeneratorJavaFile { public List generateToFile(final File parentDirectory) throws IOException { final List result = new ArrayList<>(); for (Type type : types) { - for (CodeGenerator generator : generators) { - File generatedJavaFile = generateTypeToJavaFile(parentDirectory, type, generator); - if (generatedJavaFile != null) { - result.add(generatedJavaFile); + if (type != null) { + for (CodeGenerator generator : generators) { + File generatedJavaFile = generateTypeToJavaFile(parentDirectory, type, generator); + if (generatedJavaFile != null) { + result.add(generatedJavaFile); + } } } } @@ -84,7 +86,7 @@ public final class GeneratorJavaFile { * are generated according to packages to which the type belongs (e. g. if * type belongs to the package org.pcg then in parentDir * is created directory org which contains pcg). - * + * * @param parentDir * directory where should be the new file generated * @param type @@ -145,7 +147,7 @@ public final class GeneratorJavaFile { * parentDirectory and parsed packageName. The * parsing of packageName is realized as replacement of the * package name dots with the file system separator. - * + * * @param parentDirectory * File object with reference to parent directory * @param packageName diff --git a/code-generator/binding-java-api-generator/src/test/java/org/opendaylight/yangtools/sal/java/api/generator/test/AugmentToUsesInAugmentCompilationTest.java b/code-generator/binding-java-api-generator/src/test/java/org/opendaylight/yangtools/sal/java/api/generator/test/AugmentToUsesInAugmentCompilationTest.java index 8c1bbbf707..6f0aaae29e 100644 --- a/code-generator/binding-java-api-generator/src/test/java/org/opendaylight/yangtools/sal/java/api/generator/test/AugmentToUsesInAugmentCompilationTest.java +++ b/code-generator/binding-java-api-generator/src/test/java/org/opendaylight/yangtools/sal/java/api/generator/test/AugmentToUsesInAugmentCompilationTest.java @@ -8,6 +8,7 @@ package org.opendaylight.yangtools.sal.java.api.generator.test; import static org.junit.Assert.assertTrue; +import static org.opendaylight.yangtools.sal.java.api.generator.test.CompilationTestUtils.*; import java.io.File; import java.net.URL; diff --git a/code-generator/binding-java-api-generator/src/test/java/org/opendaylight/yangtools/sal/java/api/generator/test/BaseCompilationTest.java b/code-generator/binding-java-api-generator/src/test/java/org/opendaylight/yangtools/sal/java/api/generator/test/BaseCompilationTest.java index 762c224f0e..8d8e843f25 100644 --- a/code-generator/binding-java-api-generator/src/test/java/org/opendaylight/yangtools/sal/java/api/generator/test/BaseCompilationTest.java +++ b/code-generator/binding-java-api-generator/src/test/java/org/opendaylight/yangtools/sal/java/api/generator/test/BaseCompilationTest.java @@ -7,19 +7,8 @@ */ package org.opendaylight.yangtools.sal.java.api.generator.test; -import static org.junit.Assert.*; - -import java.io.File; -import java.io.FileNotFoundException; -import java.lang.reflect.ParameterizedType; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.List; - -import javax.tools.JavaCompiler; -import javax.tools.JavaFileObject; -import javax.tools.StandardJavaFileManager; -import javax.tools.ToolProvider; +import static org.junit.Assert.assertTrue; +import static org.opendaylight.yangtools.sal.java.api.generator.test.CompilationTestUtils.*; import org.junit.Before; import org.junit.BeforeClass; @@ -28,23 +17,6 @@ import org.opendaylight.yangtools.sal.binding.generator.impl.BindingGeneratorImp import org.opendaylight.yangtools.yang.parser.impl.YangParserImpl; public abstract class BaseCompilationTest { - public static final String FS = File.separator; - protected static final String BASE_PKG = "org.opendaylight.yang.gen.v1"; - - protected static final String TEST_PATH = "target" + FS + "test"; - protected static final File TEST_DIR = new File(TEST_PATH); - - protected static final String GENERATOR_OUTPUT_PATH = TEST_PATH + FS + "src"; - protected static final File GENERATOR_OUTPUT_DIR = new File(GENERATOR_OUTPUT_PATH); - protected static final String COMPILER_OUTPUT_PATH = TEST_PATH + FS + "bin"; - protected static final File COMPILER_OUTPUT_DIR = new File(COMPILER_OUTPUT_PATH); - - protected static final String BASE_PATH = "org" + FS + "opendaylight" + FS + "yang" + FS + "gen" + FS + "v1"; - protected static final String NS_TEST = BASE_PATH + FS + "urn" + FS + "opendaylight" + FS + "test" + FS - + "rev131008"; - protected static final String NS_FOO = BASE_PATH + FS + "urn" + FS + "opendaylight" + FS + "foo" + FS + "rev131008"; - protected static final String NS_BAR = BASE_PATH + FS + "urn" + FS + "opendaylight" + FS + "bar" + FS + "rev131008"; - protected static final String NS_BAZ = BASE_PATH + FS + "urn" + FS + "opendaylight" + FS + "baz" + FS + "rev131008"; protected YangParserImpl parser; protected BindingGenerator bindingGenerator; @@ -64,142 +36,4 @@ public abstract class BaseCompilationTest { bindingGenerator = new BindingGeneratorImpl(); } - /** - * Method to clean resources. It is manually called at the end of each test - * instead of marking it with @After annotation to prevent removing - * generated code if test fails. - */ - protected void cleanUp(File... resourceDirs) { - for (File resourceDir : resourceDirs) { - if (resourceDir.exists()) { - deleteTestDir(resourceDir); - } - } - } - - /** - * Test if generated source implements interface. - * - * @param classToTest - * source to test - * @param ifcClass - * expected interface type - */ - protected static void testImplementsIfc(Class classToTest, Class ifcClass) { - Class[] interfaces = classToTest.getInterfaces(); - List> ifcsList = Arrays.asList(interfaces); - if (!ifcsList.contains(ifcClass)) { - throw new AssertionError(classToTest + " should implement " + ifcClass); - } - } - - /** - * Test if interface generated from augment extends Augmentation interface - * with correct generic type. - * - * @param classToTest - * interface generated from augment - * @param paramClass - * fully qualified name of expected parameter type - */ - protected static void testAugmentation(Class classToTest, String paramClass) { - final String augmentationIfc = "interface org.opendaylight.yangtools.yang.binding.Augmentation"; - ParameterizedType augmentation = null; - for (java.lang.reflect.Type ifc : classToTest.getGenericInterfaces()) { - if (ifc instanceof ParameterizedType) { - ParameterizedType pt = (ParameterizedType) ifc; - if (augmentationIfc.equals(pt.getRawType().toString())) { - augmentation = pt; - } - } - } - assertNotNull(augmentation); - - java.lang.reflect.Type[] typeArguments = augmentation.getActualTypeArguments(); - assertEquals(1, typeArguments.length); - assertEquals("interface " + paramClass, typeArguments[0].toString()); - } - - /** - * Test if source code is compilable. - * - * @param sourcesOutputDir - * directory containing source files - * @param compiledOutputDir - * compiler output directory - */ - protected static void testCompilation(File sourcesOutputDir, File compiledOutputDir) { - JavaCompiler compiler = ToolProvider.getSystemJavaCompiler(); - StandardJavaFileManager fileManager = compiler.getStandardFileManager(null, null, null); - List filesList = getJavaFiles(sourcesOutputDir); - Iterable compilationUnits = fileManager.getJavaFileObjectsFromFiles(filesList); - Iterable options = Arrays.asList("-d", compiledOutputDir.getAbsolutePath()); - boolean compiled = compiler.getTask(null, null, null, options, null, compilationUnits).call(); - assertTrue(compiled); - } - - protected static void testFilesCount(File dir, int count) { - File[] dirContent = dir.listFiles(); - if (dirContent == null) { - throw new AssertionError("File " + dir + " doesn't exists or it's not a directory"); - } else { - assertEquals("Unexpected count of generated files", count, dirContent.length); - } - } - - /** - * Search recursively given directory for *.java files. - * - * @param directory - * directory to search - * @return List of java files found - */ - private static List getJavaFiles(File directory) { - List result = new ArrayList<>(); - File[] filesToRead = directory.listFiles(); - if (filesToRead != null) { - for (File file : filesToRead) { - if (file.isDirectory()) { - result.addAll(getJavaFiles(file)); - } else { - String absPath = file.getAbsolutePath(); - if (absPath.endsWith(".java")) { - result.add(file); - } - } - } - } - return result; - } - - protected static List getSourceFiles(String path) throws FileNotFoundException { - final String resPath = BaseCompilationTest.class.getResource(path).getPath(); - final File sourcesDir = new File(resPath); - if (sourcesDir.exists()) { - final List sourceFiles = new ArrayList<>(); - final File[] fileArray = sourcesDir.listFiles(); - if (fileArray == null) { - throw new IllegalArgumentException("Unable to locate files in " + sourcesDir); - } - sourceFiles.addAll(Arrays.asList(fileArray)); - return sourceFiles; - } else { - throw new FileNotFoundException("Testing files were not found(" + sourcesDir.getName() + ")"); - } - } - - private static void deleteTestDir(File file) { - if (file.isDirectory()) { - File[] filesToDelete = file.listFiles(); - if (filesToDelete != null) { - for (File f : filesToDelete) { - deleteTestDir(f); - } - } - } - if (!file.delete()) { - throw new RuntimeException("Failed to clean up after test"); - } - } - } diff --git a/code-generator/binding-java-api-generator/src/test/java/org/opendaylight/yangtools/sal/java/api/generator/test/CascadeUsesCompilationTest.java b/code-generator/binding-java-api-generator/src/test/java/org/opendaylight/yangtools/sal/java/api/generator/test/CascadeUsesCompilationTest.java index c29d28bd85..6528c48dee 100644 --- a/code-generator/binding-java-api-generator/src/test/java/org/opendaylight/yangtools/sal/java/api/generator/test/CascadeUsesCompilationTest.java +++ b/code-generator/binding-java-api-generator/src/test/java/org/opendaylight/yangtools/sal/java/api/generator/test/CascadeUsesCompilationTest.java @@ -8,6 +8,7 @@ package org.opendaylight.yangtools.sal.java.api.generator.test; import static org.junit.Assert.*; +import static org.opendaylight.yangtools.sal.java.api.generator.test.CompilationTestUtils.*; import java.io.File; import java.lang.reflect.Constructor; diff --git a/code-generator/binding-java-api-generator/src/test/java/org/opendaylight/yangtools/sal/java/api/generator/test/CompilationTest.java b/code-generator/binding-java-api-generator/src/test/java/org/opendaylight/yangtools/sal/java/api/generator/test/CompilationTest.java index 29c7334e4d..e722fe00f2 100644 --- a/code-generator/binding-java-api-generator/src/test/java/org/opendaylight/yangtools/sal/java/api/generator/test/CompilationTest.java +++ b/code-generator/binding-java-api-generator/src/test/java/org/opendaylight/yangtools/sal/java/api/generator/test/CompilationTest.java @@ -9,6 +9,7 @@ package org.opendaylight.yangtools.sal.java.api.generator.test; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertTrue; +import static org.opendaylight.yangtools.sal.java.api.generator.test.CompilationTestUtils.*; import java.io.File; import java.lang.annotation.Annotation; @@ -50,7 +51,6 @@ public class CompilationTest extends BaseCompilationTest { // Test if all sources are generated File parent = new File(sourcesOutputDir, NS_TEST); - testFilesCount(parent, 6); File keyArgs = new File(parent, "KeyArgs.java"); File links = new File(parent, "Links.java"); File linksBuilder = new File(parent, "LinksBuilder.java"); @@ -61,9 +61,9 @@ public class CompilationTest extends BaseCompilationTest { assertTrue(linksBuilder.exists()); assertTrue(linksKey.exists()); assertTrue(testData.exists()); + testFilesCount(parent, 6); parent = new File(sourcesOutputDir, NS_TEST + FS + "links"); - testFilesCount(parent, 7); File level = new File(parent, "Level.java"); File linkGroup = new File(parent, "LinkGroup.java"); File node = new File(parent, "Node.java"); @@ -78,6 +78,7 @@ public class CompilationTest extends BaseCompilationTest { assertTrue(nodeList.exists()); assertTrue(nodeListBuilder.exists()); assertTrue(nodesType.exists()); + testFilesCount(parent, 7); // Test if sources are compilable testCompilation(sourcesOutputDir, compiledOutputDir); @@ -134,60 +135,60 @@ public class CompilationTest extends BaseCompilationTest { // Test if all sources were generated from 'module foo' File parent = new File(sourcesOutputDir, NS_FOO); - testFilesCount(parent, 7); assertTrue(new File(parent, "Object.java").exists()); assertTrue(new File(parent, "OpenObject.java").exists()); assertTrue(new File(parent, "ExplicitRouteObject.java").exists()); assertTrue(new File(parent, "PathKeySubobject.java").exists()); + testFilesCount(parent, 7); parent = new File(parent, "object"); - testFilesCount(parent, 2); assertTrue(new File(parent, "Nodes.java").exists()); assertTrue(new File(parent, "NodesBuilder.java").exists()); + testFilesCount(parent, 2); parent = new File(sourcesOutputDir, NS_FOO + FS + "open"); testFilesCount(parent, 1); parent = new File(parent, "object"); - testFilesCount(parent, 3); assertTrue(new File(parent, "Nodes1.java").exists()); assertTrue(new File(parent, "Nodes1Builder.java").exists()); + testFilesCount(parent, 3); parent = new File(parent, "nodes"); - testFilesCount(parent, 2); assertTrue(new File(parent, "Links.java").exists()); assertTrue(new File(parent, "LinksBuilder.java").exists()); + testFilesCount(parent, 2); parent = new File(sourcesOutputDir, NS_FOO + FS + "explicit"); testFilesCount(parent, 1); parent = new File(parent, "route"); testFilesCount(parent, 1); parent = new File(parent, "object"); - testFilesCount(parent, 3); assertTrue(new File(parent, "Subobjects.java").exists()); assertTrue(new File(parent, "SubobjectsBuilder.java").exists()); + testFilesCount(parent, 3); parent = new File(parent, "subobjects"); testFilesCount(parent, 1); parent = new File(parent, "subobject"); testFilesCount(parent, 1); parent = new File(parent, "type"); - testFilesCount(parent, 3); assertTrue(new File(parent, "PathKey.java").exists()); assertTrue(new File(parent, "PathKeyBuilder.java").exists()); + testFilesCount(parent, 3); parent = new File(parent, "path"); testFilesCount(parent, 1); parent = new File(parent, "key"); - testFilesCount(parent, 2); assertTrue(new File(parent, "PathKey.java").exists()); assertTrue(new File(parent, "PathKeyBuilder.java").exists()); + testFilesCount(parent, 2); // Test if all sources were generated from 'module bar' parent = new File(sourcesOutputDir, NS_BAR); - testFilesCount(parent, 3); assertTrue(new File(parent, "BasicExplicitRouteSubobjects.java").exists()); assertTrue(new File(parent, "ExplicitRouteSubobjects.java").exists()); + testFilesCount(parent, 3); parent = new File(parent, "basic"); testFilesCount(parent, 1); @@ -204,11 +205,11 @@ public class CompilationTest extends BaseCompilationTest { testFilesCount(parent, 1); parent = new File(parent, "type"); - testFilesCount(parent, 4); assertTrue(new File(parent, "IpPrefix.java").exists()); assertTrue(new File(parent, "IpPrefixBuilder.java").exists()); assertTrue(new File(parent, "Label.java").exists()); assertTrue(new File(parent, "LabelBuilder.java").exists()); + testFilesCount(parent, 4); // Test if sources are compilable testCompilation(sourcesOutputDir, compiledOutputDir); @@ -232,7 +233,6 @@ public class CompilationTest extends BaseCompilationTest { // Test if all sources were generated from 'module foo' File parent = new File(sourcesOutputDir, NS_FOO); - testFilesCount(parent, 6); File fooListener = new File(parent, "FooListener.java"); File pathAttributes = new File(parent, "PathAttributes.java"); File update = new File(parent, "Update.java"); @@ -241,6 +241,7 @@ public class CompilationTest extends BaseCompilationTest { assertTrue(pathAttributes.exists()); assertTrue(update.exists()); assertTrue(updateBuilder.exists()); + testFilesCount(parent, 6); parent = new File(sourcesOutputDir, NS_FOO + FS + "path"); testFilesCount(parent, 1); @@ -260,13 +261,13 @@ public class CompilationTest extends BaseCompilationTest { // Test if all sources were generated from 'module bar' parent = new File(sourcesOutputDir, NS_BAR); - testFilesCount(parent, 5); File destination = new File(parent, "Destination.java"); File pathAttributes1 = new File(parent, "PathAttributes1.java"); File pathAttributes1Builder = new File(parent, "PathAttributes1Builder.java"); assertTrue(destination.exists()); assertTrue(pathAttributes1.exists()); assertTrue(pathAttributes1Builder.exists()); + testFilesCount(parent, 5); parent = new File(sourcesOutputDir, NS_BAR + FS + "destination"); testFilesCount(parent, 2); @@ -287,29 +288,22 @@ public class CompilationTest extends BaseCompilationTest { parent = new File(parent, "path"); testFilesCount(parent, 1); parent = new File(parent, "attributes"); - testFilesCount(parent, 3); File mpUnreachNlri = new File(parent, "MpUnreachNlri.java"); File mpUnreachNlriBuilder = new File(parent, "MpUnreachNlriBuilder.java"); assertTrue(mpUnreachNlri.exists()); assertTrue(mpUnreachNlriBuilder.exists()); + testFilesCount(parent, 3); parent = new File(parent, "mp"); testFilesCount(parent, 1); parent = new File(parent, "unreach"); testFilesCount(parent, 1); parent = new File(parent, "nlri"); - testFilesCount(parent, 3); File withdrawnRoutes = new File(parent, "WithdrawnRoutes.java"); File withdrawnRoutesBuilder = new File(parent, "WithdrawnRoutesBuilder.java"); assertTrue(withdrawnRoutes.exists()); assertTrue(withdrawnRoutesBuilder.exists()); - - parent = new File(parent, "withdrawn"); - testFilesCount(parent, 1); - parent = new File(parent, "routes"); - testFilesCount(parent, 1); - destinationType = new File(parent, "DestinationType.java"); - assertTrue(destinationType.exists()); + testFilesCount(parent, 2); // Test if all sources were generated from 'module baz' parent = new File(sourcesOutputDir, NS_BAZ); @@ -336,11 +330,31 @@ public class CompilationTest extends BaseCompilationTest { parent = new File(parent, "destination"); testFilesCount(parent, 1); parent = new File(parent, "type"); - testFilesCount(parent, 2); File destinationLinkstate = new File(parent, "DestinationLinkstate.java"); File destinationLinkstateBuilder = new File(parent, "DestinationLinkstateBuilder.java"); assertTrue(destinationLinkstate.exists()); assertTrue(destinationLinkstateBuilder.exists()); + testFilesCount(parent, 3); + parent = new File(parent, "destination"); + testFilesCount(parent, 1); + parent = new File(parent, "linkstate"); + File links = new File(parent, "Links.java"); + File linksBuilder = new File(parent, "LinksBuilder.java"); + assertTrue(links.exists()); + assertTrue(linksBuilder.exists()); + testFilesCount(parent, 3); + parent = new File(parent, "links"); + File source = new File(parent, "Source.java"); + File sourceBuilder = new File(parent, "SourceBuilder.java"); + assertTrue(source.exists()); + assertTrue(sourceBuilder.exists()); + testFilesCount(parent, 3); + parent = new File(parent, "source"); + File address = new File(parent, "Address.java"); + File addressBuilder = new File(parent, "AddressBuilder.java"); + assertTrue(address.exists()); + assertTrue(addressBuilder.exists()); + testFilesCount(parent, 2); // Test if sources are compilable testCompilation(sourcesOutputDir, compiledOutputDir); @@ -477,7 +491,6 @@ public class CompilationTest extends BaseCompilationTest { cleanUp(sourcesOutputDir, compiledOutputDir); } - private void testReturnType(Class clazz, String methodName, Class returnType) throws Exception { Method method; try { diff --git a/code-generator/binding-java-api-generator/src/test/java/org/opendaylight/yangtools/sal/java/api/generator/test/CompilationTestUtils.java b/code-generator/binding-java-api-generator/src/test/java/org/opendaylight/yangtools/sal/java/api/generator/test/CompilationTestUtils.java new file mode 100644 index 0000000000..2830e18230 --- /dev/null +++ b/code-generator/binding-java-api-generator/src/test/java/org/opendaylight/yangtools/sal/java/api/generator/test/CompilationTestUtils.java @@ -0,0 +1,185 @@ +/* + * 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.java.api.generator.test; + +import static org.junit.Assert.*; + +import java.io.File; +import java.io.FileNotFoundException; +import java.lang.reflect.ParameterizedType; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; + +import javax.tools.JavaCompiler; +import javax.tools.JavaFileObject; +import javax.tools.StandardJavaFileManager; +import javax.tools.ToolProvider; + +public class CompilationTestUtils { + public static final String FS = File.separator; + static final String BASE_PKG = "org.opendaylight.yang.gen.v1"; + + static final String TEST_PATH = "target" + FS + "test"; + static final File TEST_DIR = new File(TEST_PATH); + + static final String GENERATOR_OUTPUT_PATH = TEST_PATH + FS + "src"; + static final File GENERATOR_OUTPUT_DIR = new File(GENERATOR_OUTPUT_PATH); + static final String COMPILER_OUTPUT_PATH = TEST_PATH + FS + "bin"; + static final File COMPILER_OUTPUT_DIR = new File(COMPILER_OUTPUT_PATH); + + static final String BASE_PATH = "org" + FS + "opendaylight" + FS + "yang" + FS + "gen" + FS + "v1"; + static final String NS_TEST = BASE_PATH + FS + "urn" + FS + "opendaylight" + FS + "test" + FS + + "rev131008"; + static final String NS_FOO = BASE_PATH + FS + "urn" + FS + "opendaylight" + FS + "foo" + FS + "rev131008"; + static final String NS_BAR = BASE_PATH + FS + "urn" + FS + "opendaylight" + FS + "bar" + FS + "rev131008"; + static final String NS_BAZ = BASE_PATH + FS + "urn" + FS + "opendaylight" + FS + "baz" + FS + "rev131008"; + + /** + * Method to clean resources. It is manually called at the end of each test + * instead of marking it with @After annotation to prevent removing + * generated code if test fails. + */ + static void cleanUp(File... resourceDirs) { + for (File resourceDir : resourceDirs) { + if (resourceDir.exists()) { + deleteTestDir(resourceDir); + } + } + } + + /** + * Test if generated source implements interface. + * + * @param classToTest + * source to test + * @param ifcClass + * expected interface type + */ + static void testImplementsIfc(Class classToTest, Class ifcClass) { + Class[] interfaces = classToTest.getInterfaces(); + List> ifcsList = Arrays.asList(interfaces); + if (!ifcsList.contains(ifcClass)) { + throw new AssertionError(classToTest + " should implement " + ifcClass); + } + } + + /** + * Test if interface generated from augment extends Augmentation interface + * with correct generic type. + * + * @param classToTest + * interface generated from augment + * @param genericType + * fully qualified name of expected parameter type + */ + static void testAugmentation(Class classToTest, String genericType) { + final String ifcToImplement = "interface org.opendaylight.yangtools.yang.binding.Augmentation"; + testImplementParameterizedIfc(classToTest, ifcToImplement, genericType); + } + + static void testImplementParameterizedIfc(Class classToTest, String ifcToImplement, String genericType) { + ParameterizedType augmentation = null; + for (java.lang.reflect.Type ifc : classToTest.getGenericInterfaces()) { + if (ifc instanceof ParameterizedType) { + ParameterizedType pt = (ParameterizedType) ifc; + if (ifcToImplement.equals(pt.getRawType().toString())) { + augmentation = pt; + } + } + } + assertNotNull(augmentation); + + java.lang.reflect.Type[] typeArguments = augmentation.getActualTypeArguments(); + assertEquals(1, typeArguments.length); + assertEquals("interface " + genericType, typeArguments[0].toString()); + } + + /** + * Test if source code is compilable. + * + * @param sourcesOutputDir + * directory containing source files + * @param compiledOutputDir + * compiler output directory + */ + static void testCompilation(File sourcesOutputDir, File compiledOutputDir) { + JavaCompiler compiler = ToolProvider.getSystemJavaCompiler(); + StandardJavaFileManager fileManager = compiler.getStandardFileManager(null, null, null); + List filesList = getJavaFiles(sourcesOutputDir); + Iterable compilationUnits = fileManager.getJavaFileObjectsFromFiles(filesList); + Iterable options = Arrays.asList("-d", compiledOutputDir.getAbsolutePath()); + boolean compiled = compiler.getTask(null, null, null, options, null, compilationUnits).call(); + assertTrue(compiled); + } + + static void testFilesCount(File dir, int count) { + File[] dirContent = dir.listFiles(); + if (dirContent == null) { + throw new AssertionError("File " + dir + " doesn't exists or it's not a directory"); + } else { + assertEquals("Unexpected count of generated files", count, dirContent.length); + } + } + + /** + * Search recursively given directory for *.java files. + * + * @param directory + * directory to search + * @return List of java files found + */ + private static List getJavaFiles(File directory) { + List result = new ArrayList<>(); + File[] filesToRead = directory.listFiles(); + if (filesToRead != null) { + for (File file : filesToRead) { + if (file.isDirectory()) { + result.addAll(getJavaFiles(file)); + } else { + String absPath = file.getAbsolutePath(); + if (absPath.endsWith(".java")) { + result.add(file); + } + } + } + } + return result; + } + + static List getSourceFiles(String path) throws FileNotFoundException { + final String resPath = BaseCompilationTest.class.getResource(path).getPath(); + final File sourcesDir = new File(resPath); + if (sourcesDir.exists()) { + final List sourceFiles = new ArrayList<>(); + final File[] fileArray = sourcesDir.listFiles(); + if (fileArray == null) { + throw new IllegalArgumentException("Unable to locate files in " + sourcesDir); + } + sourceFiles.addAll(Arrays.asList(fileArray)); + return sourceFiles; + } else { + throw new FileNotFoundException("Testing files were not found(" + sourcesDir.getName() + ")"); + } + } + + static void deleteTestDir(File file) { + if (file.isDirectory()) { + File[] filesToDelete = file.listFiles(); + if (filesToDelete != null) { + for (File f : filesToDelete) { + deleteTestDir(f); + } + } + } + if (!file.delete()) { + throw new RuntimeException("Failed to clean up after test"); + } + } + +} diff --git a/code-generator/binding-java-api-generator/src/test/resources/compilation/augment-of-augment/baz.yang b/code-generator/binding-java-api-generator/src/test/resources/compilation/augment-of-augment/baz.yang index f361b34b5a..f10762c462 100644 --- a/code-generator/binding-java-api-generator/src/test/resources/compilation/augment-of-augment/baz.yang +++ b/code-generator/binding-java-api-generator/src/test/resources/compilation/augment-of-augment/baz.yang @@ -12,6 +12,11 @@ module baz { augment "/fo:update/fo:path-attributes/br:mp-unreach-nlri/br:withdrawn-routes/br:destination-type" { case destination-linkstate { uses linkstate-destination; + container links { + container source { + container address {} + } + } } } diff --git a/model/pom.xml b/model/pom.xml index 32a8f2dd68..0ad3549507 100644 --- a/model/pom.xml +++ b/model/pom.xml @@ -132,7 +132,7 @@ org.opendaylight.yangtools yang-binding - 0.5.9-SNAPSHOT + 0.6.0-SNAPSHOT org.opendaylight.yangtools -- 2.36.6