From: Tony Tkacik Date: Thu, 22 Aug 2013 16:21:52 +0000 (+0200) Subject: Updated code generation X-Git-Tag: yangtools-0.1.0~53 X-Git-Url: https://git.opendaylight.org/gerrit/gitweb?a=commitdiff_plain;h=472d40a3c6ba0d10fdb50c3d7f8d80f58c3fe71d;p=yangtools.git Updated code generation - Clean up of templates - Added generation of copy constructors and parent class constructors Change-Id: I92f72d68d8d417b991c5f40204a58ff6492cf1c8 Signed-off-by: Tony Tkacik --- 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 ce3f7397b4..9e14532d5a 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,2000 +1,2004 @@ -/* - * 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.*; -import static org.opendaylight.yangtools.yang.model.util.SchemaContextUtil.*; - -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.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.Augmentable; -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; -import static org.opendaylight.yangtools.binding.generator.util.Types.*; -import static org.opendaylight.yangtools.binding.generator.util.BindingTypes.*; - - -import com.google.common.base.Preconditions; -import com.google.common.base.Predicates; - -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(); - - /** - * Constant with the concrete name of namespace. - */ - private final static String YANG_EXT_NAMESPACE = "urn:opendaylight:yang:extension:yang-ext"; - - /** - * Constant with the concrete name of identifier. - */ - private final static String AUGMENT_IDENTIFIER_NAME = "augment-identifier"; - - /** - * Only parent constructor is invoked. - */ - 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) { - Preconditions.checkArgument(context != null,"Schema Context reference cannot be NULL."); - Preconditions.checkState(context.getModules() != null,"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) { - Preconditions.checkArgument(context != null,"Schema Context reference cannot be NULL."); - Preconditions.checkState(context.getModules() != null,"Schema Context does not contain defined modules."); - Preconditions.checkArgument(modules != null,"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) { - Preconditions.checkArgument(module != null,"Module reference cannot be NULL."); - Preconditions.checkArgument(module.getName() != null,"Module name cannot be NULL."); - Preconditions.checkArgument(module.getTypeDefinitions() != null,"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) { - Preconditions.checkArgument(module != null,"Module reference cannot be NULL."); - - Preconditions.checkArgument(module.getName() != null,"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) { - Preconditions.checkArgument(module != null,"Module reference cannot be NULL."); - - Preconditions.checkArgument(module.getName() != null,"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) { - Preconditions.checkArgument(module != null,"Module reference cannot be NULL."); - Preconditions.checkArgument(module.getName() != null,"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) { - Preconditions.checkArgument(module != null,"Module reference cannot be NULL."); - Preconditions.checkArgument(module.getName() != null,"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) { - Preconditions.checkArgument(module != null,"Module reference cannot be NULL."); - Preconditions.checkState(module.getAugmentations() != null,"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) { - Preconditions.checkArgument(module != null,"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) { - Preconditions.checkArgument(module != null,"Module reference cannot be NULL."); - - Preconditions.checkArgument(module.getName() != null,"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(DATA_OBJECT); - inType.addImplementsType(augmentable(inType)); - 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(DATA_OBJECT); - outType.addImplementsType(augmentable(outType)); - - 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) { - Preconditions.checkArgument(module != null,"Module reference cannot be NULL."); - - Preconditions.checkArgument(module.getName() != null,"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) { - Preconditions.checkArgument(module != null,"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); - enumBuilder.updateEnumPairsFromEnumTypeDef(enumTypeDef); - - return enumBuilder; - } - return null; - } - - /** - * Generates type builder for module. - * - * @param module - * Module which is source of package name for generated type - * builder - * @param postfix - * string which is added to the module class name representation - * as suffix - * @return instance of GeneratedTypeBuilder which represents - * module. - * @throws IllegalArgumentException - * if module equals null - */ - private GeneratedTypeBuilder moduleTypeBuilder(final Module module, final String postfix) { - Preconditions.checkArgument(module != null,"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) { - Preconditions.checkArgument(augmentPackageName != null,"Package Name cannot be NULL."); - Preconditions.checkArgument(augSchema != null,"Augmentation Schema cannot be NULL."); - Preconditions.checkState(augSchema.getTargetPath() != null,"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(DATA_OBJECT); - augTypeBuilder.addImplementsType(Types.augmentationTypeFor(targetTypeRef)); - addImplementedInterfaceFromUses(augSchema, augTypeBuilder); - - augSchemaNodeToMethods(augmentPackageName, augTypeBuilder, augChildNodes); - augmentBuilders.put(augTypeName, augTypeBuilder); - return augTypeBuilder; - } - - /** - * - * @param unknownSchemaNodes - * @return - */ - 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) { - Preconditions.checkArgument(basePackageName != null,"Base Package Name cannot be NULL."); - Preconditions.checkArgument(typeBuilder != null,"Generated Type Builder cannot be NULL."); - Preconditions.checkArgument(choiceNode != null,"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) { - Preconditions.checkArgument(basePackageName != null,"Base Package Name cannot be NULL."); - Preconditions.checkArgument(choiceNode != null,"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(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) { - Preconditions.checkArgument(basePackageName != null,"Base Package Name cannot be NULL."); - Preconditions.checkArgument(refChoiceType != null,"Referenced Choice Type cannot be NULL."); - Preconditions.checkArgument(caseNodes != null,"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) { - Preconditions.checkArgument(basePackageName != null,"Base Package Name cannot be NULL."); - Preconditions.checkArgument(refChoiceType != null,"Referenced Choice Type cannot be NULL."); - Preconditions.checkArgument(caseNodes != null,"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 = ""; - } - - final Module parentModule = findParentModule(schemaContext, leaf); - 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, parentModule); - if (genTOBuilder != null) { - returnType = new ReferencedTypeImpl(genTOBuilder.getPackageName(), genTOBuilder.getName()); - } - } else if (typeDef instanceof BitsTypeDefinition) { - GeneratedTOBuilder genTOBuilder = addTOToTypeBuilder(typeDef, typeBuilder, leafName, parentModule); - 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(DATA_OBJECT); - if (!(schemaNode instanceof GroupingDefinition)) { - builder.addImplementsType(augmentable(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) { - Preconditions.checkArgument(schemaNode != null,"Data Schema Node cannot be NULL."); - Preconditions.checkArgument(packageName != null,"Package Name for Generated Type cannot be NULL."); - Preconditions.checkArgument(schemaNode.getQName() != null,"QName for Data Schema Node cannot be NULL."); - final String schemaNodeName = schemaNode.getQName().getLocalName(); - Preconditions.checkArgument(schemaNodeName != null,"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) { - Preconditions.checkArgument(basePackageName != null,"Package Name for Generated Type cannot be NULL."); - Preconditions.checkArgument(list != null,"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) { - Preconditions.checkArgument(schemaNode != null,"Data Schema Node cannot be NULL."); - - Preconditions.checkArgument(typeBuilder != null,"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<>(); - Preconditions.checkArgument(typeBuilder != null,"Generated Type Builder cannot be NULL."); - - if (genTOBuilder != null) { - final GeneratedTransferObject genTO = genTOBuilder.toInstance(); - constructGetter(typeBuilder, "key", "Returns Primary Key of Yang List Type", genTO); - 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. - * - * If more then one generated TO builder is created for enclosing then all - * of the generated TO builders are added to typeBuilder as - * enclosing transfer objects. - * - * @param typeDef - * type definition which can be of type UnionType or - * BitsTypeDefinition - * @param typeBuilder - * generated type builder to which is added generated TO created - * from typeDef - * @param leafName - * string with name for generated TO builder - * @return generated TO builder for typeDef - */ - private GeneratedTOBuilder addTOToTypeBuilder(TypeDefinition typeDef, GeneratedTypeBuilder typeBuilder, - String leafName, Module parentModule) { - final String classNameFromLeaf = parseToClassName(leafName); - List genTOBuilders = new ArrayList<>(); - final String packageName = typeBuilder.getFullyQualifiedName(); - if (typeDef instanceof UnionTypeDefinition) { - genTOBuilders.addAll(((TypeProviderImpl) typeProvider).provideGeneratedTOBuildersForUnionTypeDef( - packageName, typeDef, classNameFromLeaf)); - } else if (typeDef instanceof BitsTypeDefinition) { - genTOBuilders.add(((TypeProviderImpl) typeProvider).provideGeneratedTOBuilderForBitsTypeDefinition( - packageName, typeDef, classNameFromLeaf)); - } - if (genTOBuilders != null && !genTOBuilders.isEmpty()) { - for (GeneratedTOBuilder genTOBuilder : genTOBuilders) { - typeBuilder.addEnclosingTransferObject(genTOBuilder); - } - return genTOBuilders.get(0); - } - return null; - - } - - /** - * Adds the implemented types to type builder. - * - * The method passes through the list of uses in - * {@code dataNodeContainer}. For every use is obtained coresponding - * generated type from {@link BindingGeneratorImpl#allGroupings - * allGroupings} which is 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; - } - -} +/* + * 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.*; +import static org.opendaylight.yangtools.yang.model.util.SchemaContextUtil.*; + +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.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.Augmentable; +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; +import static org.opendaylight.yangtools.binding.generator.util.Types.*; +import static org.opendaylight.yangtools.binding.generator.util.BindingTypes.*; + + +import com.google.common.base.Preconditions; +import com.google.common.base.Predicates; + +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(); + + /** + * Constant with the concrete name of namespace. + */ + private final static String YANG_EXT_NAMESPACE = "urn:opendaylight:yang:extension:yang-ext"; + + /** + * Constant with the concrete name of identifier. + */ + private final static String AUGMENT_IDENTIFIER_NAME = "augment-identifier"; + + /** + * Only parent constructor is invoked. + */ + 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) { + Preconditions.checkArgument(context != null,"Schema Context reference cannot be NULL."); + Preconditions.checkState(context.getModules() != null,"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) { + Preconditions.checkArgument(context != null,"Schema Context reference cannot be NULL."); + Preconditions.checkState(context.getModules() != null,"Schema Context does not contain defined modules."); + Preconditions.checkArgument(modules != null,"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) { + Preconditions.checkArgument(module != null,"Module reference cannot be NULL."); + Preconditions.checkArgument(module.getName() != null,"Module name cannot be NULL."); + Preconditions.checkArgument(module.getTypeDefinitions() != null,"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) { + Preconditions.checkArgument(module != null,"Module reference cannot be NULL."); + + Preconditions.checkArgument(module.getName() != null,"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) { + Preconditions.checkArgument(module != null,"Module reference cannot be NULL."); + + Preconditions.checkArgument(module.getName() != null,"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) { + Preconditions.checkArgument(module != null,"Module reference cannot be NULL."); + Preconditions.checkArgument(module.getName() != null,"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) { + Preconditions.checkArgument(module != null,"Module reference cannot be NULL."); + Preconditions.checkArgument(module.getName() != null,"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) { + Preconditions.checkArgument(module != null,"Module reference cannot be NULL."); + Preconditions.checkState(module.getAugmentations() != null,"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) { + Preconditions.checkArgument(module != null,"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) { + Preconditions.checkArgument(module != null,"Module reference cannot be NULL."); + + Preconditions.checkArgument(module.getName() != null,"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(DATA_OBJECT); + inType.addImplementsType(augmentable(inType)); + 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(DATA_OBJECT); + outType.addImplementsType(augmentable(outType)); + + 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) { + Preconditions.checkArgument(module != null,"Module reference cannot be NULL."); + + Preconditions.checkArgument(module.getName() != null,"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) { + Preconditions.checkArgument(module != null,"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); + enumBuilder.updateEnumPairsFromEnumTypeDef(enumTypeDef); + + return enumBuilder; + } + return null; + } + + /** + * Generates type builder for module. + * + * @param module + * Module which is source of package name for generated type + * builder + * @param postfix + * string which is added to the module class name representation + * as suffix + * @return instance of GeneratedTypeBuilder which represents + * module. + * @throws IllegalArgumentException + * if module equals null + */ + private GeneratedTypeBuilder moduleTypeBuilder(final Module module, final String postfix) { + Preconditions.checkArgument(module != null,"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) { + Preconditions.checkArgument(augmentPackageName != null,"Package Name cannot be NULL."); + Preconditions.checkArgument(augSchema != null,"Augmentation Schema cannot be NULL."); + Preconditions.checkState(augSchema.getTargetPath() != null,"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(DATA_OBJECT); + augTypeBuilder.addImplementsType(Types.augmentationTypeFor(targetTypeRef)); + addImplementedInterfaceFromUses(augSchema, augTypeBuilder); + + augSchemaNodeToMethods(augmentPackageName, augTypeBuilder, augChildNodes); + augmentBuilders.put(augTypeName, augTypeBuilder); + return augTypeBuilder; + } + + /** + * + * @param unknownSchemaNodes + * @return + */ + 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) { + Preconditions.checkArgument(basePackageName != null,"Base Package Name cannot be NULL."); + Preconditions.checkArgument(typeBuilder != null,"Generated Type Builder cannot be NULL."); + Preconditions.checkArgument(choiceNode != null,"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) { + Preconditions.checkArgument(basePackageName != null,"Base Package Name cannot be NULL."); + Preconditions.checkArgument(choiceNode != null,"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(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) { + Preconditions.checkArgument(basePackageName != null,"Base Package Name cannot be NULL."); + Preconditions.checkArgument(refChoiceType != null,"Referenced Choice Type cannot be NULL."); + Preconditions.checkArgument(caseNodes != null,"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) { + Preconditions.checkArgument(basePackageName != null,"Base Package Name cannot be NULL."); + Preconditions.checkArgument(refChoiceType != null,"Referenced Choice Type cannot be NULL."); + Preconditions.checkArgument(caseNodes != null,"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 = ""; + } + + final Module parentModule = findParentModule(schemaContext, leaf); + 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, parentModule); + if (genTOBuilder != null) { + returnType = new ReferencedTypeImpl(genTOBuilder.getPackageName(), genTOBuilder.getName()); + } + } else if (typeDef instanceof BitsTypeDefinition) { + GeneratedTOBuilder genTOBuilder = addTOToTypeBuilder(typeDef, typeBuilder, leafName, parentModule); + 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(DATA_OBJECT); + if (!(schemaNode instanceof GroupingDefinition)) { + builder.addImplementsType(augmentable(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) { + Preconditions.checkArgument(schemaNode != null,"Data Schema Node cannot be NULL."); + Preconditions.checkArgument(packageName != null,"Package Name for Generated Type cannot be NULL."); + Preconditions.checkArgument(schemaNode.getQName() != null,"QName for Data Schema Node cannot be NULL."); + final String schemaNodeName = schemaNode.getQName().getLocalName(); + Preconditions.checkArgument(schemaNodeName != null,"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,Type returnType) { + final StringBuilder method = new StringBuilder(); + if(BOOLEAN.equals(returnType)) { + method.append("is"); + } else { + 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,returnType)); + + 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) { + Preconditions.checkArgument(basePackageName != null,"Package Name for Generated Type cannot be NULL."); + Preconditions.checkArgument(list != null,"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) { + Preconditions.checkArgument(schemaNode != null,"Data Schema Node cannot be NULL."); + + Preconditions.checkArgument(typeBuilder != null,"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<>(); + Preconditions.checkArgument(typeBuilder != null,"Generated Type Builder cannot be NULL."); + + if (genTOBuilder != null) { + final GeneratedTransferObject genTO = genTOBuilder.toInstance(); + constructGetter(typeBuilder, "key", "Returns Primary Key of Yang List Type", genTO); + 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. + * + * If more then one generated TO builder is created for enclosing then all + * of the generated TO builders are added to typeBuilder as + * enclosing transfer objects. + * + * @param typeDef + * type definition which can be of type UnionType or + * BitsTypeDefinition + * @param typeBuilder + * generated type builder to which is added generated TO created + * from typeDef + * @param leafName + * string with name for generated TO builder + * @return generated TO builder for typeDef + */ + private GeneratedTOBuilder addTOToTypeBuilder(TypeDefinition typeDef, GeneratedTypeBuilder typeBuilder, + String leafName, Module parentModule) { + final String classNameFromLeaf = parseToClassName(leafName); + List genTOBuilders = new ArrayList<>(); + final String packageName = typeBuilder.getFullyQualifiedName(); + if (typeDef instanceof UnionTypeDefinition) { + genTOBuilders.addAll(((TypeProviderImpl) typeProvider).provideGeneratedTOBuildersForUnionTypeDef( + packageName, typeDef, classNameFromLeaf)); + } else if (typeDef instanceof BitsTypeDefinition) { + genTOBuilders.add(((TypeProviderImpl) typeProvider).provideGeneratedTOBuilderForBitsTypeDefinition( + packageName, typeDef, classNameFromLeaf)); + } + if (genTOBuilders != null && !genTOBuilders.isEmpty()) { + for (GeneratedTOBuilder genTOBuilder : genTOBuilders) { + typeBuilder.addEnclosingTransferObject(genTOBuilder); + } + return genTOBuilders.get(0); + } + return null; + + } + + /** + * Adds the implemented types to type builder. + * + * The method passes through the list of uses in + * {@code dataNodeContainer}. For every use is obtained coresponding + * generated type from {@link BindingGeneratorImpl#allGroupings + * allGroupings} which is 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/test/java/org/opendaylight/yangtools/sal/binding/generator/impl/ChoiceCaseGenTypesTest.java b/code-generator/binding-generator-impl/src/test/java/org/opendaylight/yangtools/sal/binding/generator/impl/ChoiceCaseGenTypesTest.java index 3f3bd0f1a0..28d818f89e 100644 --- a/code-generator/binding-generator-impl/src/test/java/org/opendaylight/yangtools/sal/binding/generator/impl/ChoiceCaseGenTypesTest.java +++ b/code-generator/binding-generator-impl/src/test/java/org/opendaylight/yangtools/sal/binding/generator/impl/ChoiceCaseGenTypesTest.java @@ -161,7 +161,7 @@ public class ChoiceCaseGenTypesTest { genType = checkGeneratedType(genTypes, "Bar", pcgPref + ".netconf.state.datastores.datastore.locks.lock.type.partial.lock.aug._case.by.choice"); // case - containsMethods(genType, new NameTypePattern("getBar", "Boolean")); + containsMethods(genType, new NameTypePattern("isBar", "Boolean")); containsInterface("AugCaseByChoice", genType); // augment "/nm:netconf-state/nm:datastores/nm:datastore" { diff --git a/code-generator/binding-generator-util/src/main/java/org/opendaylight/yangtools/binding/generator/util/generated/type/builder/AbstractTypeMember.java b/code-generator/binding-generator-util/src/main/java/org/opendaylight/yangtools/binding/generator/util/generated/type/builder/AbstractTypeMember.java index cf0a05c130..787dda84d9 100644 --- a/code-generator/binding-generator-util/src/main/java/org/opendaylight/yangtools/binding/generator/util/generated/type/builder/AbstractTypeMember.java +++ b/code-generator/binding-generator-util/src/main/java/org/opendaylight/yangtools/binding/generator/util/generated/type/builder/AbstractTypeMember.java @@ -1,138 +1,138 @@ -/* - * 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.generated.type.builder; - - -import org.opendaylight.yangtools.sal.binding.model.api.AccessModifier; -import org.opendaylight.yangtools.sal.binding.model.api.AnnotationType; -import org.opendaylight.yangtools.sal.binding.model.api.Type; -import org.opendaylight.yangtools.sal.binding.model.api.TypeMember; - -import java.util.Collections; -import java.util.List; - -abstract class AbstractTypeMember implements TypeMember { - - private final String name; - private final String comment; - private final Type definingType; - private final Type returnType; - private final List annotations; - private final boolean isFinal; - private final AccessModifier accessModifier; - - public AbstractTypeMember(final Type definingType, final String name, final List annotations, - final String comment, final AccessModifier accessModifier, final Type returnType, - boolean isFinal) { - super(); - this.definingType = definingType; - this.name = name; - this.annotations = Collections.unmodifiableList(annotations); - this.comment = comment; - this.accessModifier = accessModifier; - this.returnType = returnType; - this.isFinal = isFinal; - } - - @Override - public List getAnnotations() { - return annotations; - } - - @Override - public String getName() { - return name; - } - - @Override - public String getComment() { - return comment; - } - - @Override - public Type getDefiningType() { - return definingType; - } - - @Override - public AccessModifier getAccessModifier() { - return accessModifier; - } - - @Override - public Type getReturnType() { - return returnType; - } - - @Override - public boolean isFinal() { - return isFinal; - } - - @Override - public int hashCode() { - final int prime = 31; - int result = 1; - result = prime * result + ((getName() == null) ? 0 : getName().hashCode()); - result = prime * result - + ((getReturnType() == null) ? 0 : getReturnType().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; - } - MethodSignatureImpl other = (MethodSignatureImpl) obj; - if (getName() == null) { - if (other.getName() != null) { - return false; - } - } else if (!getName().equals(other.getName())) { - return false; - } - if (getReturnType() == null) { - if (other.getReturnType() != null) { - return false; - } - } else if (!getReturnType().equals(other.getReturnType())) { - return false; - } - return true; - } - - @Override - public String toString() { - StringBuilder builder = new StringBuilder(); - builder.append("MethodSignatureImpl [name="); - builder.append(getName()); - builder.append(", comment="); - builder.append(getComment()); - if (getDefiningType() != null) { - builder.append(", definingType="); - builder.append(getDefiningType().getPackageName()); - builder.append("."); - builder.append(getDefiningType().getName()); - } else { - builder.append(", definingType= null"); - } - builder.append(", returnType="); - builder.append(getReturnType()); - builder.append(", annotations="); - builder.append(getAnnotations()); - builder.append("]"); - return builder.toString(); - } -} +/* + * 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.generated.type.builder; + + +import org.opendaylight.yangtools.sal.binding.model.api.AccessModifier; +import org.opendaylight.yangtools.sal.binding.model.api.AnnotationType; +import org.opendaylight.yangtools.sal.binding.model.api.Type; +import org.opendaylight.yangtools.sal.binding.model.api.TypeMember; + +import java.util.Collections; +import java.util.List; + +abstract class AbstractTypeMember implements TypeMember { + + private final String name; + private final String comment; + private final Type definingType; + private final Type returnType; + private final List annotations; + private final boolean isFinal; + private final AccessModifier accessModifier; + + public AbstractTypeMember(final Type definingType, final String name, final List annotations, + final String comment, final AccessModifier accessModifier, final Type returnType, + boolean isFinal) { + super(); + this.definingType = definingType; + this.name = name; + this.annotations = Collections.unmodifiableList(annotations); + this.comment = comment; + this.accessModifier = accessModifier; + this.returnType = returnType; + this.isFinal = isFinal; + } + + @Override + public List getAnnotations() { + return annotations; + } + + @Override + public String getName() { + return name; + } + + @Override + public String getComment() { + return comment; + } + + @Override + public Type getDefiningType() { + return definingType; + } + + @Override + public AccessModifier getAccessModifier() { + return accessModifier; + } + + @Override + public Type getReturnType() { + return returnType; + } + + @Override + public boolean isFinal() { + return isFinal; + } + + @Override + public int hashCode() { + final int prime = 31; + int result = 1; + result = prime * result + ((getName() == null) ? 0 : getName().hashCode()); + result = prime * result + + ((getReturnType() == null) ? 0 : getReturnType().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; + } + AbstractTypeMember other = (AbstractTypeMember) obj; + if (getName() == null) { + if (other.getName() != null) { + return false; + } + } else if (!getName().equals(other.getName())) { + return false; + } + if (getReturnType() == null) { + if (other.getReturnType() != null) { + return false; + } + } else if (!getReturnType().equals(other.getReturnType())) { + return false; + } + return true; + } + + @Override + public String toString() { + StringBuilder builder = new StringBuilder(); + builder.append("MethodSignatureImpl [name="); + builder.append(getName()); + builder.append(", comment="); + builder.append(getComment()); + if (getDefiningType() != null) { + builder.append(", definingType="); + builder.append(getDefiningType().getPackageName()); + builder.append("."); + builder.append(getDefiningType().getName()); + } else { + builder.append(", definingType= null"); + } + builder.append(", returnType="); + builder.append(getReturnType()); + builder.append(", annotations="); + builder.append(getAnnotations()); + builder.append("]"); + return builder.toString(); + } +} 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 c258684065..5291f67c82 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 @@ -1,394 +1,433 @@ -/* - * 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.generated.type.builder; - -import static org.opendaylight.yangtools.binding.generator.util.BindingGeneratorUtil.parseToClassName; - -import java.util.ArrayList; -import java.util.Collections; -import java.util.List; - -import org.opendaylight.yangtools.binding.generator.util.AbstractBaseType; -import org.opendaylight.yangtools.sal.binding.model.api.AnnotationType; -import org.opendaylight.yangtools.sal.binding.model.api.Enumeration; -import org.opendaylight.yangtools.sal.binding.model.api.Type; -import org.opendaylight.yangtools.sal.binding.model.api.type.builder.AnnotationTypeBuilder; -import org.opendaylight.yangtools.sal.binding.model.api.type.builder.EnumBuilder; -import org.opendaylight.yangtools.yang.model.api.type.EnumTypeDefinition; -import org.opendaylight.yangtools.yang.model.api.type.EnumTypeDefinition.EnumPair; - -public final class EnumerationBuilderImpl extends AbstractBaseType implements EnumBuilder { - private final String packageName; - 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; - this.name = name; - values = new ArrayList<>(); - } - - @Override - public AnnotationTypeBuilder addAnnotation(final String packageName, final String name) { - if (packageName != null && name != null) { - final AnnotationTypeBuilder builder = new AnnotationTypeBuilderImpl(packageName, name); - if (annotationBuilders.add(builder)) { - return builder; - } - } - return null; - } - - @Override - public void addValue(final String name, final Integer value) { - values.add(new EnumPairImpl(name, value)); - } - - @Override - public Enumeration toInstance(final Type definingType) { - return new EnumerationImpl(definingType, annotationBuilders, packageName, name, values); - } - - /* - * (non-Javadoc) - * - * @see java.lang.Object#hashCode() - */ - @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; - } - - /* - * (non-Javadoc) - * - * @see java.lang.Object#equals(java.lang.Object) - */ - @Override - public boolean equals(Object obj) { - if (this == obj) { - return true; - } - if (obj == null) { - return false; - } - if (getClass() != obj.getClass()) { - return false; - } - EnumerationBuilderImpl other = (EnumerationBuilderImpl) obj; - if (name == null) { - if (other.name != null) { - return false; - } - } else if (!name.equals(other.name)) { - return false; - } - if (packageName == null) { - if (other.packageName != null) { - return false; - } - } else if (!packageName.equals(other.packageName)) { - return false; - } - return true; - } - - /* - * (non-Javadoc) - * - * @see java.lang.Object#toString() - */ - @Override - public String toString() { - StringBuilder builder = new StringBuilder(); - builder.append("EnumerationBuilderImpl [packageName="); - builder.append(packageName); - builder.append(", name="); - builder.append(name); - builder.append(", values="); - builder.append(values); - builder.append("]"); - return builder.toString(); - } - - @Override - public void updateEnumPairsFromEnumTypeDef(final EnumTypeDefinition enumTypeDef) { - 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; - } - this.addValue(enumPairName, enumPairValue); - listIndex++; - } - } - } - - } - - private static final class EnumPairImpl implements Enumeration.Pair { - - private final String name; - private final Integer value; - - public EnumPairImpl(String name, Integer value) { - super(); - this.name = name; - this.value = value; - } - - @Override - public String getName() { - return name; - } - - @Override - public Integer getValue() { - return value; - } - - /* - * (non-Javadoc) - * - * @see java.lang.Object#hashCode() - */ - @Override - public int hashCode() { - final int prime = 31; - int result = 1; - result = prime * result + ((name == null) ? 0 : name.hashCode()); - result = prime * result + ((value == null) ? 0 : value.hashCode()); - return result; - } - - /* - * (non-Javadoc) - * - * @see java.lang.Object#equals(java.lang.Object) - */ - @Override - public boolean equals(Object obj) { - if (this == obj) { - return true; - } - if (obj == null) { - return false; - } - if (getClass() != obj.getClass()) { - return false; - } - EnumPairImpl other = (EnumPairImpl) obj; - if (name == null) { - if (other.name != null) { - return false; - } - } else if (!name.equals(other.name)) { - return false; - } - if (value == null) { - if (other.value != null) { - return false; - } - } else if (!value.equals(other.value)) { - return false; - } - return true; - } - - /* - * (non-Javadoc) - * - * @see java.lang.Object#toString() - */ - @Override - public String toString() { - StringBuilder builder = new StringBuilder(); - builder.append("EnumPair [name="); - builder.append(name); - builder.append(", value="); - builder.append(value); - builder.append("]"); - return builder.toString(); - } - } - - private static final class EnumerationImpl implements Enumeration { - - private final Type definingType; - private final String packageName; - 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) { - super(); - this.definingType = definingType; - for (final AnnotationTypeBuilder builder : annotationBuilders) { - annotations.add(builder.toInstance()); - } - this.annotations = Collections.unmodifiableList(annotations); - this.packageName = packageName; - this.name = name; - this.values = Collections.unmodifiableList(values); - } - - @Override - public Type getDefiningType() { - return definingType; - } - - @Override - public String getPackageName() { - return packageName; - } - - @Override - public String getName() { - return name; - } - - @Override - public String getFullyQualifiedName() { - return packageName + "." + name; - } - - @Override - public List getValues() { - return values; - } - - @Override - public List getAnnotations() { - return annotations; - } - - @Override - public String toFormattedString() { - StringBuilder builder = new StringBuilder(); - builder.append("public enum"); - builder.append(" "); - builder.append(name); - builder.append(" {"); - builder.append("\n"); - - int i = 0; - for (final Enumeration.Pair valPair : values) { - builder.append("\t"); - builder.append(" "); - builder.append(valPair.getName()); - builder.append(" ("); - builder.append(valPair.getValue()); - - if (i == (values.size() - 1)) { - builder.append(" );"); - } else { - builder.append(" ),"); - } - ++i; - } - builder.append("\n}"); - return builder.toString(); - } - - /* - * (non-Javadoc) - * - * @see java.lang.Object#hashCode() - */ - @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()); - result = prime * result + ((values == null) ? 0 : values.hashCode()); - - return result; - } - - /* - * (non-Javadoc) - * - * @see java.lang.Object#equals(java.lang.Object) - */ - @Override - public boolean equals(Object obj) { - if (this == obj) { - return true; - } - if (obj == null) { - return false; - } - if (getClass() != obj.getClass()) { - return false; - } - EnumerationImpl other = (EnumerationImpl) obj; - if (name == null) { - if (other.name != null) { - return false; - } - } else if (!name.equals(other.name)) { - return false; - } - if (packageName == null) { - if (other.packageName != null) { - return false; - } - } else if (!packageName.equals(other.packageName)) { - return false; - } - if (values == null) { - if (other.values != null) { - return false; - } - } else if (!values.equals(other.values)) { - return false; - } - return true; - } - - /* - * (non-Javadoc) - * - * @see java.lang.Object#toString() - */ - @Override - public String toString() { - StringBuilder builder = new StringBuilder(); - builder.append("Enumeration [packageName="); - builder.append(packageName); - if (definingType != null) { - builder.append(", definingType="); - builder.append(definingType.getPackageName()); - builder.append("."); - builder.append(definingType.getName()); - } else { - builder.append(", definingType= null"); - } - builder.append(", name="); - builder.append(name); - builder.append(", values="); - builder.append(values); - builder.append("]"); - return builder.toString(); - } - } -} +/* + * 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.generated.type.builder; + +import static org.opendaylight.yangtools.binding.generator.util.BindingGeneratorUtil.parseToClassName; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; + +import org.opendaylight.yangtools.binding.generator.util.AbstractBaseType; +import org.opendaylight.yangtools.sal.binding.model.api.AnnotationType; +import org.opendaylight.yangtools.sal.binding.model.api.Constant; +import org.opendaylight.yangtools.sal.binding.model.api.Enumeration; +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 org.opendaylight.yangtools.sal.binding.model.api.type.builder.AnnotationTypeBuilder; +import org.opendaylight.yangtools.sal.binding.model.api.type.builder.EnumBuilder; +import org.opendaylight.yangtools.yang.model.api.type.EnumTypeDefinition; +import org.opendaylight.yangtools.yang.model.api.type.EnumTypeDefinition.EnumPair; + +public final class EnumerationBuilderImpl extends AbstractBaseType implements EnumBuilder { + private final String packageName; + 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; + this.name = name; + values = new ArrayList<>(); + } + + @Override + public AnnotationTypeBuilder addAnnotation(final String packageName, final String name) { + if (packageName != null && name != null) { + final AnnotationTypeBuilder builder = new AnnotationTypeBuilderImpl(packageName, name); + if (annotationBuilders.add(builder)) { + return builder; + } + } + return null; + } + + @Override + public void addValue(final String name, final Integer value) { + values.add(new EnumPairImpl(name, value)); + } + + @Override + public Enumeration toInstance(final Type definingType) { + return new EnumerationImpl(definingType, annotationBuilders, packageName, name, values); + } + + /* + * (non-Javadoc) + * + * @see java.lang.Object#hashCode() + */ + @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; + } + + /* + * (non-Javadoc) + * + * @see java.lang.Object#equals(java.lang.Object) + */ + @Override + public boolean equals(Object obj) { + if (this == obj) { + return true; + } + if (obj == null) { + return false; + } + if (getClass() != obj.getClass()) { + return false; + } + EnumerationBuilderImpl other = (EnumerationBuilderImpl) obj; + if (name == null) { + if (other.name != null) { + return false; + } + } else if (!name.equals(other.name)) { + return false; + } + if (packageName == null) { + if (other.packageName != null) { + return false; + } + } else if (!packageName.equals(other.packageName)) { + return false; + } + return true; + } + + /* + * (non-Javadoc) + * + * @see java.lang.Object#toString() + */ + @Override + public String toString() { + StringBuilder builder = new StringBuilder(); + builder.append("EnumerationBuilderImpl [packageName="); + builder.append(packageName); + builder.append(", name="); + builder.append(name); + builder.append(", values="); + builder.append(values); + builder.append("]"); + return builder.toString(); + } + + @Override + public void updateEnumPairsFromEnumTypeDef(final EnumTypeDefinition enumTypeDef) { + 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; + } + this.addValue(enumPairName, enumPairValue); + listIndex++; + } + } + } + + } + + private static final class EnumPairImpl implements Enumeration.Pair { + + private final String name; + private final Integer value; + + public EnumPairImpl(String name, Integer value) { + super(); + this.name = name; + this.value = value; + } + + @Override + public String getName() { + return name; + } + + @Override + public Integer getValue() { + return value; + } + + /* + * (non-Javadoc) + * + * @see java.lang.Object#hashCode() + */ + @Override + public int hashCode() { + final int prime = 31; + int result = 1; + result = prime * result + ((name == null) ? 0 : name.hashCode()); + result = prime * result + ((value == null) ? 0 : value.hashCode()); + return result; + } + + /* + * (non-Javadoc) + * + * @see java.lang.Object#equals(java.lang.Object) + */ + @Override + public boolean equals(Object obj) { + if (this == obj) { + return true; + } + if (obj == null) { + return false; + } + if (getClass() != obj.getClass()) { + return false; + } + EnumPairImpl other = (EnumPairImpl) obj; + if (name == null) { + if (other.name != null) { + return false; + } + } else if (!name.equals(other.name)) { + return false; + } + if (value == null) { + if (other.value != null) { + return false; + } + } else if (!value.equals(other.value)) { + return false; + } + return true; + } + + /* + * (non-Javadoc) + * + * @see java.lang.Object#toString() + */ + @Override + public String toString() { + StringBuilder builder = new StringBuilder(); + builder.append("EnumPair [name="); + builder.append(name); + builder.append(", value="); + builder.append(value); + builder.append("]"); + return builder.toString(); + } + } + + private static final class EnumerationImpl implements Enumeration { + + private final Type definingType; + private final String packageName; + 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) { + super(); + this.definingType = definingType; + for (final AnnotationTypeBuilder builder : annotationBuilders) { + annotations.add(builder.toInstance()); + } + this.annotations = Collections.unmodifiableList(annotations); + this.packageName = packageName; + this.name = name; + this.values = Collections.unmodifiableList(values); + } + + @Override + public Type getParentType() { + return definingType; + } + + @Override + public String getPackageName() { + return packageName; + } + + @Override + public String getName() { + return name; + } + + @Override + public String getFullyQualifiedName() { + return packageName + "." + name; + } + + @Override + public List getValues() { + return values; + } + + @Override + public List getAnnotations() { + return annotations; + } + + @Override + public String toFormattedString() { + StringBuilder builder = new StringBuilder(); + builder.append("public enum"); + builder.append(" "); + builder.append(name); + builder.append(" {"); + builder.append("\n"); + + int i = 0; + for (final Enumeration.Pair valPair : values) { + builder.append("\t"); + builder.append(" "); + builder.append(valPair.getName()); + builder.append(" ("); + builder.append(valPair.getValue()); + + if (i == (values.size() - 1)) { + builder.append(" );"); + } else { + builder.append(" ),"); + } + ++i; + } + builder.append("\n}"); + return builder.toString(); + } + + /* + * (non-Javadoc) + * + * @see java.lang.Object#hashCode() + */ + @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()); + result = prime * result + ((values == null) ? 0 : values.hashCode()); + + return result; + } + + /* + * (non-Javadoc) + * + * @see java.lang.Object#equals(java.lang.Object) + */ + @Override + public boolean equals(Object obj) { + if (this == obj) { + return true; + } + if (obj == null) { + return false; + } + if (getClass() != obj.getClass()) { + return false; + } + EnumerationImpl other = (EnumerationImpl) obj; + if (name == null) { + if (other.name != null) { + return false; + } + } else if (!name.equals(other.name)) { + return false; + } + if (packageName == null) { + if (other.packageName != null) { + return false; + } + } else if (!packageName.equals(other.packageName)) { + return false; + } + if (values == null) { + if (other.values != null) { + return false; + } + } else if (!values.equals(other.values)) { + return false; + } + return true; + } + + /* + * (non-Javadoc) + * + * @see java.lang.Object#toString() + */ + @Override + public String toString() { + StringBuilder builder = new StringBuilder(); + builder.append("Enumeration [packageName="); + builder.append(packageName); + if (definingType != null) { + builder.append(", definingType="); + builder.append(definingType.getPackageName()); + builder.append("."); + builder.append(definingType.getName()); + } else { + builder.append(", definingType= null"); + } + builder.append(", name="); + builder.append(name); + builder.append(", values="); + builder.append(values); + builder.append("]"); + return builder.toString(); + } + + @Override + public String getComment() { + return null; + } + + @Override + public boolean isAbstract() { + return false; + } + + @Override + public List getImplements() { + return Collections.emptyList(); + } + + @Override + public List getEnclosedTypes() { + return Collections.emptyList(); + } + + @Override + public List getEnumerations() { + return Collections.emptyList(); + } + + @Override + public List getConstantDefinitions() { + return Collections.emptyList(); + } + + @Override + public List getMethodDefinitions() { + // TODO Auto-generated method stub + return Collections.emptyList(); + } + } +} diff --git a/code-generator/binding-java-api-generator/pom.xml b/code-generator/binding-java-api-generator/pom.xml index 818c8b7b2f..eb56ff1826 100644 --- a/code-generator/binding-java-api-generator/pom.xml +++ b/code-generator/binding-java-api-generator/pom.xml @@ -67,6 +67,10 @@ org.eclipse.xtend.lib 2.4.2 + + com.google.guava + guava + diff --git a/code-generator/binding-java-api-generator/src/main/java/org/opendaylight/yangtools/sal/java/api/generator/BaseTemplate.xtend b/code-generator/binding-java-api-generator/src/main/java/org/opendaylight/yangtools/sal/java/api/generator/BaseTemplate.xtend new file mode 100644 index 0000000000..2cbe0e6df5 --- /dev/null +++ b/code-generator/binding-java-api-generator/src/main/java/org/opendaylight/yangtools/sal/java/api/generator/BaseTemplate.xtend @@ -0,0 +1,110 @@ +package org.opendaylight.yangtools.sal.java.api.generator + +import org.opendaylight.yangtools.sal.binding.model.api.GeneratedProperty +import org.opendaylight.yangtools.sal.binding.model.api.GeneratedType +import java.util.Map +import org.opendaylight.yangtools.sal.binding.model.api.Type +import org.opendaylight.yangtools.binding.generator.util.Types + +abstract class BaseTemplate { + + + protected val GeneratedType type; + protected val Map importMap; + + new(GeneratedType _type) { + if (_type== null) { + throw new IllegalArgumentException("Generated type reference cannot be NULL!") + } + this.type = _type; + this.importMap = GeneratorUtil.createImports(type) + } + + def packageDefinition () '''package «type.packageName»;''' + + + final public def generate() { + val _body = body() + ''' + «packageDefinition» + «imports» + + «_body» + '''.toString + } + protected def imports() ''' + «IF !importMap.empty» + «FOR entry : importMap.entrySet» + import «entry.value».«entry.key»; + «ENDFOR» + «ENDIF» + + ''' + + protected abstract def CharSequence body(); + + // Helper patterns + + final protected def fieldName(GeneratedProperty property) '''_«property.name»''' + + /** + * 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 + */ + final protected def getterMethod(GeneratedProperty field) { + val prefix = if(field.returnType.equals(Types.BOOLEAN)) "is" else "get" + ''' + public «field.returnType.importedName» «prefix»«field.name.toFirstUpper»() { + return «field.fieldName»; + } + ''' + } + + /** + * 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 + */ + final protected def setterMethod(GeneratedProperty field) ''' + «val returnType = field.returnType.importedName» + public «type.name» set«field.name.toFirstUpper»(«returnType» value) { + this.«field.fieldName» = value; + return this; + } + ''' + + final protected def importedName(Type intype) { + GeneratorUtil.putTypeIntoImports(type, intype, importMap); + GeneratorUtil.getExplicitType(type, intype, importMap) + } + + final protected def importedName(Class cls) { + importedName(Types.typeForClass(cls)) + } + + /** + * 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 final protected asArgumentsDeclaration(Iterable parameters) + '''«IF !parameters.empty»«FOR parameter : parameters SEPARATOR ", "»«parameter.returnType.importedName» «parameter.fieldName»«ENDFOR»«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 final protected asArguments(Iterable parameters) + '''«IF !parameters.empty»«FOR parameter : parameters SEPARATOR ", "»«parameter.fieldName»«ENDFOR»«ENDIF»''' + +} \ No newline at end of file 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 5f842a29ff..1aef46dd20 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 @@ -1,387 +1,330 @@ -package org.opendaylight.yangtools.sal.java.api.generator - -import java.util.LinkedHashSet -import java.util.List -import java.util.Map -import java.util.Set -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.sal.binding.model.api.GeneratedProperty -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.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!") - } - - this.genType = genType - this.imports = GeneratorUtil.createChildImports(genType) - 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) - storeMethodsOfImplementedIfcs(methods, genType.implements) - 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 - } - for (implementedIfc : implementedIfcs) { - if ((implementedIfc instanceof GeneratedType && !(implementedIfc instanceof GeneratedTransferObject))) { - val ifc = implementedIfc as GeneratedType - methods.addAll(ifc.methodDefinitions) - storeMethodsOfImplementedIfcs(methods, ifc.implements) - } else if (implementedIfc.fullyQualifiedName == Augmentable.name) { - for (m : Augmentable.methods) { - if (m.name == GET_AUGMENTATION_METHOD_NAME) { - addToImports(JAVA_UTIL, HASH_MAP) - addToImports(JAVA_UTIL, MAP) - val fullyQualifiedName = m.returnType.name - val pkg = fullyQualifiedName.package - val name = fullyQualifiedName.name - addToImports(pkg, name) - val tmpGenTO = new GeneratedTOBuilderImpl(pkg, name) - val type = new ReferencedTypeImpl(pkg, name) - val generic = new ReferencedTypeImpl(genType.packageName, genType.name) - val parametrizedReturnType = Types.parameterizedTypeFor(type, generic) - tmpGenTO.addMethod(m.name).setReturnType(parametrizedReturnType) - augmentField = tmpGenTO.toInstance.methodDefinitions.first.createFieldFromGetter - } - } - } - } - } - - /** - * 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 - } - if (!imports.containsKey(typeName)) { - imports.put(typeName, typePackageName) - } - } - - /** - * 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 - - if (methods == null || methods.isEmpty()) { - return result - } - - for (m : methods) { - val createdField = m.createFieldFromGetter - if (createdField != null) { - result.add(createdField) - } - } - 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!") - } - if (method.name.startsWith(GET_PREFIX)) { - val fieldName = method.getName().substring(GET_PREFIX.length()).toFirstLower - val tmpGenTO = new GeneratedTOBuilderImpl("foo", "foo") - tmpGenTO.addProperty(fieldName).setReturnType(method.returnType) - return tmpGenTO.toInstance.properties.first - } - } - - /** - * 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» { - - «generateFields(false)» - - «generateSetters» - - public «genType.name» build() { - return new «genType.name»«IMPL»(); - } - - private class «genType.name»«IMPL» implements «genType.name» { - - «generateFields(true)» - - «generateConstructor» - - «generateGetters» - - } - - } - ''' - - /** - * 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» - private «IF _final»final«ENDIF» «f.returnType.resolveName» «f.name»; - «ENDFOR» - «ENDIF» - «IF augmentField != null» - private Map, «augmentField.returnType.resolveName»> «augmentField.name» = new HashMap<>(); - «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») { - this.«field.name» = «field.name»; - return this; - } - «ENDFOR» - «IF augmentField != null» - - public «genType.name»«BUILDER» add«augmentField.name.toFirstUpper»(Class augmentationType, «augmentField.returnType.resolveName» augmentation) { - this.«augmentField.name».put(augmentationType, augmentation); - return this; - } - «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» - «FOR field : fields» - this.«field.name» = «genType.name»«BUILDER».this.«field.name»; - «ENDFOR» - «ENDIF» - «IF augmentField != null» - this.«augmentField.name».putAll(«genType.name»«BUILDER».this.«augmentField.name»); - «ENDIF» - } - ''' - - /** - * 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'» - @Override - public «field.returnType.resolveName» get«field.name.toFirstUpper»() { - return «field.name»; - } - «ENDFOR» - «ENDIF» - «IF augmentField != null» - - @SuppressWarnings("unchecked") - @Override - public E get«augmentField.name.toFirstUpper»(Class augmentationType) { - if (augmentationType == null) { - throw new IllegalArgumentException("Augmentation Type reference cannot be NULL!"); - } - return (E) «augmentField.name».get(augmentationType); - } - «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»; - - - «IF !imports.empty» - «FOR entry : imports.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) - } - -} - +package org.opendaylight.yangtools.sal.java.api.generator + +import java.util.LinkedHashSet +import java.util.List +import java.util.Map +import java.util.Set +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.sal.binding.model.api.GeneratedProperty +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.MethodSignature +import org.opendaylight.yangtools.sal.binding.model.api.Type +import org.opendaylight.yangtools.yang.binding.Augmentable +import static org.opendaylight.yangtools.binding.generator.util.Types.* +import java.util.HashMap +import java.util.Collections + +/** + * Template for generating JAVA builder classes. + */ + +class BuilderTemplate extends BaseTemplate { + /** + * 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' + + /** + * 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 properties + + /** + * Constructs new instance of this class. + * @throws IllegalArgumentException if genType equals null + */ + new(GeneratedType genType) { + super(genType) + this.properties = propertiesFromMethods(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(type.methodDefinitions) + collectImplementedMethods(methods, type.implements) + 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 collectImplementedMethods(Set methods, List implementedIfcs) { + if (implementedIfcs == null || implementedIfcs.empty) { + return + } + for (implementedIfc : implementedIfcs) { + if ((implementedIfc instanceof GeneratedType && !(implementedIfc instanceof GeneratedTransferObject))) { + val ifc = implementedIfc as GeneratedType + methods.addAll(ifc.methodDefinitions) + collectImplementedMethods(methods, ifc.implements) + } else if (implementedIfc.fullyQualifiedName == Augmentable.name) { + for (m : Augmentable.methods) { + if (m.name == GET_AUGMENTATION_METHOD_NAME) { + //addToImports(JAVA_UTIL, HASH_MAP) + //addToImports(JAVA_UTIL, MAP) + val fullyQualifiedName = m.returnType.name + val pkg = fullyQualifiedName.package + val name = fullyQualifiedName.name + //addToImports(pkg, name) + val tmpGenTO = new GeneratedTOBuilderImpl(pkg, name) + val refType = new ReferencedTypeImpl(pkg, name) + val generic = new ReferencedTypeImpl(type.packageName, type.name) + val parametrizedReturnType = Types.parameterizedTypeFor(refType, generic) + tmpGenTO.addMethod(m.name).setReturnType(parametrizedReturnType) + augmentField = tmpGenTO.toInstance.methodDefinitions.first.propertyFromGetter + } + } + } + } + } + + + /** + * 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 propertiesFromMethods(Set methods) { + + + if (methods == null || methods.isEmpty()) { + return Collections.emptySet + } + val Set result = new LinkedHashSet + for (m : methods) { + val createdField = m.propertyFromGetter + if (createdField != null) { + result.add(createdField) + } + } + 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 propertyFromGetter(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!") + } + var prefix = "get"; + if(BOOLEAN.equals(method.returnType)) { + prefix = "is"; + } + if (method.name.startsWith(prefix)) { + val fieldName = method.getName().substring(prefix.length()).toFirstLower + val tmpGenTO = new GeneratedTOBuilderImpl("foo", "foo") + tmpGenTO.addProperty(fieldName).setReturnType(method.returnType) + return tmpGenTO.toInstance.properties.first + } + } + + /** + * Template method which generates JAVA class body for builder class and for IMPL class. + * + * @return string with JAVA source code + */ + override body() ''' + + public class «type.name»«BUILDER» { + + «generateFields(false)» + + «generateGetters(false)» + + «generateSetters» + + + public «type.name» build() { + return new «type.name»«IMPL»(this); + } + + private static class «type.name»«IMPL» implements «type.name» { + + «generateFields(true)» + + «generateConstructor» + + «generateGetters(true)» + + } + + } + ''' + + /** + * 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 !properties.empty» + «FOR f : properties» + private «IF _final»final«ENDIF» «f.returnType.importedName» «f.fieldName»; + «ENDFOR» + «ENDIF» + «IF augmentField != null» + private «Map.importedName», «augmentField.returnType.importedName»> «augmentField.name» = new «HashMap.importedName»<>(); + «ENDIF» + ''' + + /** + * Template method which generates setter methods + * + * @return string with the setter methods + */ + def private generateSetters() ''' + «FOR field : properties SEPARATOR '\n'» + public «type.name»«BUILDER» set«field.name.toFirstUpper»(«field.returnType.importedName» value) { + this.«field.fieldName» = value; + return this; + } + «ENDFOR» + «IF augmentField != null» + + public «type.name»«BUILDER» add«augmentField.name.toFirstUpper»(Class augmentationType, «augmentField.returnType.importedName» augmentation) { + this.«augmentField.name».put(augmentationType, augmentation); + return this; + } + «ENDIF» + ''' + + /** + * Template method which generate constructor for IMPL class. + * + * @return string with IMPL class constructor + */ + def private generateConstructor() ''' + private «type.name»«IMPL»(«type.name»«BUILDER» builder) { + «IF !properties.empty» + «FOR field : properties» + this.«field.fieldName» = builder.«field.fieldName»; + «ENDFOR» + «ENDIF» + «IF augmentField != null» + this.«augmentField.name».putAll(builder.«augmentField.name»); + «ENDIF» + } + ''' + + + /** + * Template method which generate getter methods for IMPL class. + * + * @return string with getter methods + */ + def private generateGetters(boolean addOverride) ''' + «IF !properties.empty» + «FOR field : properties SEPARATOR '\n'» + «IF addOverride»@Override«ENDIF» + «field.getterMethod» + «ENDFOR» + «ENDIF» + «IF augmentField != null» + + @SuppressWarnings("unchecked") + «IF addOverride»@Override«ENDIF» + public E get«augmentField.name.toFirstUpper»(Class augmentationType) { + if (augmentationType == null) { + throw new IllegalArgumentException("Augmentation Type reference cannot be NULL!"); + } + return (E) «augmentField.name».get(augmentationType); + } + «ENDIF» + ''' +} + 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 44263a526e..ed1e97bc23 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 @@ -1,460 +1,369 @@ -package org.opendaylight.yangtools.sal.java.api.generator - -import java.util.List -import java.util.Map -import org.opendaylight.yangtools.binding.generator.util.TypeConstants -import org.opendaylight.yangtools.sal.binding.model.api.Constant -import org.opendaylight.yangtools.sal.binding.model.api.Enumeration -import org.opendaylight.yangtools.sal.binding.model.api.GeneratedProperty -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 -import org.opendaylight.yangtools.sal.binding.model.api.GeneratedType - -/** - * 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 - - /** - * List of generated types which are enclosed inside genType - */ - val List enclosedGeneratedTypes; - - /** - * 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!") - } - - this.genTO = genTO - this.imports = GeneratorUtil.createImports(genTO) - this.fields = genTO.properties - this.enums = genTO.enumerations - this.consts = genTO.constantDefinitions - this.enclosedGeneratedTypes = genTO.enclosedTypes - } - - /** - * 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)» { - «generateInnerClasses» - - «generateEnums» - - «generateConstants» - - «generateFields» - - «generateConstructor» - - «FOR field : fields SEPARATOR "\n"» - «field.generateGetter» - «IF !field.readOnly» - - «field.generateSetter» - «ENDIF» - «ENDFOR» - - «generateHashCode» - - «generateEquals» - - «generateToString» - - } - ''' - - - /** - * 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"» - «IF (innerClass instanceof GeneratedTransferObject)» - «val classTemplate = new ClassTemplate(innerClass as GeneratedTransferObject)» - «classTemplate.generateAsInnerClass» - - «ENDIF» - «ENDFOR» - «ENDIF» - ''' - - /** - * 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» - /* - «comment» - */ - «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)»« - " static final "»« - ELSEIF (genTO.abstract)»« - " abstract "»« - ELSE»« - " "»« - ENDIF»class «genTO.name»« - IF (genTO.extends != null)»« - " extends "»«genTO.extends.resolveName»« - ENDIF»« - IF (!genTO.implements.empty)»« - " implements "»« - FOR type : genTO.implements SEPARATOR ", "»« - type.resolveName»« - 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"» - «val enumTemplate = new EnumTemplate(e)» - «enumTemplate.generateAsInnerClass» - «ENDFOR» - «ENDIF» - ''' - - /** - * Template method wich generates JAVA constants. - * - * @return string with constants in JAVA format - */ - def private generateConstants() ''' - «IF !consts.empty» - «FOR c : consts» - «IF c.name == TypeConstants.PATTERN_CONSTANT_NAME» - «val cValue = c.value» - «IF cValue instanceof List» - «val cValues = cValue as List» - private static final List «Constants.MEMBER_PATTERN_LIST» = new ArrayList(); - public static final List «TypeConstants.PATTERN_CONSTANT_NAME» = Arrays.asList(« - FOR v : cValues SEPARATOR ", "»« - IF v instanceof String»"« - v as String»"« - ENDIF»« - ENDFOR»); - - «generateStaticInicializationBlock» - «ENDIF» - «ELSE» - public static final «c.type.resolveName» «c.name» = «c.value»; - «ENDIF» - «ENDFOR» - «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») { - «Constants.MEMBER_PATTERN_LIST».add(Pattern.compile(regEx)); - } - } - ''' - - /** - * 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» - private «f.returnType.resolveName» «f.fieldName»; - «ENDFOR» - «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)» - «val propertiesAllParents = GeneratorUtil.getPropertiesOfAllParents(genTO)» - «IF !genTO.unionType» -««« create constructor for every parent property - «IF genTOTopParent != genTO && genTOTopParent.unionType» - «FOR parentProperty : propertiesAllParents SEPARATOR "\n"» - «val parentPropertyAndProperties = properties + #[parentProperty]» - «if (genTO.abstract) "protected" else "public"» «genTO.name»(«parentPropertyAndProperties.generateParameters») { - super(«#[parentProperty].generateParameterNames»); - «FOR property : properties» - this.«property.fieldName» = «property.name»; - «ENDFOR» - } - «ENDFOR» -««« create one constructor - «ELSE» - «val propertiesAll = propertiesAllParents + properties» - «if (genTO.abstract) "protected" else "public"» «genTO.name»(«propertiesAll.generateParameters») { - super(«propertiesAllParents.generateParameterNames()»); - «FOR property : properties» - this.«property.fieldName» = «property.fieldName»; - «ENDFOR» - } - «ENDIF» -««« create constructor for every property - «ELSE» - «FOR property : properties SEPARATOR "\n"» - «val propertyAndTopParentProperties = propertiesAllParents + #[property]» - «if (genTO.abstract) "protected" else "public"» «genTO.name»(«propertyAndTopParentProperties.generateParameters») { - super(«propertiesAllParents.generateParameterNames()»); - this.«property.fieldName» = «property.fieldName»; - } - «ENDFOR» - «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»; - - } - ''' - } - /** - * 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 ", "»« - parameter.returnType.resolveName» «parameter.fieldName»« - ENDFOR»« - 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 ", "»« - parameter.fieldName»« - ENDFOR»« - 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 - public int hashCode() { - final int prime = 31; - int result = 1; - «FOR property : genTO.hashCodeIdentifiers» - result = prime * result + ((«property.fieldName» == null) ? 0 : «property.fieldName».hashCode()); - «ENDFOR» - return result; - } - «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 - public boolean equals(java.lang.Object obj) { - if (this == obj) { - return true; - } - if (obj == null) { - return false; - } - if (getClass() != obj.getClass()) { - return false; - } - «genTO.name» other = («genTO.name») obj; - «FOR property : genTO.equalsIdentifiers» - «val fieldName = property.fieldName» - if («fieldName» == null) { - if (other.«fieldName» != null) { - return false; - } - } else if(!«fieldName».equals(other.«fieldName»)) { - return false; - } - «ENDFOR» - return true; - } - «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 - public String toString() { - StringBuilder builder = new StringBuilder(); - «val properties = genTO.toStringIdentifiers» - builder.append("«genTO.name» [«properties.get(0).fieldName»="); - builder.append(«properties.get(0).fieldName»); - «FOR i : 1..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) - } - - def private fieldName(GeneratedProperty property) { - '''_«property.name»''' - } -} +package org.opendaylight.yangtools.sal.java.api.generator + +import java.util.List +import java.util.Map +import org.opendaylight.yangtools.binding.generator.util.TypeConstants +import org.opendaylight.yangtools.sal.binding.model.api.Constant +import org.opendaylight.yangtools.sal.binding.model.api.Enumeration +import org.opendaylight.yangtools.sal.binding.model.api.GeneratedProperty +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 +import org.opendaylight.yangtools.sal.binding.model.api.GeneratedType + + +/** + * Template for generating JAVA class. + */ +class ClassTemplate extends BaseTemplate { + + protected val List properties + protected val List finalProperties + protected val List parentProperties + protected val Iterable allProperties; + + /** + * List of enumeration which are generated as JAVA enum type. + */ + protected val List enums + + /** + * List of constant instances which are generated as JAVA public static final attributes. + */ + protected val List consts + + /** + * List of generated types which are enclosed inside genType + */ + protected val List enclosedGeneratedTypes; + + + protected val GeneratedTransferObject genTO; + + /** + * Creates instance of this class with concrete genType. + * + * @param genType generated transfer object which will be transformed to JAVA class source code + */ + new(GeneratedTransferObject genType) { + super(genType) + this.genTO = genType + this.properties = genType.properties + this.finalProperties = GeneratorUtil.resolveReadOnlyPropertiesFromTO(genTO.properties) + this.parentProperties = GeneratorUtil.getPropertiesOfAllParents(genTO) + this.allProperties = properties + parentProperties + this.enums = genType.enumerations + this.consts = genType.constantDefinitions + this.enclosedGeneratedTypes = genType.enclosedTypes + } + + + + + + /** + * Generates JAVA class source code (class body only). + * + * @return string with JAVA class body source code + */ + def generateAsInnerClass() { + return generateBody(true) + } + + + + override protected body() { + generateBody(false); + } + + /** + * 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 protected generateBody(boolean isInnerClass) ''' + «type.comment.generateComment» + «generateClassDeclaration(isInnerClass)» { + «innerClassesDeclarations» + + «enumDeclarations» + + «constantsDeclarations» + + «generateFields» + + «constructors» + + «FOR field : properties SEPARATOR "\n"» + «field.getterMethod» + «IF !field.readOnly» + + «field.setterMethod» + «ENDIF» + «ENDFOR» + + «generateHashCode» + + «generateEquals» + + «generateToString» + + } + ''' + + + /** + * Template method which generates inner classes inside this interface. + * + * @return string with the source code for inner classes in JAVA format + */ + def protected innerClassesDeclarations() ''' + «IF !enclosedGeneratedTypes.empty» + «FOR innerClass : enclosedGeneratedTypes SEPARATOR "\n"» + «IF (innerClass instanceof GeneratedTransferObject)» + «val classTemplate = new ClassTemplate(innerClass as GeneratedTransferObject)» + «classTemplate.generateAsInnerClass» + + «ENDIF» + «ENDFOR» + «ENDIF» + ''' + + + def protected constructors() ''' + «allValuesConstructor» + «IF !allProperties.empty» + «copyConstructor» + «ENDIF» + «IF properties.empty && !parentProperties.empty » + «parentConstructor» + «ENDIF» + ''' + + def protected allValuesConstructor() ''' + public «type.name»(«allProperties.asArgumentsDeclaration») { + «IF false == parentProperties.empty» + super(«parentProperties.asArguments»); + «ENDIF» + «FOR p : properties» + this.«p.fieldName» = «p.fieldName»; + «ENDFOR» + } + ''' + + + def protected copyConstructor() ''' + /** + * Creates a copy from Source Object. + * + * @param source Source object + */ + public «type.name»(«type.name» source) { + «IF false == parentProperties.empty» + super(source); + «ENDIF» + «FOR p : properties» + this.«p.fieldName» = source.«p.fieldName»; + «ENDFOR» + } + ''' + + def protected parentConstructor() ''' + /** + * Creates a new instance from «genTO.extends.importedName» + * + * @param source Source object + */ + public «type.name»(«genTO.extends.importedName» source) { + super(source); + } + ''' + + /** + * Template method which generates JAVA comments. + * + * @param string with the comment for whole JAVA class + * @return string with comment in JAVA format + */ + def protected generateComment(String comment) ''' + «IF comment != null && !comment.empty» + /** + «comment» + **/ + «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 protected generateClassDeclaration(boolean isInnerClass) ''' + public« + IF (isInnerClass)»« + " static final "»« + ELSEIF (type.abstract)»« + " abstract "»« + ELSE»« + " "»« + ENDIF»class «type.name»« + IF (genTO.extends != null)»« + " extends "»«genTO.extends.importedName»« + ENDIF»« + IF (!type.implements.empty)»« + " implements "»« + FOR type : type.implements SEPARATOR ", "»« + type.importedName»« + ENDFOR»« + ENDIF + »''' + + /** + * Template method which generates JAVA enum type. + * + * @return string with inner enum source code in JAVA format + */ + def protected enumDeclarations() ''' + «IF !enums.empty» + «FOR e : enums SEPARATOR "\n"» + «val enumTemplate = new EnumTemplate(e)» + «enumTemplate.generateAsInnerClass» + «ENDFOR» + «ENDIF» + ''' + + /** + * Template method wich generates JAVA constants. + * + * @return string with constants in JAVA format + */ + def protected constantsDeclarations() ''' + «IF !consts.empty» + «FOR c : consts» + «IF c.name == TypeConstants.PATTERN_CONSTANT_NAME» + «val cValue = c.value» + «IF cValue instanceof List» + «val cValues = cValue as List» + private static final List «Constants.MEMBER_PATTERN_LIST» = new ArrayList(); + public static final List «TypeConstants.PATTERN_CONSTANT_NAME» = Arrays.asList(« + FOR v : cValues SEPARATOR ", "»« + IF v instanceof String»"« + v as String»"« + ENDIF»« + ENDFOR»); + + «generateStaticInicializationBlock» + «ENDIF» + «ELSE» + public static final «c.type.importedName» «c.name» = «c.value»; + «ENDIF» + «ENDFOR» + «ENDIF» + ''' + + /** + * Template method which generates JAVA static initialization block. + * + * @return string with static initialization block in JAVA format + */ + def protected generateStaticInicializationBlock() ''' + static { + for (String regEx : «TypeConstants.PATTERN_CONSTANT_NAME») { + «Constants.MEMBER_PATTERN_LIST».add(Pattern.compile(regEx)); + } + } + ''' + + /** + * Template method which generates JAVA class attributes. + * + * @return string with the class attributes in JAVA format + */ + def protected generateFields() ''' + «IF !properties.empty» + «FOR f : properties» + «IF f.readOnly»final«ENDIF» private «f.returnType.importedName» «f.fieldName»; + «ENDFOR» + «ENDIF» + ''' + + + /** + * Template method which generates the method hashCode(). + * + * @return string with the hashCode() method definition in JAVA format + */ + def protected generateHashCode() ''' + «IF !genTO.hashCodeIdentifiers.empty» + @Override + public int hashCode() { + final int prime = 31; + int result = 1; + «FOR property : genTO.hashCodeIdentifiers» + result = prime * result + ((«property.fieldName» == null) ? 0 : «property.fieldName».hashCode()); + «ENDFOR» + return result; + } + «ENDIF» + ''' + + /** + * Template method which generates the method equals(). + * + * @return string with the equals() method definition in JAVA format + */ + def protected generateEquals() ''' + «IF !genTO.equalsIdentifiers.empty» + @Override + public boolean equals(java.lang.Object obj) { + if (this == obj) { + return true; + } + if (obj == null) { + return false; + } + if (getClass() != obj.getClass()) { + return false; + } + «type.name» other = («type.name») obj; + «FOR property : genTO.equalsIdentifiers» + «val fieldName = property.fieldName» + if («fieldName» == null) { + if (other.«fieldName» != null) { + return false; + } + } else if(!«fieldName».equals(other.«fieldName»)) { + return false; + } + «ENDFOR» + return true; + } + «ENDIF» + ''' + + /** + * Template method which generates the method toString(). + * + * @return string with the toString() method definition in JAVA format + */ + def protected generateToString() ''' + «IF !genTO.toStringIdentifiers.empty» + @Override + public String toString() { + StringBuilder builder = new StringBuilder(); + «val properties = genTO.toStringIdentifiers» + builder.append("«type.name» [«properties.get(0).fieldName»="); + builder.append(«properties.get(0).fieldName»); + «FOR i : 1..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"» - «" "»«v.name»(«v.value»)« - ENDFOR»; - - int value; - - private «enums.name»(int value) { - this.value = value; - } - } - ''' - - /** - * Template method which generates the package name line. - * - * @return string with the package name line - */ - def private generatePkg() ''' - package «enums.packageName»; - - - ''' - +package org.opendaylight.yangtools.sal.java.api.generator + +import org.opendaylight.yangtools.sal.binding.model.api.Enumeration +import org.opendaylight.yangtools.sal.binding.model.api.GeneratedType +/** + * Template for generating JAVA enumeration type. + */ +class EnumTemplate extends BaseTemplate { + + + /** + * 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) { + super(enums as GeneratedType ) + this.enums = enums + } + + + /** + * Generates only JAVA enumeration source code. + * + * @return string with JAVA enumeration source code + */ + def generateAsInnerClass() { + return body + } + + /** + * Template method which generates enumeration body (declaration + enumeration items). + * + * @return string with the enumeration body + */ + override body() ''' + public enum «enums.name» { + «FOR v : enums.values SEPARATOR ",\n"» + «" "»«v.name»(«v.value»)« + ENDFOR»; + + int value; + + private «enums.name»(int value) { + this.value = value; + } + } + ''' } \ No newline at end of file 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 3b319ca955..2182f3d3e9 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 @@ -1,427 +1,426 @@ -/* - * 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 static org.opendaylight.yangtools.sal.java.api.generator.Constants.COMMA; - -import java.util.ArrayList; -import java.util.LinkedHashMap; -import java.util.List; -import java.util.Map; - -import org.opendaylight.yangtools.binding.generator.util.TypeConstants; -import org.opendaylight.yangtools.binding.generator.util.Types; -import org.opendaylight.yangtools.sal.binding.model.api.Constant; -import org.opendaylight.yangtools.sal.binding.model.api.GeneratedProperty; -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.MethodSignature; -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!"); - } - final Map imports = new LinkedHashMap<>(); - - List childGeneratedTypes = genType.getEnclosedTypes(); - if (!childGeneratedTypes.isEmpty()) { - for (GeneratedType genTypeChild : childGeneratedTypes) { - imports.putAll(createImports(genTypeChild)); - } - } - - final List constants = genType.getConstantDefinitions(); - final List methods = genType.getMethodDefinitions(); - final List impl = genType.getImplements(); - - // IMPLEMENTATIONS - if (impl != null) { - for (final Type type : impl) { - putTypeIntoImports(genType, type, imports); - } - } - - // CONSTANTS - if (constants != null) { - for (final Constant constant : constants) { - final Type constantType = constant.getType(); - putTypeIntoImports(genType, constantType, imports); - } - } - - // REGULAR EXPRESSION - if (genType instanceof GeneratedTransferObject) { - if (isConstantInTO(TypeConstants.PATTERN_CONSTANT_NAME, (GeneratedTransferObject) genType)) { - putTypeIntoImports(genType, Types.typeForClass(java.util.regex.Pattern.class), imports); - putTypeIntoImports(genType, Types.typeForClass(java.util.Arrays.class), imports); - putTypeIntoImports(genType, Types.typeForClass(java.util.ArrayList.class), imports); - } - } - - // METHODS - if (methods != null) { - for (final MethodSignature method : methods) { - final Type methodReturnType = method.getReturnType(); - putTypeIntoImports(genType, methodReturnType, imports); - for (final MethodSignature.Parameter methodParam : method.getParameters()) { - putTypeIntoImports(genType, methodParam.getType(), imports); - } - } - } - - // PROPERTIES - if (genType instanceof GeneratedTransferObject) { - final GeneratedTransferObject genTO = (GeneratedTransferObject) genType; - final List properties = genTO.getProperties(); - if (properties != null) { - for (GeneratedProperty property : properties) { - final Type propertyType = property.getReturnType(); - putTypeIntoImports(genType, propertyType, imports); - } - } - } - - 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) { - throw new IllegalArgumentException("Parent Generated Type parameter MUST be specified and cannot be " - + "NULL!"); - } - if (parentGenType.getName() == null) { - throw new IllegalArgumentException("Parent Generated Type name cannot be NULL!"); - } - if (parentGenType.getPackageName() == null) { - throw new IllegalArgumentException("Parent Generated Type cannot have Package Name referenced as NULL!"); - } - if (type == null) { - throw new IllegalArgumentException("Type parameter MUST be specified and cannot be NULL!"); - } - if (type.getName() == null) { - throw new IllegalArgumentException("Type name cannot be NULL!"); - } - if (type.getPackageName() == null) { - throw new IllegalArgumentException("Type cannot have Package Name referenced as NULL!"); - } - - final String typeName = type.getName(); - final String typePackageName = type.getPackageName(); - final String parentTypeName = parentGenType.getName(); - final String parentTypePackageName = parentGenType.getPackageName(); - if (typeName.equals(parentTypeName) || typePackageName.startsWith("java.lang") - || typePackageName.equals(parentTypePackageName) || typePackageName.isEmpty()) { - return; - } - if (!imports.containsKey(typeName)) { - imports.put(typeName, typePackageName); - } - if (type instanceof ParameterizedType) { - final ParameterizedType paramType = (ParameterizedType) type; - final Type[] params = paramType.getActualTypeArguments(); - for (Type param : params) { - putTypeIntoImports(parentGenType, param, imports); - } - } - } - - /** - * 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(); - List consts = genTO.getConstantDefinitions(); - for (Constant cons : consts) { - if (cons.getName().equals(constName)) { - return true; - } - - } - 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(); - if (!childGeneratedTypes.isEmpty()) { - for (GeneratedType genTypeChild : childGeneratedTypes) { - createChildImports(genTypeChild); - childImports.put(genTypeChild.getName(), genTypeChild.getPackageName()); - } - } - return childImports; - } - - /** - * 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!"); - } - if (type.getName() == null) { - throw new IllegalArgumentException("Type name cannot be NULL!"); - } - if (type.getPackageName() == null) { - throw new IllegalArgumentException("Type cannot have Package Name referenced as NULL!"); - } - if (imports == null) { - throw new IllegalArgumentException("Imports Map cannot be NULL!"); - } - - final String typePackageName = type.getPackageName(); - final String typeName = type.getName(); - final String importedPackageName = imports.get(typeName); - if (typePackageName.equals(importedPackageName) || typePackageName.equals(parentGenType.getPackageName())) { - final StringBuilder builder = new StringBuilder(type.getName()); - if (type instanceof ParameterizedType) { - final ParameterizedType pType = (ParameterizedType) type; - final Type[] pTypes = pType.getActualTypeArguments(); - builder.append("<"); - builder.append(getParameters(parentGenType, pTypes, imports)); - builder.append(">"); - } - if (builder.toString().equals("Void")) { - return "void"; - } - return builder.toString(); - } else { - final StringBuilder builder = new StringBuilder(); - if (typePackageName.startsWith("java.lang")) { - builder.append(type.getName()); - } else { - if (!typePackageName.isEmpty()) { - builder.append(typePackageName + Constants.DOT + type.getName()); - } else { - builder.append(type.getName()); - } - } - if (type.equals(Types.voidType())) { - return "void"; - } - if (type instanceof ParameterizedType) { - final ParameterizedType pType = (ParameterizedType) type; - final Type[] pTypes = pType.getActualTypeArguments(); - builder.append("<"); - builder.append(getParameters(parentGenType, pTypes, imports)); - builder.append(">"); - } - return builder.toString(); - } - } - - /** - * 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]; - - String separator = COMMA; - if (i == (pTypes.length - 1)) { - separator = ""; - } - - String wildcardParam = ""; - if (t.equals(Types.voidType())) { - builder.append("java.lang.Void" + separator); - continue; - } else { - - if (t instanceof WildcardType) { - wildcardParam = "? extends "; - } - - builder.append(wildcardParam + getExplicitType(parentGenType, t, availableImports) + separator); - } - } - return builder.toString(); - } - - /** - * 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) { - throw new IllegalArgumentException("Parameter childTransportObject can't be null."); - } - if (childTransportObject.getExtends() == null) { - return childTransportObject; - } else { - return getTopParrentTransportObject(childTransportObject.getExtends()); - } - } - - /** - * Selects from input list of properties only those which have read only - * attribute set to true. - * - * @param properties - * list of properties of generated transfer object - * @return subset of properties which have read only attribute - * set to true - */ - public static List resolveReadOnlyPropertiesFromTO(List properties) { - List readOnlyProperties = new ArrayList(); - if (properties != null) { - for (final GeneratedProperty property : properties) { - if (property.isReadOnly()) { - readOnlyProperties.add(property); - } - } - } - return readOnlyProperties; - } - - /** - * Returns the list of the read only properties of all extending generated - * transfer object from genTO to highest parent generated - * transfer object - * - * @param genTO - * 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. - */ - public static List getPropertiesOfAllParents(GeneratedTransferObject genTO) { - List propertiesOfAllParents = new ArrayList(); - if (genTO.getExtends() != null) { - final List allPropertiesOfTO = genTO.getExtends().getProperties(); - List readOnlyPropertiesOfTO = resolveReadOnlyPropertiesFromTO(allPropertiesOfTO); - propertiesOfAllParents.addAll(readOnlyPropertiesOfTO); - propertiesOfAllParents.addAll(getPropertiesOfAllParents(genTO.getExtends())); - } - return propertiesOfAllParents; - } - -} +/* + * 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 static org.opendaylight.yangtools.sal.java.api.generator.Constants.COMMA; + +import java.util.ArrayList; +import java.util.LinkedHashMap; +import java.util.List; +import java.util.Map; + +import org.opendaylight.yangtools.binding.generator.util.TypeConstants; +import org.opendaylight.yangtools.binding.generator.util.Types; +import org.opendaylight.yangtools.sal.binding.model.api.Constant; +import org.opendaylight.yangtools.sal.binding.model.api.GeneratedProperty; +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.MethodSignature; +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!"); + } + final Map imports = new LinkedHashMap<>(); + + List childGeneratedTypes = genType.getEnclosedTypes(); + if (!childGeneratedTypes.isEmpty()) { + for (GeneratedType genTypeChild : childGeneratedTypes) { + imports.putAll(createImports(genTypeChild)); + } + } + + final List constants = genType.getConstantDefinitions(); + final List methods = genType.getMethodDefinitions(); + final List impl = genType.getImplements(); + + // IMPLEMENTATIONS + if (impl != null) { + for (final Type type : impl) { + putTypeIntoImports(genType, type, imports); + } + } + + // CONSTANTS + if (constants != null) { + for (final Constant constant : constants) { + final Type constantType = constant.getType(); + putTypeIntoImports(genType, constantType, imports); + } + } + + // REGULAR EXPRESSION + if (genType instanceof GeneratedTransferObject) { + if (isConstantInTO(TypeConstants.PATTERN_CONSTANT_NAME, (GeneratedTransferObject) genType)) { + putTypeIntoImports(genType, Types.typeForClass(java.util.regex.Pattern.class), imports); + putTypeIntoImports(genType, Types.typeForClass(java.util.Arrays.class), imports); + putTypeIntoImports(genType, Types.typeForClass(java.util.ArrayList.class), imports); + } + } + + // METHODS + if (methods != null) { + for (final MethodSignature method : methods) { + final Type methodReturnType = method.getReturnType(); + putTypeIntoImports(genType, methodReturnType, imports); + for (final MethodSignature.Parameter methodParam : method.getParameters()) { + putTypeIntoImports(genType, methodParam.getType(), imports); + } + } + } + + // PROPERTIES + if (genType instanceof GeneratedTransferObject) { + final GeneratedTransferObject genTO = (GeneratedTransferObject) genType; + final List properties = genTO.getProperties(); + if (properties != null) { + for (GeneratedProperty property : properties) { + final Type propertyType = property.getReturnType(); + putTypeIntoImports(genType, propertyType, imports); + } + } + } + + 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) { + throw new IllegalArgumentException("Parent Generated Type parameter MUST be specified and cannot be " + + "NULL!"); + } + if (parentGenType.getName() == null) { + throw new IllegalArgumentException("Parent Generated Type name cannot be NULL!"); + } + if (parentGenType.getPackageName() == null) { + throw new IllegalArgumentException("Parent Generated Type cannot have Package Name referenced as NULL!"); + } + if (type == null) { + throw new IllegalArgumentException("Type parameter MUST be specified and cannot be NULL!"); + } + if (type.getName() == null) { + throw new IllegalArgumentException("Type name cannot be NULL!"); + } + if (type.getPackageName() == null) { + throw new IllegalArgumentException("Type cannot have Package Name referenced as NULL!"); + } + + final String typeName = type.getName(); + final String typePackageName = type.getPackageName(); + final String parentTypeName = parentGenType.getName(); + final String parentTypePackageName = parentGenType.getPackageName(); + if (typeName.equals(parentTypeName) || typePackageName.startsWith("java.lang") + || typePackageName.equals(parentTypePackageName) || typePackageName.isEmpty()) { + return; + } + if (!imports.containsKey(typeName)) { + imports.put(typeName, typePackageName); + } + if (type instanceof ParameterizedType) { + final ParameterizedType paramType = (ParameterizedType) type; + final Type[] params = paramType.getActualTypeArguments(); + for (Type param : params) { + putTypeIntoImports(parentGenType, param, imports); + } + } + } + + /** + * 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(); + List consts = genTO.getConstantDefinitions(); + for (Constant cons : consts) { + if (cons.getName().equals(constName)) { + return true; + } + } + 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(); + if (!childGeneratedTypes.isEmpty()) { + for (GeneratedType genTypeChild : childGeneratedTypes) { + createChildImports(genTypeChild); + childImports.put(genTypeChild.getName(), genTypeChild.getPackageName()); + } + } + return childImports; + } + + /** + * 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!"); + } + if (type.getName() == null) { + throw new IllegalArgumentException("Type name cannot be NULL!"); + } + if (type.getPackageName() == null) { + throw new IllegalArgumentException("Type cannot have Package Name referenced as NULL!"); + } + if (imports == null) { + throw new IllegalArgumentException("Imports Map cannot be NULL!"); + } + + final String typePackageName = type.getPackageName(); + final String typeName = type.getName(); + final String importedPackageName = imports.get(typeName); + if (typePackageName.equals(importedPackageName) || typePackageName.equals(parentGenType.getPackageName())) { + final StringBuilder builder = new StringBuilder(type.getName()); + if (type instanceof ParameterizedType) { + final ParameterizedType pType = (ParameterizedType) type; + final Type[] pTypes = pType.getActualTypeArguments(); + builder.append("<"); + builder.append(getParameters(parentGenType, pTypes, imports)); + builder.append(">"); + } + if (builder.toString().equals("Void")) { + return "void"; + } + return builder.toString(); + } else { + final StringBuilder builder = new StringBuilder(); + if (typePackageName.startsWith("java.lang")) { + builder.append(type.getName()); + } else { + if (!typePackageName.isEmpty()) { + builder.append(typePackageName + Constants.DOT + type.getName()); + } else { + builder.append(type.getName()); + } + } + if (type.equals(Types.voidType())) { + return "void"; + } + if (type instanceof ParameterizedType) { + final ParameterizedType pType = (ParameterizedType) type; + final Type[] pTypes = pType.getActualTypeArguments(); + builder.append("<"); + builder.append(getParameters(parentGenType, pTypes, imports)); + builder.append(">"); + } + return builder.toString(); + } + } + + /** + * 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]; + + String separator = COMMA; + if (i == (pTypes.length - 1)) { + separator = ""; + } + + String wildcardParam = ""; + if (t.equals(Types.voidType())) { + builder.append("java.lang.Void" + separator); + continue; + } else { + + if (t instanceof WildcardType) { + wildcardParam = "? extends "; + } + + builder.append(wildcardParam + getExplicitType(parentGenType, t, availableImports) + separator); + } + } + return builder.toString(); + } + + /** + * 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) { + throw new IllegalArgumentException("Parameter childTransportObject can't be null."); + } + if (childTransportObject.getExtends() == null) { + return childTransportObject; + } else { + return getTopParrentTransportObject(childTransportObject.getExtends()); + } + } + + /** + * Selects from input list of properties only those which have read only + * attribute set to true. + * + * @param properties + * list of properties of generated transfer object + * @return subset of properties which have read only attribute + * set to true + */ + public static List resolveReadOnlyPropertiesFromTO(List properties) { + List readOnlyProperties = new ArrayList(); + if (properties != null) { + for (final GeneratedProperty property : properties) { + if (property.isReadOnly()) { + readOnlyProperties.add(property); + } + } + } + return readOnlyProperties; + } + + /** + * Returns the list of the read only properties of all extending generated + * transfer object from genTO to highest parent generated + * transfer object + * + * @param genTO + * 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. + */ + public static List getPropertiesOfAllParents(GeneratedTransferObject genTO) { + List propertiesOfAllParents = new ArrayList(); + if (genTO.getExtends() != null) { + final List allPropertiesOfTO = genTO.getExtends().getProperties(); + List readOnlyPropertiesOfTO = resolveReadOnlyPropertiesFromTO(allPropertiesOfTO); + propertiesOfAllParents.addAll(readOnlyPropertiesOfTO); + propertiesOfAllParents.addAll(getPropertiesOfAllParents(genTO.getExtends())); + } + return propertiesOfAllParents; + } + +} 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 70ea929bc3..0ebc3ccbe9 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 @@ -1,252 +1,186 @@ -package org.opendaylight.yangtools.sal.java.api.generator - -import java.util.List -import java.util.Map -import org.opendaylight.yangtools.binding.generator.util.TypeConstants -import org.opendaylight.yangtools.sal.binding.model.api.Constant -import org.opendaylight.yangtools.sal.binding.model.api.Enumeration -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.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!") - } - - this.genType = genType - imports = GeneratorUtil.createImports(genType) - consts = genType.constantDefinitions - methods = genType.methodDefinitions - enums = genType.enumerations - 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» { - - «generateInnerClasses» - - «generateEnums» - - «generateConstants» - - «generateMethods» - - } - - ''' - - /** - * 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» - /* - «comment» - */ - «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)»« - " extends "»« - FOR type : genType.implements SEPARATOR ", "»« - type.resolveName»« - ENDFOR»« - 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"» - «IF (innerClass instanceof GeneratedTransferObject)» - «val classTemplate = new ClassTemplate(innerClass as GeneratedTransferObject)» - «classTemplate.generateAsInnerClass» - - «ENDIF» - «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"» - «val enumTemplate = new EnumTemplate(e)» - «enumTemplate.generateAsInnerClass» - «ENDFOR» - «ENDIF» - ''' - - /** - * Template method wich generates JAVA constants. - * - * @return string with constants in JAVA format - */ - def private generateConstants() ''' - «IF !consts.empty» - «FOR c : consts» - «IF c.name != TypeConstants.PATTERN_CONSTANT_NAME» - public static final «c.type.resolveName» «c.name» = «c.value»; - «ENDIF» - «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"» - «m.comment.generateComment» - «m.returnType.resolveName» «m.name»(«m.parameters.generateParameters»); - «ENDFOR» - «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 ", "»« - parameter.type.resolveName» «parameter.name»« - 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 - for (Map.Entry entry : imports.entrySet() + innerTypeImports.entrySet) { - val typeName = entry.getKey(); - val packageName = entry.getValue(); - if (packageName != genType.packageName && packageName != genType.fullyQualifiedName) { - resolvedImports.put(typeName, packageName); - } - } - 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) - } - -} \ No newline at end of file +package org.opendaylight.yangtools.sal.java.api.generator + +import java.util.List +import org.opendaylight.yangtools.binding.generator.util.TypeConstants +import org.opendaylight.yangtools.sal.binding.model.api.Constant +import org.opendaylight.yangtools.sal.binding.model.api.Enumeration +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.MethodSignature + + +/** + * Template for generating JAVA interfaces. + */ +class InterfaceTemplate extends BaseTemplate { + + /** + * 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) { + super(genType) + if (genType == null) { + throw new IllegalArgumentException("Generated type reference cannot be NULL!") + } + + consts = genType.constantDefinitions + methods = genType.methodDefinitions + enums = genType.enumerations + enclosedGeneratedTypes = genType.enclosedTypes + } + + + + /** + * Template method which generate the whole body of the interface. + * + * @return string with code for interface body in JAVA format + */ + override body() ''' + «type.comment.generateComment» + public interface «type.name» + «superInterfaces» { + + «generateInnerClasses» + + «generateEnums» + + «generateConstants» + + «generateMethods» + + } + + ''' + + /** + * 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» + /* + «comment» + */ + «ENDIF» + ''' + + /** + * Template method which generates the interface name declaration. + * + * @return string with the code for the interface declaration in JAVA format + */ + def private superInterfaces() + ''' + «IF (!type.implements.empty)» + extends + «FOR type : type.implements SEPARATOR ","» + + «type.importedName» + «ENDFOR» + « 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"» + «IF (innerClass instanceof GeneratedTransferObject)» + «val classTemplate = new ClassTemplate(innerClass as GeneratedTransferObject)» + «classTemplate.generateAsInnerClass» + + «ENDIF» + «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"» + «val enumTemplate = new EnumTemplate(e)» + «enumTemplate.generateAsInnerClass» + «ENDFOR» + «ENDIF» + ''' + + /** + * Template method wich generates JAVA constants. + * + * @return string with constants in JAVA format + */ + def private generateConstants() ''' + «IF !consts.empty» + «FOR c : consts» + «IF c.name != TypeConstants.PATTERN_CONSTANT_NAME» + public static final «c.type.importedName» «c.name» = «c.value»; + «ENDIF» + «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"» + «m.comment.generateComment» + «m.returnType.importedName» «m.name»(«m.parameters.generateParameters»); + «ENDFOR» + «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 ", "»« + parameter.type.importedName» «parameter.name»« + ENDFOR»« + ENDIF + »''' + + +} + 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 0299b1b644..994fd79031 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,48 +1,53 @@ -/* - * 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(); - } - -} +/* + * 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; + if(genTO.isUnionType()) { + final UnionTemplate template = new UnionTemplate(genTO); + return template.generate(); + } else { + 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-java-api-generator/src/main/java/org/opendaylight/yangtools/sal/java/api/generator/UnionTemplate.xtend b/code-generator/binding-java-api-generator/src/main/java/org/opendaylight/yangtools/sal/java/api/generator/UnionTemplate.xtend new file mode 100644 index 0000000000..a17bdadf73 --- /dev/null +++ b/code-generator/binding-java-api-generator/src/main/java/org/opendaylight/yangtools/sal/java/api/generator/UnionTemplate.xtend @@ -0,0 +1,57 @@ +package org.opendaylight.yangtools.sal.java.api.generator + +import java.util.List +import java.util.Map +import org.opendaylight.yangtools.binding.generator.util.TypeConstants +import org.opendaylight.yangtools.sal.binding.model.api.Constant +import org.opendaylight.yangtools.sal.binding.model.api.Enumeration +import org.opendaylight.yangtools.sal.binding.model.api.GeneratedProperty +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 +import org.opendaylight.yangtools.sal.binding.model.api.GeneratedType + + +/** + * Template for generating JAVA class. + */ +class UnionTemplate extends ClassTemplate { + + + + /** + * Creates instance of this class with concrete genType. + * + * @param genType generated transfer object which will be transformed to JAVA class source code + */ + new(GeneratedTransferObject genType) { + super(genType) + } + + + + + override constructors() ''' + «unionConstructors» + «IF !allProperties.empty» + «copyConstructor» + «ENDIF» + «IF properties.empty && !parentProperties.empty » + «parentConstructor» + «ENDIF» + ''' + + + def unionConstructors() ''' + «FOR property : finalProperties SEPARATOR "\n"» + «val propertyAndTopParentProperties = parentProperties + #[property]» + public «type.name»(«propertyAndTopParentProperties.asArgumentsDeclaration») { + super(«parentProperties.asArguments»); + this.«property.fieldName» = «property.fieldName»; + «FOR other : finalProperties» + «IF property != other»this.«other.fieldName» = null;«ENDIF» + «ENDFOR» + } + «ENDFOR» + ''' +} diff --git a/code-generator/binding-java-api-generator/src/test/java/org/opendaylight/yangtools/sal/java/api/generator/test/ClassCodeGeneratorTest.java b/code-generator/binding-java-api-generator/src/test/java/org/opendaylight/yangtools/sal/java/api/generator/test/ClassCodeGeneratorTest.java index 2d83c9ac16..86d7c413c1 100644 --- a/code-generator/binding-java-api-generator/src/test/java/org/opendaylight/yangtools/sal/java/api/generator/test/ClassCodeGeneratorTest.java +++ b/code-generator/binding-java-api-generator/src/test/java/org/opendaylight/yangtools/sal/java/api/generator/test/ClassCodeGeneratorTest.java @@ -10,6 +10,7 @@ import java.util.List; import java.util.Set; import org.junit.BeforeClass; +import org.junit.Ignore; import org.junit.Test; import org.opendaylight.yangtools.binding.generator.util.Types; import org.opendaylight.yangtools.binding.generator.util.generated.type.builder.GeneratedTOBuilderImpl; @@ -95,6 +96,7 @@ public class ClassCodeGeneratorTest { assertEquals(2, genTOsCount); } + @Ignore @Test public void defaultConstructorTest() { final GeneratedTOBuilder toBuilder = new GeneratedTOBuilderImpl( 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 7d5054a227..acb4256e48 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 @@ -1,62 +1,62 @@ -/* - * 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.util.List; - -/** - * Interface provide methods for reading data of enumeration class. - */ -public interface Enumeration extends Type { - - /** - * - * Returns list of annotation definitions associated with enumeration type. - * - * @return list of annotation definitions associated with enumeration type. - * - */ - public List getAnnotations(); - - public Type getDefiningType(); - - /** - * Returns list of the couples - name and value. - * - * @return list of the enumeration pairs. - */ - public List getValues(); - - /** - * 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(); - } -} +/* + * 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.util.List; + +/** + * Interface provide methods for reading data of enumeration class. + */ +public interface Enumeration extends GeneratedType { + + /** + * + * Returns list of annotation definitions associated with enumeration type. + * + * @return list of annotation definitions associated with enumeration type. + * + */ + public List getAnnotations(); + + public Type getParentType(); + + /** + * Returns list of the couples - name and value. + * + * @return list of the enumeration pairs. + */ + public List getValues(); + + /** + * 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(); + } +}