From: Jozef Gloncak Date: Thu, 15 Aug 2013 14:03:34 +0000 (+0200) Subject: Comments of source code. X-Git-Tag: yangtools-0.1.0~61 X-Git-Url: https://git.opendaylight.org/gerrit/gitweb?a=commitdiff_plain;h=c173dce5639bef5016b14debdef051e79ebe91f1;p=yangtools.git Comments of source code. Comments were added to files: - BindingGeneratorImpl.java - BaseYangTypes.java - GroupingDefinitionDependencySort.java - NodeWrappedType.java - TypeProviderImpl.java - UnionDependencySort.java - AbstractBaseType.java - BindingGeneratorUtil.java - ReferencedTypeImpl.java - TypeConstants.java - Types.java - EnumerationBuilderImpl.java - BuilderGenerator.java - BuilderTemplate.xtend - ClassTemplate.xtend - Constants.java - EnumGenerator.java - EnumTemplate.xtend - GeneratorJavaFile.java - GeneratorUtil.java - InterfaceGenerator.java - InterfaceTemplate.xtend - TOGenerator.java - CodeGenerator.java - Enumeration.java - WildcardType.java -> new class NodeWrappedType was created instead of GroupingDefinitionNode a UnionNode -> the method resolveListTypeBuilder of BindingGeneratorImpl was removed and its using was replaced with method addDefaultInterfaceDefinition Change-Id: Iea6317aea75bc37883cf0f2fbf094cb8d4f02f00 Signed-off-by: Jozef Gloncak --- diff --git a/code-generator/binding-generator-impl/src/main/java/org/opendaylight/yangtools/sal/binding/generator/impl/BindingGeneratorImpl.java b/code-generator/binding-generator-impl/src/main/java/org/opendaylight/yangtools/sal/binding/generator/impl/BindingGeneratorImpl.java index ea3b472710..8a5705410d 100644 --- a/code-generator/binding-generator-impl/src/main/java/org/opendaylight/yangtools/sal/binding/generator/impl/BindingGeneratorImpl.java +++ b/code-generator/binding-generator-impl/src/main/java/org/opendaylight/yangtools/sal/binding/generator/impl/BindingGeneratorImpl.java @@ -1,1739 +1,2092 @@ -/* - * 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 static org.opendaylight.yangtools.binding.generator.util.BindingGeneratorUtil.moduleNamespaceToPackageName; -import static org.opendaylight.yangtools.binding.generator.util.BindingGeneratorUtil.packageNameForGeneratedType; -import static org.opendaylight.yangtools.binding.generator.util.BindingGeneratorUtil.parseToClassName; -import static org.opendaylight.yangtools.binding.generator.util.BindingGeneratorUtil.parseToValidParamName; -import static org.opendaylight.yangtools.binding.generator.util.BindingGeneratorUtil.schemaNodeToTransferObjectBuilder; -import static org.opendaylight.yangtools.yang.model.util.SchemaContextUtil.findDataSchemaNode; -import static org.opendaylight.yangtools.yang.model.util.SchemaContextUtil.findParentModule; - -import java.net.URI; -import java.net.URISyntaxException; -import java.util.ArrayList; -import java.util.Collections; -import java.util.Comparator; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.Set; -import java.util.concurrent.Future; - -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.ConcreteType; -import org.opendaylight.yangtools.sal.binding.model.api.GeneratedTransferObject; -import org.opendaylight.yangtools.sal.binding.model.api.GeneratedType; -import org.opendaylight.yangtools.sal.binding.model.api.ParameterizedType; -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.GeneratedPropertyBuilder; -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.DataRoot; -import org.opendaylight.yangtools.yang.binding.Identifiable; -import org.opendaylight.yangtools.yang.binding.Identifier; -import org.opendaylight.yangtools.yang.binding.RpcService; -import org.opendaylight.yangtools.yang.common.QName; -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.NotificationDefinition; -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.UsesNode; -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.EnumTypeDefinition.EnumPair; -import org.opendaylight.yangtools.yang.model.util.DataNodeIterator; -import org.opendaylight.yangtools.yang.model.util.ExtendedType; -import org.opendaylight.yangtools.yang.model.util.SchemaContextUtil; -import org.opendaylight.yangtools.yang.model.util.UnionType; - -public final class BindingGeneratorImpl implements BindingGenerator { - - /** - * Outter key represents the package name. Outter value represents map of - * all builders in the same package. Inner key represents the schema node - * name (in JAVA class/interface name format). Inner value represents - * instance of builder for schema node specified in key part. - */ - private Map> genTypeBuilders; - - /** - * Provide methods for converting YANG types to JAVA types. - */ - private TypeProvider typeProvider; - - /** - * Holds reference to schema context to resolve data of augmented elemnt - * when creating augmentation builder - */ - private 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 final Map allGroupings = new HashMap(); - - /** - * Only parent constructor is invoked. - */ - - private final static String YANG_EXT_NAMESPACE = "urn:opendaylight:yang:extension:yang-ext"; - private final static String AUGMENT_IDENTIFIER_NAME = "augment-identifier"; - - public BindingGeneratorImpl() { - super(); - } - - /** - * Resolves generated types from context schema nodes of all - * modules. - * - * Generated types are created for modules, groupings, types, containers, - * lists, choices, augments, rpcs, notification, identities. - * - * @param context - * schema context which contains data about all schema nodes - * saved in modules - * @return list of types (usually GeneratedType - * GeneratedTransferObjectwhich are generated from - * context data. - * @throws IllegalArgumentException - * if param context is null - * @throws IllegalStateException - * if context contain no modules - */ - @Override - public List generateTypes(final SchemaContext context) { - if (context == null) { - throw new IllegalArgumentException("Schema Context reference cannot be NULL!"); - } - if (context.getModules() == null) { - throw new IllegalStateException("Schema Context does not contain defined modules!"); - } - - final List generatedTypes = new ArrayList<>(); - schemaContext = context; - typeProvider = new TypeProviderImpl(context); - final Set modules = context.getModules(); - genTypeBuilders = new HashMap<>(); - for (final Module module : modules) { - - generatedTypes.addAll(allGroupingsToGenTypes(module)); - - if (false == module.getChildNodes().isEmpty()) { - generatedTypes.add(moduleToDataType(module)); - } - generatedTypes.addAll(allTypeDefinitionsToGenTypes(module)); - generatedTypes.addAll(allContainersToGenTypes(module)); - generatedTypes.addAll(allListsToGenTypes(module)); - generatedTypes.addAll(allChoicesToGenTypes(module)); - generatedTypes.addAll(allAugmentsToGenTypes(module)); - generatedTypes.addAll(allRPCMethodsToGenType(module)); - generatedTypes.addAll(allNotificationsToGenType(module)); - generatedTypes.addAll(allIdentitiesToGenTypes(module, context)); - - } - return generatedTypes; - } - - /** - * Resolves generated types from context schema nodes only for - * modules specified in modules - * - * Generated types are created for modules, groupings, types, containers, - * lists, choices, augments, rpcs, notification, identities. - * - * @param context - * schema context which contains data about all schema nodes - * saved in modules - * @param modules - * set of modules for which schema nodes should be generated - * types - * @return list of types (usually GeneratedType or - * GeneratedTransferObject) which: - *
    - *
  • are generated from context schema nodes and
  • - *
  • are also part of some of the module in modules - * set
  • . - *
- * @throws IllegalArgumentException - *
    - *
  • if param context is null or
  • - *
  • if param modules is null
  • - *
