Author: fdesbois Date: 2010-06-25 20:03:00 +0200 (Fri, 25 Jun 2010) New Revision: 2035 Url: http://nuiton.org/repositories/revision/topia/2035 Log: Evo #609 : Refactor constant generation + clean generate header for interface Modified: trunk/topia-persistence/src/main/java/org/nuiton/topia/generator/EntityTransformer.java Modified: trunk/topia-persistence/src/main/java/org/nuiton/topia/generator/EntityTransformer.java =================================================================== --- trunk/topia-persistence/src/main/java/org/nuiton/topia/generator/EntityTransformer.java 2010-06-25 17:14:37 UTC (rev 2034) +++ trunk/topia-persistence/src/main/java/org/nuiton/topia/generator/EntityTransformer.java 2010-06-25 18:03:00 UTC (rev 2035) @@ -95,6 +95,8 @@ protected ObjectModelClass outputImpl; + private boolean associationClass; + protected void clean() { outputInterface = null; outputAbstract = null; @@ -140,10 +142,21 @@ outputInterface = createInterface(clazzName, packageName); outputAbstract = createAbstractClass(clazzName + "Abstract", packageName); - // Generate all methods needed for each entity attribute - generateOperationsFromAttributes(input.getAttributes()); + generateHeaders(input); - generateInterface(input, outputInterface, attributes, operations); + generateProperties(input); + + // Case of association class : properties from participants/extremities + // of the association class. + if (input instanceof ObjectModelAssociationClass) { + ObjectModelAssociationClass association = (ObjectModelAssociationClass)input; + generatePropertiesFromAssociation(association); + } + + generateExtraConstants(input); + + generateExtraOperations(input); + generateAbstract(input, outputAbstract, attributes, operations); boolean generateImpl = isGenerateImpl(input, operations); @@ -169,54 +182,104 @@ clean(); } - protected boolean isGenerateImpl(ObjectModelClass input, - Collection<ObjectModelOperation> operations) { + protected void generateHeaders(ObjectModelClass input) { - String fqn = input.getQualifiedName() + "Impl"; + ////// For Interface + addImport(outputInterface, TopiaEntity.class); - URL fileLocation = getFileInClassPath(fqn); + if (TopiaGeneratorUtil.hasDocumentation(input)) { + setDocumentation(outputInterface, input.getDocumentation()); + } - if (fileLocation != null) { + // super interfaces + for (ObjectModelClassifier parent : input.getInterfaces()) { + addInterface(outputInterface, parent.getQualifiedName()); + } - // there is already a existing file in class-path, skip - if (isVerbose()) { - log.info("Will not generate [" + fqn + "], found existing file in class-path : " + fileLocation); + boolean needTopiaEntity = true; + for (ObjectModelClassifier parent : input.getSuperclasses()) { + if (parent.hasStereotype(STEREOTYPE_ENTITY)) { + addInterface(outputInterface, parent.getQualifiedName()); + needTopiaEntity = false; + break; } - return false; } - // On ne génère pas le impl si l'entité a des opérations qui ne sont - // pas seulement pour le DAO - if (!operations.isEmpty()) { + if (needTopiaEntity) { + addInterface(outputInterface, TopiaEntity.class); + } + } - if (isVerbose()) { - log.info("Will not generate [" + fqn + "], there is some operations and not only DAO ones"); + /** + * Generate properties from {@code input} entity class. Generate + * constant and operations for each property. + * + * @param input Input entity class + */ + protected void generateProperties(ObjectModelClass input) { + for (ObjectModelAttribute attribute : input.getAttributes()) { + + // FIXME-fdesbois-2010-06-25 : Stupid case, need to be removed + if (!attribute.isNavigable() && attribute.hasAssociationClass()) { + generatePropertyConstant(attribute); } - return false; - } - //De même, on ne génère pas le impl si il y a des opérations venant des - // superclasses non implémentées - for (ObjectModelOperation otherOp : input.getAllOtherOperations(false)) { - if (otherOp.isAbstract()) { - if (isVerbose()) { - log.info("Will not generate [" + fqn + "], there is a abstract operation [" + otherOp.getName() + "] in allOtherOperations."); - } - return false; + if (!attribute.isNavigable() && + !TopiaGeneratorUtil.hasUnidirectionalRelationOnAbstractType( + attribute.getReverseAttribute(), model)) { + continue; } + + generatePropertyConstant(attribute); + + generatePropertyOperations(attribute); } + } - return true; + /** + * Generate properties from {@code input} entity assocation class. Generate + * constant and operations for each property. + * + * @param association Input entity association class + */ + protected void generatePropertiesFromAssociation(ObjectModelAssociationClass association) { + associationClass = true; + for (ObjectModelAttribute attribute : association.getParticipantsAttributes()) { + + generatePropertyConstant(attribute); + + addSingleSetOperation(attribute); + + addSingleGetOperation(attribute, null); + } + associationClass = false; } /** - * Generation operations for each attribute from {@code attributes} collection. - * One method is created for each operation to generate. Methods starting + * Generate constant in interface for {@code attribute}. + * + * @param attribute Input attribute to treate + * @see #getPropertyName(ObjectModelAttribute) + */ + protected void generatePropertyConstant(ObjectModelAttribute attribute) { + String attrName = getPropertyName(attribute); + + if (isVerbose()) { + log.info("Generate constant for property : " + attrName); + } + + addAttribute(outputInterface, getConstantName(attrName), String.class, + "\"" + attrName + "\""); + } + + /** + * Generation operations for {@code attributes}. + * One method exists for each operation to generate. Methods starting * with 'addSingle' is for maxMultiplicity attribute = 1 and for collection * case, methods start with 'addMultiple'. Other case are take care in each * method (association class, reverse, entity reference, ...). * - * @param attributes Input attributes to treate + * @param attribute Input attribute to treate * @see #addSingleGetOperation(ObjectModelAttribute, String) * @see #addSingleSetOperation(ObjectModelAttribute) * @see #addMultipleAddOperation(ObjectModelAttribute, String) @@ -230,79 +293,154 @@ * @see #addMultipleSizeOperation(ObjectModelAttribute) * @see #addMultipleIsEmptyOperation(ObjectModelAttribute) */ - protected void generateOperationsFromAttributes(Collection<ObjectModelAttribute> attributes) { + protected void generatePropertyOperations(ObjectModelAttribute attribute) { - for (ObjectModelAttribute attribute : attributes) { + if (attribute.getMaxMultiplicity() == 1) { - if (!attribute.isNavigable() && - !TopiaGeneratorUtil.hasUnidirectionalRelationOnAbstractType( - attribute.getReverseAttribute(), model)) { - continue; - } + // setXXX + addSingleSetOperation(attribute); - if (attribute.getMaxMultiplicity() == 1) { + // getXXX + addSingleGetOperation(attribute, null); - // setXXX - addSingleSetOperation(attribute); + } else { - // getXXX - addSingleGetOperation(attribute, null); + // List, Set or Collection ? + String collectionInterface = + TopiaGeneratorUtil.getNMultiplicityInterfaceType(attribute); + String collectionImpl = + TopiaGeneratorUtil.getNMultiplicityObjectType(attribute); - } else { + addImport(outputInterface, collectionInterface); + addImport(outputAbstract, collectionInterface); + addImport(outputAbstract, collectionImpl); - // List, Set or Collection ? - String collectionInterface = - TopiaGeneratorUtil.getNMultiplicityInterfaceType(attribute); - String collectionImpl = - TopiaGeneratorUtil.getNMultiplicityObjectType(attribute); + collectionInterface = + TopiaGeneratorUtil.getSimpleName(collectionInterface); + collectionImpl = + TopiaGeneratorUtil.getSimpleName(collectionImpl); - addImport(outputInterface, collectionInterface); - addImport(outputAbstract, collectionInterface); - addImport(outputAbstract, collectionImpl); + // addXXX + addMultipleAddOperation(attribute, collectionImpl); - collectionInterface = - TopiaGeneratorUtil.getSimpleName(collectionInterface); - collectionImpl = - TopiaGeneratorUtil.getSimpleName(collectionImpl); + // addAllXXX + addMultipleAddAllOperation(attribute, collectionInterface); - // addXXX - addMultipleAddOperation(attribute, collectionImpl); + // setXXX + addMultipleSetOperation(attribute, collectionInterface, collectionImpl); - // addAllXXX - addMultipleAddAllOperation(attribute, collectionInterface); + // removeXXX + addMultipleRemoveOperation(attribute); - // setXXX - addMultipleSetOperation(attribute, collectionInterface, collectionImpl); + // clearXXX + addMultipleClearOperation(attribute, collectionInterface, collectionImpl); - // removeXXX - addMultipleRemoveOperation(attribute); + // getXXX + addMultipleGetOperation(attribute, collectionInterface); - // clearXXX - addMultipleClearOperation(attribute, collectionInterface, collectionImpl); + if (!TopiaGeneratorUtil.isPrimitiveType(attribute) && + !TopiaGeneratorUtil.isDateType(attribute)) { - // getXXX - addMultipleGetOperation(attribute, collectionInterface); + // getXXXByTopiaId + addMultipleGetTopiaIdOperation(attribute); + } - if (!TopiaGeneratorUtil.isPrimitiveType(attribute) && - !TopiaGeneratorUtil.isDateType(attribute)) { + if (attribute.hasAssociationClass()) { + // getXXX with entity parameter + addMultipleGetOperationFromEntity(attribute); + } - // getXXXByTopiaId - addMultipleGetTopiaIdOperation(attribute); - } + // sizeXXX + addMultipleSizeOperation(attribute); - if (attribute.hasAssociationClass()) { - // getXXX with entity parameter - addMultipleGetOperationFromEntity(attribute); + // isXXXEmpty + addMultipleIsEmptyOperation(attribute); + } + } + + /** + * Generate extra constants if {@code input} has dependencies on + * enum used as constant injector. + * + * @param input Entity class to treate + */ + protected void generateExtraConstants(ObjectModelClass input) { + Set<String> constants = addConstantsFromDependency(input, outputInterface); + + if (log.isDebugEnabled()) { + log.debug("Add constants from dependency : " + constants); + } + } + + protected void generateExtraOperations(ObjectModelClass input) { + for (ObjectModelOperation operation : input.getOperations()) { + String visibility = operation.getVisibility(); + if (operation.hasStereotype(TopiaGeneratorUtil.STEREOTYPE_DAO) || + !visibility.equals(ObjectModelModifier.PUBLIC.toString())) { + // Pas de génération des signatures de méthodes pour celles à intégrer au DAO de l'entité + return; + } + + String opName = operation.getName(); + String opType = operation.getReturnType(); + + ObjectModelOperation op2 = addOperation(outputInterface, opName, opType, ObjectModelModifier.PACKAGE); + if (TopiaGeneratorUtil.hasDocumentation(operation)) { + setDocumentation(op2, operation.getDocumentation()); + } + + for (ObjectModelParameter param : operation.getParameters()) { + String paramName = param.getName(); + String paramType = param.getType(); + ObjectModelParameter param2 = addParameter(op2, paramType, paramName); + if (TopiaGeneratorUtil.hasDocumentation(param)) { + setDocumentation(param2, param.getDocumentation()); } + } + for (String exception : operation.getExceptions()) { + addException(op2, exception); + } + } + } - // sizeXXX - addMultipleSizeOperation(attribute); + protected boolean isGenerateImpl(ObjectModelClass input, + Collection<ObjectModelOperation> operations) { - // isXXXEmpty - addMultipleIsEmptyOperation(attribute); + String fqn = input.getQualifiedName() + "Impl"; + + URL fileLocation = getFileInClassPath(fqn); + + if (fileLocation != null) { + + // there is already a existing file in class-path, skip + if (isVerbose()) { + log.info("Will not generate [" + fqn + "], found existing file in class-path : " + fileLocation); } + return false; + } + // On ne génère pas le impl si l'entité a des opérations qui ne sont + // pas seulement pour le DAO + if (!operations.isEmpty()) { + + if (isVerbose()) { + log.info("Will not generate [" + fqn + "], there is some operations and not only DAO ones"); + } + return false; } + + //De même, on ne génère pas le impl si il y a des opérations venant des + // superclasses non implémentées + for (ObjectModelOperation otherOp : input.getAllOtherOperations(false)) { + if (otherOp.isAbstract()) { + if (isVerbose()) { + log.info("Will not generate [" + fqn + "], there is a abstract operation [" + otherOp.getName() + "] in allOtherOperations."); + } + return false; + } + } + + return true; } protected void addSingleSetOperation(ObjectModelAttribute attribute) { @@ -310,6 +448,11 @@ String attrName = getPropertyName(attribute); String attrType = getPropertyType(attribute); + if (isVerbose()) { + log.info("Generate single 'set' operation for property : " + attrName + + " [" + attrType + "]"); + } + // Interface operation ObjectModelOperation interfaceOperation = createPropertySetterSignature(outputInterface, attrType, attrName, @@ -351,9 +494,9 @@ operationPrefix = TopiaGeneratorUtil.OPERATION_GETTER_DEFAULT_PREFIX; } - if (log.isDebugEnabled()) { - log.debug("Add getter operation for " + attrName + - " prefix = " + operationPrefix); + if (isVerbose()) { + log.info("Generate single '" + operationPrefix + "' operation for property : " + + attrName + " [" + attrType + "]"); } // Interface operation @@ -395,6 +538,11 @@ String attrType = getPropertyType(attribute); ObjectModelAttribute reverse = attribute.getReverseAttribute(); + if (isVerbose()) { + log.info("Generate multiple 'add' operation for property : " + attrName + + " [" + attrType + "]"); + } + // Interface operation ObjectModelOperation interfaceOperation = addOperation(outputInterface, "add" + StringUtils.capitalize(attrName), @@ -461,6 +609,11 @@ String attrName = getPropertyName(attribute); String attrType = getPropertyType(attribute); + if (isVerbose()) { + log.info("Generate multiple 'addAll' operation for property : " + attrName + + " [" + attrType + "]"); + } + // Interface operation ObjectModelOperation interfaceOperation = addOperation(outputInterface, "addAll" + StringUtils.capitalize(attrName), @@ -498,6 +651,11 @@ String referenceType = getPropertyType(attribute); String attrType = collectionInterface + "<" + referenceType + ">"; + if (isVerbose()) { + log.info("Generate multiple 'set' operation for property : " + attrName + + " [" + attrType + "]"); + } + // Interface operation ObjectModelOperation interfaceOperation = createPropertySetterSignature(outputInterface, attrType, attrName, @@ -527,6 +685,11 @@ String attrType = getPropertyType(attribute); ObjectModelAttribute reverse = attribute.getReverseAttribute(); + if (isVerbose()) { + log.info("Generate 'remove' operation for property : " + attrName + + " [" + attrType + "]"); + } + // Interface operation ObjectModelOperation interfaceOperation = addOperation(outputInterface, "remove" + StringUtils.capitalize(attrName), @@ -591,6 +754,11 @@ String attrType = getPropertyType(attribute); ObjectModelAttribute reverse = attribute.getReverseAttribute(); + if (isVerbose()) { + log.info("Generate multiple 'clear' operation for property : " + attrName + + " [" + attrType + "]"); + } + // Interface operation ObjectModelOperation interfaceOperation = addOperation(outputInterface, "clear" + StringUtils.capitalize(attrName), @@ -655,6 +823,11 @@ String attrName = getPropertyName(attribute); String attrType = collectionInterface + "<" + getPropertyType(attribute) + ">"; + if (isVerbose()) { + log.info("Generate multiple 'get' operation for property : " + attrName + + " [" + attrType + "]"); + } + // Interface operation ObjectModelOperation interfaceOperation = addOperation(outputInterface, "get" + StringUtils.capitalize(attrName), @@ -679,6 +852,11 @@ String attrName = getPropertyName(attribute); String attrType = getPropertyType(attribute); + if (isVerbose()) { + log.info("Generate multiple 'getByTopiaId' operation for property : " + attrName + + " [" + attrType + "]"); + } + // Interface operation ObjectModelOperation interfaceOperation = addOperation(outputInterface, "get" + StringUtils.capitalize(attrName) + "ByTopiaId", @@ -714,6 +892,11 @@ String attrName = getPropertyName(attribute); String attrType = getPropertyType(attribute); + if (isVerbose()) { + log.info("Generate multiple 'getFromEntity' operation for property : " + attrName + + " [" + attrType + "]"); + } + // Interface operation ObjectModelOperation interfaceOperation = addOperation(outputInterface, @@ -749,6 +932,10 @@ String attrName = getPropertyName(attribute); + if (isVerbose()) { + log.info("Generate multiple 'size' operation for property : " + attrName); + } + // Interface operation ObjectModelOperation interfaceOperation = addOperation(outputInterface, "size" + StringUtils.capitalize(attrName), @@ -775,6 +962,10 @@ String attrName = getPropertyName(attribute); + if (isVerbose()) { + log.info("Generate multiple 'isEmpty' operation for property : " + attrName); + } + // Interface operation ObjectModelOperation interfaceOperation = addOperation(outputInterface, "is" + StringUtils.capitalize(attrName) + "Empty", @@ -798,6 +989,7 @@ ///////////////////////////////// OLD + @Deprecated protected void generateInterface(ObjectModelClass input, ObjectModelInterface output, Collection<ObjectModelAttribute> attributes, @@ -862,6 +1054,7 @@ } } + @Deprecated protected void generateAbstract(ObjectModelClass input, ObjectModelClass output, Collection<ObjectModelAttribute> attributes, @@ -1057,20 +1250,20 @@ // transformAttribute(output, attr, reverse); // } - + // DONE //Méthodes d'accès aux attributs d'une classe d'associations - if (input instanceof ObjectModelAssociationClass) { +// if (input instanceof ObjectModelAssociationClass) { +// +// for (ObjectModelAttribute attr : +// ((ObjectModelAssociationClass) input).getParticipantsAttributes()) { +// if (attr != null) { +// String attrType = TopiaGeneratorUtil.getSimpleName(attr.getType()); +// String attrName = attr.getName(); +// generateAssociationAccessors(output, attrName, attrType); +// } +// } +// } - for (ObjectModelAttribute attr : - ((ObjectModelAssociationClass) input).getParticipantsAttributes()) { - if (attr != null) { - String attrType = TopiaGeneratorUtil.getSimpleName(attr.getType()); - String attrName = attr.getName(); - generateAssociationAccessors(output, attrName, attrType); - } - } - } - generateAbstractMethods(output, input); boolean doGenerateToString = TopiaGeneratorUtil.generateToString(input, @@ -1100,15 +1293,16 @@ // Interface generation // ------------------------------------------------------------------------- + @Deprecated private void generateInterfaceStaticColumnNames(ObjectModelClass input, ObjectModelInterface output) { for (ObjectModelAttribute attr : input.getAttributes()) { ObjectModelAttribute reverse = attr.getReverseAttribute(); - if (!(attr.isNavigable() || - TopiaGeneratorUtil.hasUnidirectionalRelationOnAbstractType( + if (!attr.isNavigable() && + !TopiaGeneratorUtil.hasUnidirectionalRelationOnAbstractType( reverse, model) - || attr.hasAssociationClass())) { + && !attr.hasAssociationClass()) { continue; } String attrName; @@ -1143,6 +1337,7 @@ } } + @Deprecated private void generateInterfaceOperation(ObjectModelOperation op, ObjectModelInterface output) { @@ -1175,6 +1370,7 @@ } } + @Deprecated private void generateInterfaceAssociationAccessors(ObjectModelInterface output, String attrName, String attrType) { @@ -1631,7 +1827,7 @@ protected String getPropertyName(ObjectModelAttribute attribute) { String propertyName = attribute.getName(); - if (attribute.hasAssociationClass()) { + if (!associationClass && attribute.hasAssociationClass()) { propertyName = TopiaGeneratorUtil.getAssocAttrName(attribute); } return propertyName; @@ -1639,7 +1835,7 @@ protected String getPropertyType(ObjectModelAttribute attribute) { String propertyType = attribute.getType(); - if (attribute.hasAssociationClass()) { + if (!associationClass && attribute.hasAssociationClass()) { propertyType = attribute.getAssociationClass().getQualifiedName(); } return propertyType;