From ed6390f52f3bb8fd7a2269fffde0ae40329e8b1e Mon Sep 17 00:00:00 2001 From: Jozef Gloncak Date: Tue, 20 Aug 2013 16:06:31 +0200 Subject: [PATCH] Code refactoring -> the method provideGeneratedTOBuildersForUnionTypeDef in TypeProviderImpl.java was refactored. New code wrapping methods were addded: --> resolveUnionSubtypeAsUnion --> resolveExtendedSubtypeAsUnion --> findGenTO --> storeGenTO and helper method --> provideAvailableNameForGenTOBuilder -> the method updateEnumPairsFromEnumTypeDef (next as new method) was added to EnumerationBuilderImpl.java -> the method updateEnumPairsFromEnumTypeDef in TypeProviderImpl was replaced with new method -> piece of code in method resolveInnerEnumFromTypeDefinition in BindingGeneratorImpl with new method Change-Id: Iea389ac83d3eb2252cf4789b356c65d272a4a9ad Signed-off-by: Jozef Gloncak --- .../generator/impl/BindingGeneratorImpl.java | 58 +-- .../binding/yang/types/TypeProviderImpl.java | 432 ++++++++++++------ .../type/builder/EnumerationBuilderImpl.java | 25 + .../java/api/generator/ClassTemplate.xtend | 26 ++ .../sal/java/api/generator/GeneratorUtil.java | 2 +- .../api/generator/InterfaceTemplate.xtend | 1 + code-generator/binding-model-api/pom.xml | 37 +- .../model/api/type/builder/EnumBuilder.java | 38 +- 8 files changed, 412 insertions(+), 207 deletions(-) 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 44adb2235d..1760a7e13d 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 @@ -103,12 +103,18 @@ public final class BindingGeneratorImpl implements BindingGenerator { private final Map allGroupings = new HashMap(); /** - * Only parent constructor is invoked. + * 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(); } @@ -859,26 +865,9 @@ public final class BindingGeneratorImpl implements BindingGenerator { final String enumerationName = parseToClassName(enumName); final EnumBuilder enumBuilder = typeBuilder.addEnumeration(enumerationName); + enumBuilder.updateEnumPairsFromEnumTypeDef(enumTypeDef); - if (enumBuilder != null) { - final List enums = enumTypeDef.getValues(); - if (enums != null) { - int listIndex = 0; - for (final EnumPair enumPair : enums) { - if (enumPair != null) { - final String enumPairName = parseToClassName(enumPair.getName()); - Integer enumPairValue = enumPair.getValue(); - - if (enumPairValue == null) { - enumPairValue = listIndex; - } - enumBuilder.addValue(enumPairName, enumPairValue); - listIndex++; - } - } - } - return enumBuilder; - } + return enumBuilder; } return null; } @@ -1018,6 +1007,11 @@ public final class BindingGeneratorImpl implements BindingGenerator { return augTypeBuilder; } + /** + * + * @param unknownSchemaNodes + * @return + */ private String getAugmentIdentifier(List unknownSchemaNodes) { String ret = null; for (UnknownSchemaNode unknownSchemaNode : unknownSchemaNodes) { @@ -2023,6 +2017,10 @@ public final class BindingGeneratorImpl implements BindingGenerator { * 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 @@ -2036,18 +2034,20 @@ public final class BindingGeneratorImpl implements BindingGenerator { private GeneratedTOBuilder addTOToTypeBuilder(TypeDefinition typeDef, GeneratedTypeBuilder typeBuilder, String leafName, Module parentModule) { final String classNameFromLeaf = parseToClassName(leafName); - GeneratedTOBuilder genTOBuilder = null; + List genTOBuilders = new ArrayList<>(); final String packageName = typeBuilder.getFullyQualifiedName(); if (typeDef instanceof UnionTypeDefinition) { - genTOBuilder = ((TypeProviderImpl) typeProvider).provideGeneratedTOBuilderForUnionTypeDefinition( - packageName, typeDef, classNameFromLeaf, parentModule); + genTOBuilders.addAll(((TypeProviderImpl) typeProvider).provideGeneratedTOBuildersForUnionTypeDef( + packageName, typeDef, classNameFromLeaf)); } else if (typeDef instanceof BitsTypeDefinition) { - genTOBuilder = ((TypeProviderImpl) typeProvider).provideGeneratedTOBuilderForBitsTypeDefinition( - packageName, typeDef, classNameFromLeaf); + genTOBuilders.add(((TypeProviderImpl) typeProvider).provideGeneratedTOBuilderForBitsTypeDefinition( + packageName, typeDef, classNameFromLeaf)); } - if (genTOBuilder != null) { - typeBuilder.addEnclosingTransferObject(genTOBuilder); - return genTOBuilder; + if (genTOBuilders != null && !genTOBuilders.isEmpty()) { + for (GeneratedTOBuilder genTOBuilder : genTOBuilders) { + typeBuilder.addEnclosingTransferObject(genTOBuilder); + } + return genTOBuilders.get(0); } return null; diff --git a/code-generator/binding-generator-impl/src/main/java/org/opendaylight/yangtools/sal/binding/yang/types/TypeProviderImpl.java b/code-generator/binding-generator-impl/src/main/java/org/opendaylight/yangtools/sal/binding/yang/types/TypeProviderImpl.java index a119d4f155..01862296fa 100644 --- a/code-generator/binding-generator-impl/src/main/java/org/opendaylight/yangtools/sal/binding/yang/types/TypeProviderImpl.java +++ b/code-generator/binding-generator-impl/src/main/java/org/opendaylight/yangtools/sal/binding/yang/types/TypeProviderImpl.java @@ -16,6 +16,8 @@ import java.util.List; import java.util.Map; import java.util.Set; import java.util.TreeMap; +import java.util.regex.Matcher; +import java.util.regex.Pattern; import org.apache.commons.lang.StringEscapeUtils; import org.opendaylight.yangtools.binding.generator.util.TypeConstants; @@ -73,7 +75,7 @@ public final class TypeProviderImpl implements TypeProvider { /** * Creates new instance of class TypeProviderImpl. - * + * * @param schemaContext * contains the schema data red from YANG files * @throws IllegalArgumentException @@ -92,7 +94,7 @@ public final class TypeProviderImpl implements TypeProvider { /** * Puts refType to map with key refTypePath - * + * * @param refTypePath * schema path used as the map key * @param refType @@ -102,7 +104,7 @@ public final class TypeProviderImpl implements TypeProvider { *
  • if refTypePath equal null
  • *
  • if refType equal null
  • * - * + * */ public void putReferencedType(final SchemaPath refTypePath, final Type refType) { if (refTypePath == null) { @@ -116,9 +118,9 @@ public final class TypeProviderImpl implements TypeProvider { } /** - * + * * Converts basic YANG type type to JAVA Type. - * + * * @param type * string with YANG name of type * @returns JAVA Type for YANG type type @@ -127,14 +129,13 @@ public final class TypeProviderImpl implements TypeProvider { */ @Override public Type javaTypeForYangType(String type) { - Type t = BaseYangTypes.BASE_YANG_TYPES_PROVIDER.javaTypeForYangType(type); - return t; + return BaseYangTypes.BASE_YANG_TYPES_PROVIDER.javaTypeForYangType(type); } /** * Converts schema definition type typeDefinition to JAVA * Type - * + * * @param typeDefinition * type definition which is converted to JAVA type * @throws IllegalArgumentException @@ -157,17 +158,60 @@ public final class TypeProviderImpl implements TypeProvider { if (typeDefinition.getQName().getLocalName() == null) { throw new IllegalArgumentException("Type Definitions Local Name cannot be NULL!"); } - final String typedefName = typeDefinition.getQName().getLocalName(); + if (typeDefinition instanceof ExtendedType) { - final TypeDefinition baseTypeDef = baseTypeDefForExtendedType(typeDefinition); + returnType = javaTypeForExtendedType(typeDefinition); + } else { + returnType = javaTypeForLeafrefOrIdentityRef(typeDefinition); + if (returnType == null) { + returnType = BaseYangTypes.BASE_YANG_TYPES_PROVIDER.javaTypeForSchemaDefinitionType(typeDefinition); + } + } + // TODO: add throw exception when we will be able to resolve ALL yang + // types! + // if (returnType == null) { + // throw new IllegalArgumentException("Type Provider can't resolve " + + // "type for specified Type Definition " + typedefName); + // } + return returnType; + } + + /** + * Returns JAVA Type for instances of the type + * LeafrefTypeDefinition or + * IdentityrefTypeDefinition. + * + * @param typeDefinition + * type definition which is converted to JAVA Type + * @return JAVA Type instance for typeDefinition + */ + private Type javaTypeForLeafrefOrIdentityRef(TypeDefinition typeDefinition) { + if (typeDefinition instanceof LeafrefTypeDefinition) { + final LeafrefTypeDefinition leafref = (LeafrefTypeDefinition) typeDefinition; + return provideTypeForLeafref(leafref); + } else if (typeDefinition instanceof IdentityrefTypeDefinition) { + final IdentityrefTypeDefinition idref = (IdentityrefTypeDefinition) typeDefinition; + return provideTypeForIdentityref(idref); + } else { + return null; + } + } - if (baseTypeDef instanceof LeafrefTypeDefinition) { - final LeafrefTypeDefinition leafref = (LeafrefTypeDefinition) baseTypeDef; - returnType = provideTypeForLeafref(leafref); - } else if (baseTypeDef instanceof IdentityrefTypeDefinition) { - final IdentityrefTypeDefinition idref = (IdentityrefTypeDefinition) baseTypeDef; - returnType = provideTypeForIdentityref(idref); - } else if (baseTypeDef instanceof EnumTypeDefinition) { + /** + * Returns JAVA Type for instances of the type + * ExtendedType. + * + * @param typeDefinition + * type definition which is converted to JAVA Type + * @return JAVA Type instance for typeDefinition + */ + private Type javaTypeForExtendedType(TypeDefinition typeDefinition) { + final String typedefName = typeDefinition.getQName().getLocalName(); + final TypeDefinition baseTypeDef = baseTypeDefForExtendedType(typeDefinition); + Type returnType = null; + returnType = javaTypeForLeafrefOrIdentityRef(baseTypeDef); + if (returnType == null) { + if (baseTypeDef instanceof EnumTypeDefinition) { final EnumTypeDefinition enumTypeDef = (EnumTypeDefinition) baseTypeDef; returnType = provideTypeForEnum(enumTypeDef, typedefName); } else { @@ -183,23 +227,7 @@ public final class TypeProviderImpl implements TypeProvider { } } } - } else { - if (typeDefinition instanceof LeafrefTypeDefinition) { - final LeafrefTypeDefinition leafref = (LeafrefTypeDefinition) typeDefinition; - returnType = provideTypeForLeafref(leafref); - } else if (typeDefinition instanceof IdentityrefTypeDefinition) { - final IdentityrefTypeDefinition idref = (IdentityrefTypeDefinition) typeDefinition; - returnType = provideTypeForIdentityref(idref); - } else { - returnType = BaseYangTypes.BASE_YANG_TYPES_PROVIDER.javaTypeForSchemaDefinitionType(typeDefinition); - } } - // TODO: add throw exception when we will be able to resolve ALL yang - // types! - // if (returnType == null) { - // throw new IllegalArgumentException("Type Provider can't resolve " + - // "type for specified Type Definition " + typedefName); - // } return returnType; } @@ -207,11 +235,11 @@ public final class TypeProviderImpl implements TypeProvider { * Seeks for identity reference idref the JAVA * type.
    *
    - * + * * Example:
    * If identy which is referenced via idref has name Idn * then returning type is {@code Class}
    - * + * * @param idref * identityref type definition for which JAVA Type * is sought @@ -237,13 +265,12 @@ public final class TypeProviderImpl implements TypeProvider { Type baseType = Types.typeForClass(Class.class); Type paramType = Types.wildcardTypeFor(packageName, genTypeName); - Type returnType = Types.parameterizedTypeFor(baseType, paramType); - return returnType; + return Types.parameterizedTypeFor(baseType, paramType); } /** * Converts typeDefinition to concrete JAVA Type. - * + * * @param typeDefinition * type definition which should be converted to JAVA * Type @@ -290,7 +317,7 @@ public final class TypeProviderImpl implements TypeProvider { /** * Gets base type definition for extendTypeDef. The method is * recursivelly called until non ExtendedType type is found. - * + * * @param extendTypeDef * type definition for which is the base type definition sought * @return type definition which is base type for extendTypeDef @@ -312,10 +339,10 @@ public final class TypeProviderImpl implements TypeProvider { /** * Converts leafrefType to JAVA Type. - * + * * The path of leafrefType is followed to find referenced node * and its Type is returned. - * + * * @param leafrefType * leafref type definition for which is the type sought * @return JAVA Type of data schema node which is referenced in @@ -325,7 +352,7 @@ public final class TypeProviderImpl implements TypeProvider { *
  • if leafrefType equal null
  • *
  • if path statement of leafrefType equal null
  • * - * + * */ public Type provideTypeForLeafref(final LeafrefTypeDefinition leafrefType) { Type returnType = null; @@ -369,7 +396,7 @@ public final class TypeProviderImpl implements TypeProvider { /** * Checks if dataNode is LeafSchemaNode and if it * so then checks if it is of type EnumTypeDefinition. - * + * * @param dataNode * data schema node for which is checked if it is leaf and if it * is of enum type @@ -392,7 +419,7 @@ public final class TypeProviderImpl implements TypeProvider { /** * Checks if dataNode is LeafListSchemaNode and if * it so then checks if it is of type EnumTypeDefinition. - * + * * @param dataNode * data schema node for which is checked if it is leaflist and if * it is of enum type @@ -417,7 +444,7 @@ public final class TypeProviderImpl implements TypeProvider { * Converts enumTypeDef to * {@link org.opendaylight.yangtools.sal.binding.model.api.Enumeration * enumeration}. - * + * * @param enumTypeDef * enumeration type definition which is converted to enumeration * @param enumName @@ -452,14 +479,14 @@ public final class TypeProviderImpl implements TypeProvider { final String basePackageName = moduleNamespaceToPackageName(module); final EnumBuilder enumBuilder = new EnumerationBuilderImpl(basePackageName, enumerationName); - updateEnumPairsFromEnumTypeDef(enumTypeDef, enumBuilder); + enumBuilder.updateEnumPairsFromEnumTypeDef(enumTypeDef); return enumBuilder.toInstance(null); } /** * Adds enumeration to typeBuilder. The enumeration data are * taken from enumTypeDef. - * + * * @param enumTypeDef * enumeration type definition is source of enumeration data for * typeBuilder @@ -477,7 +504,7 @@ public final class TypeProviderImpl implements TypeProvider { *
  • if name of enumTypeDef equal null
  • *
  • if name of typeBuilder equal null
  • * - * + * */ private Enumeration addInnerEnumerationToTypeBuilder(final EnumTypeDefinition enumTypeDef, final String enumName, final GeneratedTypeBuilder typeBuilder) { @@ -500,45 +527,13 @@ public final class TypeProviderImpl implements TypeProvider { final String enumerationName = parseToClassName(enumName); final EnumBuilder enumBuilder = typeBuilder.addEnumeration(enumerationName); - updateEnumPairsFromEnumTypeDef(enumTypeDef, enumBuilder); + enumBuilder.updateEnumPairsFromEnumTypeDef(enumTypeDef); return enumBuilder.toInstance(enumBuilder); } - /** - * Updates enumBuilder with data from enumTypeDef. - * Specifically this data represents list of value-name pairs. - * - * @param enumTypeDef - * enum type definition as source of enum data for - * enumBuilder - * @param enumBuilder - * enum builder to which are saved enum data from - * enumTypeDef - */ - private void updateEnumPairsFromEnumTypeDef(final EnumTypeDefinition enumTypeDef, final EnumBuilder enumBuilder) { - if (enumBuilder != null) { - final List enums = enumTypeDef.getValues(); - if (enums != null) { - int listIndex = 0; - for (final EnumPair enumPair : enums) { - if (enumPair != null) { - final String enumPairName = parseToClassName(enumPair.getName()); - Integer enumPairValue = enumPair.getValue(); - - if (enumPairValue == null) { - enumPairValue = listIndex; - } - enumBuilder.addValue(enumPairName, enumPairValue); - listIndex++; - } - } - } - } - } - /** * Converts dataNode to JAVA Type. - * + * * @param dataNode * contains information about YANG type * @return JAVA Type representation of dataNode @@ -560,7 +555,7 @@ public final class TypeProviderImpl implements TypeProvider { /** * Passes through all modules and through all its type definitions and * convert it to generated types. - * + * * The modules are firstly sorted by mutual dependencies. The modules are * sequentially passed. All type definitions of a module are at the * beginning sorted so that type definition with less amount of references @@ -569,7 +564,7 @@ public final class TypeProviderImpl implements TypeProvider { * {@link TypeProviderImpl#genTypeDefsContextMap genTypeDefsContextMap} * which map current module name to the map which maps type names to * returned types (generated types). - * + * */ private void resolveTypeDefsFromContext() { final Set modules = schemaContext.getModules(); @@ -605,7 +600,7 @@ public final class TypeProviderImpl implements TypeProvider { } /** - * + * * @param basePackageName * string with name of package to which the module belongs * @param moduleName @@ -632,9 +627,8 @@ public final class TypeProviderImpl implements TypeProvider { ExtendedType innerExtendedType = (ExtendedType) innerTypeDefinition; returnType = provideGeneratedTOFromExtendedType(innerExtendedType, basePackageName, typedefName); } else if (innerTypeDefinition instanceof UnionTypeDefinition) { - final Module parentModule = findParentModuleForTypeDefinition(schemaContext, typedef); - final GeneratedTOBuilder genTOBuilder = provideGeneratedTOBuilderForUnionTypeDefinition( - basePackageName, typedef, typedefName, parentModule); + final GeneratedTOBuilder genTOBuilder = provideGeneratedTOBuilderForUnionTypeDef(basePackageName, + typedef, typedefName); returnType = genTOBuilder.toInstance(); } else if (innerTypeDefinition instanceof EnumTypeDefinition) { final EnumTypeDefinition enumTypeDef = (EnumTypeDefinition) innerTypeDefinition; @@ -666,7 +660,7 @@ public final class TypeProviderImpl implements TypeProvider { /** * Wraps base YANG type to generated TO. - * + * * @param basePackageName * string with name of package to which the module belongs * @param typedef @@ -689,22 +683,49 @@ public final class TypeProviderImpl implements TypeProvider { genTOBuilder.addEqualsIdentity(genPropBuilder); genTOBuilder.addHashIdentity(genPropBuilder); genTOBuilder.addToStringProperty(genPropBuilder); - if (javaType == BaseYangTypes.STRING_TYPE) { - if (typedef instanceof ExtendedType) { - final List regExps = resolveRegExpressionsFromTypedef((ExtendedType) typedef); - addStringRegExAsConstant(genTOBuilder, regExps); - } + if (javaType == BaseYangTypes.STRING_TYPE && typedef instanceof ExtendedType) { + final List regExps = resolveRegExpressionsFromTypedef((ExtendedType) typedef); + addStringRegExAsConstant(genTOBuilder, regExps); } return genTOBuilder.toInstance(); } return null; } + /** + * Converts output list of generated TO builders to one TO builder (first + * from list) which contains the remaining builders as its enclosing TO. + * + * @param basePackageName + * string with name of package to which the module belongs + * @param typedef + * type definition which should be of type + * UnionTypeDefinition + * @param typeDefName + * string with name for generated TO + * @return generated TO builder with the list of enclosed generated TO + * builders + */ + public GeneratedTOBuilder provideGeneratedTOBuilderForUnionTypeDef(final String basePackageName, + final TypeDefinition typedef, String typeDefName) { + final List genTOBuilders = provideGeneratedTOBuildersForUnionTypeDef(basePackageName, + typedef, typeDefName); + GeneratedTOBuilder resultTOBuilder = null; + if (!genTOBuilders.isEmpty()) { + resultTOBuilder = genTOBuilders.get(0); + genTOBuilders.remove(0); + for (GeneratedTOBuilder genTOBuilder : genTOBuilders) { + resultTOBuilder.addEnclosingTransferObject(genTOBuilder); + } + } + return resultTOBuilder; + } + /** * Converts typedef to generated TO with * typeDefName. Every union type from typedef is * added to generated TO builder as property. - * + * * @param basePackageName * string with name of package to which the module belongs * @param typedef @@ -720,8 +741,8 @@ public final class TypeProviderImpl implements TypeProvider { *
  • if Q name of typedef equals null
  • * */ - public GeneratedTOBuilder provideGeneratedTOBuilderForUnionTypeDefinition(final String basePackageName, - final TypeDefinition typedef, final String typeDefName, final Module parentModule) { + public List provideGeneratedTOBuildersForUnionTypeDef(final String basePackageName, + final TypeDefinition typedef, final String typeDefName) { if (basePackageName == null) { throw new IllegalArgumentException("Base Package Name cannot be NULL!"); } @@ -733,81 +754,174 @@ public final class TypeProviderImpl implements TypeProvider { "Type Definition cannot have non specified QName (QName cannot be NULL!)"); } + final List generatedTOBuilders = new ArrayList<>(); + final TypeDefinition baseTypeDefinition = typedef.getBaseType(); if ((baseTypeDefinition != null) && (baseTypeDefinition instanceof UnionTypeDefinition)) { final UnionTypeDefinition unionTypeDef = (UnionTypeDefinition) baseTypeDefinition; final List> unionTypes = unionTypeDef.getTypes(); - final GeneratedTOBuilder unionGenTransObject; + final GeneratedTOBuilder unionGenTOBuilder; if (typeDefName != null && !typeDefName.isEmpty()) { final String typeName = parseToClassName(typeDefName); - unionGenTransObject = new GeneratedTOBuilderImpl(basePackageName, typeName); + unionGenTOBuilder = new GeneratedTOBuilderImpl(basePackageName, typeName); } else { - unionGenTransObject = typedefToTransferObject(basePackageName, typedef); + unionGenTOBuilder = typedefToTransferObject(basePackageName, typedef); } - unionGenTransObject.setIsUnion(true); + generatedTOBuilders.add(unionGenTOBuilder); + unionGenTOBuilder.setIsUnion(true); final List regularExpressions = new ArrayList(); for (final TypeDefinition unionType : unionTypes) { - final String typeName = unionType.getQName().getLocalName(); - if (unionType instanceof ExtendedType) { - final Module unionTypeModule = findParentModuleForTypeDefinition(schemaContext, unionType); - if (unionTypeModule != null && unionTypeModule.getName() != null) { - final Map innerGenTOs = genTypeDefsContextMap.get(unionTypeModule.getName()); - Type genTransferObject = null; - if (innerGenTOs != null) { - genTransferObject = innerGenTOs.get(typeName); - } - if (genTransferObject != null) { - updateUnionTypeAsProperty(unionGenTransObject, genTransferObject, - genTransferObject.getName()); - } else { - final TypeDefinition baseType = baseTypeDefForExtendedType(unionType); - if (typeName.equals(baseType.getQName().getLocalName())) { - final Type javaType = BaseYangTypes.BASE_YANG_TYPES_PROVIDER - .javaTypeForSchemaDefinitionType(baseType); - if (javaType != null) { - updateUnionTypeAsProperty(unionGenTransObject, javaType, typeName); - } - } - if (baseType instanceof StringType) { - regularExpressions.addAll(resolveRegExpressionsFromTypedef((ExtendedType) unionType)); - } - } - } + final String unionTypeName = unionType.getQName().getLocalName(); + if (unionType instanceof UnionType) { + generatedTOBuilders + .addAll(resolveUnionSubtypeAsUnion(unionGenTOBuilder, unionType, basePackageName)); + } else if (unionType instanceof ExtendedType) { + resolveExtendedSubtypeAsUnion(unionGenTOBuilder, (ExtendedType) unionType, unionTypeName, + regularExpressions); } else if (unionType instanceof EnumTypeDefinition) { final Enumeration enumeration = addInnerEnumerationToTypeBuilder((EnumTypeDefinition) unionType, - typeName, unionGenTransObject); - updateUnionTypeAsProperty(unionGenTransObject, enumeration, typeName); + unionTypeName, unionGenTOBuilder); + updateUnionTypeAsProperty(unionGenTOBuilder, enumeration, unionTypeName); } else { final Type javaType = BaseYangTypes.BASE_YANG_TYPES_PROVIDER .javaTypeForSchemaDefinitionType(unionType); if (javaType != null) { - updateUnionTypeAsProperty(unionGenTransObject, javaType, typeName); + updateUnionTypeAsProperty(unionGenTOBuilder, javaType, unionTypeName); } } } if (!regularExpressions.isEmpty()) { - addStringRegExAsConstant(unionGenTransObject, regularExpressions); + addStringRegExAsConstant(unionGenTOBuilder, regularExpressions); } + storeGenTO(typedef, unionGenTOBuilder); + } + return generatedTOBuilders; + } + + /** + * Wraps code which handle case when union subtype is also of the type + * UnionType. + * + * In this case the new generated TO is created for union subtype (recursive + * call of method + * {@link #provideGeneratedTOBuilderForUnionTypeDef(String, TypeDefinition, String) + * provideGeneratedTOBuilderForUnionTypeDef} and in parent TO builder + * parentUnionGenTOBuilder is created property which type is + * equal to new generated TO. + * + * @param parentUnionGenTOBuilder + * generated TO builder to which is the property with the child + * union subtype added + * @param basePackageName + * string with the name of the module package + * @param unionSubtype + * type definition which represents union subtype + * @return list of generated TO builders. The number of the builders can be + * bigger one due to recursive call of + * provideGeneratedTOBuildersForUnionTypeDef method. + */ + private List resolveUnionSubtypeAsUnion(final GeneratedTOBuilder parentUnionGenTOBuilder, + final TypeDefinition unionSubtype, final String basePackageName) { + final String newTOBuilderName = provideAvailableNameForGenTOBuilder(parentUnionGenTOBuilder.getName()); + final List subUnionGenTOBUilders = provideGeneratedTOBuildersForUnionTypeDef( + basePackageName, unionSubtype, newTOBuilderName); + + GeneratedPropertyBuilder propertyBuilder = parentUnionGenTOBuilder.addProperty(newTOBuilderName); + propertyBuilder.setReturnType(subUnionGenTOBUilders.get(0)); + parentUnionGenTOBuilder.addEqualsIdentity(propertyBuilder); + parentUnionGenTOBuilder.addToStringProperty(propertyBuilder); + + return subUnionGenTOBUilders; + } + + /** + * Wraps code which handle case when union subtype is of the type + * ExtendedType. + * + * If TO for this type already exists it is used for the creation of the + * property in parentUnionGenTOBuilder. In other case the base + * type is used for the property creation. + * + * @param parentUnionGenTOBuilder + * generated TO builder in which new property is created + * @param unionSubtype + * type definition of the ExtendedType type which + * represents union subtype + * @param unionTypeName + * string with the name for unionSubtype + * @param regularExpressions + * list of strings with the regular expressions + */ + private void resolveExtendedSubtypeAsUnion(final GeneratedTOBuilder parentUnionGenTOBuilder, + final ExtendedType unionSubtype, final String unionTypeName, final List regularExpressions) { + final Type genTO = findGenTO(unionSubtype, unionTypeName); + if (genTO != null) { + updateUnionTypeAsProperty(parentUnionGenTOBuilder, genTO, genTO.getName()); + } else { + final TypeDefinition baseType = baseTypeDefForExtendedType(unionSubtype); + if (unionTypeName.equals(baseType.getQName().getLocalName())) { + final Type javaType = BaseYangTypes.BASE_YANG_TYPES_PROVIDER.javaTypeForSchemaDefinitionType(baseType); + if (javaType != null) { + updateUnionTypeAsProperty(parentUnionGenTOBuilder, javaType, unionTypeName); + } + } + if (baseType instanceof StringType) { + regularExpressions.addAll(resolveRegExpressionsFromTypedef(unionSubtype)); + } + } + } + + /** + * Searches for generated TO for searchedTypeDef type + * definition in {@link #genTypeDefsContextMap genTypeDefsContextMap} + * + * @param searchedTypeDef + * type definition for which is generatet TO sought + * @param searchedTypeName + * string with name of searchedTypeDef + * @return generated TO for searchedTypeDef or + * null it it doesn't exist + */ + private Type findGenTO(final TypeDefinition searchedTypeDef, final String searchedTypeName) { + final Module typeModule = findParentModuleForTypeDefinition(schemaContext, searchedTypeDef); + if (typeModule != null && typeModule.getName() != null) { + final Map genTOs = genTypeDefsContextMap.get(typeModule.getName()); + if (genTOs != null) { + return genTOs.get(searchedTypeName); + } + } + return null; + } + + /** + * Stores generated TO created from genTOBuilder for + * newTypeDef to {@link #genTypeDefsContextMap + * genTypeDefsContextMap} if the module for newTypeDef exists + * + * @param newTypeDef + * type definition for which is genTOBuilder created + * @param genTOBuilder + * generated TO builder which is converted to generated TO and + * stored + */ + private void storeGenTO(TypeDefinition newTypeDef, GeneratedTOBuilder genTOBuilder) { + if (!(newTypeDef instanceof UnionType)) { Map genTOsMap = null; - // final Module parentModule = - // findParentModuleForTypeDefinition(schemaContext, typedef); + final Module parentModule = findParentModuleForTypeDefinition(schemaContext, newTypeDef); if (parentModule != null && parentModule.getName() != null) { genTOsMap = genTypeDefsContextMap.get(parentModule.getName()); - genTOsMap.put(typedef.getQName().getLocalName(), unionGenTransObject.toInstance()); + genTOsMap.put(newTypeDef.getQName().getLocalName(), genTOBuilder.toInstance()); } - - return unionGenTransObject; } - return null; } /** * Adds a new property with the name propertyName and with type * type to unonGenTransObject. - * + * * @param unionGenTransObject * generated TO to which should be property added * @param type @@ -834,7 +948,7 @@ public final class TypeProviderImpl implements TypeProvider { /** * Converts typedef to the generated TO builder. - * + * * @param basePackageName * string with name of package to which the module belongs * @param typedef @@ -859,10 +973,10 @@ public final class TypeProviderImpl implements TypeProvider { /** * Converts typeDef which should be of the type * BitsTypeDefinition to GeneratedTOBuilder. - * + * * All the bits of the typeDef are added to returning generated TO as * properties. - * + * * @param basePackageName * string with name of package to which the module belongs * @param typeDef @@ -913,13 +1027,13 @@ public final class TypeProviderImpl implements TypeProvider { /** * Converts the pattern constraints from typedef to the list of * the strings which represents these constraints. - * + * * @param typedef * extended type in which are the pattern constraints sought * @return list of strings which represents the constraint patterns * @throws IllegalArgumentException * if typedef equals null - * + * */ private List resolveRegExpressionsFromTypedef(ExtendedType typedef) { final List regExps = new ArrayList(); @@ -943,10 +1057,10 @@ public final class TypeProviderImpl implements TypeProvider { } /** - * + * * Adds to the genTOBuilder the constant which contains regular * expressions from the regularExpressions - * + * * @param genTOBuilder * generated TO builder to which are * regular expressions added @@ -975,11 +1089,11 @@ public final class TypeProviderImpl implements TypeProvider { * innerExtendedType, about the package name * typedefName and about the generated TO name * typedefName. - * + * * It is supposed that innerExtendedType is already present in * {@link TypeProviderImpl#genTypeDefsContextMap genTypeDefsContextMap} to * be possible set it as extended type for the returning generated TO. - * + * * @param innerExtendedType * extended type which is part of some other extended type * @param basePackageName @@ -1035,7 +1149,7 @@ public final class TypeProviderImpl implements TypeProvider { * equal depth. In next step are lists from this map concatenated to one * list in ascending order according to their depth. All type definitions * are in the list behind all type definitions on which depends. - * + * * @param unsortedTypeDefinitions * list of type definitions which should be sorted by depth * @return list of type definitions sorted according their each other @@ -1069,7 +1183,7 @@ public final class TypeProviderImpl implements TypeProvider { /** * Returns how many immersion is necessary to get from the type definition * to the base type. - * + * * @param typeDefinition * type definition for which is depth sought. * @return number of immersions which are necessary to get from the type @@ -1099,4 +1213,24 @@ public final class TypeProviderImpl implements TypeProvider { return depth; } + /** + * Returns string which contains the same value as name but + * integer suffix is incremented by one. If name contains no + * number suffix then number 1 is added. + * + * @param name + * string with name of augmented node + * @return string with the number suffix incremented by one (or 1 is added) + */ + private String provideAvailableNameForGenTOBuilder(String name) { + Pattern searchedPattern = Pattern.compile("[0-9]+\\z"); + Matcher mtch = searchedPattern.matcher(name); + if (mtch.find()) { + final int newSuffix = Integer.valueOf(name.substring(mtch.start())) + 1; + return name.substring(0, mtch.start()) + newSuffix; + } else { + return name + 1; + } + } + } 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 1ef58b9ec9..c258684065 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 @@ -7,6 +7,8 @@ */ 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; @@ -17,6 +19,8 @@ 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; @@ -118,6 +122,27 @@ public final class EnumerationBuilderImpl extends AbstractBaseType implements En 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; 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 c58a781761..44263a526e 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 @@ -9,6 +9,7 @@ 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. @@ -40,6 +41,11 @@ class ClassTemplate { */ val List consts + /** + * List of generated types which are enclosed inside genType + */ + val List enclosedGeneratedTypes; + /** * Creates instance of this class with concrete genTO. * @@ -55,6 +61,7 @@ class ClassTemplate { this.fields = genTO.properties this.enums = genTO.enumerations this.consts = genTO.constantDefinitions + this.enclosedGeneratedTypes = genTO.enclosedTypes } /** @@ -86,6 +93,7 @@ class ClassTemplate { def private generateBody(boolean isInnerClass) ''' «genTO.comment.generateComment» «generateClassDeclaration(isInnerClass)» { + «generateInnerClasses» «generateEnums» @@ -112,6 +120,24 @@ class ClassTemplate { } ''' + + /** + * 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. * 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 f4cab6242f..3b319ca955 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 @@ -50,7 +50,7 @@ public final class GeneratorUtil { throw new IllegalArgumentException("Generated Type cannot be NULL!"); } final Map imports = new LinkedHashMap<>(); - imports.put(genType.getName(), genType.getPackageName()); + List childGeneratedTypes = genType.getEnclosedTypes(); if (!childGeneratedTypes.isEmpty()) { for (GeneratedType genTypeChild : childGeneratedTypes) { 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 d49edf9f5e..70ea929bc3 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 @@ -137,6 +137,7 @@ class InterfaceTemplate { «IF (innerClass instanceof GeneratedTransferObject)» «val classTemplate = new ClassTemplate(innerClass as GeneratedTransferObject)» «classTemplate.generateAsInnerClass» + «ENDIF» «ENDFOR» «ENDIF» diff --git a/code-generator/binding-model-api/pom.xml b/code-generator/binding-model-api/pom.xml index e2a3824736..5c8dc5ba4e 100644 --- a/code-generator/binding-model-api/pom.xml +++ b/code-generator/binding-model-api/pom.xml @@ -1,15 +1,22 @@ - - - - org.opendaylight.yangtools - binding-generator - 0.5.7-SNAPSHOT - - - 4.0.0 - binding-model-api - ${project.artifactId} - ${project.artifactId} - - + + + + org.opendaylight.yangtools + binding-generator + 0.5.7-SNAPSHOT + + + 4.0.0 + binding-model-api + ${project.artifactId} + ${project.artifactId} + + + + org.opendaylight.yangtools + yang-model-api + 0.5.7-SNAPSHOT + + + diff --git a/code-generator/binding-model-api/src/main/java/org/opendaylight/yangtools/sal/binding/model/api/type/builder/EnumBuilder.java b/code-generator/binding-model-api/src/main/java/org/opendaylight/yangtools/sal/binding/model/api/type/builder/EnumBuilder.java index 4342cb93d1..71a36caf32 100644 --- a/code-generator/binding-model-api/src/main/java/org/opendaylight/yangtools/sal/binding/model/api/type/builder/EnumBuilder.java +++ b/code-generator/binding-model-api/src/main/java/org/opendaylight/yangtools/sal/binding/model/api/type/builder/EnumBuilder.java @@ -9,41 +9,53 @@ package org.opendaylight.yangtools.sal.binding.model.api.type.builder; import org.opendaylight.yangtools.sal.binding.model.api.Enumeration; import org.opendaylight.yangtools.sal.binding.model.api.Type; +import org.opendaylight.yangtools.yang.model.api.type.EnumTypeDefinition; /** * Enum Builder is interface that contains methods to build and instantiate * Enumeration definition. - * + * * @see Enumeration */ public interface EnumBuilder extends Type { /** - * The method creates new AnnotationTypeBuilder containing specified - * package name an annotation name. - *
    - * Neither the package name or annotation name can contain - * null references. In case that - * any of parameters contains null the method SHOULD thrown - * {@link IllegalArgumentException} - * - * @param packageName Package Name of Annotation Type - * @param name Name of Annotation Type + * The method creates new AnnotationTypeBuilder containing specified package + * name an annotation name.
    + * Neither the package name or annotation name can contain null + * references. In case that any of parameters contains null the + * method SHOULD thrown {@link IllegalArgumentException} + * + * @param packageName + * Package Name of Annotation Type + * @param name + * Name of Annotation Type * @return new instance of Annotation Type Builder. */ public AnnotationTypeBuilder addAnnotation(final String packageName, final String name); /** - * + * * @param name * @param value */ public void addValue(final String name, final Integer value); /** - * + * * @param definingType * @return */ public Enumeration toInstance(final Type definingType); + + /** + * Updates this builder with data from enumTypeDef. + * Specifically this data represents list of value-name pairs. + * + * @param enumTypeDef + * enum type definition as source of enum data for + * enumBuilder + */ + public void updateEnumPairsFromEnumTypeDef(final EnumTypeDefinition enumTypeDef); + } -- 2.36.6