- * @throws IllegalStateException - * if context contain no modules - */ - @Override - public List generateTypes(final SchemaContext context, final Set modules) { - if (context == null) { - throw new IllegalArgumentException("Schema Context reference cannot be NULL!"); - } - if (context.getModules() == null) { - throw new IllegalStateException("Schema Context does not contain defined modules!"); - } - if (modules == null) { - throw new IllegalArgumentException("Sef of Modules cannot be NULL!"); - } - - final List filteredGenTypes = new ArrayList<>(); - schemaContext = context; - typeProvider = new TypeProviderImpl(context); - final Set contextModules = context.getModules(); - genTypeBuilders = new HashMap<>(); - for (final Module contextModule : contextModules) { - final List generatedTypes = new ArrayList<>(); - - generatedTypes.addAll(allGroupingsToGenTypes(contextModule)); - if (false == contextModule.getChildNodes().isEmpty()) { - generatedTypes.add(moduleToDataType(contextModule)); - } - generatedTypes.addAll(allTypeDefinitionsToGenTypes(contextModule)); - generatedTypes.addAll(allContainersToGenTypes(contextModule)); - generatedTypes.addAll(allListsToGenTypes(contextModule)); - generatedTypes.addAll(allChoicesToGenTypes(contextModule)); - generatedTypes.addAll(allAugmentsToGenTypes(contextModule)); - generatedTypes.addAll(allRPCMethodsToGenType(contextModule)); - generatedTypes.addAll(allNotificationsToGenType(contextModule)); - generatedTypes.addAll(allIdentitiesToGenTypes(contextModule, context)); - - if (modules.contains(contextModule)) { - filteredGenTypes.addAll(generatedTypes); - } - } - return filteredGenTypes; - } - - /** - * Converts all extended type definitions of module to the list of - * Type objects. - * - * @param module - * module from which is obtained set of type definitions - * @return list of Type which are generated from extended - * definition types (object of type ExtendedType) - * @throws IllegalArgumentException - *
    - *
  • if module equals null
  • - *
  • if name of module equals null
  • - *
  • if type definitions of module equal null
  • - *
- * - */ - private List allTypeDefinitionsToGenTypes(final Module module) { - if (module == null) { - throw new IllegalArgumentException("Module reference cannot be NULL!"); - } - if (module.getName() == null) { - throw new IllegalArgumentException("Module name cannot be NULL!"); - } - if (module.getTypeDefinitions() == null) { - throw new IllegalArgumentException("Type Definitions for module " + module.getName() + " cannot be NULL!"); - } - - final Set> typeDefinitions = module.getTypeDefinitions(); - final List generatedTypes = new ArrayList<>(); - for (final TypeDefinition typedef : typeDefinitions) { - if (typedef != null) { - final Type type = ((TypeProviderImpl) typeProvider).generatedTypeForExtendedDefinitionType(typedef); - if ((type != null) && !generatedTypes.contains(type)) { - generatedTypes.add(type); - } - } - } - return generatedTypes; - } - - /** - * Converts all containers of the module to the list of - * Type objects. - * - * @param module - * module from which is obtained DataNodeIterator to iterate over - * all containers - * @return list of Type which are generated from containers - * (objects of type ContainerSchemaNode) - * @throws IllegalArgumentException - *
    - *
  • if the module equals null
  • - *
  • if the name of module equals null
  • - *
  • if the set of child nodes equals null
  • - *
- * - */ - private List allContainersToGenTypes(final Module module) { - if (module == null) { - throw new IllegalArgumentException("Module reference cannot be NULL!"); - } - - if (module.getName() == null) { - throw new IllegalArgumentException("Module name cannot be NULL!"); - } - - if (module.getChildNodes() == null) { - throw new IllegalArgumentException("Reference to Set of Child Nodes in module " + module.getName() - + " cannot be NULL!"); - } - - final List generatedTypes = new ArrayList<>(); - final DataNodeIterator it = new DataNodeIterator(module); - final List schemaContainers = it.allContainers(); - final String basePackageName = moduleNamespaceToPackageName(module); - for (final ContainerSchemaNode container : schemaContainers) { - if (!container.isAddedByUses()) { - generatedTypes.add(containerToGenType(basePackageName, container)); - } - } - return generatedTypes; - } - - /** - * Converts all lists of the module to the list of Type - * objects. - * - * @param module - * module from which is obtained DataNodeIterator to iterate over - * all lists - * @return list of Type which are generated from lists (objects - * of type ListSchemaNode) - * @throws IllegalArgumentException - *
    - *
  • if the module equals null
  • - *
  • if the name of module equals null
  • - *
  • if the set of child nodes equals null
  • - *
- * - */ - private List allListsToGenTypes(final Module module) { - if (module == null) { - throw new IllegalArgumentException("Module reference cannot be NULL!"); - } - - if (module.getName() == null) { - throw new IllegalArgumentException("Module name cannot be NULL!"); - } - - if (module.getChildNodes() == null) { - throw new IllegalArgumentException("Reference to Set of Child Nodes in module " + module.getName() - + " cannot be NULL!"); - } - - final List generatedTypes = new ArrayList<>(); - final DataNodeIterator it = new DataNodeIterator(module); - final List schemaLists = it.allLists(); - final String basePackageName = moduleNamespaceToPackageName(module); - if (schemaLists != null) { - for (final ListSchemaNode list : schemaLists) { - if (!list.isAddedByUses()) { - generatedTypes.addAll(listToGenType(basePackageName, list)); - } - } - } - return generatedTypes; - } - - /** - * Converts all choices of the module to the list of - * Type objects. - * - * @param module - * module from which is obtained DataNodeIterator to iterate over - * all choices - * @return list of Type which are generated from choices - * (objects of type ChoiceNode) - * @throws IllegalArgumentException - *
    - *
  • if the module equals null
  • - *
  • if the name of module equals null
  • * - *
- * - */ - private List allChoicesToGenTypes(final Module module) { - if (module == null) { - throw new IllegalArgumentException("Module reference cannot be NULL!"); - } - if (module.getName() == null) { - throw new IllegalArgumentException("Module name cannot be NULL!"); - } - - final DataNodeIterator it = new DataNodeIterator(module); - final List choiceNodes = it.allChoices(); - final String basePackageName = moduleNamespaceToPackageName(module); - - final List generatedTypes = new ArrayList<>(); - for (final ChoiceNode choice : choiceNodes) { - if ((choice != null) && !choice.isAddedByUses()) { - generatedTypes.addAll(choiceToGeneratedType(basePackageName, choice)); - } - } - return generatedTypes; - } - - /** - * Converts all augmentation of the module to the list - * Type objects. - * - * @param module - * module from which is obtained list of all augmentation objects - * to iterate over them - * @return list of Type which are generated from augments - * (objects of type AugmentationSchema) - * @throws IllegalArgumentException - *
    - *
  • if the module equals null
  • - *
  • if the name of module equals null
  • - *
  • if the set of child nodes equals null
  • - *
- * - */ - private List allAugmentsToGenTypes(final Module module) { - if (module == null) { - throw new IllegalArgumentException("Module reference cannot be NULL!"); - } - if (module.getName() == null) { - throw new IllegalArgumentException("Module name cannot be NULL!"); - } - if (module.getChildNodes() == null) { - throw new IllegalArgumentException("Reference to Set of Augmentation Definitions in module " - + module.getName() + " cannot be NULL!"); - } - - final List generatedTypes = new ArrayList<>(); - final String basePackageName = moduleNamespaceToPackageName(module); - final List augmentations = resolveAugmentations(module); - for (final AugmentationSchema augment : augmentations) { - generatedTypes.addAll(augmentationToGenTypes(basePackageName, augment)); - } - return generatedTypes; - } - - /** - * Returns list of AugmentationSchema objects. The objects are - * sorted according to the length of their target path from the shortest to - * the longest. - * - * @param module - * module from which is obtained list of all augmentation objects - * @return list of sorted AugmentationSchema objects obtained - * from module - * @throws IllegalArgumentException - *
    - *
  • if the module equals null
  • - *
  • if the set of augmentation equals null
  • - *
- * - */ - private List resolveAugmentations(final Module module) { - if (module == null) { - throw new IllegalArgumentException("Module reference cannot be NULL!"); - } - if (module.getAugmentations() == null) { - throw new IllegalStateException("Augmentations Set cannot be NULL!"); - } - - final Set augmentations = module.getAugmentations(); - final List sortedAugmentations = new ArrayList<>(augmentations); - Collections.sort(sortedAugmentations, new Comparator() { - - @Override - public int compare(AugmentationSchema augSchema1, AugmentationSchema augSchema2) { - - if (augSchema1.getTargetPath().getPath().size() > augSchema2.getTargetPath().getPath().size()) { - return 1; - } else if (augSchema1.getTargetPath().getPath().size() < augSchema2.getTargetPath().getPath().size()) { - return -1; - } - return 0; - - } - }); - - return sortedAugmentations; - } - - /** - * Converts whole module to GeneratedType object. - * Firstly is created the module builder object from which is finally - * obtained reference to GeneratedType object. - * - * @param module - * module from which are obtained the module name, child nodes, - * uses and is derived package name - * @return GeneratedType which is internal representation of - * the module - * @throws IllegalArgumentException - * if the module equals null - * - */ - private GeneratedType moduleToDataType(final Module module) { - if (module == null) { - throw new IllegalArgumentException("Module reference cannot be NULL!"); - } - - final GeneratedTypeBuilder moduleDataTypeBuilder = moduleTypeBuilder(module, "Data"); - addImplementedInterfaceFromUses(module, moduleDataTypeBuilder); - moduleDataTypeBuilder.addImplementsType(Types.typeForClass(DataRoot.class)); - - final String basePackageName = moduleNamespaceToPackageName(module); - if (moduleDataTypeBuilder != null) { - final Set dataNodes = module.getChildNodes(); - resolveDataSchemaNodes(basePackageName, moduleDataTypeBuilder, dataNodes); - } - return moduleDataTypeBuilder.toInstance(); - } - - /** - * Converts all rpcs inputs and outputs substatements of the module - * to the list of Type objects. In addition are to containers - * and lists which belong to input or output also part of returning list. - * - * @param module - * module from which is obtained set of all rpc objects to - * iterate over them - * @return list of Type which are generated from rpcs inputs, - * outputs + container and lists which are part of inputs or outputs - * @throws IllegalArgumentException - *
    - *
  • if the module equals null
  • - *
  • if the name of module equals null
  • - *
  • if the set of child nodes equals null
  • - *
- * - */ - private List allRPCMethodsToGenType(final Module module) { - if (module == null) { - throw new IllegalArgumentException("Module reference cannot be NULL!"); - } - - if (module.getName() == null) { - throw new IllegalArgumentException("Module name cannot be NULL!"); - } - - if (module.getChildNodes() == null) { - throw new IllegalArgumentException("Reference to Set of RPC Method Definitions in module " - + module.getName() + " cannot be NULL!"); - } - - final String basePackageName = moduleNamespaceToPackageName(module); - final Set rpcDefinitions = module.getRpcs(); - - if (rpcDefinitions.isEmpty()) { - return Collections.emptyList(); - } - - final List genRPCTypes = new ArrayList<>(); - final GeneratedTypeBuilder interfaceBuilder = moduleTypeBuilder(module, "Service"); - interfaceBuilder.addImplementsType(Types.typeForClass(RpcService.class)); - final Type future = Types.typeForClass(Future.class); - for (final RpcDefinition rpc : rpcDefinitions) { - if (rpc != null) { - - String rpcName = parseToClassName(rpc.getQName().getLocalName()); - String rpcMethodName = parseToValidParamName(rpcName); - MethodSignatureBuilder method = interfaceBuilder.addMethod(rpcMethodName); - - final List rpcInOut = new ArrayList<>(); - - ContainerSchemaNode input = rpc.getInput(); - ContainerSchemaNode output = rpc.getOutput(); - - if (input != null) { - rpcInOut.add(new DataNodeIterator(input)); - GeneratedTypeBuilder inType = addRawInterfaceDefinition(basePackageName, input, rpcName); - addImplementedInterfaceFromUses(input, inType); - inType.addImplementsType(Types.DATA_OBJECT); - resolveDataSchemaNodes(basePackageName, inType, input.getChildNodes()); - Type inTypeInstance = inType.toInstance(); - genRPCTypes.add(inTypeInstance); - method.addParameter(inTypeInstance, "input"); - } - - Type outTypeInstance = Types.typeForClass(Void.class); - if (output != null) { - rpcInOut.add(new DataNodeIterator(output)); - GeneratedTypeBuilder outType = addRawInterfaceDefinition(basePackageName, output, rpcName); - addImplementedInterfaceFromUses(output, outType); - outType.addImplementsType(Types.DATA_OBJECT); - resolveDataSchemaNodes(basePackageName, outType, output.getChildNodes()); - outTypeInstance = outType.toInstance(); - genRPCTypes.add(outTypeInstance); - - } - - final Type rpcRes = Types.parameterizedTypeFor(Types.typeForClass(RpcResult.class), outTypeInstance); - method.setReturnType(Types.parameterizedTypeFor(future, rpcRes)); - for (DataNodeIterator it : rpcInOut) { - List nContainers = it.allContainers(); - if ((nContainers != null) && !nContainers.isEmpty()) { - for (final ContainerSchemaNode container : nContainers) { - if (!container.isAddedByUses()) { - genRPCTypes.add(containerToGenType(basePackageName, container)); - } - } - } - List nLists = it.allLists(); - if ((nLists != null) && !nLists.isEmpty()) { - for (final ListSchemaNode list : nLists) { - if (!list.isAddedByUses()) { - genRPCTypes.addAll(listToGenType(basePackageName, list)); - } - } - } - } - } - } - genRPCTypes.add(interfaceBuilder.toInstance()); - return genRPCTypes; - } - - /** - * Converts all notifications of the module to the list of - * Type objects. In addition are to this list added containers - * and lists which are part of this notification. - * - * @param module - * module from which is obtained set of all notification objects - * to iterate over them - * @return list of Type which are generated from notification - * (object of type NotificationDefinition - * @throws IllegalArgumentException - *
    - *
  • if the module equals null
  • - *
  • if the name of module equals null
  • - *
  • if the set of child nodes equals null
  • - *
- * - */ - private List allNotificationsToGenType(final Module module) { - if (module == null) { - throw new IllegalArgumentException("Module reference cannot be NULL!"); - } - - if (module.getName() == null) { - throw new IllegalArgumentException("Module name cannot be NULL!"); - } - - if (module.getChildNodes() == null) { - throw new IllegalArgumentException("Reference to Set of Notification Definitions in module " - + module.getName() + " cannot be NULL!"); - } - - final String basePackageName = moduleNamespaceToPackageName(module); - final List genNotifyTypes = new ArrayList<>(); - final Set notifications = module.getNotifications(); - - for (final NotificationDefinition notification : notifications) { - if (notification != null) { - DataNodeIterator it = new DataNodeIterator(notification); - - // Containers - for (ContainerSchemaNode node : it.allContainers()) { - if (!node.isAddedByUses()) { - genNotifyTypes.add(containerToGenType(basePackageName, node)); - } - } - // Lists - for (ListSchemaNode node : it.allLists()) { - if (!node.isAddedByUses()) { - genNotifyTypes.addAll(listToGenType(basePackageName, node)); - } - } - final GeneratedTypeBuilder notificationTypeBuilder = addDefaultInterfaceDefinition(basePackageName, - notification); - notificationTypeBuilder.addImplementsType(Types - .typeForClass(org.opendaylight.yangtools.yang.binding.Notification.class)); - // Notification object - resolveDataSchemaNodes(basePackageName, notificationTypeBuilder, notification.getChildNodes()); - genNotifyTypes.add(notificationTypeBuilder.toInstance()); - } - } - return genNotifyTypes; - } - - /** - * Converts all identities of the module to the list of - * Type objects. - * - * @param module - * module from which is obtained set of all identity objects to - * iterate over them - * @param context - * schema context only used as input parameter for method - * {@link identityToGenType} - * @return list of Type which are generated from identities - * (object of type IdentitySchemaNode - * - */ - private List allIdentitiesToGenTypes(final Module module, final SchemaContext context) { - List genTypes = new ArrayList<>(); - - final Set schemaIdentities = module.getIdentities(); - - final String basePackageName = moduleNamespaceToPackageName(module); - - if (schemaIdentities != null && !schemaIdentities.isEmpty()) { - for (final IdentitySchemaNode identity : schemaIdentities) { - genTypes.add(identityToGenType(basePackageName, identity, context)); - } - } - return genTypes; - } - - /** - * Converts the identity object to GeneratedType. Firstly it is - * created transport object builder. If identity contains base identity then - * reference to base identity is added to superior identity as its extend. - * If identity doesn't contain base identity then only reference to abstract - * class {@link org.opendaylight.yangtools.yang.model.api.BaseIdentity - * BaseIdentity} is added - * - * @param basePackageName - * string containing package name to which identity belongs - * @param identity - * IdentitySchemaNode which contains data about identity - * @param context - * SchemaContext which is used to get package and name - * information about base of identity - * - * @return GeneratedType which is generated from identity (object of type - * IdentitySchemaNode - * - */ - private GeneratedType identityToGenType(final String basePackageName, final IdentitySchemaNode identity, - final SchemaContext context) { - if (identity == null) { - return null; - } - - final String packageName = packageNameForGeneratedType(basePackageName, identity.getPath()); - final String genTypeName = parseToClassName(identity.getQName().getLocalName()); - final GeneratedTOBuilderImpl newType = new GeneratedTOBuilderImpl(packageName, genTypeName); - - IdentitySchemaNode baseIdentity = identity.getBaseIdentity(); - if (baseIdentity != null) { - Module baseIdentityParentModule = SchemaContextUtil.findParentModule(context, baseIdentity); - - final String returnTypePkgName = moduleNamespaceToPackageName(baseIdentityParentModule); - final String returnTypeName = parseToClassName(baseIdentity.getQName().getLocalName()); - - GeneratedTransferObject gto = new GeneratedTOBuilderImpl(returnTypePkgName, returnTypeName).toInstance(); - newType.setExtendsType(gto); - } else { - newType.setExtendsType(Types.getBaseIdentityTO()); - } - newType.setAbstract(true); - return newType.toInstance(); - } - - /** - * Converts all groupings of the module to the list of - * Type objects. Firstly are groupings sorted according mutual - * dependencies. At least dependend (indepedent) groupings are in the list - * saved at first positions. For every grouping the record is added to map - * {@link BindingGeneratorImpl#allGroupings allGroupings} - * - * @param module - * module from which is obtained set of all grouping objects to - * iterate over them - * @return list of Type which are generated from groupings - * (object of type GroupingDefinition) - * - */ - private List allGroupingsToGenTypes(final Module module) { - if (module == null) { - throw new IllegalArgumentException("Module parameter can not be null"); - } - final List genTypes = new ArrayList<>(); - final String basePackageName = moduleNamespaceToPackageName(module); - final Set groupings = module.getGroupings(); - List groupingsSortedByDependencies; - - groupingsSortedByDependencies = GroupingDefinitionDependencySort.sort(groupings); - - for (final GroupingDefinition grouping : groupingsSortedByDependencies) { - GeneratedType genType = groupingToGenType(basePackageName, grouping); - genTypes.add(genType); - SchemaPath schemaPath = grouping.getPath(); - allGroupings.put(schemaPath, genType); - } - return genTypes; - } - - /** - * Converts individual grouping to GeneratedType. Firstly generated type - * builder is created and every child node of grouping is resolved to the - * method. - * - * @param basePackageName - * string containing name of package to which grouping belongs. - * @param grouping - * GroupingDefinition which contains data about grouping - * @return GeneratedType which is generated from grouping (object of type - * GroupingDefinition) - */ - private GeneratedType groupingToGenType(final String basePackageName, GroupingDefinition grouping) { - if (grouping == null) { - return null; - } - - final String packageName = packageNameForGeneratedType(basePackageName, grouping.getPath()); - final Set schemaNodes = grouping.getChildNodes(); - final GeneratedTypeBuilder typeBuilder = addDefaultInterfaceDefinition(packageName, grouping); - - resolveDataSchemaNodes(basePackageName, typeBuilder, schemaNodes); - return typeBuilder.toInstance(); - } - - /** - * Tries to find EnumTypeDefinition in typeDefinition. If base - * type of typeDefinition is of the type ExtendedType then this - * method is recursivelly called with this base type. - * - * @param typeDefinition - * TypeDefinition in which should be EnumTypeDefinition found as - * base type - * @return EnumTypeDefinition if it is found inside - * typeDefinition or null in other case - */ - private EnumTypeDefinition enumTypeDefFromExtendedType(final TypeDefinition typeDefinition) { - if (typeDefinition != null) { - if (typeDefinition.getBaseType() instanceof EnumTypeDefinition) { - return (EnumTypeDefinition) typeDefinition.getBaseType(); - } else if (typeDefinition.getBaseType() instanceof ExtendedType) { - return enumTypeDefFromExtendedType(typeDefinition.getBaseType()); - } - } - return null; - } - - /** - * Adds enumeration builder created from enumTypeDef to - * typeBuilder. - * - * Each enumTypeDef item is added to builder with its name and - * value. - * - * @param enumTypeDef - * EnumTypeDefinition contains enum data - * @param enumName - * string contains name which will be assigned to enumeration - * builder - * @param typeBuilder - * GeneratedTypeBuilder to which will be enum builder assigned - * @return enumeration builder which contais data from - * enumTypeDef - */ - private EnumBuilder resolveInnerEnumFromTypeDefinition(final EnumTypeDefinition enumTypeDef, final String enumName, - final GeneratedTypeBuilder typeBuilder) { - if ((enumTypeDef != null) && (typeBuilder != null) && (enumTypeDef.getQName() != null) - && (enumTypeDef.getQName().getLocalName() != null)) { - - final String enumerationName = parseToClassName(enumName); - final EnumBuilder enumBuilder = typeBuilder.addEnumeration(enumerationName); - - if (enumBuilder != null) { - final List enums = enumTypeDef.getValues(); - if (enums != null) { - int listIndex = 0; - for (final EnumPair enumPair : enums) { - if (enumPair != null) { - final String enumPairName = parseToClassName(enumPair.getName()); - Integer enumPairValue = enumPair.getValue(); - - if (enumPairValue == null) { - enumPairValue = listIndex; - } - enumBuilder.addValue(enumPairName, enumPairValue); - listIndex++; - } - } - } - return enumBuilder; - } - } - return null; - } - - /** - * Generates type builder for module. - * - * @param module - * Module which is source of package name for generated type - * builder - * @param postfix - * string which is added to the module class name representation - * as suffix - * @return instance of GeneratedTypeBuilder which represents - * module. - * @throws IllegalArgumentException - * if module equals null - */ - private GeneratedTypeBuilder moduleTypeBuilder(final Module module, final String postfix) { - if (module == null) { - throw new IllegalArgumentException("Module reference cannot be NULL!"); - } - String packageName = moduleNamespaceToPackageName(module); - final String moduleName = parseToClassName(module.getName()) + postfix; - - return new GeneratedTypeBuilderImpl(packageName, moduleName); - - } - - /** - * Converts augSchema to list of Type which - * contains generated type for augmentation. In addition there are also - * generated types for all containers, list and choices which are child of - * augSchema node or a generated types for cases are added if - * augmented node is choice. - * - * @param augmentPackageName - * string with the name of the package to which the augmentation - * belongs - * @param augSchema - * AugmentationSchema which is contains data about agumentation - * (target path, childs...) - * @return list of Type objects which contains generated type - * for augmentation and for container, list and choice child nodes - * @throws IllegalArgumentException - *
    - *
  • if augmentPackageName equals null
  • - *
  • if augSchema equals null
  • - *
  • if target path of augSchema equals null
  • - *
- */ - private List augmentationToGenTypes(final String augmentPackageName, final AugmentationSchema augSchema) { - if (augmentPackageName == null) { - throw new IllegalArgumentException("Package Name cannot be NULL!"); - } - if (augSchema == null) { - throw new IllegalArgumentException("Augmentation Schema cannot be NULL!"); - } - if (augSchema.getTargetPath() == null) { - throw new IllegalStateException("Augmentation Schema does not contain Target Path (Target Path is NULL)."); - } - - final List genTypes = new ArrayList<>(); - - // EVERY augmented interface will extends Augmentation interface - // and DataObject interface!!! - final SchemaPath targetPath = augSchema.getTargetPath(); - final DataSchemaNode targetSchemaNode = findDataSchemaNode(schemaContext, targetPath); - if ((targetSchemaNode != null) && (targetSchemaNode.getQName() != null) - && (targetSchemaNode.getQName().getLocalName() != null)) { - final Module targetModule = findParentModule(schemaContext, targetSchemaNode); - final String targetBasePackage = moduleNamespaceToPackageName(targetModule); - final String targetPackageName = packageNameForGeneratedType(targetBasePackage, targetSchemaNode.getPath()); - final String targetSchemaNodeName = targetSchemaNode.getQName().getLocalName(); - final Set augChildNodes = augSchema.getChildNodes(); - - if (!(targetSchemaNode instanceof ChoiceNode)) { - final GeneratedTypeBuilder augTypeBuilder = addRawAugmentGenTypeDefinition(augmentPackageName, - targetPackageName, targetSchemaNodeName, augSchema); - final GeneratedType augType = augTypeBuilder.toInstance(); - genTypes.add(augType); - } else { - final Type refChoiceType = new ReferencedTypeImpl(targetPackageName, - parseToClassName(targetSchemaNodeName)); - final ChoiceNode choiceTarget = (ChoiceNode) targetSchemaNode; - final Set choiceCaseNodes = choiceTarget.getCases(); - genTypes.addAll(generateTypesFromAugmentedChoiceCases(augmentPackageName, refChoiceType, - choiceCaseNodes)); - } - genTypes.addAll(augmentationBodyToGenTypes(augmentPackageName, augChildNodes)); - } - return genTypes; - } - - /** - * Returns a generated type builder for an augmentation. - * - * The name of the type builder is equal to the name of augmented node with - * serial number as suffix. - * - * @param augmentPackageName - * string with contains the package name to which the augment - * belongs - * @param targetPackageName - * string with the package name to which the augmented node - * belongs - * @param targetSchemaNodeName - * string with the name of the augmented node - * @param augSchema - * augmentation schema which contains data about the child nodes - * and uses of augment - * @return generated type builder for augment - */ - private GeneratedTypeBuilder addRawAugmentGenTypeDefinition(final String augmentPackageName, - final String targetPackageName, final String targetSchemaNodeName, final AugmentationSchema augSchema) { - final String targetTypeName = parseToClassName(targetSchemaNodeName); - Map augmentBuilders = genTypeBuilders.get(augmentPackageName); - if (augmentBuilders == null) { - augmentBuilders = new HashMap<>(); - genTypeBuilders.put(augmentPackageName, augmentBuilders); - } - final String augIdentifier = getAugmentIdentifier(augSchema.getUnknownSchemaNodes()); - - final String augTypeName = augIdentifier != null ? parseToClassName(augIdentifier): augGenTypeName(augmentBuilders, targetTypeName); - final Type targetTypeRef = new ReferencedTypeImpl(targetPackageName, targetTypeName); - final Set augChildNodes = augSchema.getChildNodes(); - - final GeneratedTypeBuilder augTypeBuilder = new GeneratedTypeBuilderImpl(augmentPackageName, augTypeName); - - augTypeBuilder.addImplementsType(Types.DATA_OBJECT); - augTypeBuilder.addImplementsType(Types.augmentationTypeFor(targetTypeRef)); - addImplementedInterfaceFromUses(augSchema, augTypeBuilder); - - augSchemaNodeToMethods(augmentPackageName, augTypeBuilder, augChildNodes); - augmentBuilders.put(augTypeName, augTypeBuilder); - return augTypeBuilder; - } - - private String getAugmentIdentifier(List unknownSchemaNodes) { - String ret = null; - for (UnknownSchemaNode unknownSchemaNode : unknownSchemaNodes) { - QName nodeType = unknownSchemaNode.getNodeType(); - if(AUGMENT_IDENTIFIER_NAME.equals(nodeType.getLocalName()) && - YANG_EXT_NAMESPACE.equals(nodeType.getNamespace().toString())) { - return unknownSchemaNode.getNodeParameter(); - } - } - return ret; - } - - /** - * 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 List augmentationBodyToGenTypes(final String augBasePackageName, - final Set augChildNodes) { - final List genTypes = new ArrayList<>(); - final List augSchemaIts = new ArrayList<>(); - for (final DataSchemaNode childNode : augChildNodes) { - if (childNode instanceof DataNodeContainer) { - augSchemaIts.add(new DataNodeIterator((DataNodeContainer) childNode)); - - if (childNode instanceof ContainerSchemaNode) { - genTypes.add(containerToGenType(augBasePackageName, (ContainerSchemaNode) childNode)); - } else if (childNode instanceof ListSchemaNode) { - genTypes.addAll(listToGenType(augBasePackageName, (ListSchemaNode) childNode)); - } - } else if (childNode instanceof ChoiceNode) { - final ChoiceNode choice = (ChoiceNode) childNode; - for (final ChoiceCaseNode caseNode : choice.getCases()) { - augSchemaIts.add(new DataNodeIterator(caseNode)); - } - genTypes.addAll(choiceToGeneratedType(augBasePackageName, (ChoiceNode) childNode)); - } - } - - for (final DataNodeIterator it : augSchemaIts) { - final List augContainers = it.allContainers(); - final List augLists = it.allLists(); - final List augChoices = it.allChoices(); - - if (augContainers != null) { - for (final ContainerSchemaNode container : augContainers) { - genTypes.add(containerToGenType(augBasePackageName, container)); - } - } - if (augLists != null) { - for (final ListSchemaNode list : augLists) { - genTypes.addAll(listToGenType(augBasePackageName, list)); - } - } - if (augChoices != null) { - for (final ChoiceNode choice : augChoices) { - genTypes.addAll(choiceToGeneratedType(augBasePackageName, choice)); - } - } - } - return genTypes; - } - - /** - * Returns first unique name for the augment generated type builder. The - * generated type builder name for augment consists from name of augmented - * node and serial number of its augmentation. - * - * @param builders - * map of builders which were created in the package to which the - * augmentation belongs - * @param genTypeName - * string with name of augmented node - * @return string with unique name for augmentation builder - */ - private String augGenTypeName(final Map builders, final String genTypeName) { - String augTypeName = genTypeName; - - int index = 1; - while ((builders != null) && builders.containsKey(genTypeName + index)) { - index++; - } - augTypeName += index; - return augTypeName; - } - - /** - * Converts containerNode to generated type. Firstly the - * generated type builder is created. The subnodes of - * containerNode are added as methods and the instance of - * GeneratedType is returned. - * - * @param basePackageName - * string with name of the package to which the superior node - * belongs - * @param containerNode - * container schema node with the data about childs nodes and - * schema paths - * @return generated type for containerNode - */ - private GeneratedType containerToGenType(final String basePackageName, ContainerSchemaNode containerNode) { - if (containerNode == null) { - return null; - } - - final String packageName = packageNameForGeneratedType(basePackageName, containerNode.getPath()); - final Set schemaNodes = containerNode.getChildNodes(); - final GeneratedTypeBuilder typeBuilder = addDefaultInterfaceDefinition(packageName, containerNode); - - resolveDataSchemaNodes(basePackageName, typeBuilder, schemaNodes); - return typeBuilder.toInstance(); - } - - /** - * - * @param basePackageName - * @param typeBuilder - * @param schemaNodes - * @return - */ - private GeneratedTypeBuilder resolveDataSchemaNodes(final String basePackageName, - final GeneratedTypeBuilder typeBuilder, final Set schemaNodes) { - if ((schemaNodes != null) && (typeBuilder != null)) { - for (final DataSchemaNode schemaNode : schemaNodes) { - if (schemaNode.isAugmenting() || schemaNode.isAddedByUses()) { - continue; - } - addSchemaNodeToBuilderAsMethod(basePackageName, schemaNode, typeBuilder); - } - } - return typeBuilder; - } - - private GeneratedTypeBuilder augSchemaNodeToMethods(final String basePackageName, - final GeneratedTypeBuilder typeBuilder, final Set schemaNodes) { - if ((schemaNodes != null) && (typeBuilder != null)) { - for (final DataSchemaNode schemaNode : schemaNodes) { - if (schemaNode.isAugmenting()) { - addSchemaNodeToBuilderAsMethod(basePackageName, schemaNode, typeBuilder); - } - } - } - return typeBuilder; - } - - private void addSchemaNodeToBuilderAsMethod(final String basePackageName, final DataSchemaNode schemaNode, - final GeneratedTypeBuilder typeBuilder) { - if (schemaNode != null && typeBuilder != null) { - if (schemaNode instanceof LeafSchemaNode) { - resolveLeafSchemaNodeAsMethod(typeBuilder, (LeafSchemaNode) schemaNode); - } else if (schemaNode instanceof LeafListSchemaNode) { - resolveLeafListSchemaNode(typeBuilder, (LeafListSchemaNode) schemaNode); - } else if (schemaNode instanceof ContainerSchemaNode) { - resolveContainerSchemaNode(basePackageName, typeBuilder, (ContainerSchemaNode) schemaNode); - } else if (schemaNode instanceof ListSchemaNode) { - resolveListSchemaNode(basePackageName, typeBuilder, (ListSchemaNode) schemaNode); - } else if (schemaNode instanceof ChoiceNode) { - resolveChoiceSchemaNode(basePackageName, typeBuilder, (ChoiceNode) schemaNode); - } - } - } - - private void resolveChoiceSchemaNode(final String basePackageName, final GeneratedTypeBuilder typeBuilder, - final ChoiceNode choiceNode) { - if (basePackageName == null) { - throw new IllegalArgumentException("Base Package Name cannot be NULL!"); - } - if (typeBuilder == null) { - throw new IllegalArgumentException("Generated Type Builder cannot be NULL!"); - } - if (choiceNode == null) { - throw new IllegalArgumentException("Choice Schema Node cannot be NULL!"); - } - - final String choiceName = choiceNode.getQName().getLocalName(); - if (choiceName != null && !choiceNode.isAddedByUses()) { - final String packageName = packageNameForGeneratedType(basePackageName, choiceNode.getPath()); - final GeneratedTypeBuilder choiceType = addDefaultInterfaceDefinition(packageName, choiceNode); - constructGetter(typeBuilder, choiceName, choiceNode.getDescription(), choiceType); - } - } - - private List choiceToGeneratedType(final String basePackageName, final ChoiceNode choiceNode) { - if (basePackageName == null) { - throw new IllegalArgumentException("Base Package Name cannot be NULL!"); - } - if (choiceNode == null) { - throw new IllegalArgumentException("Choice Schema Node cannot be NULL!"); - } - - final List generatedTypes = new ArrayList<>(); - final String packageName = packageNameForGeneratedType(basePackageName, choiceNode.getPath()); - final GeneratedTypeBuilder choiceTypeBuilder = addRawInterfaceDefinition(packageName, choiceNode); - choiceTypeBuilder.addImplementsType(Types.DATA_OBJECT); - final GeneratedType choiceType = choiceTypeBuilder.toInstance(); - - generatedTypes.add(choiceType); - final Set caseNodes = choiceNode.getCases(); - if ((caseNodes != null) && !caseNodes.isEmpty()) { - generatedTypes.addAll(generateTypesFromChoiceCases(basePackageName, choiceType, caseNodes)); - } - return generatedTypes; - } - - private List generateTypesFromChoiceCases(final String basePackageName, final Type refChoiceType, - final Set caseNodes) { - if (basePackageName == null) { - throw new IllegalArgumentException("Base Package Name cannot be NULL!"); - } - if (refChoiceType == null) { - throw new IllegalArgumentException("Referenced Choice Type cannot be NULL!"); - } - if (caseNodes == null) { - throw new IllegalArgumentException("Set of Choice Case Nodes cannot be NULL!"); - } - - final List generatedTypes = new ArrayList<>(); - for (final ChoiceCaseNode caseNode : caseNodes) { - if (caseNode != null && !caseNode.isAddedByUses() && !caseNode.isAugmenting()) { - final String packageName = packageNameForGeneratedType(basePackageName, caseNode.getPath()); - final GeneratedTypeBuilder caseTypeBuilder = addDefaultInterfaceDefinition(packageName, caseNode); - caseTypeBuilder.addImplementsType(refChoiceType); - - final Set childNodes = caseNode.getChildNodes(); - if (childNodes != null) { - resolveDataSchemaNodes(basePackageName, caseTypeBuilder, childNodes); - } - generatedTypes.add(caseTypeBuilder.toInstance()); - } - } - - return generatedTypes; - } - - /** - * Generates list of generated types for all the cases of a choice which are - * added to the choice through the augment. - * - * - * @param basePackageName - * string contains name of package to which augment belongs. If - * an augmented choice is from an other package (pcg1) than an - * augmenting choice (pcg2) then case's of the augmenting choice - * will belong to pcg2. - * @param refChoiceType - * Type which represents the choice to which case belongs. Every - * case has to contain its choice in extend part. - * @param caseNodes - * set of choice case nodes for which is checked if are/aren't - * added to choice through augmentation - * @return list of generated types which represents augmented cases of - * choice refChoiceType - * @throws IllegalArgumentException - *
    - *
  • if basePackageName equals null
  • - *
  • if refChoiceType equals null
  • - *
  • if caseNodes equals null
  • - *
- */ - private List generateTypesFromAugmentedChoiceCases(final String basePackageName, - final Type refChoiceType, final Set caseNodes) { - if (basePackageName == null) { - throw new IllegalArgumentException("Base Package Name cannot be NULL!"); - } - if (refChoiceType == null) { - throw new IllegalArgumentException("Referenced Choice Type cannot be NULL!"); - } - if (caseNodes == null) { - throw new IllegalArgumentException("Set of Choice Case Nodes cannot be NULL!"); - } - - final List generatedTypes = new ArrayList<>(); - for (final ChoiceCaseNode caseNode : caseNodes) { - if (caseNode != null && caseNode.isAugmenting()) { - final String packageName = packageNameForGeneratedType(basePackageName, caseNode.getPath()); - final GeneratedTypeBuilder caseTypeBuilder = addDefaultInterfaceDefinition(packageName, caseNode); - caseTypeBuilder.addImplementsType(refChoiceType); - - final Set childNodes = caseNode.getChildNodes(); - if (childNodes != null) { - resolveDataSchemaNodes(basePackageName, caseTypeBuilder, childNodes); - } - generatedTypes.add(caseTypeBuilder.toInstance()); - } - } - - return generatedTypes; - } - - private boolean resolveLeafSchemaNodeAsMethod(final GeneratedTypeBuilder typeBuilder, final LeafSchemaNode leaf) { - if ((leaf != null) && (typeBuilder != null)) { - final String leafName = leaf.getQName().getLocalName(); - String leafDesc = leaf.getDescription(); - if (leafDesc == null) { - leafDesc = ""; - } - - if (leafName != null && !leaf.isAddedByUses()) { - final TypeDefinition typeDef = leaf.getType(); - - Type returnType = null; - if (typeDef instanceof EnumTypeDefinition) { - returnType = typeProvider.javaTypeForSchemaDefinitionType(typeDef); - final EnumTypeDefinition enumTypeDef = enumTypeDefFromExtendedType(typeDef); - final EnumBuilder enumBuilder = resolveInnerEnumFromTypeDefinition(enumTypeDef, leafName, - typeBuilder); - - if (enumBuilder != null) { - returnType = new ReferencedTypeImpl(enumBuilder.getPackageName(), enumBuilder.getName()); - } - ((TypeProviderImpl) typeProvider).putReferencedType(leaf.getPath(), returnType); - } else if (typeDef instanceof UnionType) { - GeneratedTOBuilder genTOBuilder = addEnclosedTOToTypeBuilder(typeDef, typeBuilder, leafName); - if (genTOBuilder != null) { - returnType = new ReferencedTypeImpl(genTOBuilder.getPackageName(), genTOBuilder.getName()); - } - } else if (typeDef instanceof BitsTypeDefinition) { - GeneratedTOBuilder genTOBuilder = addEnclosedTOToTypeBuilder(typeDef, typeBuilder, leafName); - if (genTOBuilder != null) { - returnType = new ReferencedTypeImpl(genTOBuilder.getPackageName(), genTOBuilder.getName()); - } - } else { - returnType = typeProvider.javaTypeForSchemaDefinitionType(typeDef); - } - if (returnType != null) { - constructGetter(typeBuilder, leafName, leafDesc, returnType); - return true; - } - } - } - return false; - } - - private boolean resolveLeafSchemaNodeAsProperty(final GeneratedTOBuilder toBuilder, final LeafSchemaNode leaf, - boolean isReadOnly) { - if ((leaf != null) && (toBuilder != null)) { - final String leafName = leaf.getQName().getLocalName(); - String leafDesc = leaf.getDescription(); - if (leafDesc == null) { - leafDesc = ""; - } - - if (leafName != null && !leaf.isAddedByUses()) { - final TypeDefinition typeDef = leaf.getType(); - - // TODO: properly resolve enum types - final Type returnType = typeProvider.javaTypeForSchemaDefinitionType(typeDef); - - if (returnType != null) { - final GeneratedPropertyBuilder propBuilder = toBuilder.addProperty(parseToClassName(leafName)); - - propBuilder.setReadOnly(isReadOnly); - propBuilder.setReturnType(returnType); - propBuilder.setComment(leafDesc); - - toBuilder.addEqualsIdentity(propBuilder); - toBuilder.addHashIdentity(propBuilder); - toBuilder.addToStringProperty(propBuilder); - - return true; - } - } - } - return false; - } - - private boolean resolveLeafListSchemaNode(final GeneratedTypeBuilder typeBuilder, final LeafListSchemaNode node) { - if ((node != null) && (typeBuilder != null)) { - final String nodeName = node.getQName().getLocalName(); - String nodeDesc = node.getDescription(); - if (nodeDesc == null) { - nodeDesc = ""; - } - - if (nodeName != null && !node.isAddedByUses()) { - final TypeDefinition type = node.getType(); - final Type listType = Types.listTypeFor(typeProvider.javaTypeForSchemaDefinitionType(type)); - - constructGetter(typeBuilder, nodeName, nodeDesc, listType); - return true; - } - } - return false; - } - - private boolean resolveContainerSchemaNode(final String basePackageName, final GeneratedTypeBuilder typeBuilder, - final ContainerSchemaNode containerNode) { - if ((containerNode != null) && (typeBuilder != null)) { - final String nodeName = containerNode.getQName().getLocalName(); - - if (nodeName != null && !containerNode.isAddedByUses()) { - final String packageName = packageNameForGeneratedType(basePackageName, containerNode.getPath()); - - final GeneratedTypeBuilder rawGenType = addDefaultInterfaceDefinition(packageName, containerNode); - constructGetter(typeBuilder, nodeName, containerNode.getDescription(), rawGenType); - - return true; - } - } - return false; - } - - private boolean resolveListSchemaNode(final String basePackageName, final GeneratedTypeBuilder typeBuilder, - final ListSchemaNode schemaNode) { - if ((schemaNode != null) && (typeBuilder != null)) { - final String listName = schemaNode.getQName().getLocalName(); - - if (listName != null && !schemaNode.isAddedByUses()) { - final String packageName = packageNameForGeneratedType(basePackageName, schemaNode.getPath()); - final GeneratedTypeBuilder rawGenType = addDefaultInterfaceDefinition(packageName, schemaNode); - constructGetter(typeBuilder, listName, schemaNode.getDescription(), Types.listTypeFor(rawGenType)); - return true; - } - } - return false; - } - - /** - * Method instantiates new Generated Type Builder and sets the implements - * definitions of Data Object and Augmentable. - * - * @param packageName - * Generated Type Package Name - * @param schemaNode - * Schema Node definition - * @return Generated Type Builder instance for Schema Node definition - */ - private GeneratedTypeBuilder addDefaultInterfaceDefinition(final String packageName, final SchemaNode schemaNode) { - final GeneratedTypeBuilder builder = addRawInterfaceDefinition(packageName, schemaNode, ""); - builder.addImplementsType(Types.DATA_OBJECT); - if (!(schemaNode instanceof GroupingDefinition)) { - builder.addImplementsType(Types.augmentableTypeFor(builder)); - } - - if (schemaNode instanceof DataNodeContainer) { - addImplementedInterfaceFromUses((DataNodeContainer) schemaNode, builder); - } - - return builder; - } - - /** - * - * @param packageName - * @param schemaNode - * @return - */ - private GeneratedTypeBuilder addRawInterfaceDefinition(final String packageName, final SchemaNode schemaNode) { - return addRawInterfaceDefinition(packageName, schemaNode, ""); - } - - private GeneratedTypeBuilder addRawInterfaceDefinition(final String packageName, final SchemaNode schemaNode, - final String prefix) { - if (schemaNode == null) { - throw new IllegalArgumentException("Data Schema Node cannot be NULL!"); - } - if (packageName == null) { - throw new IllegalArgumentException("Package Name for Generated Type cannot be NULL!"); - } - if (schemaNode.getQName() == null) { - throw new IllegalArgumentException("QName for Data Schema Node cannot be NULL!"); - } - final String schemaNodeName = schemaNode.getQName().getLocalName(); - if (schemaNodeName == null) { - throw new IllegalArgumentException("Local Name of QName for Data Schema Node cannot be NULL!"); - } - - final String genTypeName; - if (prefix == null) { - genTypeName = parseToClassName(schemaNodeName); - } else { - genTypeName = prefix + parseToClassName(schemaNodeName); - } - - final GeneratedTypeBuilder newType = new GeneratedTypeBuilderImpl(packageName, genTypeName); - if (!genTypeBuilders.containsKey(packageName)) { - final Map builders = new HashMap<>(); - builders.put(genTypeName, newType); - genTypeBuilders.put(packageName, builders); - } else { - final Map builders = genTypeBuilders.get(packageName); - if (!builders.containsKey(genTypeName)) { - builders.put(genTypeName, newType); - } - } - return newType; - } - - private String getterMethodName(final String methodName) { - final StringBuilder method = new StringBuilder(); - method.append("get"); - method.append(parseToClassName(methodName)); - return method.toString(); - } - - private String setterMethodName(final String methodName) { - final StringBuilder method = new StringBuilder(); - method.append("set"); - method.append(parseToClassName(methodName)); - return method.toString(); - } - - private MethodSignatureBuilder constructGetter(final GeneratedTypeBuilder interfaceBuilder, - final String schemaNodeName, final String comment, final Type returnType) { - final MethodSignatureBuilder getMethod = interfaceBuilder.addMethod(getterMethodName(schemaNodeName)); - - getMethod.setComment(comment); - getMethod.setReturnType(returnType); - - return getMethod; - } - - private MethodSignatureBuilder constructSetter(final GeneratedTypeBuilder interfaceBuilder, - final String schemaNodeName, final String comment, final Type parameterType) { - final MethodSignatureBuilder setMethod = interfaceBuilder.addMethod(setterMethodName(schemaNodeName)); - - setMethod.setComment(comment); - setMethod.addParameter(parameterType, parseToValidParamName(schemaNodeName)); - setMethod.setReturnType(Types.voidType()); - - return setMethod; - } - - private List listToGenType(final String basePackageName, final ListSchemaNode list) { - if (basePackageName == null) { - throw new IllegalArgumentException("Package Name for Generated Type cannot be NULL!"); - } - if (list == null) { - throw new IllegalArgumentException("List Schema Node cannot be NULL!"); - } - - final String packageName = packageNameForGeneratedType(basePackageName, list.getPath()); - final GeneratedTypeBuilder typeBuilder = resolveListTypeBuilder(packageName, list); - final List listKeys = listKeys(list); - GeneratedTOBuilder genTOBuilder = resolveListKeyTOBuilder(packageName, list, listKeys); - - - if(genTOBuilder != null) { - ParameterizedType identifierMarker = Types.parameterizedTypeFor( Types.typeForClass(Identifier.class), typeBuilder); - ParameterizedType identifiableMarker = Types.parameterizedTypeFor(Types.typeForClass(Identifiable.class), genTOBuilder); - genTOBuilder.addImplementsType(identifierMarker); - typeBuilder.addImplementsType(identifiableMarker); - } - final Set schemaNodes = list.getChildNodes(); - - for (final DataSchemaNode schemaNode : schemaNodes) { - if (schemaNode.isAugmenting()) { - continue; - } - addSchemaNodeToListBuilders(basePackageName, schemaNode, typeBuilder, genTOBuilder, listKeys); - } - return typeBuildersToGenTypes(typeBuilder, genTOBuilder); - } - - private void addSchemaNodeToListBuilders(final String basePackageName, final DataSchemaNode schemaNode, - final GeneratedTypeBuilder typeBuilder, final GeneratedTOBuilder genTOBuilder, final List listKeys) { - if (schemaNode == null) { - throw new IllegalArgumentException("Data Schema Node cannot be NULL!"); - } - - if (typeBuilder == null) { - throw new IllegalArgumentException("Generated Type Builder cannot be NULL!"); - } - - if (schemaNode instanceof LeafSchemaNode) { - final LeafSchemaNode leaf = (LeafSchemaNode) schemaNode; - if (!isPartOfListKey(leaf, listKeys)) { - resolveLeafSchemaNodeAsMethod(typeBuilder, leaf); - } else { - resolveLeafSchemaNodeAsProperty(genTOBuilder, leaf, true); - } - } else if (schemaNode instanceof LeafListSchemaNode) { - resolveLeafListSchemaNode(typeBuilder, (LeafListSchemaNode) schemaNode); - } else if (schemaNode instanceof ContainerSchemaNode) { - resolveContainerSchemaNode(basePackageName, typeBuilder, (ContainerSchemaNode) schemaNode); - } else if (schemaNode instanceof ListSchemaNode) { - resolveListSchemaNode(basePackageName, typeBuilder, (ListSchemaNode) schemaNode); - } - } - - private List typeBuildersToGenTypes(final GeneratedTypeBuilder typeBuilder, GeneratedTOBuilder genTOBuilder) { - final List genTypes = new ArrayList<>(); - if (typeBuilder == null) { - throw new IllegalArgumentException("Generated Type Builder cannot be NULL!"); - } - - if (genTOBuilder != null) { - final GeneratedTransferObject genTO = genTOBuilder.toInstance(); - constructGetter(typeBuilder, "key", "Returns Primary Key of Yang List Type", genTO); - genTypes.add(genTO); - } - genTypes.add(typeBuilder.toInstance()); - return genTypes; - } - - /** - * @param list - * @return - */ - private GeneratedTOBuilder resolveListKey(final String packageName, final ListSchemaNode list) { - final String listName = list.getQName().getLocalName() + "Key"; - return schemaNodeToTransferObjectBuilder(packageName, list, listName); - } - - private boolean isPartOfListKey(final LeafSchemaNode leaf, final List keys) { - if ((leaf != null) && (keys != null) && (leaf.getQName() != null)) { - final String leafName = leaf.getQName().getLocalName(); - if (keys.contains(leafName)) { - return true; - } - } - return false; - } - - private List listKeys(final ListSchemaNode list) { - final List listKeys = new ArrayList<>(); - - if (list.getKeyDefinition() != null) { - final List keyDefinitions = list.getKeyDefinition(); - - for (final QName keyDefinition : keyDefinitions) { - listKeys.add(keyDefinition.getLocalName()); - } - } - return listKeys; - } - - private GeneratedTypeBuilder resolveListTypeBuilder(final String packageName, final ListSchemaNode list) { - if (packageName == null) { - throw new IllegalArgumentException("Package Name for Generated Type cannot be NULL!"); - } - if (list == null) { - throw new IllegalArgumentException("List Schema Node cannot be NULL!"); - } - - final String schemaNodeName = list.getQName().getLocalName(); - final String genTypeName = parseToClassName(schemaNodeName); - - GeneratedTypeBuilder typeBuilder = null; - final Map builders = genTypeBuilders.get(packageName); - if (builders != null) { - typeBuilder = builders.get(genTypeName); - } - if (typeBuilder == null) { - typeBuilder = addDefaultInterfaceDefinition(packageName, list); - } - return typeBuilder; - } - - private GeneratedTOBuilder resolveListKeyTOBuilder(final String packageName, final ListSchemaNode list, - final List listKeys) { - GeneratedTOBuilder genTOBuilder = null; - if (listKeys.size() > 0) { - genTOBuilder = resolveListKey(packageName, list); - } - return genTOBuilder; - } - - private GeneratedTOBuilder addEnclosedTOToTypeBuilder(TypeDefinition typeDef, GeneratedTypeBuilder typeBuilder, - String leafName) { - String className = parseToClassName(leafName); - GeneratedTOBuilder genTOBuilder = null; - if (typeDef instanceof UnionType) { - genTOBuilder = ((TypeProviderImpl) typeProvider).addUnionGeneratedTypeDefinition( - typeBuilder.getFullyQualifiedName(), typeDef, className); - } else if (typeDef instanceof BitsTypeDefinition) { - genTOBuilder = ((TypeProviderImpl) typeProvider).bitsTypedefToTransferObject( - typeBuilder.getFullyQualifiedName(), typeDef, className); - } - if (genTOBuilder != null) { - typeBuilder.addEnclosingTransferObject(genTOBuilder); - return genTOBuilder; - } - return null; - - } - - /** - * Adds the implemented types to type builder. The method passes through the - * list of elements which contains {@code dataNodeContainer} and adds them - * as implements type to builder - * - * @param dataNodeContainer - * element which contains the list of used YANG groupings - * @param builder - * builder to which are added implemented types according to - * dataNodeContainer - * @return generated type builder which contains implemented types - */ - private GeneratedTypeBuilder addImplementedInterfaceFromUses(final DataNodeContainer dataNodeContainer, - final GeneratedTypeBuilder builder) { - for (UsesNode usesNode : dataNodeContainer.getUses()) { - if (usesNode.getGroupingPath() != null) { - GeneratedType genType = allGroupings.get(usesNode.getGroupingPath()); - if (genType == null) { - throw new IllegalStateException("Grouping " + usesNode.getGroupingPath() + "is not resolved for " - + builder.getName()); - } - builder.addImplementsType(genType); - } - } - return builder; - } - -} +/* + * 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 static org.opendaylight.yangtools.binding.generator.util.BindingGeneratorUtil.moduleNamespaceToPackageName; +import static org.opendaylight.yangtools.binding.generator.util.BindingGeneratorUtil.packageNameForGeneratedType; +import static org.opendaylight.yangtools.binding.generator.util.BindingGeneratorUtil.parseToClassName; +import static org.opendaylight.yangtools.binding.generator.util.BindingGeneratorUtil.parseToValidParamName; +import static org.opendaylight.yangtools.binding.generator.util.BindingGeneratorUtil.schemaNodeToTransferObjectBuilder; +import static org.opendaylight.yangtools.yang.model.util.SchemaContextUtil.findDataSchemaNode; +import static org.opendaylight.yangtools.yang.model.util.SchemaContextUtil.findParentModule; + +import java.net.URI; +import java.net.URISyntaxException; +import java.util.ArrayList; +import java.util.Collections; +import java.util.Comparator; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Set; +import java.util.concurrent.Future; + +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.ConcreteType; +import org.opendaylight.yangtools.sal.binding.model.api.GeneratedTransferObject; +import org.opendaylight.yangtools.sal.binding.model.api.GeneratedType; +import org.opendaylight.yangtools.sal.binding.model.api.ParameterizedType; +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.GeneratedPropertyBuilder; +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.DataRoot; +import org.opendaylight.yangtools.yang.binding.Identifiable; +import org.opendaylight.yangtools.yang.binding.Identifier; +import org.opendaylight.yangtools.yang.binding.RpcService; +import org.opendaylight.yangtools.yang.common.QName; +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.NotificationDefinition; +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.UsesNode; +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.EnumTypeDefinition.EnumPair; +import org.opendaylight.yangtools.yang.model.api.type.UnionTypeDefinition; +import org.opendaylight.yangtools.yang.model.util.DataNodeIterator; +import org.opendaylight.yangtools.yang.model.util.ExtendedType; +import org.opendaylight.yangtools.yang.model.util.SchemaContextUtil; +import org.opendaylight.yangtools.yang.model.util.UnionType; + +public final class BindingGeneratorImpl implements BindingGenerator { + + /** + * Outter key represents the package name. Outter value represents map of + * all builders in the same package. Inner key represents the schema node + * name (in JAVA class/interface name format). Inner value represents + * instance of builder for schema node specified in key part. + */ + private Map> genTypeBuilders; + + /** + * Provide methods for converting YANG types to JAVA types. + */ + private TypeProvider typeProvider; + + /** + * Holds reference to schema context to resolve data of augmented elemnt + * when creating augmentation builder + */ + private 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 final Map allGroupings = new HashMap(); + + /** + * Only parent constructor is invoked. + */ + + private final static String YANG_EXT_NAMESPACE = "urn:opendaylight:yang:extension:yang-ext"; + private final static String AUGMENT_IDENTIFIER_NAME = "augment-identifier"; + + public BindingGeneratorImpl() { + super(); + } + + /** + * Resolves generated types from context schema nodes of all + * modules. + * + * Generated types are created for modules, groupings, types, containers, + * lists, choices, augments, rpcs, notification, identities. + * + * @param context + * schema context which contains data about all schema nodes + * saved in modules + * @return list of types (usually GeneratedType + * GeneratedTransferObjectwhich are generated from + * context data. + * @throws IllegalArgumentException + * if param context is null + * @throws IllegalStateException + * if context contain no modules + */ + @Override + public List generateTypes(final SchemaContext context) { + if (context == null) { + throw new IllegalArgumentException("Schema Context reference cannot be NULL!"); + } + if (context.getModules() == null) { + throw new IllegalStateException("Schema Context does not contain defined modules!"); + } + + final List generatedTypes = new ArrayList<>(); + schemaContext = context; + typeProvider = new TypeProviderImpl(context); + final Set modules = context.getModules(); + genTypeBuilders = new HashMap<>(); + for (final Module module : modules) { + + generatedTypes.addAll(allGroupingsToGenTypes(module)); + + if (false == module.getChildNodes().isEmpty()) { + generatedTypes.add(moduleToDataType(module)); + } + generatedTypes.addAll(allTypeDefinitionsToGenTypes(module)); + generatedTypes.addAll(allContainersToGenTypes(module)); + generatedTypes.addAll(allListsToGenTypes(module)); + generatedTypes.addAll(allChoicesToGenTypes(module)); + generatedTypes.addAll(allAugmentsToGenTypes(module)); + generatedTypes.addAll(allRPCMethodsToGenType(module)); + generatedTypes.addAll(allNotificationsToGenType(module)); + generatedTypes.addAll(allIdentitiesToGenTypes(module, context)); + + } + return generatedTypes; + } + + /** + * Resolves generated types from context schema nodes only for + * modules specified in modules + * + * Generated types are created for modules, groupings, types, containers, + * lists, choices, augments, rpcs, notification, identities. + * + * @param context + * schema context which contains data about all schema nodes + * saved in modules + * @param modules + * set of modules for which schema nodes should be generated + * types + * @return list of types (usually GeneratedType or + * GeneratedTransferObject) which: + *
    + *
  • are generated from context schema nodes and
  • + *
  • are also part of some of the module in modules + * set
  • . + *
+ * @throws IllegalArgumentException + *
    + *
  • if param context is null or
  • + *
  • if param modules is null
  • + *
+ * @throws IllegalStateException + * if context contain no modules + */ + @Override + public List generateTypes(final SchemaContext context, final Set modules) { + if (context == null) { + throw new IllegalArgumentException("Schema Context reference cannot be NULL!"); + } + if (context.getModules() == null) { + throw new IllegalStateException("Schema Context does not contain defined modules!"); + } + if (modules == null) { + throw new IllegalArgumentException("Sef of Modules cannot be NULL!"); + } + + final List filteredGenTypes = new ArrayList<>(); + schemaContext = context; + typeProvider = new TypeProviderImpl(context); + final Set contextModules = context.getModules(); + genTypeBuilders = new HashMap<>(); + for (final Module contextModule : contextModules) { + final List generatedTypes = new ArrayList<>(); + + generatedTypes.addAll(allGroupingsToGenTypes(contextModule)); + if (false == contextModule.getChildNodes().isEmpty()) { + generatedTypes.add(moduleToDataType(contextModule)); + } + generatedTypes.addAll(allTypeDefinitionsToGenTypes(contextModule)); + generatedTypes.addAll(allContainersToGenTypes(contextModule)); + generatedTypes.addAll(allListsToGenTypes(contextModule)); + generatedTypes.addAll(allChoicesToGenTypes(contextModule)); + generatedTypes.addAll(allAugmentsToGenTypes(contextModule)); + generatedTypes.addAll(allRPCMethodsToGenType(contextModule)); + generatedTypes.addAll(allNotificationsToGenType(contextModule)); + generatedTypes.addAll(allIdentitiesToGenTypes(contextModule, context)); + + if (modules.contains(contextModule)) { + filteredGenTypes.addAll(generatedTypes); + } + } + return filteredGenTypes; + } + + /** + * Converts all extended type definitions of module to the list of + * Type objects. + * + * @param module + * module from which is obtained set of type definitions + * @return list of Type which are generated from extended + * definition types (object of type ExtendedType) + * @throws IllegalArgumentException + *
    + *
  • if module equals null
  • + *
  • if name of module equals null
  • + *
  • if type definitions of module equal null
  • + *
+ * + */ + private List allTypeDefinitionsToGenTypes(final Module module) { + if (module == null) { + throw new IllegalArgumentException("Module reference cannot be NULL!"); + } + if (module.getName() == null) { + throw new IllegalArgumentException("Module name cannot be NULL!"); + } + if (module.getTypeDefinitions() == null) { + throw new IllegalArgumentException("Type Definitions for module " + module.getName() + " cannot be NULL!"); + } + + final Set> typeDefinitions = module.getTypeDefinitions(); + final List generatedTypes = new ArrayList<>(); + for (final TypeDefinition typedef : typeDefinitions) { + if (typedef != null) { + final Type type = ((TypeProviderImpl) typeProvider).generatedTypeForExtendedDefinitionType(typedef); + if ((type != null) && !generatedTypes.contains(type)) { + generatedTypes.add(type); + } + } + } + return generatedTypes; + } + + /** + * Converts all containers of the module to the list of + * Type objects. + * + * @param module + * module from which is obtained DataNodeIterator to iterate over + * all containers + * @return list of Type which are generated from containers + * (objects of type ContainerSchemaNode) + * @throws IllegalArgumentException + *
    + *
  • if the module equals null
  • + *
  • if the name of module equals null
  • + *
  • if the set of child nodes equals null
  • + *
+ * + */ + private List allContainersToGenTypes(final Module module) { + if (module == null) { + throw new IllegalArgumentException("Module reference cannot be NULL!"); + } + + if (module.getName() == null) { + throw new IllegalArgumentException("Module name cannot be NULL!"); + } + + if (module.getChildNodes() == null) { + throw new IllegalArgumentException("Reference to Set of Child Nodes in module " + module.getName() + + " cannot be NULL!"); + } + + final List generatedTypes = new ArrayList<>(); + final DataNodeIterator it = new DataNodeIterator(module); + final List schemaContainers = it.allContainers(); + final String basePackageName = moduleNamespaceToPackageName(module); + for (final ContainerSchemaNode container : schemaContainers) { + if (!container.isAddedByUses()) { + generatedTypes.add(containerToGenType(basePackageName, container)); + } + } + return generatedTypes; + } + + /** + * Converts all lists of the module to the list of Type + * objects. + * + * @param module + * module from which is obtained DataNodeIterator to iterate over + * all lists + * @return list of Type which are generated from lists (objects + * of type ListSchemaNode) + * @throws IllegalArgumentException + *
    + *
  • if the module equals null
  • + *
  • if the name of module equals null
  • + *
  • if the set of child nodes equals null
  • + *
+ * + */ + private List allListsToGenTypes(final Module module) { + if (module == null) { + throw new IllegalArgumentException("Module reference cannot be NULL!"); + } + + if (module.getName() == null) { + throw new IllegalArgumentException("Module name cannot be NULL!"); + } + + if (module.getChildNodes() == null) { + throw new IllegalArgumentException("Reference to Set of Child Nodes in module " + module.getName() + + " cannot be NULL!"); + } + + final List generatedTypes = new ArrayList<>(); + final DataNodeIterator it = new DataNodeIterator(module); + final List schemaLists = it.allLists(); + final String basePackageName = moduleNamespaceToPackageName(module); + if (schemaLists != null) { + for (final ListSchemaNode list : schemaLists) { + if (!list.isAddedByUses()) { + generatedTypes.addAll(listToGenType(basePackageName, list)); + } + } + } + return generatedTypes; + } + + /** + * Converts all choices of the module to the list of + * Type objects. + * + * @param module + * module from which is obtained DataNodeIterator to iterate over + * all choices + * @return list of Type which are generated from choices + * (objects of type ChoiceNode) + * @throws IllegalArgumentException + *
    + *
  • if the module equals null
  • + *
  • if the name of module equals null
  • * + *
+ * + */ + private List allChoicesToGenTypes(final Module module) { + if (module == null) { + throw new IllegalArgumentException("Module reference cannot be NULL!"); + } + if (module.getName() == null) { + throw new IllegalArgumentException("Module name cannot be NULL!"); + } + + final DataNodeIterator it = new DataNodeIterator(module); + final List choiceNodes = it.allChoices(); + final String basePackageName = moduleNamespaceToPackageName(module); + + final List generatedTypes = new ArrayList<>(); + for (final ChoiceNode choice : choiceNodes) { + if ((choice != null) && !choice.isAddedByUses()) { + generatedTypes.addAll(choiceToGeneratedType(basePackageName, choice)); + } + } + return generatedTypes; + } + + /** + * Converts all augmentation of the module to the list + * Type objects. + * + * @param module + * module from which is obtained list of all augmentation objects + * to iterate over them + * @return list of Type which are generated from augments + * (objects of type AugmentationSchema) + * @throws IllegalArgumentException + *
    + *
  • if the module equals null
  • + *
  • if the name of module equals null
  • + *
  • if the set of child nodes equals null
  • + *
+ * + */ + private List allAugmentsToGenTypes(final Module module) { + if (module == null) { + throw new IllegalArgumentException("Module reference cannot be NULL!"); + } + if (module.getName() == null) { + throw new IllegalArgumentException("Module name cannot be NULL!"); + } + if (module.getChildNodes() == null) { + throw new IllegalArgumentException("Reference to Set of Augmentation Definitions in module " + + module.getName() + " cannot be NULL!"); + } + + final List generatedTypes = new ArrayList<>(); + final String basePackageName = moduleNamespaceToPackageName(module); + final List augmentations = resolveAugmentations(module); + for (final AugmentationSchema augment : augmentations) { + generatedTypes.addAll(augmentationToGenTypes(basePackageName, augment)); + } + return generatedTypes; + } + + /** + * Returns list of AugmentationSchema objects. The objects are + * sorted according to the length of their target path from the shortest to + * the longest. + * + * @param module + * module from which is obtained list of all augmentation objects + * @return list of sorted AugmentationSchema objects obtained + * from module + * @throws IllegalArgumentException + *
    + *
  • if the module equals null
  • + *
  • if the set of augmentation equals null
  • + *
+ * + */ + private List resolveAugmentations(final Module module) { + if (module == null) { + throw new IllegalArgumentException("Module reference cannot be NULL!"); + } + if (module.getAugmentations() == null) { + throw new IllegalStateException("Augmentations Set cannot be NULL!"); + } + + final Set augmentations = module.getAugmentations(); + final List sortedAugmentations = new ArrayList<>(augmentations); + Collections.sort(sortedAugmentations, new Comparator() { + + @Override + public int compare(AugmentationSchema augSchema1, AugmentationSchema augSchema2) { + + if (augSchema1.getTargetPath().getPath().size() > augSchema2.getTargetPath().getPath().size()) { + return 1; + } else if (augSchema1.getTargetPath().getPath().size() < augSchema2.getTargetPath().getPath().size()) { + return -1; + } + return 0; + + } + }); + + return sortedAugmentations; + } + + /** + * Converts whole module to GeneratedType object. + * Firstly is created the module builder object from which is finally + * obtained reference to GeneratedType object. + * + * @param module + * module from which are obtained the module name, child nodes, + * uses and is derived package name + * @return GeneratedType which is internal representation of + * the module + * @throws IllegalArgumentException + * if the module equals null + * + */ + private GeneratedType moduleToDataType(final Module module) { + if (module == null) { + throw new IllegalArgumentException("Module reference cannot be NULL!"); + } + + final GeneratedTypeBuilder moduleDataTypeBuilder = moduleTypeBuilder(module, "Data"); + addImplementedInterfaceFromUses(module, moduleDataTypeBuilder); + moduleDataTypeBuilder.addImplementsType(Types.typeForClass(DataRoot.class)); + + final String basePackageName = moduleNamespaceToPackageName(module); + if (moduleDataTypeBuilder != null) { + final Set dataNodes = module.getChildNodes(); + resolveDataSchemaNodes(basePackageName, moduleDataTypeBuilder, dataNodes); + } + return moduleDataTypeBuilder.toInstance(); + } + + /** + * Converts all rpcs inputs and outputs substatements of the module + * to the list of Type objects. In addition are to containers + * and lists which belong to input or output also part of returning list. + * + * @param module + * module from which is obtained set of all rpc objects to + * iterate over them + * @return list of Type which are generated from rpcs inputs, + * outputs + container and lists which are part of inputs or outputs + * @throws IllegalArgumentException + *
    + *
  • if the module equals null
  • + *
  • if the name of module equals null
  • + *
  • if the set of child nodes equals null
  • + *
+ * + */ + private List allRPCMethodsToGenType(final Module module) { + if (module == null) { + throw new IllegalArgumentException("Module reference cannot be NULL!"); + } + + if (module.getName() == null) { + throw new IllegalArgumentException("Module name cannot be NULL!"); + } + + if (module.getChildNodes() == null) { + throw new IllegalArgumentException("Reference to Set of RPC Method Definitions in module " + + module.getName() + " cannot be NULL!"); + } + + final String basePackageName = moduleNamespaceToPackageName(module); + final Set rpcDefinitions = module.getRpcs(); + + if (rpcDefinitions.isEmpty()) { + return Collections.emptyList(); + } + + final List genRPCTypes = new ArrayList<>(); + final GeneratedTypeBuilder interfaceBuilder = moduleTypeBuilder(module, "Service"); + interfaceBuilder.addImplementsType(Types.typeForClass(RpcService.class)); + final Type future = Types.typeForClass(Future.class); + for (final RpcDefinition rpc : rpcDefinitions) { + if (rpc != null) { + + String rpcName = parseToClassName(rpc.getQName().getLocalName()); + String rpcMethodName = parseToValidParamName(rpcName); + MethodSignatureBuilder method = interfaceBuilder.addMethod(rpcMethodName); + + final List rpcInOut = new ArrayList<>(); + + ContainerSchemaNode input = rpc.getInput(); + ContainerSchemaNode output = rpc.getOutput(); + + if (input != null) { + rpcInOut.add(new DataNodeIterator(input)); + GeneratedTypeBuilder inType = addRawInterfaceDefinition(basePackageName, input, rpcName); + addImplementedInterfaceFromUses(input, inType); + inType.addImplementsType(Types.DATA_OBJECT); + resolveDataSchemaNodes(basePackageName, inType, input.getChildNodes()); + Type inTypeInstance = inType.toInstance(); + genRPCTypes.add(inTypeInstance); + method.addParameter(inTypeInstance, "input"); + } + + Type outTypeInstance = Types.typeForClass(Void.class); + if (output != null) { + rpcInOut.add(new DataNodeIterator(output)); + GeneratedTypeBuilder outType = addRawInterfaceDefinition(basePackageName, output, rpcName); + addImplementedInterfaceFromUses(output, outType); + outType.addImplementsType(Types.DATA_OBJECT); + resolveDataSchemaNodes(basePackageName, outType, output.getChildNodes()); + outTypeInstance = outType.toInstance(); + genRPCTypes.add(outTypeInstance); + + } + + final Type rpcRes = Types.parameterizedTypeFor(Types.typeForClass(RpcResult.class), outTypeInstance); + method.setReturnType(Types.parameterizedTypeFor(future, rpcRes)); + for (DataNodeIterator it : rpcInOut) { + List nContainers = it.allContainers(); + if ((nContainers != null) && !nContainers.isEmpty()) { + for (final ContainerSchemaNode container : nContainers) { + if (!container.isAddedByUses()) { + genRPCTypes.add(containerToGenType(basePackageName, container)); + } + } + } + List nLists = it.allLists(); + if ((nLists != null) && !nLists.isEmpty()) { + for (final ListSchemaNode list : nLists) { + if (!list.isAddedByUses()) { + genRPCTypes.addAll(listToGenType(basePackageName, list)); + } + } + } + } + } + } + genRPCTypes.add(interfaceBuilder.toInstance()); + return genRPCTypes; + } + + /** + * Converts all notifications of the module to the list of + * Type objects. In addition are to this list added containers + * and lists which are part of this notification. + * + * @param module + * module from which is obtained set of all notification objects + * to iterate over them + * @return list of Type which are generated from notification + * (object of type NotificationDefinition + * @throws IllegalArgumentException + *
    + *
  • if the module equals null
  • + *
  • if the name of module equals null
  • + *
  • if the set of child nodes equals null
  • + *
+ * + */ + private List allNotificationsToGenType(final Module module) { + if (module == null) { + throw new IllegalArgumentException("Module reference cannot be NULL!"); + } + + if (module.getName() == null) { + throw new IllegalArgumentException("Module name cannot be NULL!"); + } + + if (module.getChildNodes() == null) { + throw new IllegalArgumentException("Reference to Set of Notification Definitions in module " + + module.getName() + " cannot be NULL!"); + } + + final String basePackageName = moduleNamespaceToPackageName(module); + final List genNotifyTypes = new ArrayList<>(); + final Set notifications = module.getNotifications(); + + for (final NotificationDefinition notification : notifications) { + if (notification != null) { + DataNodeIterator it = new DataNodeIterator(notification); + + // Containers + for (ContainerSchemaNode node : it.allContainers()) { + if (!node.isAddedByUses()) { + genNotifyTypes.add(containerToGenType(basePackageName, node)); + } + } + // Lists + for (ListSchemaNode node : it.allLists()) { + if (!node.isAddedByUses()) { + genNotifyTypes.addAll(listToGenType(basePackageName, node)); + } + } + final GeneratedTypeBuilder notificationTypeBuilder = addDefaultInterfaceDefinition(basePackageName, + notification); + notificationTypeBuilder.addImplementsType(Types + .typeForClass(org.opendaylight.yangtools.yang.binding.Notification.class)); + // Notification object + resolveDataSchemaNodes(basePackageName, notificationTypeBuilder, notification.getChildNodes()); + genNotifyTypes.add(notificationTypeBuilder.toInstance()); + } + } + return genNotifyTypes; + } + + /** + * Converts all identities of the module to the list of + * Type objects. + * + * @param module + * module from which is obtained set of all identity objects to + * iterate over them + * @param context + * schema context only used as input parameter for method + * {@link identityToGenType} + * @return list of Type which are generated from identities + * (object of type IdentitySchemaNode + * + */ + private List allIdentitiesToGenTypes(final Module module, final SchemaContext context) { + List genTypes = new ArrayList<>(); + + final Set schemaIdentities = module.getIdentities(); + + final String basePackageName = moduleNamespaceToPackageName(module); + + if (schemaIdentities != null && !schemaIdentities.isEmpty()) { + for (final IdentitySchemaNode identity : schemaIdentities) { + genTypes.add(identityToGenType(basePackageName, identity, context)); + } + } + return genTypes; + } + + /** + * Converts the identity object to GeneratedType. Firstly it is + * created transport object builder. If identity contains base identity then + * reference to base identity is added to superior identity as its extend. + * If identity doesn't contain base identity then only reference to abstract + * class {@link org.opendaylight.yangtools.yang.model.api.BaseIdentity + * BaseIdentity} is added + * + * @param basePackageName + * string contains the module package name + * @param identity + * IdentitySchemaNode which contains data about identity + * @param context + * SchemaContext which is used to get package and name + * information about base of identity + * + * @return GeneratedType which is generated from identity (object of type + * IdentitySchemaNode + * + */ + private GeneratedType identityToGenType(final String basePackageName, final IdentitySchemaNode identity, + final SchemaContext context) { + if (identity == null) { + return null; + } + + final String packageName = packageNameForGeneratedType(basePackageName, identity.getPath()); + final String genTypeName = parseToClassName(identity.getQName().getLocalName()); + final GeneratedTOBuilderImpl newType = new GeneratedTOBuilderImpl(packageName, genTypeName); + + IdentitySchemaNode baseIdentity = identity.getBaseIdentity(); + if (baseIdentity != null) { + Module baseIdentityParentModule = SchemaContextUtil.findParentModule(context, baseIdentity); + + final String returnTypePkgName = moduleNamespaceToPackageName(baseIdentityParentModule); + final String returnTypeName = parseToClassName(baseIdentity.getQName().getLocalName()); + + GeneratedTransferObject gto = new GeneratedTOBuilderImpl(returnTypePkgName, returnTypeName).toInstance(); + newType.setExtendsType(gto); + } else { + newType.setExtendsType(Types.getBaseIdentityTO()); + } + newType.setAbstract(true); + return newType.toInstance(); + } + + /** + * Converts all groupings of the module to the list of + * Type objects. Firstly are groupings sorted according mutual + * dependencies. At least dependend (indepedent) groupings are in the list + * saved at first positions. For every grouping the record is added to map + * {@link BindingGeneratorImpl#allGroupings allGroupings} + * + * @param module + * module from which is obtained set of all grouping objects to + * iterate over them + * @return list of Type which are generated from groupings + * (object of type GroupingDefinition) + * + */ + private List allGroupingsToGenTypes(final Module module) { + if (module == null) { + throw new IllegalArgumentException("Module parameter can not be null"); + } + final List genTypes = new ArrayList<>(); + final String basePackageName = moduleNamespaceToPackageName(module); + final Set groupings = module.getGroupings(); + List groupingsSortedByDependencies; + + groupingsSortedByDependencies = GroupingDefinitionDependencySort.sort(groupings); + + for (final GroupingDefinition grouping : groupingsSortedByDependencies) { + GeneratedType genType = groupingToGenType(basePackageName, grouping); + genTypes.add(genType); + SchemaPath schemaPath = grouping.getPath(); + allGroupings.put(schemaPath, genType); + } + return genTypes; + } + + /** + * Converts individual grouping to GeneratedType. Firstly generated type + * builder is created and every child node of grouping is resolved to the + * method. + * + * @param basePackageName + * string contains the module package name + * @param grouping + * GroupingDefinition which contains data about grouping + * @return GeneratedType which is generated from grouping (object of type + * GroupingDefinition) + */ + private GeneratedType groupingToGenType(final String basePackageName, GroupingDefinition grouping) { + if (grouping == null) { + return null; + } + + final String packageName = packageNameForGeneratedType(basePackageName, grouping.getPath()); + final Set schemaNodes = grouping.getChildNodes(); + final GeneratedTypeBuilder typeBuilder = addDefaultInterfaceDefinition(packageName, grouping); + + resolveDataSchemaNodes(basePackageName, typeBuilder, schemaNodes); + return typeBuilder.toInstance(); + } + + /** + * Tries to find EnumTypeDefinition in typeDefinition. If base + * type of typeDefinition is of the type ExtendedType then this + * method is recursivelly called with this base type. + * + * @param typeDefinition + * TypeDefinition in which should be EnumTypeDefinition found as + * base type + * @return EnumTypeDefinition if it is found inside + * typeDefinition or null in other case + */ + private EnumTypeDefinition enumTypeDefFromExtendedType(final TypeDefinition typeDefinition) { + if (typeDefinition != null) { + if (typeDefinition.getBaseType() instanceof EnumTypeDefinition) { + return (EnumTypeDefinition) typeDefinition.getBaseType(); + } else if (typeDefinition.getBaseType() instanceof ExtendedType) { + return enumTypeDefFromExtendedType(typeDefinition.getBaseType()); + } + } + return null; + } + + /** + * Adds enumeration builder created from enumTypeDef to + * typeBuilder. + * + * Each enumTypeDef item is added to builder with its name and + * value. + * + * @param enumTypeDef + * EnumTypeDefinition contains enum data + * @param enumName + * string contains name which will be assigned to enumeration + * builder + * @param typeBuilder + * GeneratedTypeBuilder to which will be enum builder assigned + * @return enumeration builder which contais data from + * enumTypeDef + */ + private EnumBuilder resolveInnerEnumFromTypeDefinition(final EnumTypeDefinition enumTypeDef, final String enumName, + final GeneratedTypeBuilder typeBuilder) { + if ((enumTypeDef != null) && (typeBuilder != null) && (enumTypeDef.getQName() != null) + && (enumTypeDef.getQName().getLocalName() != null)) { + + final String enumerationName = parseToClassName(enumName); + final EnumBuilder enumBuilder = typeBuilder.addEnumeration(enumerationName); + + if (enumBuilder != null) { + final List enums = enumTypeDef.getValues(); + if (enums != null) { + int listIndex = 0; + for (final EnumPair enumPair : enums) { + if (enumPair != null) { + final String enumPairName = parseToClassName(enumPair.getName()); + Integer enumPairValue = enumPair.getValue(); + + if (enumPairValue == null) { + enumPairValue = listIndex; + } + enumBuilder.addValue(enumPairName, enumPairValue); + listIndex++; + } + } + } + return enumBuilder; + } + } + return null; + } + + /** + * Generates type builder for module. + * + * @param module + * Module which is source of package name for generated type + * builder + * @param postfix + * string which is added to the module class name representation + * as suffix + * @return instance of GeneratedTypeBuilder which represents + * module. + * @throws IllegalArgumentException + * if module equals null + */ + private GeneratedTypeBuilder moduleTypeBuilder(final Module module, final String postfix) { + if (module == null) { + throw new IllegalArgumentException("Module reference cannot be NULL!"); + } + String packageName = moduleNamespaceToPackageName(module); + final String moduleName = parseToClassName(module.getName()) + postfix; + + return new GeneratedTypeBuilderImpl(packageName, moduleName); + + } + + /** + * Converts augSchema to list of Type which + * contains generated type for augmentation. In addition there are also + * generated types for all containers, list and choices which are child of + * augSchema node or a generated types for cases are added if + * augmented node is choice. + * + * @param augmentPackageName + * string with the name of the package to which the augmentation + * belongs + * @param augSchema + * AugmentationSchema which is contains data about agumentation + * (target path, childs...) + * @return list of Type objects which contains generated type + * for augmentation and for container, list and choice child nodes + * @throws IllegalArgumentException + *
    + *
  • if augmentPackageName equals null
  • + *
  • if augSchema equals null
  • + *
  • if target path of augSchema equals null
  • + *
+ */ + private List augmentationToGenTypes(final String augmentPackageName, final AugmentationSchema augSchema) { + if (augmentPackageName == null) { + throw new IllegalArgumentException("Package Name cannot be NULL!"); + } + if (augSchema == null) { + throw new IllegalArgumentException("Augmentation Schema cannot be NULL!"); + } + if (augSchema.getTargetPath() == null) { + throw new IllegalStateException("Augmentation Schema does not contain Target Path (Target Path is NULL)."); + } + + final List genTypes = new ArrayList<>(); + + // EVERY augmented interface will extends Augmentation interface + // and DataObject interface!!! + final SchemaPath targetPath = augSchema.getTargetPath(); + final DataSchemaNode targetSchemaNode = findDataSchemaNode(schemaContext, targetPath); + if ((targetSchemaNode != null) && (targetSchemaNode.getQName() != null) + && (targetSchemaNode.getQName().getLocalName() != null)) { + final Module targetModule = findParentModule(schemaContext, targetSchemaNode); + final String targetBasePackage = moduleNamespaceToPackageName(targetModule); + final String targetPackageName = packageNameForGeneratedType(targetBasePackage, targetSchemaNode.getPath()); + final String targetSchemaNodeName = targetSchemaNode.getQName().getLocalName(); + final Set augChildNodes = augSchema.getChildNodes(); + + if (!(targetSchemaNode instanceof ChoiceNode)) { + final GeneratedTypeBuilder augTypeBuilder = addRawAugmentGenTypeDefinition(augmentPackageName, + targetPackageName, targetSchemaNodeName, augSchema); + final GeneratedType augType = augTypeBuilder.toInstance(); + genTypes.add(augType); + } else { + final Type refChoiceType = new ReferencedTypeImpl(targetPackageName, + parseToClassName(targetSchemaNodeName)); + final ChoiceNode choiceTarget = (ChoiceNode) targetSchemaNode; + final Set choiceCaseNodes = choiceTarget.getCases(); + genTypes.addAll(generateTypesFromAugmentedChoiceCases(augmentPackageName, refChoiceType, + choiceCaseNodes)); + } + genTypes.addAll(augmentationBodyToGenTypes(augmentPackageName, augChildNodes)); + } + return genTypes; + } + + /** + * Returns a generated type builder for an augmentation. + * + * The name of the type builder is equal to the name of augmented node with + * serial number as suffix. + * + * @param augmentPackageName + * string with contains the package name to which the augment + * belongs + * @param targetPackageName + * string with the package name to which the augmented node + * belongs + * @param targetSchemaNodeName + * string with the name of the augmented node + * @param augSchema + * augmentation schema which contains data about the child nodes + * and uses of augment + * @return generated type builder for augment + */ + private GeneratedTypeBuilder addRawAugmentGenTypeDefinition(final String augmentPackageName, + final String targetPackageName, final String targetSchemaNodeName, final AugmentationSchema augSchema) { + final String targetTypeName = parseToClassName(targetSchemaNodeName); + Map augmentBuilders = genTypeBuilders.get(augmentPackageName); + if (augmentBuilders == null) { + augmentBuilders = new HashMap<>(); + genTypeBuilders.put(augmentPackageName, augmentBuilders); + } + final String augIdentifier = getAugmentIdentifier(augSchema.getUnknownSchemaNodes()); + + final String augTypeName = augIdentifier != null ? parseToClassName(augIdentifier): augGenTypeName(augmentBuilders, targetTypeName); + final Type targetTypeRef = new ReferencedTypeImpl(targetPackageName, targetTypeName); + final Set augChildNodes = augSchema.getChildNodes(); + + final GeneratedTypeBuilder augTypeBuilder = new GeneratedTypeBuilderImpl(augmentPackageName, augTypeName); + + augTypeBuilder.addImplementsType(Types.DATA_OBJECT); + augTypeBuilder.addImplementsType(Types.augmentationTypeFor(targetTypeRef)); + addImplementedInterfaceFromUses(augSchema, augTypeBuilder); + + augSchemaNodeToMethods(augmentPackageName, augTypeBuilder, augChildNodes); + augmentBuilders.put(augTypeName, augTypeBuilder); + return augTypeBuilder; + } + + private String getAugmentIdentifier(List unknownSchemaNodes) { + String ret = null; + for (UnknownSchemaNode unknownSchemaNode : unknownSchemaNodes) { + QName nodeType = unknownSchemaNode.getNodeType(); + if(AUGMENT_IDENTIFIER_NAME.equals(nodeType.getLocalName()) && + YANG_EXT_NAMESPACE.equals(nodeType.getNamespace().toString())) { + return unknownSchemaNode.getNodeParameter(); + } + } + return ret; + } + + /** + * 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 List augmentationBodyToGenTypes(final String augBasePackageName, + final Set augChildNodes) { + final List genTypes = new ArrayList<>(); + final List augSchemaIts = new ArrayList<>(); + for (final DataSchemaNode childNode : augChildNodes) { + if (childNode instanceof DataNodeContainer) { + augSchemaIts.add(new DataNodeIterator((DataNodeContainer) childNode)); + + if (childNode instanceof ContainerSchemaNode) { + genTypes.add(containerToGenType(augBasePackageName, (ContainerSchemaNode) childNode)); + } else if (childNode instanceof ListSchemaNode) { + genTypes.addAll(listToGenType(augBasePackageName, (ListSchemaNode) childNode)); + } + } else if (childNode instanceof ChoiceNode) { + final ChoiceNode choice = (ChoiceNode) childNode; + for (final ChoiceCaseNode caseNode : choice.getCases()) { + augSchemaIts.add(new DataNodeIterator(caseNode)); + } + genTypes.addAll(choiceToGeneratedType(augBasePackageName, (ChoiceNode) childNode)); + } + } + + for (final DataNodeIterator it : augSchemaIts) { + final List augContainers = it.allContainers(); + final List augLists = it.allLists(); + final List augChoices = it.allChoices(); + + if (augContainers != null) { + for (final ContainerSchemaNode container : augContainers) { + genTypes.add(containerToGenType(augBasePackageName, container)); + } + } + if (augLists != null) { + for (final ListSchemaNode list : augLists) { + genTypes.addAll(listToGenType(augBasePackageName, list)); + } + } + if (augChoices != null) { + for (final ChoiceNode choice : augChoices) { + genTypes.addAll(choiceToGeneratedType(augBasePackageName, choice)); + } + } + } + return genTypes; + } + + /** + * Returns first unique name for the augment generated type builder. The + * generated type builder name for augment consists from name of augmented + * node and serial number of its augmentation. + * + * @param builders + * map of builders which were created in the package to which the + * augmentation belongs + * @param genTypeName + * string with name of augmented node + * @return string with unique name for augmentation builder + */ + private String augGenTypeName(final Map builders, final String genTypeName) { + String augTypeName = genTypeName; + + int index = 1; + while ((builders != null) && builders.containsKey(genTypeName + index)) { + index++; + } + augTypeName += index; + return augTypeName; + } + + /** + * Converts containerNode to generated type. Firstly the + * generated type builder is created. The subnodes of + * containerNode are added as methods and the instance of + * GeneratedType is returned. + * + * @param basePackageName + * string contains the module package name + * @param containerNode + * container schema node with the data about childs nodes and + * schema paths + * @return generated type for containerNode + */ + private GeneratedType containerToGenType(final String basePackageName, ContainerSchemaNode containerNode) { + if (containerNode == null) { + return null; + } + + final String packageName = packageNameForGeneratedType(basePackageName, containerNode.getPath()); + final Set schemaNodes = containerNode.getChildNodes(); + final GeneratedTypeBuilder typeBuilder = addDefaultInterfaceDefinition(packageName, containerNode); + + resolveDataSchemaNodes(basePackageName, typeBuilder, schemaNodes); + return typeBuilder.toInstance(); + } + + /** + * Adds the methods to typeBuilder which represent subnodes of + * node for which typeBuilder was created. + * + * The subnodes aren't mapped to the methods if they are part of grouping or + * augment (in this case are already part of them). + * + * @param basePackageName + * string contains the module package name + * @param typeBuilder + * generated type builder which represents any node. The subnodes + * of this node are added to the typeBuilder as + * methods. The subnode can be of type leaf, leaf-list, list, + * container, choice. + * @param schemaNodes + * set of data schema nodes which are the children of the node + * for which typeBuilder was created + * @return generated type builder which is the same builder as input + * parameter. The getter methods (representing child nodes) could be + * added to it. + */ + private GeneratedTypeBuilder resolveDataSchemaNodes(final String basePackageName, + final GeneratedTypeBuilder typeBuilder, final Set schemaNodes) { + if ((schemaNodes != null) && (typeBuilder != null)) { + for (final DataSchemaNode schemaNode : schemaNodes) { + if (schemaNode.isAugmenting() || schemaNode.isAddedByUses()) { + continue; + } + addSchemaNodeToBuilderAsMethod(basePackageName, schemaNode, typeBuilder); + } + } + return typeBuilder; + } + + /** + * Adds the methods to typeBuilder what represents subnodes of + * node for which typeBuilder was created. + * + * @param basePackageName + * string contains the module package name + * @param typeBuilder + * generated type builder which represents any node. The subnodes + * of this node are added to the typeBuilder as + * methods. The subnode can be of type leaf, leaf-list, list, + * container, choice. + * @param schemaNodes + * set of data schema nodes which are the children of the node + * for which typeBuilder was created + * @return generated type builder which is the same object as the input + * parameter typeBuilder. The getter method could be + * added to it. + */ + private GeneratedTypeBuilder augSchemaNodeToMethods(final String basePackageName, + final GeneratedTypeBuilder typeBuilder, final Set schemaNodes) { + if ((schemaNodes != null) && (typeBuilder != null)) { + for (final DataSchemaNode schemaNode : schemaNodes) { + if (schemaNode.isAugmenting()) { + addSchemaNodeToBuilderAsMethod(basePackageName, schemaNode, typeBuilder); + } + } + } + return typeBuilder; + } + + /** + * Adds to typeBuilder a method which is derived from + * schemaNode. + * + * @param basePackageName + * string with the module package name + * @param schemaNode + * data schema node which is added to typeBuilder as + * a method + * @param typeBuilder + * generated type builder to which is schemaNode + * added as a method. + */ + private void addSchemaNodeToBuilderAsMethod(final String basePackageName, final DataSchemaNode schemaNode, + final GeneratedTypeBuilder typeBuilder) { + if (schemaNode != null && typeBuilder != null) { + if (schemaNode instanceof LeafSchemaNode) { + resolveLeafSchemaNodeAsMethod(typeBuilder, (LeafSchemaNode) schemaNode); + } else if (schemaNode instanceof LeafListSchemaNode) { + resolveLeafListSchemaNode(typeBuilder, (LeafListSchemaNode) schemaNode); + } else if (schemaNode instanceof ContainerSchemaNode) { + resolveContainerSchemaNode(basePackageName, typeBuilder, (ContainerSchemaNode) schemaNode); + } else if (schemaNode instanceof ListSchemaNode) { + resolveListSchemaNode(basePackageName, typeBuilder, (ListSchemaNode) schemaNode); + } else if (schemaNode instanceof ChoiceNode) { + resolveChoiceSchemaNode(basePackageName, typeBuilder, (ChoiceNode) schemaNode); + } + } + } + + /** + * 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 void resolveChoiceSchemaNode(final String basePackageName, final GeneratedTypeBuilder typeBuilder, + final ChoiceNode choiceNode) { + if (basePackageName == null) { + throw new IllegalArgumentException("Base Package Name cannot be NULL!"); + } + if (typeBuilder == null) { + throw new IllegalArgumentException("Generated Type Builder cannot be NULL!"); + } + if (choiceNode == null) { + throw new IllegalArgumentException("Choice Schema Node cannot be NULL!"); + } + + final String choiceName = choiceNode.getQName().getLocalName(); + if (choiceName != null && !choiceNode.isAddedByUses()) { + final String packageName = packageNameForGeneratedType(basePackageName, choiceNode.getPath()); + final GeneratedTypeBuilder choiceType = addDefaultInterfaceDefinition(packageName, choiceNode); + constructGetter(typeBuilder, choiceName, choiceNode.getDescription(), choiceType); + } + } + + /** + * Converts choiceNode to the list of generated types for + * choice and its cases. + * + * The package names for choice and for its cases are created as + * concatenation of the module package (basePackageName) and + * names of all parents node. + * + * @param basePackageName + * string with the module package name + * @param choiceNode + * choice node which is mapped to generated type. Also child + * nodes - cases are mapped to generated types. + * @return list of generated types which contains generated type for choice + * and generated types for all cases which aren't added do choice + * through uses. + * @throws IllegalArgumentException + *
    + *
  • if basePackageName equals null
  • + *
  • if choiceNode equals null
  • + *
+ * + */ + private List choiceToGeneratedType(final String basePackageName, final ChoiceNode choiceNode) { + if (basePackageName == null) { + throw new IllegalArgumentException("Base Package Name cannot be NULL!"); + } + if (choiceNode == null) { + throw new IllegalArgumentException("Choice Schema Node cannot be NULL!"); + } + + final List generatedTypes = new ArrayList<>(); + final String packageName = packageNameForGeneratedType(basePackageName, choiceNode.getPath()); + final GeneratedTypeBuilder choiceTypeBuilder = addRawInterfaceDefinition(packageName, choiceNode); + choiceTypeBuilder.addImplementsType(Types.DATA_OBJECT); + final GeneratedType choiceType = choiceTypeBuilder.toInstance(); + + generatedTypes.add(choiceType); + final Set caseNodes = choiceNode.getCases(); + if ((caseNodes != null) && !caseNodes.isEmpty()) { + generatedTypes.addAll(generateTypesFromChoiceCases(basePackageName, choiceType, caseNodes)); + } + return generatedTypes; + } + + /** + * Converts caseNodes set to list of corresponding generated + * types. + * + * For every case which isn't added through augment or uses is + * created generated type builder. The package names for the builder is + * created as concatenation of the module package ( + * basePackageName) and names of all parents nodes of the + * concrete case. There is also relation "implements type" + * between every case builder and choice type + * + * @param basePackageName + * string with the module package name + * @param refChoiceType + * type which represents superior case + * @param caseNodes + * set of choice case nodes which are mapped to generated types + * @return list of generated types for caseNodes. + * @throws IllegalArgumentException + *
    + *
  • if basePackageName equals null
  • + *
  • if refChoiceType equals null
  • + *
  • if caseNodes equals null
  • + *
+ * * + */ + private List generateTypesFromChoiceCases(final String basePackageName, final Type refChoiceType, + final Set caseNodes) { + if (basePackageName == null) { + throw new IllegalArgumentException("Base Package Name cannot be NULL!"); + } + if (refChoiceType == null) { + throw new IllegalArgumentException("Referenced Choice Type cannot be NULL!"); + } + if (caseNodes == null) { + throw new IllegalArgumentException("Set of Choice Case Nodes cannot be NULL!"); + } + + final List generatedTypes = new ArrayList<>(); + for (final ChoiceCaseNode caseNode : caseNodes) { + if (caseNode != null && !caseNode.isAddedByUses() && !caseNode.isAugmenting()) { + final String packageName = packageNameForGeneratedType(basePackageName, caseNode.getPath()); + final GeneratedTypeBuilder caseTypeBuilder = addDefaultInterfaceDefinition(packageName, caseNode); + caseTypeBuilder.addImplementsType(refChoiceType); + + final Set childNodes = caseNode.getChildNodes(); + if (childNodes != null) { + resolveDataSchemaNodes(basePackageName, caseTypeBuilder, childNodes); + } + generatedTypes.add(caseTypeBuilder.toInstance()); + } + } + + return generatedTypes; + } + + /** + * Generates list of generated types for all the cases of a choice which are + * added to the choice through the augment. + * + * + * @param basePackageName + * string contains name of package to which augment belongs. If + * an augmented choice is from an other package (pcg1) than an + * augmenting choice (pcg2) then case's of the augmenting choice + * will belong to pcg2. + * @param refChoiceType + * Type which represents the choice to which case belongs. Every + * case has to contain its choice in extend part. + * @param caseNodes + * set of choice case nodes for which is checked if are/aren't + * added to choice through augmentation + * @return list of generated types which represents augmented cases of + * choice refChoiceType + * @throws IllegalArgumentException + *
    + *
  • if basePackageName equals null
  • + *
  • if refChoiceType equals null
  • + *
  • if caseNodes equals null
  • + *
+ */ + private List generateTypesFromAugmentedChoiceCases(final String basePackageName, + final Type refChoiceType, final Set caseNodes) { + if (basePackageName == null) { + throw new IllegalArgumentException("Base Package Name cannot be NULL!"); + } + if (refChoiceType == null) { + throw new IllegalArgumentException("Referenced Choice Type cannot be NULL!"); + } + if (caseNodes == null) { + throw new IllegalArgumentException("Set of Choice Case Nodes cannot be NULL!"); + } + + final List generatedTypes = new ArrayList<>(); + for (final ChoiceCaseNode caseNode : caseNodes) { + if (caseNode != null && caseNode.isAugmenting()) { + final String packageName = packageNameForGeneratedType(basePackageName, caseNode.getPath()); + final GeneratedTypeBuilder caseTypeBuilder = addDefaultInterfaceDefinition(packageName, caseNode); + caseTypeBuilder.addImplementsType(refChoiceType); + + final Set childNodes = caseNode.getChildNodes(); + if (childNodes != null) { + resolveDataSchemaNodes(basePackageName, caseTypeBuilder, childNodes); + } + generatedTypes.add(caseTypeBuilder.toInstance()); + } + } + + return generatedTypes; + } + + /** + * Converts leaf to the getter method which is added to + * typeBuilder. + * + * @param typeBuilder + * generated type builder to which is added getter method as + * leaf mapping + * @param leaf + * leaf schema node which is mapped as getter method which is + * added to typeBuilder + * @return boolean value + *
    + *
  • false - if leaf or typeBuilder are + * null
  • + *
  • true - in other cases
  • + *
+ */ + private boolean resolveLeafSchemaNodeAsMethod(final GeneratedTypeBuilder typeBuilder, final LeafSchemaNode leaf) { + if ((leaf != null) && (typeBuilder != null)) { + final String leafName = leaf.getQName().getLocalName(); + String leafDesc = leaf.getDescription(); + if (leafDesc == null) { + leafDesc = ""; + } + + if (leafName != null && !leaf.isAddedByUses()) { + final TypeDefinition typeDef = leaf.getType(); + + Type returnType = null; + if (typeDef instanceof EnumTypeDefinition) { + returnType = typeProvider.javaTypeForSchemaDefinitionType(typeDef); + final EnumTypeDefinition enumTypeDef = enumTypeDefFromExtendedType(typeDef); + final EnumBuilder enumBuilder = resolveInnerEnumFromTypeDefinition(enumTypeDef, leafName, + typeBuilder); + + if (enumBuilder != null) { + returnType = new ReferencedTypeImpl(enumBuilder.getPackageName(), enumBuilder.getName()); + } + ((TypeProviderImpl) typeProvider).putReferencedType(leaf.getPath(), returnType); + } else if (typeDef instanceof UnionType) { + GeneratedTOBuilder genTOBuilder = addTOToTypeBuilder(typeDef, typeBuilder, leafName); + if (genTOBuilder != null) { + returnType = new ReferencedTypeImpl(genTOBuilder.getPackageName(), genTOBuilder.getName()); + } + } else if (typeDef instanceof BitsTypeDefinition) { + GeneratedTOBuilder genTOBuilder = addTOToTypeBuilder(typeDef, typeBuilder, leafName); + if (genTOBuilder != null) { + returnType = new ReferencedTypeImpl(genTOBuilder.getPackageName(), genTOBuilder.getName()); + } + } else { + returnType = typeProvider.javaTypeForSchemaDefinitionType(typeDef); + } + if (returnType != null) { + constructGetter(typeBuilder, leafName, leafDesc, returnType); + return true; + } + } + } + return false; + } + + /** + * Converts leaf schema node to property of generated TO + * builder. + * + * @param toBuilder + * generated TO builder to which is leaf added as + * property + * @param leaf + * leaf schema node which is added to toBuilder as + * property + * @param isReadOnly + * boolean value which says if leaf property is|isn't read only + * @return boolean value + *
    + *
  • false - if leaf, toBuilder or leaf + * name equals null or if leaf is added by uses.
  • + *
  • true - other cases
  • + *
+ */ + private boolean resolveLeafSchemaNodeAsProperty(final GeneratedTOBuilder toBuilder, final LeafSchemaNode leaf, + boolean isReadOnly) { + if ((leaf != null) && (toBuilder != null)) { + final String leafName = leaf.getQName().getLocalName(); + String leafDesc = leaf.getDescription(); + if (leafDesc == null) { + leafDesc = ""; + } + + if (leafName != null && !leaf.isAddedByUses()) { + final TypeDefinition typeDef = leaf.getType(); + + // TODO: properly resolve enum types + final Type returnType = typeProvider.javaTypeForSchemaDefinitionType(typeDef); + + if (returnType != null) { + final GeneratedPropertyBuilder propBuilder = toBuilder.addProperty(parseToClassName(leafName)); + + propBuilder.setReadOnly(isReadOnly); + propBuilder.setReturnType(returnType); + propBuilder.setComment(leafDesc); + + toBuilder.addEqualsIdentity(propBuilder); + toBuilder.addHashIdentity(propBuilder); + toBuilder.addToStringProperty(propBuilder); + + return true; + } + } + } + return false; + } + + /** + * Converts node leaf list schema node to getter method of + * typeBuilder. + * + * @param typeBuilder + * generated type builder to which is node added as + * getter method + * @param node + * leaf list schema node which is added to + * typeBuilder as getter method + * @return boolean value + *
    + *
  • true - if node, typeBuilder, + * nodeName equal null or node is added by uses
  • + *
  • false - other cases
  • + *
+ */ + private boolean resolveLeafListSchemaNode(final GeneratedTypeBuilder typeBuilder, final LeafListSchemaNode node) { + if ((node != null) && (typeBuilder != null)) { + final String nodeName = node.getQName().getLocalName(); + String nodeDesc = node.getDescription(); + if (nodeDesc == null) { + nodeDesc = ""; + } + + if (nodeName != null && !node.isAddedByUses()) { + final TypeDefinition type = node.getType(); + final Type listType = Types.listTypeFor(typeProvider.javaTypeForSchemaDefinitionType(type)); + + 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 boolean resolveContainerSchemaNode(final String basePackageName, final GeneratedTypeBuilder typeBuilder, + final ContainerSchemaNode containerNode) { + if ((containerNode != null) && (typeBuilder != null)) { + final String nodeName = containerNode.getQName().getLocalName(); + + if (nodeName != null && !containerNode.isAddedByUses()) { + final String packageName = packageNameForGeneratedType(basePackageName, containerNode.getPath()); + + final GeneratedTypeBuilder rawGenType = addDefaultInterfaceDefinition(packageName, containerNode); + constructGetter(typeBuilder, nodeName, containerNode.getDescription(), 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 boolean resolveListSchemaNode(final String basePackageName, final GeneratedTypeBuilder typeBuilder, + final ListSchemaNode listNode) { + if ((listNode != null) && (typeBuilder != null)) { + final String listName = listNode.getQName().getLocalName(); + + if (listName != null && !listNode.isAddedByUses()) { + final String packageName = packageNameForGeneratedType(basePackageName, listNode.getPath()); + final GeneratedTypeBuilder rawGenType = addDefaultInterfaceDefinition(packageName, listNode); + constructGetter(typeBuilder, listName, listNode.getDescription(), Types.listTypeFor(rawGenType)); + return true; + } + } + return false; + } + + /** + * Instantiates generated type builder with packageName and + * schemaNode. + * + * The new builder always implements + * {@link org.opendaylight.yangtools.yang.binding.DataObject DataObject}.
+ * If schemaNode is instance of GroupingDefinition it also + * implements {@link org.opendaylight.yangtools.yang.binding.Augmentable + * Augmentable}.
+ * If schemaNode is instance of + * {@link org.opendaylight.yangtools.yang.model.api.DataNodeContainer + * DataNodeContainer} it can also implement nodes which are specified in + * uses. + * + * @param packageName + * string with the name of the package to which + * schemaNode belongs. + * @param schemaNode + * schema node for which is created generated type builder + * @return generated type builder schemaNode + */ + private GeneratedTypeBuilder addDefaultInterfaceDefinition(final String packageName, final SchemaNode schemaNode) { + final GeneratedTypeBuilder builder = addRawInterfaceDefinition(packageName, schemaNode, ""); + builder.addImplementsType(Types.DATA_OBJECT); + if (!(schemaNode instanceof GroupingDefinition)) { + builder.addImplementsType(Types.augmentableTypeFor(builder)); + } + + if (schemaNode instanceof DataNodeContainer) { + addImplementedInterfaceFromUses((DataNodeContainer) schemaNode, builder); + } + + return builder; + } + + /** + * Wraps the calling of the same overloaded method. + * + * @param packageName + * string with the package name to which returning generated type + * builder belongs + * @param schemaNode + * schema node which provide data about the schema node name + * @return generated type builder for schemaNode + */ + private GeneratedTypeBuilder addRawInterfaceDefinition(final String packageName, final SchemaNode schemaNode) { + return addRawInterfaceDefinition(packageName, schemaNode, ""); + } + + /** + * Returns reference to generated type builder for specified + * schemaNode with packageName. + * + * Firstly the generated type builder is searched in + * {@link BindingGeneratorImpl#genTypeBuilders genTypeBuilders}. If it isn't + * found it is created and added to genTypeBuilders. + * + * @param packageName + * string with the package name to which returning generated type + * builder belongs + * @param schemaNode + * schema node which provide data about the schema node name + * @return generated type builder for schemaNode + * @throws IllegalArgumentException + *
    + *
  • if schemaNode equals null
  • + *
  • if packageName equals null
  • + *
  • if Q name of schema node is null
  • + *
  • if schema node name is nul
  • + *
+ * + */ + private GeneratedTypeBuilder addRawInterfaceDefinition(final String packageName, final SchemaNode schemaNode, + final String prefix) { + if (schemaNode == null) { + throw new IllegalArgumentException("Data Schema Node cannot be NULL!"); + } + if (packageName == null) { + throw new IllegalArgumentException("Package Name for Generated Type cannot be NULL!"); + } + if (schemaNode.getQName() == null) { + throw new IllegalArgumentException("QName for Data Schema Node cannot be NULL!"); + } + final String schemaNodeName = schemaNode.getQName().getLocalName(); + if (schemaNodeName == null) { + throw new IllegalArgumentException("Local Name of QName for Data Schema Node cannot be NULL!"); + } + + final String genTypeName; + if (prefix == null) { + genTypeName = parseToClassName(schemaNodeName); + } else { + genTypeName = prefix + parseToClassName(schemaNodeName); + } + + final GeneratedTypeBuilder newType = new GeneratedTypeBuilderImpl(packageName, genTypeName); + if (!genTypeBuilders.containsKey(packageName)) { + final Map builders = new HashMap<>(); + builders.put(genTypeName, newType); + genTypeBuilders.put(packageName, builders); + } else { + final Map builders = genTypeBuilders.get(packageName); + if (!builders.containsKey(genTypeName)) { + builders.put(genTypeName, newType); + } + } + return newType; + } + + /** + * Creates the name of the getter method from methodName. + * + * @param methodName + * string with the name of the getter method + * @return string with the name of the getter method for + * methodName in JAVA method format + */ + private String getterMethodName(final String methodName) { + final StringBuilder method = new StringBuilder(); + method.append("get"); + method.append(parseToClassName(methodName)); + return method.toString(); + } + + /** + * Creates the name of the setter method from methodName. + * + * @param methodName + * string with the name of the setter method + * @return string with the name of the setter method for + * methodName in JAVA method format + */ + private String setterMethodName(final String methodName) { + final StringBuilder method = new StringBuilder(); + method.append("set"); + method.append(parseToClassName(methodName)); + return method.toString(); + } + + /** + * Created a method signature builder as part of + * interfaceBuilder. + * + * The method signature builder is created for the getter method of + * schemaNodeName. Also comment and + * returnType information are added to the builder. + * + * @param interfaceBuilder + * generated type builder for which the getter method should be + * created + * @param schemaNodeName + * string with schema node name. The name will be the part of the + * getter method name. + * @param comment + * string with comment for the getter method + * @param returnType + * type which represents the return type of the getter method + * @return method signature builder which represents the getter method of + * interfaceBuilder + */ + private MethodSignatureBuilder constructGetter(final GeneratedTypeBuilder interfaceBuilder, + final String schemaNodeName, final String comment, final Type returnType) { + final MethodSignatureBuilder getMethod = interfaceBuilder.addMethod(getterMethodName(schemaNodeName)); + + getMethod.setComment(comment); + getMethod.setReturnType(returnType); + + return getMethod; + } + + /** + * Creates a method signature builder as a part of + * interfaceBuilder for schemaNodeName + * + * The method signature builder is created for the setter method of + * schemaNodeName. Also comment + * parameterType data are added to the builder. The return type + * of the method is set to void. + * + * @param interfaceBuilder + * generated type builder for which the setter method should be + * created + * @param schemaNodeName + * string with schema node name. The name will be the part of the + * setter method name. + * @param comment + * string with comment for the setter method + * @param parameterType + * type which represents the type of the setter method input + * parameter + * @return method signature builder which represents the setter method of + * interfaceBuilder + */ + private MethodSignatureBuilder constructSetter(final GeneratedTypeBuilder interfaceBuilder, + final String schemaNodeName, final String comment, final Type parameterType) { + final MethodSignatureBuilder setMethod = interfaceBuilder.addMethod(setterMethodName(schemaNodeName)); + + setMethod.setComment(comment); + setMethod.addParameter(parameterType, parseToValidParamName(schemaNodeName)); + setMethod.setReturnType(Types.voidType()); + + return setMethod; + } + + private List listToGenType(final String basePackageName, final ListSchemaNode list) { + if (basePackageName == null) { + throw new IllegalArgumentException("Package Name for Generated Type cannot be NULL!"); + } + if (list == null) { + throw new IllegalArgumentException("List Schema Node cannot be NULL!"); + } + + final String packageName = packageNameForGeneratedType(basePackageName, list.getPath()); + // final GeneratedTypeBuilder typeBuilder = + // resolveListTypeBuilder(packageName, list); + final GeneratedTypeBuilder typeBuilder = addDefaultInterfaceDefinition(packageName, list); + + final List listKeys = listKeys(list); + GeneratedTOBuilder genTOBuilder = resolveListKeyTOBuilder(packageName, list); + + + if(genTOBuilder != null) { + ParameterizedType identifierMarker = Types.parameterizedTypeFor( Types.typeForClass(Identifier.class), typeBuilder); + ParameterizedType identifiableMarker = Types.parameterizedTypeFor(Types.typeForClass(Identifiable.class), genTOBuilder); + genTOBuilder.addImplementsType(identifierMarker); + typeBuilder.addImplementsType(identifiableMarker); + } + final Set schemaNodes = list.getChildNodes(); + + for (final DataSchemaNode schemaNode : schemaNodes) { + if (schemaNode.isAugmenting()) { + continue; + } + addSchemaNodeToListBuilders(basePackageName, schemaNode, typeBuilder, genTOBuilder, listKeys); + } + return typeBuildersToGenTypes(typeBuilder, genTOBuilder); + } + + /** + * Adds schemaNode to typeBuilder as getter method + * or to genTOBuilder as property. + * + * @param basePackageName + * string contains the module package name + * @param schemaNode + * data schema node which should be added as getter method to + * typeBuilder or as a property to + * genTOBuilder if is part of the list key + * @param typeBuilder + * generated type builder for the list schema node + * @param genTOBuilder + * generated TO builder for the list keys + * @param listKeys + * list of string which contains names of the list keys + * @throws IllegalArgumentException + *
    + *
  • if schemaNode equals null
  • + *
  • if typeBuilder equals null
  • + *
+ */ + private void addSchemaNodeToListBuilders(final String basePackageName, final DataSchemaNode schemaNode, + final GeneratedTypeBuilder typeBuilder, final GeneratedTOBuilder genTOBuilder, final List listKeys) { + if (schemaNode == null) { + throw new IllegalArgumentException("Data Schema Node cannot be NULL!"); + } + + if (typeBuilder == null) { + throw new IllegalArgumentException("Generated Type Builder cannot be NULL!"); + } + + if (schemaNode instanceof LeafSchemaNode) { + final LeafSchemaNode leaf = (LeafSchemaNode) schemaNode; + final String leafName = leaf.getQName().getLocalName(); + if (!listKeys.contains(leafName)) { + resolveLeafSchemaNodeAsMethod(typeBuilder, leaf); + } else { + resolveLeafSchemaNodeAsProperty(genTOBuilder, leaf, true); + } + } else if (schemaNode instanceof LeafListSchemaNode) { + resolveLeafListSchemaNode(typeBuilder, (LeafListSchemaNode) schemaNode); + } else if (schemaNode instanceof ContainerSchemaNode) { + resolveContainerSchemaNode(basePackageName, typeBuilder, (ContainerSchemaNode) schemaNode); + } else if (schemaNode instanceof ListSchemaNode) { + resolveListSchemaNode(basePackageName, typeBuilder, (ListSchemaNode) schemaNode); + } + } + + private List typeBuildersToGenTypes(final GeneratedTypeBuilder typeBuilder, GeneratedTOBuilder genTOBuilder) { + final List genTypes = new ArrayList<>(); + if (typeBuilder == null) { + throw new IllegalArgumentException("Generated Type Builder cannot be NULL!"); + } + + if (genTOBuilder != null) { + final GeneratedTransferObject genTO = genTOBuilder.toInstance(); + constructGetter(typeBuilder, "key", "Returns Primary Key of Yang List Type", genTO); + genTypes.add(genTO); + } + genTypes.add(typeBuilder.toInstance()); + return genTypes; + } + + /** + * Selects the names of the list keys from list and returns + * them as the list of the strings + * + * @param list of string with names of the list keys + * @return list of string which represents names of the list keys. If the + * list contains no keys then the empty list is + * returned. + */ + private List listKeys(final ListSchemaNode list) { + final List listKeys = new ArrayList<>(); + + if (list.getKeyDefinition() != null) { + final List keyDefinitions = list.getKeyDefinition(); + + for (final QName keyDefinition : keyDefinitions) { + listKeys.add(keyDefinition.getLocalName()); + } + } + return listKeys; + } + + + /** + * Generates for the list which contains any list keys special + * generated TO builder. + * + * @param packageName + * string with package name to which the list belongs + * @param list + * list schema node which is source of data about the list name + * @return generated TO builder which represents the keys of the + * list or null if list is null or list of + * key definitions is null or empty. + */ + private GeneratedTOBuilder resolveListKeyTOBuilder(final String packageName, final ListSchemaNode list) { + GeneratedTOBuilder genTOBuilder = null; + if ((list.getKeyDefinition() != null) && (!list.getKeyDefinition().isEmpty())) { + if (list != null) { + final String listName = list.getQName().getLocalName() + "Key"; + genTOBuilder = schemaNodeToTransferObjectBuilder(packageName, listName); + } + } + return genTOBuilder; + + } + + /** + * Builds generated TO builders for typeDef of type + * {@link org.opendaylight.yangtools.yang.model.util.UnionType UnionType} or + * {@link org.opendaylight.yangtools.yang.model.api.type.BitsTypeDefinition + * BitsTypeDefinition} which are also added to typeBuilder as + * enclosing transfer object. + * + * @param typeDef + * type definition which can be of type UnionType + * or BitsTypeDefinition + * @param typeBuilder + * generated type builder to which is added generated TO created + * from typeDef + * @param leafName + * string with name for generated TO builder + * @return generated TO builder for typeDef + */ + private GeneratedTOBuilder addTOToTypeBuilder(TypeDefinition typeDef, GeneratedTypeBuilder typeBuilder, + String leafName) { + final String classNameFromLeaf = parseToClassName(leafName); + GeneratedTOBuilder genTOBuilder = null; + final String packageName = typeBuilder.getFullyQualifiedName(); + if (typeDef instanceof UnionTypeDefinition) { + genTOBuilder = ((TypeProviderImpl) typeProvider).provideGeneratedTOBuilderForUnionTypeDefinition(packageName, typeDef, + classNameFromLeaf); + } else if (typeDef instanceof BitsTypeDefinition) { + genTOBuilder = ((TypeProviderImpl) typeProvider).provideGeneratedTOBuilderForBitsTypeDefinition(packageName, typeDef, + classNameFromLeaf); + } + if (genTOBuilder != null) { + typeBuilder.addEnclosingTransferObject(genTOBuilder); + return genTOBuilder; + } + return null; + + } + + /** + * Adds the implemented types to type builder. + * + * The method passes through the list of uses in + * {@code dataNodeContainer}. For every use is obtained coresponding + * generated type from {@link BindingGeneratorImpl#allGroupings + * allGroupings} which is adde as implements type to + * builder + * + * @param dataNodeContainer + * element which contains the list of used YANG groupings + * @param builder + * builder to which are added implemented types according to + * dataNodeContainer + * @return generated type builder with all implemented types + */ + private GeneratedTypeBuilder addImplementedInterfaceFromUses(final DataNodeContainer dataNodeContainer, + final GeneratedTypeBuilder builder) { + for (UsesNode usesNode : dataNodeContainer.getUses()) { + if (usesNode.getGroupingPath() != null) { + GeneratedType genType = allGroupings.get(usesNode.getGroupingPath()); + if (genType == null) { + throw new IllegalStateException("Grouping " + usesNode.getGroupingPath() + "is not resolved for " + + builder.getName()); + } + builder.addImplementsType(genType); + } + } + return builder; + } + +} diff --git a/code-generator/binding-generator-impl/src/main/java/org/opendaylight/yangtools/sal/binding/yang/types/BaseYangTypes.java b/code-generator/binding-generator-impl/src/main/java/org/opendaylight/yangtools/sal/binding/yang/types/BaseYangTypes.java index 964731d782..8c72960c09 100644 --- a/code-generator/binding-generator-impl/src/main/java/org/opendaylight/yangtools/sal/binding/yang/types/BaseYangTypes.java +++ b/code-generator/binding-generator-impl/src/main/java/org/opendaylight/yangtools/sal/binding/yang/types/BaseYangTypes.java @@ -9,30 +9,87 @@ package org.opendaylight.yangtools.sal.binding.yang.types; import java.math.BigDecimal; import java.math.BigInteger; +import java.math.BigDecimal; import java.util.HashMap; import java.util.Map; import org.opendaylight.yangtools.binding.generator.util.Types; import org.opendaylight.yangtools.sal.binding.generator.spi.TypeProvider; import org.opendaylight.yangtools.sal.binding.model.api.Type; + import org.opendaylight.yangtools.yang.model.api.TypeDefinition; public final class BaseYangTypes { - + /** + * mapping of basic built-in YANG types (keys) to JAVA + * {@link org.opendaylight.yangtools.sal.binding.model.api.Type Type}. This + * map is filled with mapping data in static initialization block + */ private static Map typeMap = new HashMap(); + /** + * Type representation of boolean YANG type + */ public static final Type BOOLEAN_TYPE = Types.typeForClass(Boolean.class); + + /** + * Type representation of empty YANG type + */ public static final Type EMPTY_TYPE = Types.typeForClass(Boolean.class); + + /** + * Type representation of int8 YANG type + */ public static final Type INT8_TYPE = Types.typeForClass(Byte.class); + + /** + * Type representation of int16 YANG type + */ public static final Type INT16_TYPE = Types.typeForClass(Short.class); + + /** + * Type representation of int32 YANG type + */ public static final Type INT32_TYPE = Types.typeForClass(Integer.class); + + /** + * Type representation of int64 YANG type + */ public static final Type INT64_TYPE = Types.typeForClass(Long.class); + + /** + * Type representation of string YANG type + */ public static final Type STRING_TYPE = Types.typeForClass(String.class); + + /** + * Type representation of decimal64 YANG type + */ public static final Type DECIMAL64_TYPE = Types.typeForClass(BigDecimal.class); + + /** + * Type representation of uint8 YANG type + */ public static final Type UINT8_TYPE = Types.typeForClass(Short.class); + + /** + * Type representation of uint16 YANG type + */ public static final Type UINT16_TYPE = Types.typeForClass(Integer.class); + + /** + * Type representation of uint32 YANG type + */ public static final Type UINT32_TYPE = Types.typeForClass(Long.class); + + /** + * Type representation of uint64 YANG type + */ public static final Type UINT64_TYPE = Types.typeForClass(BigInteger.class); + + /** + * Type representation of binary YANG type + */ public static final Type BINARY_TYPE = Types.primitiveType("byte[]"); static { @@ -52,12 +109,29 @@ public final class BaseYangTypes { } public static final TypeProvider BASE_YANG_TYPES_PROVIDER = new TypeProvider() { - + /** + * Searches Type value to which is YANG type + * mapped. + * + * @param type + * string with YANG type name + * @return java Type representation of type + */ @Override public Type javaTypeForYangType(String type) { return typeMap.get(type); } + /** + * Searches Type value to which is YANG type + * mapped. + * + * @param type + * type definition representation of YANG type + * @return java Type representation of type. + * If type isn't found then null is + * returned. + */ @Override public Type javaTypeForSchemaDefinitionType(TypeDefinition type) { if (type != null) { diff --git a/code-generator/binding-generator-impl/src/main/java/org/opendaylight/yangtools/sal/binding/yang/types/GroupingDefinitionDependencySort.java b/code-generator/binding-generator-impl/src/main/java/org/opendaylight/yangtools/sal/binding/yang/types/GroupingDefinitionDependencySort.java index bb928f13d5..d40483bf0f 100644 --- a/code-generator/binding-generator-impl/src/main/java/org/opendaylight/yangtools/sal/binding/yang/types/GroupingDefinitionDependencySort.java +++ b/code-generator/binding-generator-impl/src/main/java/org/opendaylight/yangtools/sal/binding/yang/types/GroupingDefinitionDependencySort.java @@ -22,56 +22,98 @@ import org.opendaylight.yangtools.yang.model.api.SchemaPath; import org.opendaylight.yangtools.yang.model.api.UsesNode; import org.opendaylight.yangtools.yang.parser.util.TopologicalSort; import org.opendaylight.yangtools.yang.parser.util.TopologicalSort.Node; -import org.opendaylight.yangtools.yang.parser.util.TopologicalSort.NodeImpl; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; import com.google.common.collect.Maps; import com.google.common.collect.Sets; -//import org.opendaylight.yangtools.yang.model.util.GroupingDefinition; - public class GroupingDefinitionDependencySort { - private static final Logger logger = LoggerFactory.getLogger(GroupingDefinitionDependencySort.class); + /** + * Sorts set groupingDefinitions according to the mutual + * dependencies.
+ * + * Elements of groupingDefinitions are firstly transformed to + * {@link org.opendaylight.yangtools.yang.parser.util.TopologicalSort.Node + * Node} interfaces and then are sorted by + * {@link org.opendaylight.yangtools.yang.parser.util.TopologicalSort#sort(Set) + * sort()} method of TopologicalSort.
+ *
+ * + * + * Definition of dependency relation:
+ * The first GroupingDefinition object (in this context) + * depends on second GroupingDefinition object if the first one + * contains in its set of UsesNode (obtained through + * {@link org.opendaylight.yangtools.yang.model.api.DataNodeContainer#getUses() + * getUses} method) reference to the second one.
+ * + * @param groupingDefinitions + * set of grouping definition which should be sorted according to + * mutual dependencies + * @return list of grouping definitiond which are sorted by mutual + * dependencies + * @throws IllegalArgumentException + * if groupingDefinitions + * + */ public static List sort(final Set groupingDefinitions) { if (groupingDefinitions == null) { - logger.error("Set of grouping definitions cannot be NULL!"); throw new IllegalArgumentException("Set of Type Definitions " + "cannot be NULL!"); } final List resultGroupingDefinitions = new ArrayList(); - final Set unsorted = groupingDefinitionsToGroupingNodes(groupingDefinitions); + final Set unsorted = groupingDefinitionsToNodes(groupingDefinitions); final List sortedNodes = TopologicalSort.sort(unsorted); for (Node node : sortedNodes) { - resultGroupingDefinitions.add(((GroupingNode) node).getGroupingDefinition()); + NodeWrappedType nodeWrappedType = (NodeWrappedType) node; + resultGroupingDefinitions.add((GroupingDefinition) (nodeWrappedType.getWrappedType())); } return resultGroupingDefinitions; } - private static Set groupingDefinitionsToGroupingNodes(final Set groupingDefinitions) { + /** + * Wraps every grouping definition to node type and adds to every node + * information about dependencies. + * + * The map with mapping from schema path (represents grouping definition) to + * node is created. For every created node (next nodeFrom) is for its + * wrapped grouping definition passed the set of its uses nodes + * through. For every uses node is found its wrapping node (next as + * nodeTo). This dependency relationship between nodeFrom and all + * found nodesTo is modeled with creating of one edge from nodeFrom to + * nodeTo. + * + * + * @param groupingDefinitions + * set of goruping definition which will be wrapped to nodes + * + * @return set of nodes where every one contains wrapped grouping definition + */ + private static Set groupingDefinitionsToNodes(final Set groupingDefinitions) { final Map nodeMap = Maps.newHashMap(); final Set resultNodes = Sets.newHashSet(); for (final GroupingDefinition groupingDefinition : groupingDefinitions) { - final Node node = new GroupingNode(groupingDefinition); + final Node node = new NodeWrappedType(groupingDefinition); nodeMap.put(groupingDefinition.getPath(), node); resultNodes.add(node); } for (final Node node : resultNodes) { - final GroupingNode groupingNode = (GroupingNode) node; - final GroupingDefinition groupingDefinition = groupingNode.getGroupingDefinition(); + final NodeWrappedType nodeWrappedType = (NodeWrappedType) node; + final GroupingDefinition groupingDefinition = (GroupingDefinition) nodeWrappedType.getWrappedType(); Set usesNodes = getAllUsesNodes(groupingDefinition); + for (UsesNode usesNode : usesNodes) { SchemaPath schemaPath = usesNode.getGroupingPath(); if (schemaPath != null) { Node nodeTo = nodeMap.get(schemaPath); if (nodeTo != null) { - groupingNode.addEdge(nodeTo); + nodeWrappedType.addEdge(nodeTo); } + } } @@ -80,6 +122,16 @@ public class GroupingDefinitionDependencySort { return resultNodes; } + /** + * Returns the set of the uses nodes which are get from uses in + * container, from uses in groupings inside + * container and from uses inside child nodes of the + * container. + * + * @param container + * data node container which can contain some uses of grouping + * @return set of uses nodes which were find in container. + */ private static Set getAllUsesNodes(DataNodeContainer container) { Set ret = new HashSet<>(); ret.addAll(container.getUses()); @@ -88,12 +140,12 @@ public class GroupingDefinitionDependencySort { for (GroupingDefinition groupingDefinition : groupings) { ret.addAll(getAllUsesNodes(groupingDefinition)); } - Set children = container.getChildNodes(); - for (DataSchemaNode dataSchemaNode : children) { - if (dataSchemaNode instanceof DataNodeContainer) { - ret.addAll(getAllUsesNodes((DataNodeContainer) dataSchemaNode)); - } else if (dataSchemaNode instanceof ChoiceNode) { - Set cases = ((ChoiceNode) dataSchemaNode).getCases(); + Set childNodes = container.getChildNodes(); + for (DataSchemaNode childNode : childNodes) { + if (childNode instanceof DataNodeContainer) { + ret.addAll(getAllUsesNodes((DataNodeContainer) childNode)); + } else if (childNode instanceof ChoiceNode) { + Set cases = ((ChoiceNode) childNode).getCases(); for (ChoiceCaseNode choiceCaseNode : cases) { ret.addAll(getAllUsesNodes(choiceCaseNode)); } @@ -105,40 +157,4 @@ public class GroupingDefinitionDependencySort { } - private static final class GroupingNode extends NodeImpl { - private final GroupingDefinition groupingDefinition; - - GroupingNode(GroupingDefinition groupingDefinition) { - this.groupingDefinition = groupingDefinition; - } - - GroupingDefinition getGroupingDefinition() { - return groupingDefinition; - } - - @Override - public boolean equals(Object o) { - if (this == o) { - return true; - } - if (!(o instanceof GroupingNode)) { - return false; - } - GroupingNode groupingNode = (GroupingNode) o; - if (!groupingDefinition.equals(groupingNode.groupingDefinition)) { - return false; - } - return true; - } - - @Override - public int hashCode() { - return groupingDefinition.hashCode(); - } - - @Override - public String toString() { - return "GroupingNode{" + "groupingType=" + groupingDefinition + '}'; - } - } } diff --git a/code-generator/binding-generator-impl/src/main/java/org/opendaylight/yangtools/sal/binding/yang/types/NodeWrappedType.java b/code-generator/binding-generator-impl/src/main/java/org/opendaylight/yangtools/sal/binding/yang/types/NodeWrappedType.java new file mode 100644 index 0000000000..bc6b150070 --- /dev/null +++ b/code-generator/binding-generator-impl/src/main/java/org/opendaylight/yangtools/sal/binding/yang/types/NodeWrappedType.java @@ -0,0 +1,55 @@ +package org.opendaylight.yangtools.sal.binding.yang.types; + +import org.opendaylight.yangtools.yang.parser.util.TopologicalSort.NodeImpl; + +public final class NodeWrappedType extends NodeImpl { + /** + * The payload which is saved inside Node + */ + private final Object wrappedType; + + /** + * Create new instance of class NodeWrappedType. + * + * @param wrappedType + * object with payload data + */ + NodeWrappedType(Object wrappedType) { + this.wrappedType = wrappedType; + } + + /** + * Gets payload from class + * + * @return object with wrappedType + */ + Object getWrappedType() { + return wrappedType; + } + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (!(o instanceof NodeWrappedType)) { + return false; + } + NodeWrappedType nodeWrappedType = (NodeWrappedType) o; + if (!wrappedType.equals(nodeWrappedType.wrappedType)) { + return false; + } + return true; + } + + @Override + public int hashCode() { + return wrappedType.hashCode(); + } + + @Override + public String toString() { + return "NodeWrappedType{" + "wrappedType=" + wrappedType + '}'; + } + +} diff --git a/code-generator/binding-generator-impl/src/main/java/org/opendaylight/yangtools/sal/binding/yang/types/TypeProviderImpl.java b/code-generator/binding-generator-impl/src/main/java/org/opendaylight/yangtools/sal/binding/yang/types/TypeProviderImpl.java index 381bff5d4b..4e6d2632e2 100644 --- a/code-generator/binding-generator-impl/src/main/java/org/opendaylight/yangtools/sal/binding/yang/types/TypeProviderImpl.java +++ b/code-generator/binding-generator-impl/src/main/java/org/opendaylight/yangtools/sal/binding/yang/types/TypeProviderImpl.java @@ -55,11 +55,30 @@ import org.opendaylight.yangtools.yang.model.util.UnionType; import org.opendaylight.yangtools.yang.parser.util.ModuleDependencySort; public final class TypeProviderImpl implements TypeProvider { - + /** + * Contains the schema data red from YANG files. + */ private final SchemaContext schemaContext; + + /** + * The outter map maps module names to the map of the types for the module. + * The inner map maps the name of the concrete type to the JAVA Type (usually it is generated TO). + */ private Map> genTypeDefsContextMap; + + /** + * The map which maps schema paths to JAVA Type. + */ private final Map referencedTypes; + /** + * Creates new instance of class TypeProviderImpl. + * + * @param schemaContext + * contains the schema data red from YANG files + * @throws IllegalArgumentException + * if schemaContext equal null. + */ public TypeProviderImpl(final SchemaContext schemaContext) { if (schemaContext == null) { throw new IllegalArgumentException("Schema Context cannot be null!"); @@ -71,6 +90,20 @@ public final class TypeProviderImpl implements TypeProvider { resolveTypeDefsFromContext(); } + /** + * Puts refType to map with key refTypePath + * + * @param refTypePath + * schema path used as the map key + * @param refType + * type which represents the map value + * @throws IllegalArgumentException + *
    + *
  • if refTypePath equal null
  • + *
  • if refType equal null
  • + *
+ * + */ public void putReferencedType(final SchemaPath refTypePath, final Type refType) { if (refTypePath == null) { throw new IllegalArgumentException("Path reference of " + "Enumeration Type Definition cannot be NULL!"); @@ -82,11 +115,15 @@ public final class TypeProviderImpl implements TypeProvider { referencedTypes.put(refTypePath, refType); } - /* - * (non-Javadoc) + /** + * + * Converts basic YANG type type to JAVA Type. * + * @param type + * string with YANG name of type + * @returns JAVA Type for YANG type type * @see org.opendaylight.controller.yang.model.type.provider.TypeProvider# - * javaTypeForYangType(java.lang.String) + * javaTypeForYangType(java.lang.String) */ @Override public Type javaTypeForYangType(String type) { @@ -94,6 +131,19 @@ public final class TypeProviderImpl implements TypeProvider { return t; } + /** + * Converts schema definition type typeDefinition to JAVA + * Type + * + * @param typeDefinition + * type definition which is converted to JAVA type + * @throws IllegalArgumentException + *
    + *
  • if typeDefinition equal null
  • + *
  • if Q name of typeDefinition equal null
  • + *
  • if name of typeDefinition equal null
  • + *
+ */ @Override public Type javaTypeForSchemaDefinitionType(final TypeDefinition typeDefinition) { Type returnType = null; @@ -116,10 +166,10 @@ public final class TypeProviderImpl implements TypeProvider { returnType = provideTypeForLeafref(leafref); } else if (baseTypeDef instanceof IdentityrefTypeDefinition) { final IdentityrefTypeDefinition idref = (IdentityrefTypeDefinition) baseTypeDef; - returnType = returnTypeForIdentityref(idref); + returnType = provideTypeForIdentityref(idref); } else if (baseTypeDef instanceof EnumTypeDefinition) { final EnumTypeDefinition enumTypeDef = (EnumTypeDefinition) baseTypeDef; - returnType = resolveEnumFromTypeDefinition(enumTypeDef, typedefName); + returnType = provideTypeForEnum(enumTypeDef, typedefName); } else { final Module module = findParentModuleForTypeDefinition(schemaContext, typeDefinition); if (module != null) { @@ -139,7 +189,7 @@ public final class TypeProviderImpl implements TypeProvider { returnType = provideTypeForLeafref(leafref); } else if (typeDefinition instanceof IdentityrefTypeDefinition) { final IdentityrefTypeDefinition idref = (IdentityrefTypeDefinition) typeDefinition; - returnType = returnTypeForIdentityref(idref); + returnType = provideTypeForIdentityref(idref); } else { returnType = BaseYangTypes.BASE_YANG_TYPES_PROVIDER.javaTypeForSchemaDefinitionType(typeDefinition); } @@ -153,7 +203,22 @@ public final class TypeProviderImpl implements TypeProvider { return returnType; } - private Type returnTypeForIdentityref(IdentityrefTypeDefinition idref) { + /** + * Seeks for identity reference idref the JAVA + * type.
+ *
+ * + * Example:
+ * If identy which is referenced via idref has name Idn + * then returning type is {@code Class}
+ * + * @param idref + * identityref type definition for which JAVA Type + * is sought + * @return JAVA Type of the identity which is refrenced through + * idref + */ + private Type provideTypeForIdentityref(IdentityrefTypeDefinition idref) { QName baseIdQName = idref.getIdentity(); Module module = schemaContext.findModuleByNamespace(baseIdQName.getNamespace()); IdentitySchemaNode identity = null; @@ -176,6 +241,21 @@ public final class TypeProviderImpl implements TypeProvider { return returnType; } + /** + * Converts typeDefinition to concrete JAVA Type. + * + * @param typeDefinition + * type definition which should be converted to JAVA + * Type + * @return JAVA Type which represents + * typeDefinition + * @throws IllegalArgumentException + *
    + *
  • if typeDefinition equal null
  • + *
  • if Q name of typeDefinition
  • + *
  • if name of typeDefinition
  • + *
+ */ public Type generatedTypeForExtendedDefinitionType(final TypeDefinition typeDefinition) { Type returnType = null; if (typeDefinition == null) { @@ -185,7 +265,7 @@ public final class TypeProviderImpl implements TypeProvider { throw new IllegalArgumentException( "Type Definition cannot have non specified QName (QName cannot be NULL!)"); } - if (typeDefinition.getQName() == null) { + if (typeDefinition.getQName().getLocalName() == null) { throw new IllegalArgumentException("Type Definitions Local Name cannot be NULL!"); } @@ -207,6 +287,16 @@ public final class TypeProviderImpl implements TypeProvider { return returnType; } + /** + * Gets base type definition for extendTypeDef. The method is + * recursivelly called until non ExtendedType type is found. + * + * @param extendTypeDef + * type definition for which is the base type definition sought + * @return type definition which is base type for extendTypeDef + * @throws IllegalArgumentException + * if extendTypeDef equal null + */ private TypeDefinition baseTypeDefForExtendedType(final TypeDefinition extendTypeDef) { if (extendTypeDef == null) { throw new IllegalArgumentException("Type Definiition reference cannot be NULL!"); @@ -220,6 +310,23 @@ public final class TypeProviderImpl implements TypeProvider { } + /** + * Converts leafrefType to JAVA Type. + * + * The path of leafrefType is followed to find referenced node + * and its Type is returned. + * + * @param leafrefType + * leafref type definition for which is the type sought + * @return JAVA Type of data schema node which is referenced in + * leafrefType + * @throws IllegalArgumentException + *
    + *
  • if leafrefType equal null
  • + *
  • if path statement of leafrefType equal null
  • + *
+ * + */ public Type provideTypeForLeafref(final LeafrefTypeDefinition leafrefType) { Type returnType = null; if (leafrefType == null) { @@ -259,6 +366,19 @@ public final class TypeProviderImpl implements TypeProvider { return returnType; } + /** + * Checks if dataNode is LeafSchemaNode and if it + * so then checks if it is of type EnumTypeDefinition. + * + * @param dataNode + * data schema node for which is checked if it is leaf and if it + * is of enum type + * @return boolean value + *
    + *
  • true - if dataNode is leaf of type enumeration
  • + *
  • false - other cases
  • + *
+ */ private boolean leafContainsEnumDefinition(final DataSchemaNode dataNode) { if (dataNode instanceof LeafSchemaNode) { final LeafSchemaNode leaf = (LeafSchemaNode) dataNode; @@ -269,6 +389,20 @@ public final class TypeProviderImpl implements TypeProvider { return false; } + /** + * Checks if dataNode is LeafListSchemaNode and if + * it so then checks if it is of type EnumTypeDefinition. + * + * @param dataNode + * data schema node for which is checked if it is leaflist and if + * it is of enum type + * @return boolean value + *
    + *
  • true - if dataNode is leaflist of type + * enumeration
  • + *
  • false - other cases
  • + *
+ */ private boolean leafListContainsEnumDefinition(final DataSchemaNode dataNode) { if (dataNode instanceof LeafListSchemaNode) { final LeafListSchemaNode leafList = (LeafListSchemaNode) dataNode; @@ -279,7 +413,26 @@ public final class TypeProviderImpl implements TypeProvider { return false; } - private Enumeration resolveEnumFromTypeDefinition(final EnumTypeDefinition enumTypeDef, final String enumName) { + /** + * Converts enumTypeDef to + * {@link org.opendaylight.yangtools.sal.binding.model.api.Enumeration + * enumeration}. + * + * @param enumTypeDef + * enumeration type definition which is converted to enumeration + * @param enumName + * string with name which is used as the enumeration name + * @return enumeration type which is built with data (name, enum values) + * from enumTypeDef + * @throws IllegalArgumentException + *
    + *
  • if enumTypeDef equals null
  • + *
  • if enum values of enumTypeDef equal null
  • + *
  • if Q name of enumTypeDef equal null
  • + *
  • if name of enumTypeDef equal null
  • + *
+ */ + private Enumeration provideTypeForEnum(final EnumTypeDefinition enumTypeDef, final String enumName) { if (enumTypeDef == null) { throw new IllegalArgumentException("EnumTypeDefinition reference cannot be NULL!"); } @@ -303,7 +456,30 @@ public final class TypeProviderImpl implements TypeProvider { return enumBuilder.toInstance(null); } - private EnumBuilder resolveInnerEnumFromTypeDefinition(final EnumTypeDefinition enumTypeDef, final String enumName, + /** + * Adds enumeration to typeBuilder. The enumeration data are + * taken from enumTypeDef. + * + * @param enumTypeDef + * enumeration type definition is source of enumeration data for + * typeBuilder + * @param enumName + * string with the name of enumeration + * @param typeBuilder + * generated type builder to which is enumeration added + * @return enumeration type which contains enumeration data form + * enumTypeDef + * @throws IllegalArgumentException + *
    + *
  • if enumTypeDef equals null
  • + *
  • if enum values of enumTypeDef equal null
  • + *
  • if Q name of enumTypeDef equal null
  • + *
  • if name of enumTypeDef equal null
  • + *
  • if name of typeBuilder equal null
  • + *
+ * + */ + private Enumeration addInnerEnumerationToTypeBuilder(final EnumTypeDefinition enumTypeDef, final String enumName, final GeneratedTypeBuilder typeBuilder) { if (enumTypeDef == null) { throw new IllegalArgumentException("EnumTypeDefinition reference cannot be NULL!"); @@ -322,13 +498,23 @@ public final class TypeProviderImpl implements TypeProvider { } final String enumerationName = parseToClassName(enumName); - final EnumBuilder enumBuilder = typeBuilder.addEnumeration(enumerationName); + final EnumBuilder enumBuilder = typeBuilder.addEnumeration(enumerationName); updateEnumPairsFromEnumTypeDef(enumTypeDef, enumBuilder); - - return enumBuilder; + return enumBuilder.toInstance(enumBuilder); } + /** + * Updates enumBuilder with data from enumTypeDef. + * Specifically this data represents list of value-name pairs. + * + * @param enumTypeDef + * enum type definition as source of enum data for + * enumBuilder + * @param enumBuilder + * enum builder to which are saved enum data from + * enumTypeDef + */ private void updateEnumPairsFromEnumTypeDef(final EnumTypeDefinition enumTypeDef, final EnumBuilder enumBuilder) { if (enumBuilder != null) { final List enums = enumTypeDef.getValues(); @@ -350,6 +536,13 @@ public final class TypeProviderImpl implements TypeProvider { } } + /** + * Converts dataNode to JAVA Type. + * + * @param dataNode + * contains information about YANG type + * @return JAVA Type representation of dataNode + */ private Type resolveTypeFromDataSchemaNode(final DataSchemaNode dataNode) { Type returnType = null; if (dataNode != null) { @@ -364,6 +557,20 @@ public final class TypeProviderImpl implements TypeProvider { return returnType; } + /** + * Passes through all modules and through all its type definitions and + * convert it to generated types. + * + * The modules are firstly sorted by mutual dependencies. The modules are + * sequentially passed. All type definitions of a module are at the + * beginning sorted so that type definition with less amount of references + * to other type definition are processed first.
+ * For each module is created mapping record in the map + * {@link TypeProviderImpl#genTypeDefsContextMap genTypeDefsContextMap} + * which map current module name to the map which maps type names to + * returned types (generated types). + * + */ private void resolveTypeDefsFromContext() { final Set modules = schemaContext.getModules(); if (modules == null) { @@ -397,6 +604,21 @@ public final class TypeProviderImpl implements TypeProvider { } } + /** + * + * @param basePackageName + * string with name of package to which the module belongs + * @param moduleName + * string with the name of the module for to which the + * typedef belongs + * @param typedef + * type definition of the node for which should be creted JAVA + * Type (usually generated TO) + * @return JAVA Type representation of typedef or + * null value if basePackageName or + * modulName or typedef or Q name of + * typedef equals null + */ private Type typedefToGeneratedType(final String basePackageName, final String moduleName, final TypeDefinition typedef) { if ((basePackageName != null) && (moduleName != null) && (typedef != null) && (typedef.getQName() != null)) { @@ -407,21 +629,20 @@ public final class TypeProviderImpl implements TypeProvider { && !(innerTypeDefinition instanceof IdentityrefTypeDefinition)) { Type returnType = null; if (innerTypeDefinition instanceof ExtendedType) { - ExtendedType extendedTypeDef = (ExtendedType) innerTypeDefinition; - returnType = resolveExtendedTypeFromTypeDef(extendedTypeDef, basePackageName, typedefName, - moduleName); + ExtendedType innerExtendedType = (ExtendedType) innerTypeDefinition; + returnType = provideGeneratedTOFromExtendedType(innerExtendedType, basePackageName, typedefName); } else if (innerTypeDefinition instanceof UnionTypeDefinition) { - final GeneratedTOBuilder genTOBuilder = addUnionGeneratedTypeDefinition(basePackageName, typedef, - typedefName); + final GeneratedTOBuilder genTOBuilder = provideGeneratedTOBuilderForUnionTypeDefinition( + basePackageName, typedef, typedefName); returnType = genTOBuilder.toInstance(); } else if (innerTypeDefinition instanceof EnumTypeDefinition) { final EnumTypeDefinition enumTypeDef = (EnumTypeDefinition) innerTypeDefinition; - returnType = resolveEnumFromTypeDefinition(enumTypeDef, typedefName); + returnType = provideTypeForEnum(enumTypeDef, typedefName); } else if (innerTypeDefinition instanceof BitsTypeDefinition) { final BitsTypeDefinition bitsTypeDefinition = (BitsTypeDefinition) innerTypeDefinition; - final GeneratedTOBuilder genTOBuilder = bitsTypedefToTransferObject(basePackageName, - bitsTypeDefinition, typedefName); + final GeneratedTOBuilder genTOBuilder = provideGeneratedTOBuilderForBitsTypeDefinition( + basePackageName, bitsTypeDefinition, typedefName); returnType = genTOBuilder.toInstance(); } else { @@ -442,6 +663,17 @@ public final class TypeProviderImpl implements TypeProvider { return null; } + /** + * Wraps base YANG type to generated TO. + * + * @param basePackageName + * string with name of package to which the module belongs + * @param typedef + * type definition which is converted to the TO + * @param javaType + * JAVA Type to which is typedef mapped + * @return generated transfer object which representjavaType + */ private GeneratedTransferObject wrapJavaTypeIntoTO(final String basePackageName, final TypeDefinition typedef, final Type javaType) { if (javaType != null) { @@ -467,7 +699,27 @@ public final class TypeProviderImpl implements TypeProvider { return null; } - public GeneratedTOBuilder addUnionGeneratedTypeDefinition(final String basePackageName, + /** + * Converts typedef to generated TO with + * typeDefName. Every union type from typedef is + * added to generated TO builder as property. + * + * @param basePackageName + * string with name of package to which the module belongs + * @param typedef + * type definition which should be of type + * UnionTypeDefinition + * @param typeDefName + * string with name for generated TO + * @return generated TO builder which represents typedef + * @throws IllegalArgumentException + *
    + *
  • if basePackageName equals null
  • + *
  • if typedef equals null
  • + *
  • if Q name of typedef equals null
  • + *
+ */ + public GeneratedTOBuilder provideGeneratedTOBuilderForUnionTypeDefinition(final String basePackageName, final TypeDefinition typedef, String typeDefName) { if (basePackageName == null) { throw new IllegalArgumentException("Base Package Name cannot be NULL!"); @@ -482,15 +734,9 @@ public final class TypeProviderImpl implements TypeProvider { final TypeDefinition baseTypeDefinition = typedef.getBaseType(); if ((baseTypeDefinition != null) && (baseTypeDefinition instanceof UnionTypeDefinition)) { - final Module parentModule = findParentModuleForTypeDefinition(schemaContext, typedef); final UnionTypeDefinition unionTypeDef = (UnionTypeDefinition) baseTypeDefinition; final List> unionTypes = unionTypeDef.getTypes(); - Map genTOsMap = null; - if (parentModule != null && parentModule.getName() != null) { - genTOsMap = genTypeDefsContextMap.get(parentModule.getName()); - } - final GeneratedTOBuilder unionGenTransObject; if (typeDefName != null && !typeDefName.isEmpty()) { final String typeName = parseToClassName(typeDefName); @@ -529,10 +775,9 @@ public final class TypeProviderImpl implements TypeProvider { } } } else if (unionType instanceof EnumTypeDefinition) { - final EnumBuilder enumBuilder = resolveInnerEnumFromTypeDefinition((EnumTypeDefinition) unionType, + final Enumeration enumeration = addInnerEnumerationToTypeBuilder((EnumTypeDefinition) unionType, typeName, unionGenTransObject); - final Type enumRefType = new ReferencedTypeImpl(enumBuilder.getPackageName(), enumBuilder.getName()); - updateUnionTypeAsProperty(unionGenTransObject, enumRefType, typeName); + updateUnionTypeAsProperty(unionGenTransObject, enumeration, typeName); } else { final Type javaType = BaseYangTypes.BASE_YANG_TYPES_PROVIDER .javaTypeForSchemaDefinitionType(unionType); @@ -545,12 +790,31 @@ public final class TypeProviderImpl implements TypeProvider { addStringRegExAsConstant(unionGenTransObject, regularExpressions); } - genTOsMap.put(typedef.getQName().getLocalName(), unionGenTransObject.toInstance()); + Map genTOsMap = null; + final Module parentModule = findParentModuleForTypeDefinition(schemaContext, typedef); + if (parentModule != null && parentModule.getName() != null) { + genTOsMap = genTypeDefsContextMap.get(parentModule.getName()); + genTOsMap.put(typedef.getQName().getLocalName(), unionGenTransObject.toInstance()); + } + return unionGenTransObject; } return null; } + /** + * Adds a new property with the name propertyName and with type + * type to unonGenTransObject. + * + * @param unionGenTransObject + * generated TO to which should be property added + * @param type + * JAVA type of the property which should be added + * to unionGentransObject + * @param propertyName + * string with name of property which should be added to + * unionGentransObject + */ private void updateUnionTypeAsProperty(final GeneratedTOBuilder unionGenTransObject, final Type type, final String propertyName) { if (unionGenTransObject != null && type != null) { @@ -559,15 +823,23 @@ public final class TypeProviderImpl implements TypeProvider { .addProperty(parseToValidParamName(propertyName)); propBuilder.setReturnType(type); - if (!(type instanceof Enumeration)) { - unionGenTransObject.addEqualsIdentity(propBuilder); - unionGenTransObject.addHashIdentity(propBuilder); - unionGenTransObject.addToStringProperty(propBuilder); - } + unionGenTransObject.addEqualsIdentity(propBuilder); + unionGenTransObject.addHashIdentity(propBuilder); + unionGenTransObject.addToStringProperty(propBuilder); } } } + /** + * Converts typedef to the generated TO builder. + * + * @param basePackageName + * string with name of package to which the module belongs + * @param typedef + * type definition from which is the generated TO builder created + * @return generated TO builder which contains data from + * typedef and basePackageName + */ private GeneratedTOBuilder typedefToTransferObject(final String basePackageName, final TypeDefinition typedef) { final String packageName = packageNameForGeneratedType(basePackageName, typedef.getPath()); @@ -582,7 +854,27 @@ public final class TypeProviderImpl implements TypeProvider { return null; } - public GeneratedTOBuilder bitsTypedefToTransferObject(final String basePackageName, + /** + * Converts typeDef which should be of the type + * BitsTypeDefinition to GeneratedTOBuilder. + * + * All the bits of the typeDef are added to returning generated TO as + * properties. + * + * @param basePackageName + * string with name of package to which the module belongs + * @param typeDef + * type definition from which is the generated TO builder created + * @param typeDefName + * string with the name for generated TO builder + * @return generated TO builder which represents typeDef + * @throws IllegalArgumentException + *
    + *
  • if typeDef equals null
  • + *
  • if basePackageName equals null
  • + *
+ */ + public GeneratedTOBuilder provideGeneratedTOBuilderForBitsTypeDefinition(final String basePackageName, final TypeDefinition typeDef, String typeDefName) { if (typeDef == null) { @@ -616,6 +908,17 @@ public final class TypeProviderImpl implements TypeProvider { return null; } + /** + * Converts the pattern constraints from typedef to the list of + * the strings which represents these constraints. + * + * @param typedef + * extended type in which are the pattern constraints sought + * @return list of strings which represents the constraint patterns + * @throws IllegalArgumentException + * if typedef equals null + * + */ private List resolveRegExpressionsFromTypedef(ExtendedType typedef) { final List regExps = new ArrayList(); if (typedef == null) { @@ -637,6 +940,22 @@ public final class TypeProviderImpl implements TypeProvider { return regExps; } + /** + * + * Adds to the genTOBuilder the constant which contains regular + * expressions from the regularExpressions + * + * @param genTOBuilder + * generated TO builder to which are + * regular expressions added + * @param regularExpressions + * list of string which represent regular expressions + * @throws IllegalArgumentException + *
    + *
  • if genTOBuilder equals null
  • + *
  • if regularExpressions equals null
  • + *
+ */ private void addStringRegExAsConstant(GeneratedTOBuilder genTOBuilder, List regularExpressions) { if (genTOBuilder == null) throw new IllegalArgumentException("genTOBuilder can't be null"); @@ -649,10 +968,35 @@ public final class TypeProviderImpl implements TypeProvider { } } - private GeneratedTransferObject resolveExtendedTypeFromTypeDef(final ExtendedType extendedType, - final String basePackageName, final String typedefName, final String moduleName) { + /** + * Creates generated TO with data about inner extended type + * innerExtendedType, about the package name + * typedefName and about the generated TO name + * typedefName. + * + * It is supposed that innerExtendedType is already present in + * {@link TypeProviderImpl#genTypeDefsContextMap genTypeDefsContextMap} to + * be possible set it as extended type for the returning generated TO. + * + * @param innerExtendedType + * extended type which is part of some other extended type + * @param basePackageName + * string with the package name of the module + * @param typedefName + * string with the name for the generated TO + * @return generated TO which extends generated TO for + * innerExtendedType + * @throws IllegalArgumentException + *
    + *
  • if extendedType equals null
  • + *
  • if basePackageName equals null
  • + *
  • if typedefName equals null
  • + *
+ */ + private GeneratedTransferObject provideGeneratedTOFromExtendedType(final ExtendedType innerExtendedType, + final String basePackageName, final String typedefName) { - if (extendedType == null) { + if (innerExtendedType == null) { throw new IllegalArgumentException("Extended type cannot be NULL!"); } if (basePackageName == null) { @@ -662,19 +1006,18 @@ public final class TypeProviderImpl implements TypeProvider { throw new IllegalArgumentException("String with type definition name cannot be NULL!"); } - final String typeDefName = parseToClassName(typedefName); - final String lowTypeDef = extendedType.getQName().getLocalName(); - final GeneratedTOBuilder genTOBuilder = new GeneratedTOBuilderImpl(basePackageName, typeDefName); - - final Module parentModule = findParentModuleForTypeDefinition(schemaContext, extendedType); + final String classTypedefName = parseToClassName(typedefName); + final String innerTypeDef = innerExtendedType.getQName().getLocalName(); + final GeneratedTOBuilder genTOBuilder = new GeneratedTOBuilderImpl(basePackageName, classTypedefName); Map typeMap = null; + final Module parentModule = findParentModuleForTypeDefinition(schemaContext, innerExtendedType); if (parentModule != null) { typeMap = genTypeDefsContextMap.get(parentModule.getName()); } if (typeMap != null) { - Type type = typeMap.get(lowTypeDef); + Type type = typeMap.get(innerTypeDef); if (type instanceof GeneratedTransferObject) { genTOBuilder.setExtendsType((GeneratedTransferObject) type); } @@ -684,15 +1027,15 @@ public final class TypeProviderImpl implements TypeProvider { } /** - * The method find out for each type definition how many immersion (depth) - * is necessary to get to the base type. Every type definition is inserted - * to the map which key is depth and value is list of type definitions with + * Finds out for each type definition how many immersion (depth) is + * necessary to get to the base type. Every type definition is inserted to + * the map which key is depth and value is list of type definitions with * equal depth. In next step are lists from this map concatenated to one * list in ascending order according to their depth. All type definitions * are in the list behind all type definitions on which depends. * * @param unsortedTypeDefinitions - * represents list of type definitions + * list of type definitions which should be sorted by depth * @return list of type definitions sorted according their each other * dependencies (type definitions which are depend on other type * definitions are in list behind them). @@ -722,13 +1065,13 @@ public final class TypeProviderImpl implements TypeProvider { } /** - * The method return how many immersion is necessary to get from type - * definition to base type. + * Returns how many immersion is necessary to get from the type definition + * to the base type. * * @param typeDefinition - * is type definition for which is depth looked for. - * @return how many immersion is necessary to get from type definition to - * base type + * type definition for which is depth sought. + * @return number of immersions which are necessary to get from the type + * definition to the base type */ private int getTypeDefinitionDepth(final TypeDefinition typeDefinition) { if (typeDefinition == null) { diff --git a/code-generator/binding-generator-impl/src/main/java/org/opendaylight/yangtools/sal/binding/yang/types/UnionDependencySort.java b/code-generator/binding-generator-impl/src/main/java/org/opendaylight/yangtools/sal/binding/yang/types/UnionDependencySort.java index 2558873f77..c23a46563a 100644 --- a/code-generator/binding-generator-impl/src/main/java/org/opendaylight/yangtools/sal/binding/yang/types/UnionDependencySort.java +++ b/code-generator/binding-generator-impl/src/main/java/org/opendaylight/yangtools/sal/binding/yang/types/UnionDependencySort.java @@ -16,50 +16,62 @@ import org.opendaylight.yangtools.yang.model.api.type.UnionTypeDefinition; import org.opendaylight.yangtools.yang.model.util.ExtendedType; import org.opendaylight.yangtools.yang.parser.util.TopologicalSort; import org.opendaylight.yangtools.yang.parser.util.TopologicalSort.Node; -import org.opendaylight.yangtools.yang.parser.util.TopologicalSort.NodeImpl; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import com.google.common.annotations.VisibleForTesting; import com.google.common.base.Function; import com.google.common.collect.Lists; import com.google.common.collect.Maps; import com.google.common.collect.Sets; public class UnionDependencySort { - private static final Logger logger = LoggerFactory - .getLogger(UnionDependencySort.class); - - public static List sort( - final Set> typeDefinitions) { + private static final Logger logger = LoggerFactory.getLogger(UnionDependencySort.class); + + /** + * Sorts union types by mutual dependencies. + * + * At the beginning the union types are selected from + * typeDefinitions and wrapped to nodes. The nodes are sorted + * and then the wrapped payload is extracted. + * + * @param typeDefinitions + * set of type definitions. + * @return list of extended type which are sorted by mutual dependencies + * @throws IllegalArgumentException + * if typeDefinitions equals null + */ + public static List sort(final Set> typeDefinitions) { if (typeDefinitions == null) { logger.error("Set of Type Definitions cannot be NULL!"); - throw new IllegalArgumentException("Set of Type Definitions " + - "cannot be NULL!"); + throw new IllegalArgumentException("Set of Type Definitions " + "cannot be NULL!"); } - final Set extUnionTypes = - unionsFromTypeDefinitions(typeDefinitions); + final Set extUnionTypes = unionsFromTypeDefinitions(typeDefinitions); - final Set unsorted = unionTypesToUnionNodes(extUnionTypes); + final Set unsorted = unionTypesToNodes(extUnionTypes); final List sortedNodes = TopologicalSort.sort(unsorted); return Lists.transform(sortedNodes, new Function() { @Override public ExtendedType apply(Node input) { - return ((UnionNode) input).getUnionType(); + return (ExtendedType) (((NodeWrappedType) input).getWrappedType()); } }); } - private static Set unionsFromTypeDefinitions( - final Set> typeDefinitions) { + /** + * Extracts only union types from typeDefinitions set. + * + * @param typeDefinitions + * set of all type definitions + * @return set of extended type which are union type definition + */ + private static Set unionsFromTypeDefinitions(final Set> typeDefinitions) { final Set unions = Sets.newHashSet(); for (final TypeDefinition typedef : typeDefinitions) { if ((typedef != null) && (typedef.getBaseType() != null)) { - if (typedef instanceof ExtendedType - && typedef.getBaseType() instanceof UnionTypeDefinition) { + if (typedef instanceof ExtendedType && typedef.getBaseType() instanceof UnionTypeDefinition) { unions.add((ExtendedType) typedef); } } @@ -67,29 +79,45 @@ public class UnionDependencySort { return unions; } - private static Set unionTypesToUnionNodes( - final Set extUnionTypes) { + /** + * Wraps every extended type which represents union to node type and adds to + * every node information about dependencies. + * + * The mapping from union type to node is created. For every created node + * (next nodeFrom) is for its wrapped union type passed the list of + * inner types through and only those inner types which represent union type + * are next considered. For every inner union type is found its wrapping + * node (next as nodeTo). This dependency relationship between + * nodeFrom and all found nodesTo is modeled with creating of one edge from + * nodeFrom to nodeTo. + * + * + * @param extUnionTypes + * set of extended types which represents union types + * @return set of nodes which contains wrapped union types set of node where + * each one contains wrapped one union type + */ + private static Set unionTypesToNodes(final Set extUnionTypes) { final Map nodeMap = Maps.newHashMap(); final Set resultNodes = Sets.newHashSet(); for (final ExtendedType unionType : extUnionTypes) { - final Node node = new UnionNode(unionType); + final Node node = new NodeWrappedType(unionType); nodeMap.put(unionType, node); resultNodes.add(node); } for (final Node node : resultNodes) { - final UnionNode unionNode = (UnionNode) node; - final ExtendedType extUnionType = unionNode.getUnionType(); + final NodeWrappedType nodeFrom = (NodeWrappedType) node; + final ExtendedType extUnionType = (ExtendedType) nodeFrom.getWrappedType(); - final UnionTypeDefinition unionType = (UnionTypeDefinition) - extUnionType.getBaseType(); + final UnionTypeDefinition unionType = (UnionTypeDefinition) extUnionType.getBaseType(); final List> innerTypes = unionType.getTypes(); for (final TypeDefinition typedef : innerTypes) { if (extUnionTypes.contains(typedef)) { final Node toNode = nodeMap.get(typedef); - unionNode.addEdge(toNode); + nodeFrom.addEdge(toNode); } } } @@ -97,66 +125,4 @@ public class UnionDependencySort { return resultNodes; } - private static UnionNode unionTypeToUnionNode( - final ExtendedType extUnionType, - final Set extUnionTypes) { - final UnionNode node = new UnionNode(extUnionType); - - if (extUnionType.getBaseType() instanceof UnionTypeDefinition) { - final UnionTypeDefinition unionType = (UnionTypeDefinition) - extUnionType.getBaseType(); - - final List> innerTypes = unionType.getTypes(); - for (final TypeDefinition typedef : innerTypes) { - if ((typedef != null) && (typedef instanceof ExtendedType) - && (typedef.getBaseType() instanceof UnionTypeDefinition)) { - if (extUnionTypes.contains(typedef)) { - node.addEdge(new UnionNode((ExtendedType) typedef)); - } - } - } - } - - return node; - } - - @VisibleForTesting - static final class UnionNode extends NodeImpl { - private final ExtendedType unionType; - - UnionNode(ExtendedType unionType) { - this.unionType = unionType; - } - - ExtendedType getUnionType() { - return unionType; - } - - @Override - public boolean equals(Object o) { - if (this == o) { - return true; - } - if (!(o instanceof UnionNode)) { - return false; - } - UnionNode unionNode = (UnionNode) o; - if (!unionType.equals(unionNode.unionType)) { - return false; - } - return true; - } - - @Override - public int hashCode() { - return unionType.hashCode(); - } - - @Override - public String toString() { - return "UnionNode{" + - "unionType=" + unionType + - '}'; - } - } } diff --git a/code-generator/binding-generator-util/src/main/java/org/opendaylight/yangtools/binding/generator/util/AbstractBaseType.java b/code-generator/binding-generator-util/src/main/java/org/opendaylight/yangtools/binding/generator/util/AbstractBaseType.java index cf3ff19dc6..5707c78053 100644 --- a/code-generator/binding-generator-util/src/main/java/org/opendaylight/yangtools/binding/generator/util/AbstractBaseType.java +++ b/code-generator/binding-generator-util/src/main/java/org/opendaylight/yangtools/binding/generator/util/AbstractBaseType.java @@ -1,80 +1,100 @@ -/* - * 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 org.opendaylight.yangtools.sal.binding.model.api.Type; - -public class AbstractBaseType implements Type { - - private final String packageName; - private final String name; - - @Override - public String getPackageName() { - return packageName; - } - - @Override - public String getName() { - return name; - } - - @Override - public String getFullyQualifiedName() { - if (packageName.isEmpty()) { - return name; - } else { - return packageName + "." + name; - } - } - - protected AbstractBaseType(String pkName, String name) { - this.packageName = pkName; - this.name = name; - } - - @Override - public int hashCode() { - final int prime = 31; - int result = 1; - result = prime * result + ((name == null) ? 0 : name.hashCode()); - result = prime * result - + ((packageName == null) ? 0 : packageName.hashCode()); - return result; - } - - @Override - public boolean equals(Object obj) { - if (this == obj) - return true; - if (obj == null) - return false; - if (getClass() != obj.getClass()) - return false; - Type other = (Type) obj; - if (name == null) { - if (other.getName() != null) - return false; - } else if (!name.equals(other.getName())) - return false; - if (packageName == null) { - if (other.getPackageName() != null) - return false; - } else if (!packageName.equals(other.getPackageName())) - return false; - return true; - } - - @Override - public String toString() { - if (packageName.isEmpty()) { - return "Type (" + name + ")"; - } - return "Type (" + packageName + "." + name + ")"; - } -} +/* + * 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 org.opendaylight.yangtools.sal.binding.model.api.Type; + +/** + * It is used only as ancestor for other Types + * + */ +public class AbstractBaseType implements Type { + + /** + * Name of the package to which this Type belongs. + */ + private final String packageName; + + /** + * Name of this Type. + */ + private final String name; + + @Override + public String getPackageName() { + return packageName; + } + + @Override + public String getName() { + return name; + } + + @Override + public String getFullyQualifiedName() { + if (packageName.isEmpty()) { + return name; + } else { + return packageName + "." + name; + } + } + + /** + * Constructs the instance of this class with the concrete package name type + * name. + * + * @param pkName + * string with the package name to which this Type + * belongs + * @param name + * string with the name for this Type + */ + protected AbstractBaseType(String pkName, String name) { + this.packageName = pkName; + this.name = name; + } + + @Override + public int hashCode() { + final int prime = 31; + int result = 1; + result = prime * result + ((name == null) ? 0 : name.hashCode()); + result = prime * result + ((packageName == null) ? 0 : packageName.hashCode()); + return result; + } + + @Override + public boolean equals(Object obj) { + if (this == obj) + return true; + if (obj == null) + return false; + if (getClass() != obj.getClass()) + return false; + Type other = (Type) obj; + if (name == null) { + if (other.getName() != null) + return false; + } else if (!name.equals(other.getName())) + return false; + if (packageName == null) { + if (other.getPackageName() != null) + return false; + } else if (!packageName.equals(other.getPackageName())) + return false; + return true; + } + + @Override + public String toString() { + if (packageName.isEmpty()) { + return "Type (" + name + ")"; + } + return "Type (" + packageName + "." + name + ")"; + } +} diff --git a/code-generator/binding-generator-util/src/main/java/org/opendaylight/yangtools/binding/generator/util/BindingGeneratorUtil.java b/code-generator/binding-generator-util/src/main/java/org/opendaylight/yangtools/binding/generator/util/BindingGeneratorUtil.java index 2c75e5d377..3a0d74c8c4 100644 --- a/code-generator/binding-generator-util/src/main/java/org/opendaylight/yangtools/binding/generator/util/BindingGeneratorUtil.java +++ b/code-generator/binding-generator-util/src/main/java/org/opendaylight/yangtools/binding/generator/util/BindingGeneratorUtil.java @@ -10,12 +10,20 @@ import org.opendaylight.yangtools.binding.generator.util.generated.type.builder. import org.opendaylight.yangtools.sal.binding.model.api.type.builder.GeneratedTOBuilder; import org.opendaylight.yangtools.yang.common.QName; import org.opendaylight.yangtools.yang.model.api.Module; -import org.opendaylight.yangtools.yang.model.api.SchemaNode; import org.opendaylight.yangtools.yang.model.api.SchemaPath; import org.opendaylight.yangtools.yang.model.api.TypeDefinition; +/** + * Contains the methods for converting strings to valid JAVA language strings + * (package names, class names, attribute names). + * + * + */ public final class BindingGeneratorUtil { + /** + * Array of strings values which represents JAVA reserved words. + */ private static final String[] SET_VALUES = new String[] { "abstract", "assert", "boolean", "break", "byte", "case", "catch", "char", "class", "const", "continue", "default", "double", "do", "else", "enum", "extends", "false", "final", "finally", "float", "for", "goto", "if", "implements", "import", "instanceof", "int", @@ -23,12 +31,29 @@ public final class BindingGeneratorUtil { "short", "static", "strictfp", "super", "switch", "synchronized", "this", "throw", "throws", "transient", "true", "try", "void", "volatile", "while" }; + /** + * Impossible to instantiate this class. All of the methods or attributes + * are static. + */ private BindingGeneratorUtil() { } - public static final Set JAVA_RESERVED_WORDS = new HashSet(Arrays.asList(SET_VALUES)); - - public static String validateJavaPackage(final String packageName) { + /** + * Hash set of words which are reserved in JAVA language. + */ + private static final Set JAVA_RESERVED_WORDS = new HashSet(Arrays.asList(SET_VALUES)); + + /** + * Converts string packageName to valid JAVA package name. + * + * If some words of package name are digits of JAVA reserved words they are + * prefixed with underscore character. + * + * @param packageName + * string which contains words separated by point. + * @return package name which contains words separated by point. + */ + private static String validateJavaPackage(final String packageName) { if (packageName != null) { final String[] packNameParts = packageName.split("\\."); if (packNameParts != null) { @@ -51,6 +76,16 @@ public final class BindingGeneratorUtil { return packageName; } + /** + * Converts parameterName to valid JAVA parameter name. + * + * If the parameterName is one of the JAVA reserved words then + * it is prefixed with underscore character. + * + * @param parameterName + * string with the parameter name + * @return string with the admissible parameter name + */ public static String validateParameterName(final String parameterName) { if (parameterName != null) { if (JAVA_RESERVED_WORDS.contains(parameterName)) { @@ -60,9 +95,22 @@ public final class BindingGeneratorUtil { return parameterName; } + /** + * Creates generated TO builder from packageName and + * transObjectName. + * + * @param packageName + * string with name of package to which the returned object + * belongs + * @param transObjectName + * string with name which the returned object has + * @return generated TO builder or null value if + * packageName or transObjectName equal + * null + */ public static GeneratedTOBuilder schemaNodeToTransferObjectBuilder(final String packageName, - final SchemaNode schemaNode, final String transObjectName) { - if (packageName != null && schemaNode != null && transObjectName != null) { + final String transObjectName) { + if (packageName != null && transObjectName != null) { final String genTOName = BindingGeneratorUtil.parseToClassName(transObjectName); final GeneratedTOBuilder newType = new GeneratedTOBuilderImpl(packageName, genTOName); @@ -73,6 +121,25 @@ public final class BindingGeneratorUtil { return null; } + /** + * Converts module name to valid JAVA package name. + * + * The package name consists of: + *
    + *
  • prefix - org.opendaylight.yang.gen.v
  • + *
  • module YANG version - org.opendaylight.yang.gen.v
  • + *
  • module namespace - invalid characters are replaced with dots
  • + *
  • revision prefix - .rev
  • + *
  • revision - YYYYMMDD (MM and DD aren't spread to the whole length)
  • + *
+ * + * @param module + * module which contains data about namespace and revision date + * @return string with the valid JAVA package name + * @throws IllegalArgumentException + * if the revision date of the module equals + * null + */ public static String moduleNamespaceToPackageName(final Module module) { final StringBuilder packageNameBuilder = new StringBuilder(); @@ -109,6 +176,21 @@ public final class BindingGeneratorUtil { return validateJavaPackage(packageNameBuilder.toString()); } + /** + * Creates package name from specified basePackageName (package + * name for module) and schemaPath. + * + * Resulting package name is concatenation of basePackageName + * and all local names of YANG nodes which are parents of some node for + * which schemaPath is specified. + * + * @param basePackageName + * string with package name of the module + * @param schemaPath + * list of names of YANG nodes which are parents of some node + + * name of this node + * @return string with valid JAVA package name + */ public static String packageNameForGeneratedType(final String basePackageName, final SchemaPath schemaPath) { if (basePackageName == null) { throw new IllegalArgumentException("Base Package Name cannot be NULL!"); @@ -132,6 +214,21 @@ public final class BindingGeneratorUtil { return validateJavaPackage(builder.toString()); } + /** + * Generates the package name for type definition from + * typeDefinition and basePackageName. + * + * @param basePackageName + * string with the package name of the module + * @param typeDefinition + * type definition for which the package name will be generated * + * @return string with valid JAVA package name + * @throws IllegalArgumentException + *
    + *
  • if basePackageName equals null
  • + *
  • if typeDefinition equals null
  • + *
+ */ public static String packageNameForTypeDefinition(final String basePackageName, final TypeDefinition typeDefinition) { if (basePackageName == null) { @@ -146,6 +243,16 @@ public final class BindingGeneratorUtil { return validateJavaPackage(builder.toString()); } + /** + * Converts token to string which is in accordance with best + * practices for JAVA class names. + * + * @param token + * string which contains characters which should be converted to + * JAVA class name + * @return string which is in accordance with best practices for JAVA class + * name. + */ public static String parseToClassName(String token) { token = token.replace(".", ""); String correctStr = parseToCamelCase(token); @@ -161,6 +268,16 @@ public final class BindingGeneratorUtil { return correctStr; } + /** + * Converts token to string which is in accordance with best + * practices for JAVA parameter names. + * + * @param token + * string which contains characters which should be converted to + * JAVA parameter name + * @return string which is in accordance with best practices for JAVA + * parameter name. + */ public static String parseToValidParamName(final String token) { final String validToken = token.replace(".", ""); String correctStr = parseToCamelCase(validToken); @@ -171,6 +288,14 @@ public final class BindingGeneratorUtil { return validateParameterName(correctStr); } + /** + * Converts token to capital letters and removes invalid + * characters. + * + * @param token + * string with characters which should be conversed to capital + * @return string with capital letters + */ public static String convertToCapitalLetters(final String token) { String convertedStr = token.replace(" ", "_"); convertedStr = convertedStr.replace(".", "_"); @@ -178,13 +303,25 @@ public final class BindingGeneratorUtil { return convertedStr; } + /** + * + * Converts string token to the cammel case format. + * + * @param token + * string which should be converted to the cammel case format + * @return string in the cammel case format + * @throws NullPointerException + * - if token equals null + * @throws IllegalArgumentException + * - if token without white spaces is empty + */ private static String parseToCamelCase(String token) { if (token == null) { throw new NullPointerException("Name can not be null"); } String correctStr = token.trim(); - if (correctStr.length() == 0) { + if (correctStr.isEmpty()) { throw new IllegalArgumentException("Name can not be emty"); } @@ -194,6 +331,20 @@ public final class BindingGeneratorUtil { return correctStr; } + /** + * Replaces all the occurances of the removalChar in the + * text with empty string and converts following character to + * upper case. + * + * @param text + * string with source text which should be converted + * @param removalChar + * character which is sought in the text + * @return string which doesn't contain removalChar and has + * following characters converted to upper case + * @throws IllegalArgumentException + * if the length of the returning string has length 0 + */ private static String replaceWithCamelCase(String text, char removalChar) { StringBuilder sb = new StringBuilder(text); String toBeRemoved = String.valueOf(removalChar); @@ -204,7 +355,7 @@ public final class BindingGeneratorUtil { // check if 'toBeRemoved' character is not the only character in // 'text' if (sb.length() == 0) { - throw new IllegalArgumentException("Name can not be '" + toBeRemoved + "'"); + throw new IllegalArgumentException("The resulting string can not be empty"); } String replacement = String.valueOf(sb.charAt(toBeRemovedPos)).toUpperCase(); sb.setCharAt(toBeRemovedPos, replacement.charAt(0)); diff --git a/code-generator/binding-generator-util/src/main/java/org/opendaylight/yangtools/binding/generator/util/ReferencedTypeImpl.java b/code-generator/binding-generator-util/src/main/java/org/opendaylight/yangtools/binding/generator/util/ReferencedTypeImpl.java index ed1c0e9937..c3c48d850f 100644 --- a/code-generator/binding-generator-util/src/main/java/org/opendaylight/yangtools/binding/generator/util/ReferencedTypeImpl.java +++ b/code-generator/binding-generator-util/src/main/java/org/opendaylight/yangtools/binding/generator/util/ReferencedTypeImpl.java @@ -7,8 +7,22 @@ */ package org.opendaylight.yangtools.binding.generator.util; +/** + * + * Wraps combination of packageName and name to the + * object representation + * + */ public final class ReferencedTypeImpl extends AbstractBaseType { + /** + * Creates instance of this class with concrete package name and type name + * + * @param packageName + * string with the package name + * @param name + * string with the name for referenced type + */ public ReferencedTypeImpl(String packageName, String name) { super(packageName, name); } diff --git a/code-generator/binding-generator-util/src/main/java/org/opendaylight/yangtools/binding/generator/util/TypeConstants.java b/code-generator/binding-generator-util/src/main/java/org/opendaylight/yangtools/binding/generator/util/TypeConstants.java index 9154f1087b..0cbe98cb0c 100644 --- a/code-generator/binding-generator-util/src/main/java/org/opendaylight/yangtools/binding/generator/util/TypeConstants.java +++ b/code-generator/binding-generator-util/src/main/java/org/opendaylight/yangtools/binding/generator/util/TypeConstants.java @@ -1,9 +1,20 @@ package org.opendaylight.yangtools.binding.generator.util; +/** + * + * Contains constants used in relations with Type. + */ public final class TypeConstants { + /** + * Name of the class constant which hold list of the regular expression + * strings. + */ public static final String PATTERN_CONSTANT_NAME = "PATTERN_CONSTANTS"; + /** + * Creation of new instance is prohibited. + */ private TypeConstants() { } } diff --git a/code-generator/binding-generator-util/src/main/java/org/opendaylight/yangtools/binding/generator/util/Types.java b/code-generator/binding-generator-util/src/main/java/org/opendaylight/yangtools/binding/generator/util/Types.java index d4735dba3f..bd447c2204 100644 --- a/code-generator/binding-generator-util/src/main/java/org/opendaylight/yangtools/binding/generator/util/Types.java +++ b/code-generator/binding-generator-util/src/main/java/org/opendaylight/yangtools/binding/generator/util/Types.java @@ -28,17 +28,37 @@ public final class Types { private static final Type MAP_TYPE = typeForClass(Map.class); public static final Type DATA_OBJECT = typeForClass(DataObject.class); + /** + * Creates the instance of type + * {@link org.opendaylight.yangtools.sal.binding.model.api.ConcreteType + * ConcreteType} which represents JAVA void type. + * + * @return ConcreteType instance which represents JAVA + * void + */ public static ConcreteType voidType() { return new ConcreteTypeImpl(Void.class.getPackage().getName(), Void.class.getSimpleName()); } + /** + * Creates the instance of type + * {@link org.opendaylight.yangtools.sal.binding.model.api.ConcreteType + * ConcreteType} which represents primitive JAVA type for which package + * doesn't exist. + * + * @param primitiveType + * string containing programaticall construction based on + * primitive type (e.g byte[]) + * @return ConcreteType instance which represents programatic + * construction with primitive JAVA type + */ public static final Type primitiveType(final String primitiveType) { return new ConcreteTypeImpl("", primitiveType); } /** * Returns an instance of {@link ConcreteType} describing the class - * + * * @param cls * Class to describe * @return Description of class @@ -50,7 +70,7 @@ public final class Types { /** * Returns an instance of {@link ParameterizedType} describing the typed * {@link Map} - * + * * @param keyType * Key Type * @param valueType @@ -64,7 +84,7 @@ public final class Types { /** * Returns an instance of {@link ParameterizedType} describing the typed * {@link Set} with concrete type of value. - * + * * @param valueType * Value Type * @return Description of generic type instance of Set @@ -76,7 +96,7 @@ public final class Types { /** * Returns an instance of {@link ParameterizedType} describing the typed * {@link List} with concrete type of value. - * + * * @param valueType * Value Type * @return Description of type instance of List @@ -85,6 +105,13 @@ public final class Types { return parameterizedTypeFor(LIST_TYPE, valueType); } + /** + * Creates generated transfer object for + * {@link org.opendaylight.yangtools.yang.binding.BaseIdentity BaseIdentity} + * + * @return generated transfer object which is used as extension when YANG + * identity is mapped to generated TO + */ public static GeneratedTransferObject getBaseIdentityTO() { Class cls = BaseIdentity.class; GeneratedTOBuilderImpl gto = new GeneratedTOBuilderImpl(cls.getPackage().getName(), cls.getSimpleName()); @@ -92,37 +119,107 @@ public final class Types { } /** - * + * Creates instance of type + * {@link org.opendaylight.yangtools.sal.binding.model.api.ParameterizedType + * ParameterizedType} + * * @param type + * JAVA Type for raw type * @param parameters - * @return + * JAVA Types for actual parameter types + * @return ParametrizedType reprezentation of type + * and its parameters parameters */ public static ParameterizedType parameterizedTypeFor(Type type, Type... parameters) { return new ParametrizedTypeImpl(type, parameters); } + /** + * Creates instance of type + * {@link org.opendaylight.yangtools.sal.binding.model.api.WildcardType + * WildcardType} + * + * @param packageName + * string with the package name + * @param typeName + * string with the type name + * @return WildcardType reprezentation of + * packageName and typeName + */ public static WildcardType wildcardTypeFor(String packageName, String typeName) { return new WildcardTypeImpl(packageName, typeName); } + /** + * Creates instance of + * {@link org.opendaylight.yangtools.sal.binding.model.api.ParameterizedType + * ParameterizedType} where raw type is + * {@link org.opendaylight.yangtools.yang.binding.Augmentable} and actual + * parameter is valueType. + * + * @param valueType + * JAVA Type with actual parameter + * @return ParametrizedType reprezentation of raw type + * Augmentable with actual parameter + * valueType + */ public static ParameterizedType augmentableTypeFor(Type valueType) { final Type augmentable = typeForClass(Augmentable.class); return parameterizedTypeFor(augmentable, valueType); } + /** + * Creates instance of + * {@link org.opendaylight.yangtools.sal.binding.model.api.ParameterizedType + * ParameterizedType} where raw type is + * {@link org.opendaylight.yangtools.yang.binding.Augmentation} and actual + * parameter is valueType. + * + * @param valueType + * JAVA Type with actual parameter + * @return ParametrizedType reprezentation of raw type + * Augmentation with actual parameter + * valueType + */ public static ParameterizedType augmentationTypeFor(Type valueType) { final Type augmentation = typeForClass(Augmentation.class); return parameterizedTypeFor(augmentation, valueType); } + /** + * + * Represents concrete JAVA type. + * + */ private static class ConcreteTypeImpl extends AbstractBaseType implements ConcreteType { + /** + * Creates instance of this class with package pkName and + * with the type name name. + * + * @param pkName + * string with package name + * @param name + * string with the name of the type + */ private ConcreteTypeImpl(String pkName, String name) { super(pkName, name); } } + /** + * + * Represents parametrized JAVA type. + * + */ private static class ParametrizedTypeImpl extends AbstractBaseType implements ParameterizedType { + /** + * Array of JAVA actual type parameters. + */ private Type[] actualTypes; + + /** + * JAVA raw type (like List, Set, Map...) + */ private Type rawType; @Override @@ -136,6 +233,15 @@ public final class Types { return rawType; } + /** + * Creates instance of this class with concrete rawType and array of + * actual parameters. + * + * @param rawType + * JAVA Type for raw type + * @param actTypes + * array of actual parameters + */ public ParametrizedTypeImpl(Type rawType, Type[] actTypes) { super(rawType.getPackageName(), rawType.getName()); this.rawType = rawType; @@ -144,7 +250,20 @@ public final class Types { } + /** + * + * Represents JAVA bounded wildcard type. + * + */ private static class WildcardTypeImpl extends AbstractBaseType implements WildcardType { + /** + * Creates instance of this class with concrete package and type name. + * + * @param packageName + * string with the package name + * @param typeName + * string with the name of type + */ public WildcardTypeImpl(String packageName, String typeName) { super(packageName, typeName); } diff --git a/code-generator/binding-generator-util/src/main/java/org/opendaylight/yangtools/binding/generator/util/generated/type/builder/EnumerationBuilderImpl.java b/code-generator/binding-generator-util/src/main/java/org/opendaylight/yangtools/binding/generator/util/generated/type/builder/EnumerationBuilderImpl.java index 11bee9f8a9..1ef58b9ec9 100644 --- a/code-generator/binding-generator-util/src/main/java/org/opendaylight/yangtools/binding/generator/util/generated/type/builder/EnumerationBuilderImpl.java +++ b/code-generator/binding-generator-util/src/main/java/org/opendaylight/yangtools/binding/generator/util/generated/type/builder/EnumerationBuilderImpl.java @@ -23,7 +23,7 @@ public final class EnumerationBuilderImpl extends AbstractBaseType implements En private final String name; private final List values; private final List annotationBuilders = new ArrayList<>(); - + public EnumerationBuilderImpl(final String packageName, final String name) { super(packageName, name); this.packageName = packageName; @@ -41,7 +41,7 @@ public final class EnumerationBuilderImpl extends AbstractBaseType implements En } return null; } - + @Override public void addValue(final String name, final Integer value) { values.add(new EnumPairImpl(name, value)); @@ -51,7 +51,7 @@ public final class EnumerationBuilderImpl extends AbstractBaseType implements En public Enumeration toInstance(final Type definingType) { return new EnumerationImpl(definingType, annotationBuilders, packageName, name, values); } - + /* * (non-Javadoc) * @@ -62,8 +62,7 @@ public final class EnumerationBuilderImpl extends AbstractBaseType implements En final int prime = 31; int result = 1; result = prime * result + ((name == null) ? 0 : name.hashCode()); - result = prime * result - + ((packageName == null) ? 0 : packageName.hashCode()); + result = prime * result + ((packageName == null) ? 0 : packageName.hashCode()); return result; } @@ -212,17 +211,15 @@ public final class EnumerationBuilderImpl extends AbstractBaseType implements En private final String name; private final List values; private List annotations = new ArrayList<>(); - - public EnumerationImpl(final Type definingType, - final List annotationBuilders, - final String packageName, final String name, - final List values) { + + public EnumerationImpl(final Type definingType, final List annotationBuilders, + final String packageName, final String name, final List values) { super(); this.definingType = definingType; for (final AnnotationTypeBuilder builder : annotationBuilders) { annotations.add(builder.toInstance()); } - this.annotations = Collections.unmodifiableList(annotations); + this.annotations = Collections.unmodifiableList(annotations); this.packageName = packageName; this.name = name; this.values = Collections.unmodifiableList(values); @@ -252,7 +249,7 @@ public final class EnumerationBuilderImpl extends AbstractBaseType implements En public List getValues() { return values; } - + @Override public List getAnnotations() { return annotations; @@ -282,6 +279,7 @@ public final class EnumerationBuilderImpl extends AbstractBaseType implements En } ++i; } + builder.append("\n}"); return builder.toString(); } @@ -295,10 +293,8 @@ public final class EnumerationBuilderImpl extends AbstractBaseType implements En final int prime = 31; int result = 1; result = prime * result + ((name == null) ? 0 : name.hashCode()); - result = prime * result - + ((packageName == null) ? 0 : packageName.hashCode()); - result = prime * result - + ((values == null) ? 0 : values.hashCode()); + result = prime * result + ((packageName == null) ? 0 : packageName.hashCode()); + result = prime * result + ((values == null) ? 0 : values.hashCode()); return result; } diff --git a/code-generator/binding-java-api-generator/src/main/java/org/opendaylight/yangtools/sal/java/api/generator/BuilderGenerator.java b/code-generator/binding-java-api-generator/src/main/java/org/opendaylight/yangtools/sal/java/api/generator/BuilderGenerator.java index 571c301b00..dab7ace248 100644 --- a/code-generator/binding-java-api-generator/src/main/java/org/opendaylight/yangtools/sal/java/api/generator/BuilderGenerator.java +++ b/code-generator/binding-java-api-generator/src/main/java/org/opendaylight/yangtools/sal/java/api/generator/BuilderGenerator.java @@ -8,10 +8,28 @@ import org.opendaylight.yangtools.yang.binding.Augmentable; import org.opendaylight.yangtools.yang.binding.Augmentation; import org.opendaylight.yangtools.yang.binding.DataObject; +/** + * + * Transformator of the data from the virtual form to JAVA programming language. + * The result source code represent java class. For generation of the source + * code is used the template written in XTEND language. + * + */ public final class BuilderGenerator implements CodeGenerator { + /** + * Constant used as sufix for builder name. + */ public static final String BUILDER = "Builder"; + /** + * Passes via list of implemented types in type. + * + * @param type + * JAVA Type + * @return boolean value which is true if any of implemented types is of the + * type Augmentable. + */ @Override public boolean isAcceptable(Type type) { if (type instanceof GeneratedType && !(type instanceof GeneratedTransferObject)) { @@ -29,6 +47,11 @@ public final class BuilderGenerator implements CodeGenerator { return false; } + /** + * Generates JAVA source code for generated type Type. The code + * is generated according to the template source code template which is + * written in XTEND language. + */ @Override public String generate(Type type) { if (type instanceof GeneratedType && !(type instanceof GeneratedTransferObject)) { diff --git a/code-generator/binding-java-api-generator/src/main/java/org/opendaylight/yangtools/sal/java/api/generator/BuilderTemplate.xtend b/code-generator/binding-java-api-generator/src/main/java/org/opendaylight/yangtools/sal/java/api/generator/BuilderTemplate.xtend index 6ffc912ebf..5f842a29ff 100644 --- a/code-generator/binding-java-api-generator/src/main/java/org/opendaylight/yangtools/sal/java/api/generator/BuilderTemplate.xtend +++ b/code-generator/binding-java-api-generator/src/main/java/org/opendaylight/yangtools/sal/java/api/generator/BuilderTemplate.xtend @@ -14,21 +14,70 @@ import org.opendaylight.yangtools.sal.binding.model.api.MethodSignature import org.opendaylight.yangtools.sal.binding.model.api.Type import org.opendaylight.yangtools.yang.binding.Augmentable +/** + * Template for generating JAVA builder classes. + */ class BuilderTemplate { + /** + * Constant with prefix for getter methods. + */ val static GET_PREFIX = "get" + + /** + * Constant with the name of the concrete package prefix. + */ val static JAVA_UTIL = "java.util" + + /** + * Constant with the name of the concrete JAVA type + */ val static HASH_MAP = "HashMap" + + /** + * Constant with the name of the concrete JAVA interface. + */ val static MAP = "Map" + + /** + * Constant with the name of the concrete method. + */ val static GET_AUGMENTATION_METHOD_NAME = "getAugmentation" + + /** + * Constant with the suffix for builder classes. + */ val static BUILDER = 'Builder' + + /** + * Constant with suffix for the classes which are generated from the builder classes. + */ val static IMPL = 'Impl' + /** + * Reference to type for which is generated builder class + */ val GeneratedType genType + + /** + * Map of imports. The keys are type names and the values are package names. + */ val Map imports + + /** + * Generated property is set if among methods is found one with the name GET_AUGMENTATION_METHOD_NAME + */ var GeneratedProperty augmentField + + /** + * Set of class attributes (fields) which are derived from the getter methods names + */ val Set fields + /** + * Constructs new instance of this class. + * @throws IllegalArgumentException if genType equals null + */ new(GeneratedType genType) { if (genType == null) { throw new IllegalArgumentException("Generated type reference cannot be NULL!") @@ -39,6 +88,12 @@ class BuilderTemplate { this.fields = createFieldsFromMethods(createMethods) } + /** + * Returns set of method signature instances which contains all the methods of the genType + * and all the methods of the implemented interfaces. + * + * @returns set of method signature instances + */ def private Set createMethods() { val Set methods = new LinkedHashSet methods.addAll(genType.methodDefinitions) @@ -46,6 +101,13 @@ class BuilderTemplate { return methods } + /** + * Adds to the methods set all the methods of the implementedIfcs + * and recursivelly their implemented interfaces. + * + * @param methods set of method signatures + * @param implementedIfcs list of implemented interfaces + */ def private void storeMethodsOfImplementedIfcs(Set methods, List implementedIfcs) { if (implementedIfcs == null || implementedIfcs.empty) { return @@ -76,6 +138,14 @@ class BuilderTemplate { } } + /** + * Adds to the imports map the package typePackageName. + * + * @param typePackageName + * string with the name of the package which is added to imports as a value + * @param typeName + * string with the name of the package which is added to imports as a key + */ def private void addToImports(String typePackageName,String typeName) { if (typePackageName.startsWith("java.lang") || typePackageName.isEmpty()) { return @@ -85,20 +155,43 @@ class BuilderTemplate { } } + /** + * Returns the first element of the list elements. + * + * @param list of elements + */ def private first(List elements) { elements.get(0) } + /** + * Returns the name of the package from fullyQualifiedName. + * + * @param fullyQualifiedName string with fully qualified type name (package + type) + * @return string with the package name + */ def private String getPackage(String fullyQualifiedName) { val lastDotIndex = fullyQualifiedName.lastIndexOf(Constants.DOT) return if (lastDotIndex == -1) "" else fullyQualifiedName.substring(0, lastDotIndex) } + /** + * Returns the name of tye type from fullyQualifiedName + * + * @param fullyQualifiedName string with fully qualified type name (package + type) + * @return string with the name of the type + */ def private String getName(String fullyQualifiedName) { val lastDotIndex = fullyQualifiedName.lastIndexOf(Constants.DOT) return if (lastDotIndex == -1) fullyQualifiedName else fullyQualifiedName.substring(lastDotIndex + 1) } + /** + * Creates set of generated property instances from getter methods. + * + * @param set of method signature instances which should be transformed to list of properties + * @return set of generated property instances which represents the getter methods + */ def private createFieldsFromMethods(Set methods) { val Set result = new LinkedHashSet @@ -115,6 +208,18 @@ class BuilderTemplate { return result } + /** + * Creates generated property instance from the getter method name and return type. + * + * @param method method signature from which is the method name and return type obtained + * @return generated property instance for the getter method + * @throws IllegalArgumentException
    + *
  • if the method equals null
  • + *
  • if the name of the method equals null
  • + *
  • if the name of the method is empty
  • + *
  • if the return type of the method equals null
  • + *
+ */ def private GeneratedProperty createFieldFromGetter(MethodSignature method) { if (method == null || method.name == null || method.name.empty || method.returnType == null) { throw new IllegalArgumentException("Method, method name, method return type reference cannot be NULL or empty!") @@ -127,12 +232,22 @@ class BuilderTemplate { } } + /** + * Builds string which contains JAVA source code. + * + * @return string with JAVA source code + */ def String generate() { val body = generateBody val pkgAndImports = generatePkgAndImports return pkgAndImports.toString + body.toString } + /** + * Template method which generates JAVA class body for builder class and for IMPL class. + * + * @return string with JAVA source code + */ def private generateBody() ''' public class «genType.name»«BUILDER» { @@ -157,6 +272,12 @@ class BuilderTemplate { } ''' + /** + * Template method which generates class attributes. + * + * @param boolean value which specify whether field is|isn't final + * @return string with class attributes and their types + */ def private generateFields(boolean _final) ''' «IF !fields.empty» «FOR f : fields» @@ -168,6 +289,11 @@ class BuilderTemplate { «ENDIF» ''' + /** + * Template method which generates setter methods + * + * @return string with the setter methods + */ def private generateSetters() ''' «FOR field : fields SEPARATOR '\n'» public «genType.name»«BUILDER» set«field.name.toFirstUpper»(«field.returnType.resolveName» «field.name») { @@ -184,6 +310,11 @@ class BuilderTemplate { «ENDIF» ''' + /** + * Template method which generate constructor for IMPL class. + * + * @return string with IMPL class constructor + */ def private generateConstructor() ''' private «genType.name»«IMPL»() { «IF !fields.empty» @@ -197,6 +328,11 @@ class BuilderTemplate { } ''' + /** + * Template method which generate getter methods for IMPL class. + * + * @return string with getter methods + */ def private generateGetters() ''' «IF !fields.empty» «FOR field : fields SEPARATOR '\n'» @@ -219,6 +355,11 @@ class BuilderTemplate { «ENDIF» ''' + /** + * Template method which generate package name line and import lines. + * + * @result string with package and import lines in JAVA format + */ def private generatePkgAndImports() ''' package «genType.packageName»; @@ -231,6 +372,12 @@ class BuilderTemplate { ''' + /** + * Adds package to imports if it is necessary and returns necessary type name (with or without package name) + * + * @param type JAVA Type + * @return string with the type name (with or without package name) + */ def private resolveName(Type type) { GeneratorUtil.putTypeIntoImports(genType, type, imports); GeneratorUtil.getExplicitType(genType, type, imports) diff --git a/code-generator/binding-java-api-generator/src/main/java/org/opendaylight/yangtools/sal/java/api/generator/ClassTemplate.xtend b/code-generator/binding-java-api-generator/src/main/java/org/opendaylight/yangtools/sal/java/api/generator/ClassTemplate.xtend index af55ac813f..c58a781761 100644 --- a/code-generator/binding-java-api-generator/src/main/java/org/opendaylight/yangtools/sal/java/api/generator/ClassTemplate.xtend +++ b/code-generator/binding-java-api-generator/src/main/java/org/opendaylight/yangtools/sal/java/api/generator/ClassTemplate.xtend @@ -10,14 +10,41 @@ import org.opendaylight.yangtools.sal.binding.model.api.GeneratedTransferObject import org.opendaylight.yangtools.sal.binding.model.api.Type import org.opendaylight.yangtools.binding.generator.util.Types +/** + * Template for generating JAVA class. + */ class ClassTemplate { + /** + * Generated transfer object for which class JAVA file is generated + */ val GeneratedTransferObject genTO + + /** + * Map of imports for this genTO. + */ val Map imports + + /** + * List of generated property instances which represents class attributes. + */ val List fields + + /** + * List of enumeration which are generated as JAVA enum type. + */ val List enums + + /** + * List of constant instances which are generated as JAVA public static final attributes. + */ val List consts + /** + * Creates instance of this class with concrete genTO. + * + * @param genTO generated transfer object which will be transformed to JAVA class source code + */ new(GeneratedTransferObject genTO) { if (genTO == null) { throw new IllegalArgumentException("Generated transfer object reference cannot be NULL!") @@ -30,16 +57,32 @@ class ClassTemplate { this.consts = genTO.constantDefinitions } + /** + * Generates JAVA class source code (package name + class body). + * + * @return string with JAVA class source code + */ def String generate() { val body = generateBody(false) val pkgAndImports = generatePkgAndImports return pkgAndImports.toString + body.toString } + /** + * Generates JAVA class source code (class body only). + * + * @return string with JAVA class body source code + */ def generateAsInnerClass() { return generateBody(true) } + /** + * Template method which generates class body. + * + * @param isInnerClass boolean value which specify if generated class is|isn't inner + * @return string with class source code in JAVA format + */ def private generateBody(boolean isInnerClass) ''' «genTO.comment.generateComment» «generateClassDeclaration(isInnerClass)» { @@ -69,6 +112,12 @@ class ClassTemplate { } ''' + /** + * Template method which generates JAVA comments. + * + * @param string with the comment for whole JAVA class + * @return string with comment in JAVA format + */ def private generateComment(String comment) ''' «IF comment != null && !comment.empty» /* @@ -77,6 +126,12 @@ class ClassTemplate { «ENDIF» ''' + /** + * Template method which generates JAVA class declaration. + * + * @param isInnerClass boolean value which specify if generated class is|isn't inner + * @return string with class declaration in JAVA format + */ def private generateClassDeclaration(boolean isInnerClass) ''' public« IF (isInnerClass)»« @@ -97,6 +152,11 @@ class ClassTemplate { ENDIF »''' + /** + * Template method which generates JAVA enum type. + * + * @return string with inner enum source code in JAVA format + */ def private generateEnums() ''' «IF !enums.empty» «FOR e : enums SEPARATOR "\n"» @@ -106,6 +166,11 @@ class ClassTemplate { «ENDIF» ''' + /** + * Template method wich generates JAVA constants. + * + * @return string with constants in JAVA format + */ def private generateConstants() ''' «IF !consts.empty» «FOR c : consts» @@ -130,6 +195,11 @@ class ClassTemplate { «ENDIF» ''' + /** + * Template method which generates JAVA static initialization block. + * + * @return string with static initialization block in JAVA format + */ def private generateStaticInicializationBlock() ''' static { for (String regEx : «TypeConstants.PATTERN_CONSTANT_NAME») { @@ -137,6 +207,12 @@ class ClassTemplate { } } ''' + + /** + * Template method which generates JAVA class attributes. + * + * @return string with the class attributes in JAVA format + */ def private generateFields() ''' «IF !fields.empty» «FOR f : fields» @@ -145,6 +221,11 @@ class ClassTemplate { «ENDIF» ''' + /** + * Template method which generates JAVA constructor(s). + * + * @return string with the class constructor(s) in JAVA format + */ def private generateConstructor() ''' «val genTOTopParent = GeneratorUtil.getTopParrentTransportObject(genTO)» «val properties = GeneratorUtil.resolveReadOnlyPropertiesFromTO(genTO.properties)» @@ -183,21 +264,43 @@ class ClassTemplate { «ENDIF» ''' + /** + * Template method which generates the getter method for field + * + * @param field + * generated property with data about field which is generated as the getter method + * @return string with the getter method source code in JAVA format + */ def private generateGetter(GeneratedProperty field) { val prefix = if(field.returnType.equals(Types.typeForClass(Boolean))) "is" else "get" ''' public «field.returnType.resolveName» «prefix»«field.name.toFirstUpper»() { return «field.fieldName»; + } ''' } - def private generateSetter(GeneratedProperty field) ''' + /** + * Template method which generates the setter method for field + * + * @param field + * generated property with data about field which is generated as the setter method + * @return string with the setter method source code in JAVA format + */ + def private generateSetter(GeneratedProperty field) ''' «val type = field.returnType.resolveName» public void set«field.name.toFirstUpper»(«type» «field.fieldName») { this.«field.fieldName» = «field.fieldName»; } ''' + /** + * Template method which generates method parameters with their types from parameters. + * + * @param parameters + * group of generated property instances which are transformed to the method parameters + * @return string with the list of the method parameters with their types in JAVA format + */ def private generateParameters(Iterable parameters) '''« IF !parameters.empty»« FOR parameter : parameters SEPARATOR ", "»« @@ -206,6 +309,13 @@ class ClassTemplate { ENDIF »''' + /** + * Template method which generates sequence of the names of the class attributes from parameters. + * + * @param parameters + * group of generated property instances which are transformed to the sequence of parameter names + * @return string with the list of the parameter names of the parameters + */ def private generateParameterNames(Iterable parameters) '''« IF !parameters.empty»« FOR parameter : parameters SEPARATOR ", "»« @@ -214,6 +324,11 @@ class ClassTemplate { ENDIF »''' + /** + * Template method which generates the method hashCode(). + * + * @return string with the hashCode() method definition in JAVA format + */ def private generateHashCode() ''' «IF !genTO.hashCodeIdentifiers.empty» @Override @@ -227,6 +342,12 @@ class ClassTemplate { } «ENDIF» ''' + + /** + * Template method which generates the method equals(). + * + * @return string with the equals() method definition in JAVA format + */ def private generateEquals() ''' «IF !genTO.equalsIdentifiers.empty» @Override @@ -256,6 +377,11 @@ class ClassTemplate { «ENDIF» ''' + /** + * Template method which generates the method toString(). + * + * @return string with the toString() method definition in JAVA format + */ def private generateToString() ''' «IF !genTO.toStringIdentifiers.empty» @Override @@ -274,6 +400,11 @@ class ClassTemplate { «ENDIF» ''' + /** + * Template method which generate package name line and import lines. + * + * @result string with package and import lines in JAVA format + */ def private generatePkgAndImports() ''' package «genTO.packageName»; @@ -285,7 +416,13 @@ class ClassTemplate { «ENDIF» ''' - + + /** + * Adds package to imports if it is necessary and returns necessary type name (with or without package name) + * + * @param type JAVA Type + * @return string with the type name (with or without package name) + */ def private resolveName(Type type) { GeneratorUtil.putTypeIntoImports(genTO, type, imports); GeneratorUtil.getExplicitType(genTO, type, imports) diff --git a/code-generator/binding-java-api-generator/src/main/java/org/opendaylight/yangtools/sal/java/api/generator/Constants.java b/code-generator/binding-java-api-generator/src/main/java/org/opendaylight/yangtools/sal/java/api/generator/Constants.java index 05b093b31c..a3f07e0f8d 100644 --- a/code-generator/binding-java-api-generator/src/main/java/org/opendaylight/yangtools/sal/java/api/generator/Constants.java +++ b/code-generator/binding-java-api-generator/src/main/java/org/opendaylight/yangtools/sal/java/api/generator/Constants.java @@ -7,48 +7,25 @@ */ package org.opendaylight.yangtools.sal.java.api.generator; +/** + * + * Various constants when generating JAVA source code. + * + */ final class Constants { - public static final String IFC = "interface"; - public static final String CLASS = "class"; - public static final String PKG = "package"; - public static final String ENUM = "enum"; - - public static final String LCB = "{"; - public static final String RCB = "}"; - - public static final String LB = "("; - public static final String RB = ")"; - - public static final String LSB = "["; - public static final String RSB = "]"; - public static final String GAP = " "; public static final String COMMA = ","; public static final String DOT = "."; - public static final String ASTERISK = "*"; - public static final String NL = "\n"; - public static final String SC = ";"; - public static final String TAB = " "; - public static final String ASSIGN = "="; - public static final String DOUBLE_QUOTE = "\""; - public static final String PUBLIC = "public"; - public static final String PRIVATE = "private"; - public static final String PROTECTED = "protected"; - public static final String STATIC = "static"; - public static final String ABSTRACT = "abstract"; - public static final String FINAL = "final"; - public static final String EXTENDS = "extends"; - public static final String IMPLEMENTS = "implements"; - - public static final String ENUMERATION_NAME = "value"; - public static final String ENUMERATION_TYPE = "int"; - - public static final String STRING_PATTERN_LIST = "STRING_PATTERNS"; + /** + * Name of the class constant which contains list of Pattern + * instances. + */ public static final String MEMBER_PATTERN_LIST = "patterns"; - public static final String NO_INDENT = ""; - + /** + * It doesn't have the sense to create the instances of this class. + */ private Constants() { } } diff --git a/code-generator/binding-java-api-generator/src/main/java/org/opendaylight/yangtools/sal/java/api/generator/EnumGenerator.java b/code-generator/binding-java-api-generator/src/main/java/org/opendaylight/yangtools/sal/java/api/generator/EnumGenerator.java index b32993b040..6cee013b1e 100644 --- a/code-generator/binding-java-api-generator/src/main/java/org/opendaylight/yangtools/sal/java/api/generator/EnumGenerator.java +++ b/code-generator/binding-java-api-generator/src/main/java/org/opendaylight/yangtools/sal/java/api/generator/EnumGenerator.java @@ -1,36 +1,48 @@ -/* - * 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; - -import org.opendaylight.yangtools.sal.binding.model.api.CodeGenerator; -import org.opendaylight.yangtools.sal.binding.model.api.Enumeration; -import org.opendaylight.yangtools.sal.binding.model.api.Type; - -public class EnumGenerator implements CodeGenerator { - - @Override - public boolean isAcceptable(Type type) { - return type instanceof Enumeration; - } - - @Override - public String generate(Type type) { - if (type instanceof Enumeration) { - final Enumeration enums = (Enumeration) type; - final EnumTemplate enumTemplate = new EnumTemplate(enums); - return enumTemplate.generate(); - } - return ""; - } - - @Override - public String getUnitName(Type type) { - return type.getName(); - } - -} +/* + * 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; + +import org.opendaylight.yangtools.sal.binding.model.api.CodeGenerator; +import org.opendaylight.yangtools.sal.binding.model.api.Enumeration; +import org.opendaylight.yangtools.sal.binding.model.api.Type; + +/** + * + * Transformator of the data from the virtual form to JAVA source code. The + * result source code represents JAVA enumeration. For generation of the source + * code is used the template written in XTEND language. + * + */ +public class EnumGenerator implements CodeGenerator { + + @Override + public boolean isAcceptable(Type type) { + return type instanceof Enumeration; + } + + /** + * Generates JAVA source code for generated type Type. The code + * is generated according to the template source code template which is + * written in XTEND language. + */ + @Override + public String generate(Type type) { + if (type instanceof Enumeration) { + final Enumeration enums = (Enumeration) type; + final EnumTemplate enumTemplate = new EnumTemplate(enums); + return enumTemplate.generate(); + } + return ""; + } + + @Override + public String getUnitName(Type type) { + return type.getName(); + } + +} diff --git a/code-generator/binding-java-api-generator/src/main/java/org/opendaylight/yangtools/sal/java/api/generator/EnumTemplate.xtend b/code-generator/binding-java-api-generator/src/main/java/org/opendaylight/yangtools/sal/java/api/generator/EnumTemplate.xtend index 741835d28f..60cbb29553 100644 --- a/code-generator/binding-java-api-generator/src/main/java/org/opendaylight/yangtools/sal/java/api/generator/EnumTemplate.xtend +++ b/code-generator/binding-java-api-generator/src/main/java/org/opendaylight/yangtools/sal/java/api/generator/EnumTemplate.xtend @@ -1,25 +1,50 @@ package org.opendaylight.yangtools.sal.java.api.generator import org.opendaylight.yangtools.sal.binding.model.api.Enumeration - +/** + * Template for generating JAVA enumeration type. + */ class EnumTemplate { + /** + * Enumeration which will be transformed to JAVA source code for enumeration + */ val Enumeration enums + /** + * Constructs instance of this class with concrete enums. + * + * @param enumeration which will be transformed to JAVA source code + */ new(Enumeration enums) { this.enums = enums } + /** + * Generates JAVA source code for the enumeration with the package name. + * + * @return JAVA source code for enumeration and for the package name + */ def String generate() { val body = generateBody val pkg = generatePkg return pkg.toString + body.toString } + /** + * Generates only JAVA enumeration source code. + * + * @return string with JAVA enumeration source code + */ def generateAsInnerClass() { return generateBody } + /** + * Template method which generates enumeration body (declaration + enumeration items). + * + * @return string with the enumeration body + */ def private generateBody() ''' public enum «enums.name» { «FOR v : enums.values SEPARATOR ",\n"» @@ -34,6 +59,11 @@ class EnumTemplate { } ''' + /** + * Template method which generates the package name line. + * + * @return string with the package name line + */ def private generatePkg() ''' package «enums.packageName»; 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 895b1972c8..ea33be2e9f 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 @@ -20,21 +20,51 @@ import org.opendaylight.yangtools.sal.binding.model.api.Type; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +/** + * Generates files with JAVA source codes for every specified type. + * + */ public final class GeneratorJavaFile { private static final Logger log = LoggerFactory.getLogger(GeneratorJavaFile.class); + + /** + * List of CodeGenerator instances. + */ private final List generators = new ArrayList<>(); + /** + * Set of Type instances for which the JAVA code is generated. + */ private final Set types; + /** + * 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 + */ public GeneratorJavaFile(final Set types) { - this.types = types; - generators.add(new InterfaceGenerator()); - generators.add(new TOGenerator()); - generators.add(new EnumGenerator()); - generators.add(new BuilderGenerator()); + this.types = types; + generators.add(new InterfaceGenerator()); + generators.add(new TOGenerator()); + generators.add(new EnumGenerator()); + generators.add(new BuilderGenerator()); } + /** + * 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 + * @throws IOException + * if the error during writting to the file occures + */ public List generateToFile(final File parentDirectory) throws IOException { final List result = new ArrayList<>(); for (Type type : types) { @@ -48,6 +78,28 @@ public final class GeneratorJavaFile { return result; } + /** + * Generates File for type. All files are stored + * to subfolders of base directory parentDir. Subdirectories + * 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 + * JAVA Type for which should be JAVA source code + * generated + * @param generator + * code generator which is used for generating of the source code + * @return file which contains JAVA source code + * @throws IOException + * if the error during writting to the file occures + * @throws IllegalArgumentException + * if type equals null + * @throws IllegalStateException + * if string with generated code is empty + */ private File generateTypeToJavaFile(final File parentDir, final Type type, final CodeGenerator generator) throws IOException { if (parentDir == null) { @@ -67,7 +119,7 @@ public final class GeneratorJavaFile { if (!packageDir.exists()) { packageDir.mkdirs(); } - + if (generator.isAcceptable(type)) { String generatedCode = generator.generate(type); if (generatedCode.isEmpty()) { @@ -87,7 +139,20 @@ public final class GeneratorJavaFile { } return null; } - + + /** + * Creates the package directory path as concatenation of + * 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 + * string with the name of the package + * @return File object which refers to the new directory for + * package packageName + */ private File packageToDirectory(final File parentDirectory, final String packageName) { if (packageName == null) { throw new IllegalArgumentException("Package Name cannot be NULL!"); diff --git a/code-generator/binding-java-api-generator/src/main/java/org/opendaylight/yangtools/sal/java/api/generator/GeneratorUtil.java b/code-generator/binding-java-api-generator/src/main/java/org/opendaylight/yangtools/sal/java/api/generator/GeneratorUtil.java index 7a7da13123..f4cab6242f 100644 --- a/code-generator/binding-java-api-generator/src/main/java/org/opendaylight/yangtools/sal/java/api/generator/GeneratorUtil.java +++ b/code-generator/binding-java-api-generator/src/main/java/org/opendaylight/yangtools/sal/java/api/generator/GeneratorUtil.java @@ -25,12 +25,26 @@ import org.opendaylight.yangtools.sal.binding.model.api.ParameterizedType; import org.opendaylight.yangtools.sal.binding.model.api.Type; import org.opendaylight.yangtools.sal.binding.model.api.WildcardType; - public final class GeneratorUtil { + /** + * It doesn't have the sense to create the instances of this class. + */ private GeneratorUtil() { } + /** + * Returns the map of imports. The map maps the type name to the package + * name. To the map are added packages for genType and for all + * enclosed types, constants, methods (parameter types, return values), + * implemented types. + * + * @param genType + * generated type for which the map of the imports is created + * @return map of the necessary imports + * @throws IllegalArgumentException + * if genType equals null + */ public static Map createImports(GeneratedType genType) { if (genType == null) { throw new IllegalArgumentException("Generated Type cannot be NULL!"); @@ -98,6 +112,34 @@ public final class GeneratorUtil { return imports; } + /** + * Evaluates if it is necessary to add the package name for + * type to the map of imports for parentGenType. + * If it is so the package name is saved to the map imports. + * + * @param parentGenType + * generated type for which is the map of the necessary imports + * built + * @param type + * JAVA Type for which is the necessary of the + * package import evaluated + * @param imports + * map of the imports for parentGenType + * @throws IllegalArgumentException + *
    + *
  • if the parentGenType equals + * null
  • + *
  • if the name of parentGenType equals + * null
  • + *
  • if the name of the package of parentGenType + * equals null
  • + *
  • if the type equals null
  • + *
  • if the name of type equals null + *
  • + *
  • if the name of the package of type equals + * null
  • + *
+ */ public static void putTypeIntoImports(final GeneratedType parentGenType, final Type type, final Map imports) { if (parentGenType == null) { @@ -140,6 +182,27 @@ public final class GeneratorUtil { } } + /** + * Checks if the constant with the name constName is in the + * list of the constant definition for genTO. + * + * @param constName + * string with the name of constant which is sought + * @param genTO + * generated transfer object in which is constName + * sought + * @return boolean value + *
    + *
  • true - if constName is in the list of the + * constant definition for genTO
  • + *
  • false - in other cases
  • + *
+ * @throws IllegalArgumentException + *
    + *
  • if constName equals null
  • + *
  • if genTO equals null
  • + *
+ */ public static boolean isConstantInTO(String constName, GeneratedTransferObject genTO) { if (constName == null || genTO == null) throw new IllegalArgumentException(); @@ -153,6 +216,16 @@ public final class GeneratorUtil { return false; } + /** + * Creates the map which maps the type name to package name and contains + * only package names for enclosed types of genType and + * recursivelly their enclosed types. + * + * @param genType + * JAVA Type for which is the map created + * @return map of the package names for all the enclosed types and + * recursivelly their enclosed types + */ public static Map createChildImports(GeneratedType genType) { Map childImports = new LinkedHashMap<>(); List childGeneratedTypes = genType.getEnclosedTypes(); @@ -165,7 +238,32 @@ public final class GeneratorUtil { return childImports; } - public static String getExplicitType(final GeneratedType parentGenType, final Type type, final Map imports) { + /** + * Builds the string which contains either the full path to the type + * (package name with type) or only type name if the package is among + * imports. + * + * @param parentGenType + * generated type which contains type + * @param type + * JAVA Type for which is the string with type info + * generated + * @param imports + * map of necessary imports for parentGenType + * @return string with type name for type in the full format or + * in the short format + * @throws IllegalArgumentException + *
    + *
  • if the type equals null
  • + *
  • if the name of the type equals + * null
  • + *
  • if the name of the package of the type + * equals null
  • + *
  • if the imports equals null
  • + *
+ */ + public static String getExplicitType(final GeneratedType parentGenType, final Type type, + final Map imports) { if (type == null) { throw new IllegalArgumentException("Type parameter MUST be specified and cannot be NULL!"); } @@ -220,7 +318,20 @@ public final class GeneratorUtil { } } - private static String getParameters(final GeneratedType parentGenType, final Type[] pTypes, Map availableImports) { + /** + * Generates the string with all actual type parameters from + * pTypes + * + * @param parentGenType + * generated type for which is the JAVA code generated + * @param pTypes + * array of Type instances = actual type parameters + * @param availableImports + * map of imports for parentGenType + * @return string with all actual type parameters from pTypes + */ + private static String getParameters(final GeneratedType parentGenType, final Type[] pTypes, + Map availableImports) { final StringBuilder builder = new StringBuilder(); for (int i = 0; i < pTypes.length; i++) { final Type t = pTypes[i]; @@ -247,15 +358,16 @@ public final class GeneratorUtil { } /** - * The method returns reference to highest (top parent) Generated Transfer - * Object. - * + * Returns the reference to highest (top parent) Generated Transfer Object. + * * @param childTransportObject * is generated transfer object which can be extended by other * generated transfer object * @return in first case that childTransportObject isn't * extended then childTransportObject is returned. In * second case the method is recursive called until first case. + * @throws IllegalArgumentException + * if childTransportObject equals null */ public static GeneratedTransferObject getTopParrentTransportObject(GeneratedTransferObject childTransportObject) { if (childTransportObject == null) { @@ -269,11 +381,11 @@ public final class GeneratorUtil { } /** - * The method selects from input list of properties only those which have - * read only attribute set to true. - * + * Selects from input list of properties only those which have read only + * attribute set to true. + * * @param properties - * contains list of properties of generated transfer object + * list of properties of generated transfer object * @return subset of properties which have read only attribute * set to true */ @@ -290,12 +402,14 @@ public final class GeneratorUtil { } /** - * The method returns the list of the properties of all extending generated + * Returns the list of the read only properties of all extending generated * transfer object from genTO to highest parent generated * transfer object - * + * * @param genTO - * @return the list of all properties from actual to highest parent + * generated transfer object for which is the list of read only + * properties generated + * @return list of all read only properties from actual to highest parent * generated transfer object. In case when extension exists the * method is recursive called. */ diff --git a/code-generator/binding-java-api-generator/src/main/java/org/opendaylight/yangtools/sal/java/api/generator/InterfaceGenerator.java b/code-generator/binding-java-api-generator/src/main/java/org/opendaylight/yangtools/sal/java/api/generator/InterfaceGenerator.java index c2f610d8db..3f03b36e42 100644 --- a/code-generator/binding-java-api-generator/src/main/java/org/opendaylight/yangtools/sal/java/api/generator/InterfaceGenerator.java +++ b/code-generator/binding-java-api-generator/src/main/java/org/opendaylight/yangtools/sal/java/api/generator/InterfaceGenerator.java @@ -1,37 +1,48 @@ -/* - * 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; - -import org.opendaylight.yangtools.sal.binding.model.api.CodeGenerator; -import org.opendaylight.yangtools.sal.binding.model.api.GeneratedTransferObject; -import org.opendaylight.yangtools.sal.binding.model.api.GeneratedType; -import org.opendaylight.yangtools.sal.binding.model.api.Type; - -public final class InterfaceGenerator implements CodeGenerator { - - @Override - public boolean isAcceptable(Type type) { - return type instanceof GeneratedType && !(type instanceof GeneratedTransferObject); - } - - @Override - public String generate(Type type) { - if (type instanceof GeneratedType && !(type instanceof GeneratedTransferObject)) { - final GeneratedType genType = (GeneratedType) type; - final InterfaceTemplate interfaceTemplate = new InterfaceTemplate(genType); - return interfaceTemplate.generate(); - } - return ""; - } - - @Override - public String getUnitName(Type type) { - return type.getName(); - } - -} +/* + * 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; + +/** + * + * Transformator of the data from the virtual form to JAVA source code. The result source code represents JAVA interface. For + * generating of the source code is used the template written in XTEND language. + * + */ +import org.opendaylight.yangtools.sal.binding.model.api.CodeGenerator; +import org.opendaylight.yangtools.sal.binding.model.api.GeneratedTransferObject; +import org.opendaylight.yangtools.sal.binding.model.api.GeneratedType; +import org.opendaylight.yangtools.sal.binding.model.api.Type; + +public final class InterfaceGenerator implements CodeGenerator { + + @Override + public boolean isAcceptable(Type type) { + return type instanceof GeneratedType && !(type instanceof GeneratedTransferObject); + } + + /** + * Generates JAVA source code for generated type Type. The code + * is generated according to the template source code template which is + * written in XTEND language. + */ + @Override + public String generate(Type type) { + if (type instanceof GeneratedType && !(type instanceof GeneratedTransferObject)) { + final GeneratedType genType = (GeneratedType) type; + final InterfaceTemplate interfaceTemplate = new InterfaceTemplate(genType); + return interfaceTemplate.generate(); + } + return ""; + } + + @Override + public String getUnitName(Type type) { + return type.getName(); + } + +} diff --git a/code-generator/binding-java-api-generator/src/main/java/org/opendaylight/yangtools/sal/java/api/generator/InterfaceTemplate.xtend b/code-generator/binding-java-api-generator/src/main/java/org/opendaylight/yangtools/sal/java/api/generator/InterfaceTemplate.xtend index ce3a91ba74..d49edf9f5e 100644 --- a/code-generator/binding-java-api-generator/src/main/java/org/opendaylight/yangtools/sal/java/api/generator/InterfaceTemplate.xtend +++ b/code-generator/binding-java-api-generator/src/main/java/org/opendaylight/yangtools/sal/java/api/generator/InterfaceTemplate.xtend @@ -10,16 +10,47 @@ import org.opendaylight.yangtools.sal.binding.model.api.GeneratedType import org.opendaylight.yangtools.sal.binding.model.api.MethodSignature import org.opendaylight.yangtools.sal.binding.model.api.Type import java.util.LinkedHashMap - +/** + * Template for generating JAVA interfaces. + */ class InterfaceTemplate { + /** + * Generated type which is transformed to interface JAVA file. + */ val GeneratedType genType + + /** + * Map of imports for this genTO. + */ val Map imports + + /** + * List of constant instances which are generated as JAVA public static final attributes. + */ val List consts + + /** + * List of method signatures which are generated as method declarations. + */ val List methods + + /** + * List of enumeration which are generated as JAVA enum type. + */ val List enums + + /** + * List of generated types which are enclosed inside genType + */ val List enclosedGeneratedTypes + /** + * Creates the instance of this class which is used for generating the interface file source + * code from genType. + * + * @throws IllegalArgumentException if genType equals null + */ new(GeneratedType genType) { if (genType == null) { throw new IllegalArgumentException("Generated type reference cannot be NULL!") @@ -33,12 +64,22 @@ class InterfaceTemplate { enclosedGeneratedTypes = genType.enclosedTypes } + /** + * Generates the source code for interface with package name, imports and interface body. + * + * @return string with the code for the interface file in JAVA format + */ def String generate() { val body = generateBody val pkgAndImports = generatePkgAndImports return pkgAndImports.toString + body.toString } + /** + * Template method which generate the whole body of the interface. + * + * @return string with code for interface body in JAVA format + */ def private generateBody() ''' «genType.comment.generateComment» «generateIfcDeclaration» { @@ -55,6 +96,13 @@ class InterfaceTemplate { ''' + /** + * Template method which generates JAVA comment. + * + * @param comment + * string with the comment for whole JAVA interface + * @return string with comment in JAVA format + */ def private generateComment(String comment) ''' «IF comment != null && !comment.empty» /* @@ -63,6 +111,11 @@ class InterfaceTemplate { «ENDIF» ''' + /** + * Template method which generates the interface name declaration. + * + * @return string with the code for the interface declaration in JAVA format + */ def private generateIfcDeclaration() ''' public interface «genType.name»« IF (!genType.implements.empty)»« @@ -73,6 +126,11 @@ class InterfaceTemplate { ENDIF »''' + /** + * Template method which generates inner classes inside this interface. + * + * @return string with the source code for inner classes in JAVA format + */ def private generateInnerClasses() ''' «IF !enclosedGeneratedTypes.empty» «FOR innerClass : enclosedGeneratedTypes SEPARATOR "\n"» @@ -83,7 +141,12 @@ class InterfaceTemplate { «ENDFOR» «ENDIF» ''' - + + /** + * Template method which generates JAVA enum type. + * + * @return string with inner enum source code in JAVA format + */ def private generateEnums() ''' «IF !enums.empty» «FOR e : enums SEPARATOR "\n"» @@ -93,6 +156,11 @@ class InterfaceTemplate { «ENDIF» ''' + /** + * Template method wich generates JAVA constants. + * + * @return string with constants in JAVA format + */ def private generateConstants() ''' «IF !consts.empty» «FOR c : consts» @@ -102,7 +170,12 @@ class InterfaceTemplate { «ENDFOR» «ENDIF» ''' - + + /** + * Template method which generates the declaration of the methods. + * + * @return string with the declaration of methods source code in JAVA format + */ def private generateMethods() ''' «IF !methods.empty» «FOR m : methods SEPARATOR "\n"» @@ -112,6 +185,13 @@ class InterfaceTemplate { «ENDIF» ''' + /** + * Template method which generates method parameters with their types from parameters. + * + * @param parameters + * list of parameter instances which are transformed to the method parameters + * @return string with the list of the method parameters with their types in JAVA format + */ def private generateParameters(List parameters) '''« IF !parameters.empty»« FOR parameter : parameters SEPARATOR ", "»« @@ -120,18 +200,13 @@ class InterfaceTemplate { ENDIF »''' - def private generatePkgAndImports() ''' - package «genType.packageName»; - - - «IF !imports.empty» - «FOR entry : resolveImports.entrySet» - import «entry.value».«entry.key»; - «ENDFOR» - «ENDIF» - - ''' - + + /** + * Template method which generates the map of all the required imports for and imports + * from extended type (and recursivelly so on). + * + * @return map which maps type name to package name + */ def private Map resolveImports() { val innerTypeImports = GeneratorUtil.createChildImports(genType) val Map resolvedImports = new LinkedHashMap @@ -145,6 +220,29 @@ class InterfaceTemplate { return resolvedImports } + /** + * Template method which generate package name line and import lines. + * + * @result string with package and import lines in JAVA format + */ + def private generatePkgAndImports() ''' + package «genType.packageName»; + + + «IF !imports.empty» + «FOR entry : resolveImports.entrySet» + import «entry.value».«entry.key»; + «ENDFOR» + «ENDIF» + + ''' + + /** + * Adds package to imports if it is necessary and returns necessary type name (with or without package name) + * + * @param type JAVA Type + * @return string with the type name (with or without package name) + */ def private resolveName(Type type) { GeneratorUtil.putTypeIntoImports(genType, type, imports); GeneratorUtil.getExplicitType(genType, type, imports) diff --git a/code-generator/binding-java-api-generator/src/main/java/org/opendaylight/yangtools/sal/java/api/generator/TOGenerator.java b/code-generator/binding-java-api-generator/src/main/java/org/opendaylight/yangtools/sal/java/api/generator/TOGenerator.java index 230fb3b890..0299b1b644 100644 --- a/code-generator/binding-java-api-generator/src/main/java/org/opendaylight/yangtools/sal/java/api/generator/TOGenerator.java +++ b/code-generator/binding-java-api-generator/src/main/java/org/opendaylight/yangtools/sal/java/api/generator/TOGenerator.java @@ -1,36 +1,48 @@ -/* - * 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; - -import org.opendaylight.yangtools.sal.binding.model.api.CodeGenerator; -import org.opendaylight.yangtools.sal.binding.model.api.GeneratedTransferObject; -import org.opendaylight.yangtools.sal.binding.model.api.Type; - -public final class TOGenerator implements CodeGenerator { - - @Override - public String generate(Type type) { - if (type instanceof GeneratedTransferObject) { - final GeneratedTransferObject genTO = (GeneratedTransferObject) type; - final ClassTemplate template = new ClassTemplate(genTO); - return template.generate(); - } - return ""; - } - - @Override - public boolean isAcceptable(Type type) { - return type instanceof GeneratedTransferObject; - } - - @Override - public String getUnitName(Type type) { - return type.getName(); - } - -} +/* + * 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; + +import org.opendaylight.yangtools.sal.binding.model.api.CodeGenerator; +import org.opendaylight.yangtools.sal.binding.model.api.GeneratedTransferObject; +import org.opendaylight.yangtools.sal.binding.model.api.Type; + +/** + * + * Transformator of the data from the virtual form to JAVA source code. The + * result source code represents JAVA class. For generating of the source code + * is used the template written in XTEND language. + * + */ +public final class TOGenerator implements CodeGenerator { + + /** + * Generates JAVA source code for generated type Type. The code + * is generated according to the template source code template which is + * written in XTEND language. + */ + @Override + public String generate(Type type) { + if (type instanceof GeneratedTransferObject) { + final GeneratedTransferObject genTO = (GeneratedTransferObject) type; + final ClassTemplate template = new ClassTemplate(genTO); + return template.generate(); + } + return ""; + } + + @Override + public boolean isAcceptable(Type type) { + return type instanceof GeneratedTransferObject; + } + + @Override + public String getUnitName(Type type) { + return type.getName(); + } + +} diff --git a/code-generator/binding-model-api/src/main/java/org/opendaylight/yangtools/sal/binding/model/api/CodeGenerator.java b/code-generator/binding-model-api/src/main/java/org/opendaylight/yangtools/sal/binding/model/api/CodeGenerator.java index df6a5f6ebb..e0dff52be9 100644 --- a/code-generator/binding-model-api/src/main/java/org/opendaylight/yangtools/sal/binding/model/api/CodeGenerator.java +++ b/code-generator/binding-model-api/src/main/java/org/opendaylight/yangtools/sal/binding/model/api/CodeGenerator.java @@ -1,37 +1,51 @@ -/* - * 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.model.api; - -import java.io.IOException; - -/** - * - * - */ -public interface CodeGenerator { - - /** - * @param type Input type to be processed - * @return generated code - * @throws IOException - */ - String generate(Type type); - - /** - * @param type Input type to be processed - * @return true if type is acceptable for processing. - */ - boolean isAcceptable(Type type); - - /** - * @param type Input type to be processed - * @return name of generated unit - */ - String getUnitName(Type type); - -} +/* + * 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.model.api; + +import java.io.IOException; + +/** + * Transformates virtual data to the concrete code in programming language. + * + */ +public interface CodeGenerator { + + /** + * Generates code for type. + * + * @param type + * Input type to be processed + * @return generated JAVA code + * @throws IOException + */ + String generate(Type type); + + /** + * Checks if the concrete instance of type fit to concrete + * implementation of this interface. + * + * (e. g. method return true if in EnumGenerator (which + * implements this interface) has input parameter of type Enumeration (which + * is subtype of Type) + * + * @param type + * Input type to be processed + * @return true if type is acceptable for processing. + */ + boolean isAcceptable(Type type); + + /** + * Returns name of type parameter. + * + * @param type + * Input type to be processed + * @return name of generated unit + */ + String getUnitName(Type type); + +} diff --git a/code-generator/binding-model-api/src/main/java/org/opendaylight/yangtools/sal/binding/model/api/Enumeration.java b/code-generator/binding-model-api/src/main/java/org/opendaylight/yangtools/sal/binding/model/api/Enumeration.java index 1bc2f76057..7d5054a227 100644 --- a/code-generator/binding-model-api/src/main/java/org/opendaylight/yangtools/sal/binding/model/api/Enumeration.java +++ b/code-generator/binding-model-api/src/main/java/org/opendaylight/yangtools/sal/binding/model/api/Enumeration.java @@ -10,41 +10,53 @@ package org.opendaylight.yangtools.sal.binding.model.api; import java.util.List; /** - * + * Interface provide methods for reading data of enumeration class. */ public interface Enumeration extends Type { /** - * - * @return + * + * Returns list of annotation definitions associated with enumeration type. + * + * @return list of annotation definitions associated with enumeration type. + * */ public List getAnnotations(); - /** - * - * @return - */ public Type getDefiningType(); /** - * - * @return + * Returns list of the couples - name and value. + * + * @return list of the enumeration pairs. */ public List getValues(); /** - * - * @return + * Formats enumeration according to rules of the programming language. + * + * @return string with source code in some programming language */ public String toFormattedString(); /** - * + * Interface is used for reading enumeration item. It means item's name and + * its value. */ interface Pair { + /** + * Returns the name of the enumeration item. + * + * @return the name of the enumeration item. + */ public String getName(); + /** + * Returns value of the enumeration item. + * + * @return the value of the enumeration item. + */ public Integer getValue(); } } diff --git a/code-generator/binding-model-api/src/main/java/org/opendaylight/yangtools/sal/binding/model/api/WildcardType.java b/code-generator/binding-model-api/src/main/java/org/opendaylight/yangtools/sal/binding/model/api/WildcardType.java index eeafccd48c..094b85738a 100644 --- a/code-generator/binding-model-api/src/main/java/org/opendaylight/yangtools/sal/binding/model/api/WildcardType.java +++ b/code-generator/binding-model-api/src/main/java/org/opendaylight/yangtools/sal/binding/model/api/WildcardType.java @@ -1,5 +1,11 @@ package org.opendaylight.yangtools.sal.binding.model.api; -public interface WildcardType extends Type { +/** + * + * Marker interface which assign to object property that it is bounded wildcard + * type. + * + */ +public interface WildcardType extends Type { }