Author: tchemit Date: 2009-12-15 00:19:01 +0100 (Tue, 15 Dec 2009) New Revision: 1711 Added: branches/from2.2.2-eugene2-beta/topia-persistence/src/main/java/org/nuiton/topia/generator/EntityAbstractTransformer.java Modified: branches/from2.2.2-eugene2-beta/topia-persistence/pom.xml Log: - add EntityAbstractTransformer - use common config in eugene goal Modified: branches/from2.2.2-eugene2-beta/topia-persistence/pom.xml =================================================================== --- branches/from2.2.2-eugene2-beta/topia-persistence/pom.xml 2009-12-14 23:17:25 UTC (rev 1710) +++ branches/from2.2.2-eugene2-beta/topia-persistence/pom.xml 2009-12-14 23:19:01 UTC (rev 1711) @@ -134,18 +134,20 @@ <plugin> <groupId>org.nuiton.eugene</groupId> <artifactId>maven-eugene-plugin</artifactId> + <configuration> + <testPhase>true</testPhase> + <extraClassPathDirectory>target/classes</extraClassPathDirectory> + </configuration> <executions> <execution> <id>Test Generator models</id> <phase>generate-test-sources</phase> <configuration> - <testPhase>true</testPhase> <modelType>objectmodel</modelType> <includes> <include>src/test/xmi:**/*.zargo</include> </includes> <outputDirectory>target/generated-sources/test-models</outputDirectory> - <extraClassPathDirectory>target/classes</extraClassPathDirectory> <fullPackagePath>org.nuiton.topia</fullPackagePath> <resolver>org.nuiton.util.FasterCachedResourceResolver</resolver> </configuration> @@ -157,7 +159,6 @@ <id>Test Generator</id> <phase>generate-test-sources</phase> <configuration> - <testPhase>true</testPhase> <reader>org.nuiton.eugene.ObjectModelReader</reader> <includes>**/*.objectmodel</includes> <templates>org.nuiton.topia.generator.TopiaMetaGenerator, @@ -166,7 +167,6 @@ org.nuiton.topia.generator.EntityDTOTransformer </templates> <defaultPackage>org.nuiton.topia</defaultPackage> - <extraClassPathDirectory>target/classes</extraClassPathDirectory> </configuration> <goals> <goal>generate</goal> Added: branches/from2.2.2-eugene2-beta/topia-persistence/src/main/java/org/nuiton/topia/generator/EntityAbstractTransformer.java =================================================================== --- branches/from2.2.2-eugene2-beta/topia-persistence/src/main/java/org/nuiton/topia/generator/EntityAbstractTransformer.java (rev 0) +++ branches/from2.2.2-eugene2-beta/topia-persistence/src/main/java/org/nuiton/topia/generator/EntityAbstractTransformer.java 2009-12-14 23:19:01 UTC (rev 1711) @@ -0,0 +1,1043 @@ +package org.nuiton.topia.generator; + +import org.apache.commons.lang.StringUtils; +import org.apache.commons.lang.builder.ToStringBuilder; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.nuiton.eugene.GeneratorUtil; +import org.nuiton.eugene.java.ObjectModelTransformerToJava; +import org.nuiton.eugene.models.object.*; +import org.nuiton.topia.TopiaException; +import org.nuiton.topia.framework.TopiaContextImplementor; +import static org.nuiton.topia.generator.TopiaGeneratorUtil.*; +import org.nuiton.topia.persistence.EntityVisitor; +import org.nuiton.topia.persistence.TopiaEntity; +import org.nuiton.topia.persistence.TopiaEntityAbstract; + +import java.io.Serializable; +import java.util.ArrayList; +import java.util.List; + +/*{generator option: parentheses = false}*/ + +/*{generator option: writeString = +}*/ + +/** + * Created: 14 déc. 2009 + * + * @author Tony Chemit <chemit@codelutin.com> Copyright Code Lutin + * @version $Revision$ + * <p/> + * Mise a jour: $Date$ par : + * $Author: tchemit $ + */ +public class EntityAbstractTransformer extends ObjectModelTransformerToJava { + + /** + * Logger + */ + private static final Log log = LogFactory.getLog(EntityAbstractTransformer.class); + + @Override + public void transformFromClass(ObjectModelClass clazz) { + if (!clazz.hasStereotype(TopiaGeneratorUtil.STEREOTYPE_ENTITY)) { + return; + } + + String clazzName = clazz.getName(); + String clazzFQN = TopiaGeneratorUtil.getSimpleName(clazz.getQualifiedName()); + + ObjectModelClass result; + + if (log.isInfoEnabled()) { + log.info("for entity : " + clazz.getQualifiedName()); + } + + result = createAbstractClass(clazzName + "Abstract", clazz.getPackageName()); + + addInterface(result, clazzName); + + addImport(result, ArrayList.class); + addImport(result, List.class); + addImport(result, Serializable.class); + addImport(result, ToStringBuilder.class); + addImport(result, TopiaEntity.class); + addImport(result, TopiaContextImplementor.class); + + // javadoc + + StringBuilder doc = new StringBuilder(); + doc.append("Implantation POJO pour l'entité {@link ").append(StringUtils.capitalize(clazzFQN)).append("}\n"); + + { + String dbName = clazz.getTagValue(TopiaGeneratorUtil.TAG_DB_NAME); + if (dbName != null) { + doc.append("<p>Nom de l'entité en BD : ").append(dbName).append(".</p>"); + } + } + + setDocumentation(result, doc.toString()); + + // super classes + + for (ObjectModelClass parent : clazz.getSuperclasses()) { + String extendClass = parent.getQualifiedName(); + //Si une des classes parentes définies des méthodes abstraites, son + // impl ne sera pas créé + boolean abstractParent = shouldBeAbstract(parent); + if (parent.hasStereotype(TopiaGeneratorUtil.STEREOTYPE_ENTITY)) { + if (abstractParent) { + extendClass += "Abstract"; + } else { + extendClass += "Impl"; + } + } + setSuperClass(result, extendClass); + } + + if (result.getSuperclasses().isEmpty()) { + setSuperClass(result, TopiaEntityAbstract.class); + } + + // serialVersionUID + + String svUID = TopiaGeneratorUtil.findTagValue("serialVersionUID", clazz, model); + if (svUID != null) { + addAttribute(result, "serialVersionUID", long.class, svUID, ObjectModelModifier.PRIVATE, ObjectModelModifier.STATIC, ObjectModelModifier.FINAL); + + } + + ObjectModelParameter attr2; + + for (ObjectModelAttribute attr : clazz.getAttributes()) { + ObjectModelAttribute reverse = attr.getReverseAttribute(); + + // pour les asso quoi qu'il arrive il faut les lier des 2 cotes + // pour pouvoir supprimer en cascade l'asso lors de la suppression + // d'un des cotes + if (!(attr.isNavigable() + || hasUnidirectionalRelationOnAbstractType(reverse, model) + || attr.hasAssociationClass())) { + continue; + } + + String type; + String name; + + if (!attr.hasAssociationClass()) { + String attrName = attr.getName(); + name = attrName; + type = attr.getType(); +// type = TopiaGeneratorUtil.getSimpleName(attr.getType()); + } else { + String assocAttrName = TopiaGeneratorUtil.getAssocAttrName(attr); + //TODO THIMEL : Je pense que les GeneratorUtil.toLowerCaseFirstLetter sont inutiles ici, ou alors il faudrait le faire partout + name = GeneratorUtil.toLowerCaseFirstLetter(assocAttrName); + type = attr.getAssociationClass().getQualifiedName(); +// type = TopiaGeneratorUtil.getSimpleName(attr.getAssociationClass().getQualifiedName()); + } + + if (GeneratorUtil.isNMultiplicity(attr)) { + String collectionType = TopiaGeneratorUtil.getNMultiplicityInterfaceType(attr); + type = collectionType + "<" + type + ">"; + } + + String attrVisibility = attr.getVisibility(); + + attr2 = addAttribute(result, name, type, null, ObjectModelModifier.toValue(attrVisibility)); + + + doc = new StringBuilder(); + + if (TopiaGeneratorUtil.hasDocumentation(attr) || attr.hasTagValue(TopiaGeneratorUtil.TAG_DB_NAME)) { + if (TopiaGeneratorUtil.hasDocumentation(attr)) { + String attrDocumentation = attr.getDocumentation(); + doc.append(attrDocumentation).append("\n"); + } + if (attr.hasTagValue(TopiaGeneratorUtil.TAG_DB_NAME)) { + String dbName = attr.getTagValue(TopiaGeneratorUtil.TAG_DB_NAME); + doc.append("Nom de l'attribut en BD : ").append(dbName).append("\n"); + } + } + + setDocumentation(attr2, doc.toString()); + + + if (attr.hasTagValue(TopiaGeneratorUtil.TAG_ANNOTATION)) { + String annotation = attr.getTagValue(TopiaGeneratorUtil.TAG_ANNOTATION); + //FIXME Make annotation works... +///* <%=annotation%> +//*/ + } + } + + //Déclaration des attributs d'une classe d'associations + if (clazz instanceof ObjectModelAssociationClass) { + ObjectModelAssociationClass assoc = (ObjectModelAssociationClass) clazz; + for (ObjectModelAttribute attr : assoc.getParticipantsAttributes()) { + if (attr != null) { + String attrVisibility = attr.getVisibility(); + String attrType = attr.getType(); + String attrName = attr.getName(); + addAttribute(result, GeneratorUtil.toLowerCaseFirstLetter(attrName), attrType, null, ObjectModelModifier.toValue(attrVisibility)); + } + } + } + + ObjectModelOperation op = addOperation(result, "update", "void", ObjectModelModifier.PUBLIC); + addException(op, TopiaException.class); + setOperationBody(op, "" +/*{ + ((TopiaContextImplementor)getTopiaContext()).getDAO(<%=clazzName%>.class).update(this); +}*/ + ); + + op = addOperation(result, "delete", "void", ObjectModelModifier.PUBLIC); + addException(op, TopiaException.class); + setOperationBody(op, "" +/*{ + ((TopiaContextImplementor)getTopiaContext()).getDAO(<%=clazzName%>.class).delete(this); +}*/ + ); + + generateAcceptMethod(result, clazz); + + generateAggregateMethod(result, clazz); + + generateCompositeMethod(result, clazz); + + + for (ObjectModelAttribute attr : clazz.getAttributes()) { + ObjectModelAttribute reverse = attr.getReverseAttribute(); + + if (!(attr.isNavigable() + || hasUnidirectionalRelationOnAbstractType(reverse, model))) { + continue; + } + + transformAttribute(result, attr, reverse); + } + + + //Méthodes d'accès aux attributs d'une classe d'associations + if (clazz instanceof ObjectModelAssociationClass) { + generateAssociationAccessors(result, (ObjectModelAssociationClass) clazz); + } + + boolean doGenerateToString = TopiaGeneratorUtil.generateToString(clazz, model); + if (doGenerateToString) { + generateToStringMethod(result, clazz); + } + + String i18nPrefix = TopiaGeneratorUtil.getI18nPrefix(clazz, model); + if (i18nPrefix != null) { + // generate i18n prefix + generateI18n(result, i18nPrefix, clazz); + } + } + + protected void transformAttribute(ObjectModelClass result, ObjectModelAttribute attr, ObjectModelAttribute reverse) { + + String attrName = attr.getName(); + String attrType = TopiaGeneratorUtil.getSimpleName(attr.getType()); + addImport(result, attrType); + + attrType = TopiaGeneratorUtil.getSimpleName(attrType); + + ObjectModelOperation op; + + if (!GeneratorUtil.isNMultiplicity(attr)) { + + if (attr.hasAssociationClass()) { + String assocAttrName = TopiaGeneratorUtil.getAssocAttrName(attr); + String assocClassFQN = attr.getAssociationClass().getQualifiedName(); + addImport(result, assocClassFQN); + assocClassFQN = TopiaGeneratorUtil.getSimpleName(assocClassFQN); + String name = GeneratorUtil.toLowerCaseFirstLetter(assocAttrName); + + // setXXX + + op = addOperation(result, "set" + StringUtils.capitalize(assocAttrName), "void", ObjectModelModifier.PUBLIC); + addParameter(op, assocClassFQN, "association"); + setOperationBody(op, "" +/*{ + <%=assocClassFQN%> _oldValue = this.<%=name%>; + fireOnPreWrite("<%=name%>", _oldValue, association); + this.<%=name%> = association; + fireOnPostWrite("<%=name%>", _oldValue, association); +}*/ + ); + + // getXXX + + op = addOperation(result, "get" + StringUtils.capitalize(assocAttrName), assocClassFQN, ObjectModelModifier.PUBLIC); + setOperationBody(op, "" +/*{ + return <%=name%>; +}*/ + ); + } else { + + // setXXX + + op = addOperation(result, "set" + StringUtils.capitalize(attrName), "void", ObjectModelModifier.PUBLIC); + addParameter(op, attrType, "value"); + setOperationBody(op, "" +/*{ + <%=attrType%> _oldValue = this.<%=attrName%>; + fireOnPreWrite("<%=attrName%>", _oldValue, value); + this.<%=attrName%> = value; + fireOnPostWrite("<%=attrName%>", _oldValue, value); +}*/ + + ); + + // getXXX + + op = addOperation(result, "get" + StringUtils.capitalize(attrName), attrType, ObjectModelModifier.PUBLIC); + setOperationBody(op, "" +/*{ + fireOnPreRead("<%=attrName%>", <%=attrName%>); + <%=attrType%> result = this.<%=attrName%>; + fireOnPostRead("<%=attrName%>", <%=attrName%>); + return result; +}*/ + ); + } + } else { //NMultiplicity + String collectionInterface = TopiaGeneratorUtil.getNMultiplicityInterfaceType(attr); + String collectionObject = TopiaGeneratorUtil.getNMultiplicityObjectType(attr); + addImport(result, collectionInterface); + addImport(result, collectionObject); + collectionInterface = TopiaGeneratorUtil.getSimpleName(collectionInterface); + collectionObject = TopiaGeneratorUtil.getSimpleName(collectionObject); + + if (!attr.hasAssociationClass()) { + //Méthodes remplacées par des accesseurs sur les classes d'assoc + + // addXXX + + op = addOperation(result, "add" + StringUtils.capitalize(attrName), "void", ObjectModelModifier.PUBLIC); + addParameter(op, attrType, attrName); + StringBuilder body = new StringBuilder(); + + body.append("" +/*{ + fireOnPreWrite("<%=attrName%>", null, <%=attrName%>); + if (this.<%=attrName%> == null) { + this.<%=attrName%> = new <%=collectionObject%><<%=attrType%>>(); + } +}*/ + ); + + if (reverse != null && (reverse.isNavigable() || + hasUnidirectionalRelationOnAbstractType(attr, model))) { + String reverseAttrName = reverse.getName(); + String reverseAttrType = TopiaGeneratorUtil.getSimpleName(reverse.getType()); + if (!GeneratorUtil.isNMultiplicity(reverse)) { + body.append("" +/*{ <%=attrName%>.set<%=StringUtils.capitalize(reverseAttrName)%>(this); +}*/ + ); + } else { + body.append("" +/*{ if (<%=attrName%>.get<%=StringUtils.capitalize(reverseAttrName)%>() == null) { + <%=attrName%>.set<%=StringUtils.capitalize(reverseAttrName)%>(new <%=collectionObject%><<%=reverseAttrType%>>()); + } + <%=attrName%>.get<%=StringUtils.capitalize(reverseAttrName)%>().add(this); +}*/ + ); + } + } + body.append("" +/*{ this.<%=attrName%>.add(<%=attrName%>); + fireOnPostWrite("<%=attrName%>", this.<%=attrName%>.size(), null, <%=attrName%>); +}*/ + ); + setOperationBody(op, body.toString()); + + // addAllXXX + + op = addOperation(result, "addAll" + StringUtils.capitalize(attrName), "void", ObjectModelModifier.PUBLIC); + addParameter(op, collectionInterface + "<" + attrType + ">", "values"); + + setOperationBody(op, "" +/*{ + if (values == null) { + return; + } + for (<%=attrType%> item : values) { + add<%=StringUtils.capitalize(attrName)%>(item); + } +}*/ + ); + + if (!isPrimitiveType(attr) && !isDateType(attr)) { + + op = addOperation(result, "get" + StringUtils.capitalize(attrName) + "ByTopiaId", attrType, ObjectModelModifier.PUBLIC); + addParameter(op, String.class, "topiaId"); + setOperationBody(op, "" +/*{ + return org.nuiton.topia.persistence.util.TopiaEntityHelper.getEntityByTopiaId(<%=attrName%>, topiaId); + }*/ + ); + + } + + // setXXX + + op = addOperation(result, "set" + StringUtils.capitalize(attrName), "void", ObjectModelModifier.PUBLIC); + addParameter(op, collectionInterface + "<" + attrType + ">", "values"); + + setOperationBody(op, "" +/*{ + <%=collectionInterface%><<%=attrType%>> _oldValue = <%=attrName%>; + fireOnPreWrite("<%=attrName%>", _oldValue, values); + <%=attrName%> = values; + fireOnPostWrite("<%=attrName%>", _oldValue, values); +}*/ + ); + + + // removeXXX + + + op = addOperation(result, "remove" + StringUtils.capitalize(attrName), "void", ObjectModelModifier.PUBLIC); + addParameter(op, attrType, "value"); + body = new StringBuilder(); + + body.append("" +/*{ + fireOnPreWrite("<%=attrName%>", value, null); + if ((this.<%=attrName%> == null) || (!this.<%=attrName%>.remove(value))) { + throw new IllegalArgumentException("List does not contain given element"); + } +}*/ + ); + + if (reverse != null && (reverse.isNavigable() || + hasUnidirectionalRelationOnAbstractType(attr, model))) { + String reverseAttrName = reverse.getName(); + if (!GeneratorUtil.isNMultiplicity(reverse)) { + body.append("" +/*{ value.set<%=StringUtils.capitalize(reverseAttrName)%>(null); +}*/ + ); + } else { + body.append("" +/*{ value.get<%=StringUtils.capitalize(reverseAttrName)%>().remove(this); +}*/ + ); + } + } + body.append("" +/*{ fireOnPostWrite("<%=attrName%>", this.<%=attrName%>.size()+1, value, null); +}*/ + ); + setOperationBody(op, body.toString()); + + + // clearXXX + + op = addOperation(result, "clear" + StringUtils.capitalize(attrName), "void", ObjectModelModifier.PUBLIC); + + body = new StringBuilder(); + + body.append("" +/*{ + if (this.<%=attrName%> == null) { + return; + } +}*/ + ); + + if (reverse != null && (reverse.isNavigable() || + hasUnidirectionalRelationOnAbstractType(attr, model))) { + String reverseAttrName = reverse.getName(); + body.append("" +/*{ for (<%=attrType%> item : this.<%=attrName%>) { +}*/ + ); + if (!GeneratorUtil.isNMultiplicity(reverse)) { + body.append("" +/*{ item.set<%=StringUtils.capitalize(reverseAttrName)%>(null); +}*/ + ); + } else { + body.append("" +/*{ item.get<%=StringUtils.capitalize(reverseAttrName)%>().remove(this); +}*/ + ); + } + body.append("" +/*{ } +}*/ + ); + } + body.append("" +/*{ <%=collectionInterface%><<%=attrType%>> _oldValue = new <%=collectionObject%><<%=attrType%>>(this.<%=attrName%>); + fireOnPreWrite("<%=attrName%>", _oldValue, this.<%=attrName%>); + this.<%=attrName%>.clear(); + fireOnPostWrite("<%=attrName%>", _oldValue, this.<%=attrName%>); +}*/ + ); + + setOperationBody(op, body.toString()); + + } else { + + + String assocAttrName = TopiaGeneratorUtil.getAssocAttrName(attr); + String assocClassFQN = attr.getAssociationClass().getQualifiedName(); +// String assocClassFQN = TopiaGeneratorUtil.getSimpleName(attr.getAssociationClass().getQualifiedName()); + + // addXXX + + op = addOperation(result, "add" + StringUtils.capitalize(assocAttrName), "void", ObjectModelModifier.PUBLIC); + addParameter(op, assocClassFQN, "value"); + + StringBuilder body = new StringBuilder(); + + body.append("" +/*{ + fireOnPreWrite("<%=GeneratorUtil.toLowerCaseFirstLetter(assocAttrName)%>", null, value); + if (this.<%=GeneratorUtil.toLowerCaseFirstLetter(assocAttrName)%> == null) { + this.<%=GeneratorUtil.toLowerCaseFirstLetter(assocAttrName)%> = new <%=collectionObject%><<%=assocClassFQN%>>(); + } +}*/ + ); + if (reverse != null && (reverse.isNavigable() || + hasUnidirectionalRelationOnAbstractType(attr, model))) { + String reverseAttrName = reverse.getName(); + body.append("" +/*{ value.set<%=StringUtils.capitalize(reverseAttrName)%>(this); +}*/ + ); + } + body.append("" +/*{ this.<%=GeneratorUtil.toLowerCaseFirstLetter(assocAttrName)%>.add(value); + fireOnPostWrite("<%=GeneratorUtil.toLowerCaseFirstLetter(assocAttrName)%>", this.<%=GeneratorUtil.toLowerCaseFirstLetter(assocAttrName)%>.size(), null, value); +}*/ + ); + setOperationBody(op, body.toString()); + + + if (!isPrimitiveType(attr) && !isDateType(attr)) { + + // getXXXByTopiaId + + op = addOperation(result, "get" + StringUtils.capitalize(assocAttrName) + "ByTopiaId", assocClassFQN, ObjectModelModifier.PUBLIC); + addParameter(op, String.class, "topiaId"); + setOperationBody(op, "" +/*{ + return org.nuiton.topia.persistence.util.TopiaEntityHelper.getEntityByTopiaId(<%=assocAttrName%>, topiaId); +}*/ + ); + + } + + // addAllXXX + + op = addOperation(result, "addAll" + StringUtils.capitalize(assocAttrName), "void", ObjectModelModifier.PUBLIC); + addParameter(op, collectionInterface + "<" + assocClassFQN + ">", "values"); + setOperationBody(op, "" +/*{ + if (values == null) { + return; + } + for (<%=assocClassFQN%> item : values) { + add<%=StringUtils.capitalize(assocAttrName)%>(item); + } +}*/ + ); + + // setXXX + + op = addOperation(result, "set" + StringUtils.capitalize(assocAttrName), "void", ObjectModelModifier.PUBLIC); + addParameter(op, collectionInterface + "<" + assocClassFQN + ">", "values"); + setOperationBody(op, "" +/*{ +// clear<%=StringUtils.capitalize(assocAttrName)%>(); +// addAll<%=StringUtils.capitalize(assocAttrName)%>(values); +// FIXME + <%=collectionInterface%><<%=assocClassFQN%>> _oldValue = <%=GeneratorUtil.toLowerCaseFirstLetter(assocAttrName)%>; + fireOnPreWrite("<%=GeneratorUtil.toLowerCaseFirstLetter(assocAttrName)%>", _oldValue, values); + <%=GeneratorUtil.toLowerCaseFirstLetter(assocAttrName)%> = values; + fireOnPostWrite("<%=GeneratorUtil.toLowerCaseFirstLetter(assocAttrName)%>", _oldValue, values); +}*/ + ); + + // removeXXX + + op = addOperation(result, "remove" + StringUtils.capitalize(assocAttrName), "void", ObjectModelModifier.PUBLIC); + addParameter(op, assocClassFQN, "value"); + + body = new StringBuilder(); + + body.append("" +/*{ + fireOnPreWrite("<%=GeneratorUtil.toLowerCaseFirstLetter(assocAttrName)%>", value, null); + if ((this.<%=GeneratorUtil.toLowerCaseFirstLetter(assocAttrName)%> == null) || (!this.<%=GeneratorUtil.toLowerCaseFirstLetter(assocAttrName)%>.remove(value))) { + throw new IllegalArgumentException("List does not contain given element"); + } +}*/ + ); + if (reverse != null && (reverse.isNavigable() || + hasUnidirectionalRelationOnAbstractType(attr, model))) { + String reverseAttrName = reverse.getName(); + body.append("" +/*{ value.set<%=StringUtils.capitalize(reverseAttrName)%>(null); +}*/ + ); + } + body.append("" +/*{ fireOnPostWrite("<%=GeneratorUtil.toLowerCaseFirstLetter(assocAttrName)%>", this.<%=GeneratorUtil.toLowerCaseFirstLetter(assocAttrName)%>.size()+1, value, null); +}*/ + ); + + setOperationBody(op, body.toString()); + + // clearXXX + + op = addOperation(result, "clear" + StringUtils.capitalize(assocAttrName), "void", ObjectModelModifier.PUBLIC); + + body = new StringBuilder(); + + body.append("" +/*{ + if (this.<%=GeneratorUtil.toLowerCaseFirstLetter(assocAttrName)%> == null) { + return; + } +}*/ + ); + + if (reverse != null && (reverse.isNavigable() || + hasUnidirectionalRelationOnAbstractType(attr, model))) { + String reverseAttrName = reverse.getName(); + body.append("" +/*{ for (<%=assocClassFQN%> item : this.<%=GeneratorUtil.toLowerCaseFirstLetter(assocAttrName)%>) { + item.set<%=StringUtils.capitalize(reverseAttrName)%>(null); + } +}*/ + ); + } + body.append("" +/*{ <%=collectionInterface%><<%=assocClassFQN%>> _oldValue = new <%=collectionObject%><<%=assocClassFQN%>>(this.<%=GeneratorUtil.toLowerCaseFirstLetter(assocAttrName)%>); + fireOnPreWrite("<%=GeneratorUtil.toLowerCaseFirstLetter(assocAttrName)%>", _oldValue, null); + this.<%=GeneratorUtil.toLowerCaseFirstLetter(assocAttrName)%>.clear(); + fireOnPostWrite("<%=GeneratorUtil.toLowerCaseFirstLetter(assocAttrName)%>", _oldValue, null); +}*/ + ); + setOperationBody(op, body.toString()); + } + + if (!attr.hasAssociationClass()) { + + // getXXX + + op = addOperation(result, "get" + StringUtils.capitalize(attrName), collectionInterface + "<" + attrType + ">", ObjectModelModifier.PUBLIC); + setOperationBody(op, "" +/*{ + return <%=attrName%>; +}*/ + ); + + // sizeXXX + + op = addOperation(result, "size" + StringUtils.capitalize(attrName), int.class, ObjectModelModifier.PUBLIC); + setOperationBody(op, "" +/*{ + if (<%=attrName%> == null) { + return 0; + } + return <%=attrName%>.size(); +}*/ + ); + + // isXXXEmpty + + op = addOperation(result, "is" + StringUtils.capitalize(attrName) + "Empty", boolean.class, ObjectModelModifier.PUBLIC); + setOperationBody(op, "" +/*{ + int size = size<%=StringUtils.capitalize(attrName)%>(); + return size == 0; +}*/ + ); + + } else { + String assocAttrName = TopiaGeneratorUtil.getAssocAttrName(attr); + String assocClassFQN = attr.getAssociationClass().getQualifiedName(); +// String assocClassFQN = TopiaGeneratorUtil.getSimpleName(attr.getAssociationClass().getQualifiedName()); + + // getXXX + + op = addOperation(result, "get" + StringUtils.capitalize(assocAttrName), collectionInterface + "<" + assocClassFQN + ">", ObjectModelModifier.PUBLIC); + setOperationBody(op, "" +/*{ + return <%=GeneratorUtil.toLowerCaseFirstLetter(assocAttrName)%>; +}*/ + ); + + // getXXX + + op = addOperation(result, "get" + StringUtils.capitalize(assocAttrName), assocClassFQN, ObjectModelModifier.PUBLIC); + addParameter(op, attrType, "value"); + setOperationBody(op, "" +/*{ + if (value == null || <%=GeneratorUtil.toLowerCaseFirstLetter(assocAttrName)%> == null) { + return null; + } + for (<%=assocClassFQN%> item : <%=GeneratorUtil.toLowerCaseFirstLetter(assocAttrName)%>) { + if (value.equals(item.get<%=StringUtils.capitalize(attrName)%>())) { + return item; + } + } + return null; +}*/ + ); + + + // sizeXXX + + op = addOperation(result, "size" + StringUtils.capitalize(assocAttrName), int.class, ObjectModelModifier.PUBLIC); + setOperationBody(op, "" +/*{ + if (<%=GeneratorUtil.toLowerCaseFirstLetter(assocAttrName)%> == null) { + return 0; + } + return <%=GeneratorUtil.toLowerCaseFirstLetter(assocAttrName)%>.size(); +}*/ + ); + + //isXXXEmpty + + op = addOperation(result, "is" + StringUtils.capitalize(assocAttrName) + "Empty", boolean.class, ObjectModelModifier.PUBLIC); + setOperationBody(op, "" +/*{ + int size = size<%=StringUtils.capitalize(assocAttrName)%>(); + return size == 0; +}*/ + ); + + } + } + } + + protected void generateAssociationAccessors(ObjectModelClass result, ObjectModelAssociationClass assoc) { + for (ObjectModelAttribute attr : assoc.getParticipantsAttributes()) { + if (attr != null) { + String attrType = TopiaGeneratorUtil.getSimpleName(attr.getType()); + String attrName = attr.getName(); + generateAssociationAccessors(result, attrName, attrType); +// //Ne sert plus à rien normalement avec la navigabilité +// ObjectModelAttribute reverse = attr.getReverseAttribute(); +// if (reverse == null) { +// attrType = ((ObjectModelClassifier)attr.getDeclaringElement()).getQualifiedName(); +// attrName = attr.getDeclaringElement().getName(); +// generateAssociationAccessors(output, attrName, attrType); +// } + } + } + } + + protected void generateToStringMethod(ObjectModelClass result, ObjectModelClass clazz) { + + ObjectModelOperation op = addOperation(result, "toString", String.class, ObjectModelModifier.PUBLIC); + StringBuilder body = new StringBuilder(); + + + body.append("" +/*{ + String result = new ToStringBuilder(this). +}*/ + ); + for (ObjectModelAttribute attr : clazz.getAttributes()) { + //FIXME possibilité de boucles (non directes) + ObjectModelClass attrEntity = null; + if (model.hasClass(attr.getType())) { + attrEntity = model.getClass(attr.getType()); + } + boolean isEntity = (attrEntity != null && attrEntity.hasStereotype(TopiaGeneratorUtil.STEREOTYPE_ENTITY)); + ObjectModelAttribute reverse = attr.getReverseAttribute(); + if ((isEntity && (reverse == null || !reverse.isNavigable()) && !attr.hasAssociationClass()) || (!isEntity)) { + String attrName = attr.getName(); + body.append("" +/*{ append("<%=attrName%>", this.<%=attrName%>). +}*/ + ); + } + } + body.append("" +/*{ toString(); + return result; +}*/ + ); + setOperationBody(op, body.length() == 0 ? " " : body.toString()); + + } + + protected void generateCompositeMethod(ObjectModelClass result, ObjectModelClass clazz) { + + ObjectModelOperation op = addOperation(result, "getComposite", List.class.getName() + "<" + TopiaEntity.class.getName() + ">", ObjectModelModifier.PUBLIC); + addException(op, TopiaException.class); + StringBuilder body = new StringBuilder(); + body.append("" +/*{ + List<TopiaEntity> tmp = new ArrayList<TopiaEntity>(); + + // pour tous les attributs rechecher les composites et les class d'asso + // on les ajoute dans tmp +}*/ + ); + for (ObjectModelAttribute attr : clazz.getAttributes()) { + if (attr.referenceClassifier() && attr.getClassifier().hasStereotype(TopiaGeneratorUtil.STEREOTYPE_ENTITY)) { + if (attr.isComposite()) { + String attrName = attr.getName(); + String getterName = "get" + StringUtils.capitalize(attrName); + if (GeneratorUtil.isNMultiplicity(attr)) { + body.append("" +/*{ if (<%=getterName%>() != null) { + tmp.addAll(<%=getterName%>()); + } +}*/ + ); + } else { + body.append("" +/*{ tmp.add(<%=getterName%>()); +}*/ + ); + } + } else if (attr.hasAssociationClass()) { + String assocAttrName = TopiaGeneratorUtil.getAssocAttrName(attr); + String assocClassFQN = TopiaGeneratorUtil.getSimpleName(attr.getAssociationClass().getQualifiedName()); + String ref = "this." + GeneratorUtil.toLowerCaseFirstLetter(assocAttrName); + if (!GeneratorUtil.isNMultiplicity(attr)) { + body.append("" +/*{ + if (<%=ref%> != null) { + tmp.add(<%=ref%>); + } +}*/ + ); + } else { + ObjectModelAttribute reverse = attr.getReverseAttribute(); + String reverseAttrName = reverse.getName(); + // On utilise pas l'attribut car il est potentiellement + // pas a jour, car pour les asso avec cardinalité + // personne ne fait de add. Ce qui est normal, mais + // pour pouvoir faire tout de meme des delete en cascade + // sur les asso, le champs est dans le mapping + // hibernate et donc il le faut aussi dans la classe + // sinon hibernate rale lorsqu'il charge l'objet +// if (<%=ref%> != null) { +// tmp.addAll(<%=ref%>); +// } + body.append("" +/*{ + { + org.nuiton.topia.persistence.TopiaDAO<<%=assocClassFQN%>> dao = ((TopiaContextImplementor) getTopiaContext()).getDAO(<%=assocClassFQN%>.class); + List<<%=assocClassFQN%>> findAllByProperties = dao.findAllByProperties("<%=reverseAttrName%>", this); + if (findAllByProperties != null) { + tmp.addAll(findAllByProperties); + } + } +}*/ + ); + } + } + } + } + body.append("" +/*{ + // on refait un tour sur chaque entity de tmp pour recuperer leur + // composite + List<TopiaEntity> result = new ArrayList<TopiaEntity>(); + for (TopiaEntity entity : tmp) { + if (entity != null) { + result.add(entity); + result.addAll(entity.getComposite()); + } + } + + return result; +}*/ + ); + + setOperationBody(op, body.length() == 0 ? " " : body.toString()); + } + + protected void generateAggregateMethod(ObjectModelClass result, ObjectModelClass clazz) { + + ObjectModelOperation op = addOperation(result, "accept", List.class.getName() + "<" + TopiaEntity.class.getName() + ">", ObjectModelModifier.PUBLIC); + addException(op, TopiaException.class); + + StringBuilder body = new StringBuilder(); + body.append("" +/*{ + List<TopiaEntity> tmp = new ArrayList<TopiaEntity>(); + + // pour tous les attributs rechecher les composites et les class d'asso + // on les ajoute dans tmp +}*/ + ); + for (ObjectModelAttribute attr : clazz.getAttributes()) { + if (attr.referenceClassifier() && attr.getClassifier().hasStereotype(TopiaGeneratorUtil.STEREOTYPE_ENTITY)) { + if (attr.isAggregate()) { + String attrName = attr.getName(); + String getterName = "get" + StringUtils.capitalize(attrName); + if (GeneratorUtil.isNMultiplicity(attr)) { + body.append("" +/*{ tmp.addAll(<%=getterName%>()); +}*/ + ); + } else { + body.append("" +/*{ tmp.add(<%=getterName%>()); +}*/ + ); + } + } + } + } + body.append("" +/*{ + // on refait un tour sur chaque entity de tmp pour recuperer leur + // composite + List<TopiaEntity> result = new ArrayList<TopiaEntity>(); + for (TopiaEntity entity : tmp) { + result.add(entity); + result.addAll(entity.getAggregate()); + } + + return result; +}*/ + ); + + setOperationBody(op, body.length() == 0 ? " " : body.toString()); + } + + protected void generateAcceptMethod(ObjectModelClass result, ObjectModelClass clazz) { + + ObjectModelOperation op = addOperation(result, "accept", "void", ObjectModelModifier.PUBLIC); + addException(op, TopiaException.class); + setDocumentation(op, "Envoi via les methodes du visitor l'ensemble des champs de l'entity\n" + + "avec leur nom, type et valeur."); + { + ObjectModelParameter attr = addParameter(op, EntityVisitor.class, "visitor"); + setDocumentation(attr, "le visiteur de l'entite."); + } + StringBuilder body = new StringBuilder(); + body.append("" +/*{ + visitor.start(this); +}*/ + ); + for (ObjectModelAttribute attr : clazz.getAttributes()) { + ObjectModelAttribute reverse = attr.getReverseAttribute(); + + // pour les asso quoi qu'il arrive il faut les lier des 2 cotes + // pour pouvoir supprimer en cascade l'asso lors de la suppression + // d'un des cotes + if (!(attr.isNavigable() + || hasUnidirectionalRelationOnAbstractType(reverse, model) + || attr.hasAssociationClass())) { + continue; + } + + if (!attr.hasAssociationClass()) { + String attrType = TopiaGeneratorUtil.getSimpleName(attr.getType()); + String attrName = attr.getName(); + if (!GeneratorUtil.isNMultiplicity(attr)) { + body.append("" +/*{ visitor.visit(this, "<%=attrName%>", <%=attrType%>.class, <%=attrName%>); +}*/ + ); + } else { + String collectionType = TopiaGeneratorUtil.getSimpleName(TopiaGeneratorUtil.getNMultiplicityInterfaceType(attr)); + body.append("" +/*{ visitor.visit(this, "<%=attrName%>", <%=collectionType%>.class, <%=attrType%>.class, <%=attrName%>); +}*/ + ); + } + } else { + String assocAttrName = TopiaGeneratorUtil.getAssocAttrName(attr); + assocAttrName = GeneratorUtil.toLowerCaseFirstLetter(assocAttrName); + String assocClassFQN = TopiaGeneratorUtil.getSimpleName(attr.getAssociationClass().getQualifiedName()); + if (!GeneratorUtil.isNMultiplicity(attr)) { + body.append("" +/*{ visitor.visit(this, "<%=assocAttrName%>", <%=assocClassFQN%>.class, <%=assocAttrName%>); +}*/ + ); + } else { + String collectionType = TopiaGeneratorUtil.getNMultiplicityInterfaceType(attr); + body.append("" +/*{ visitor.visit(this, "<%=assocAttrName%>", <%=collectionType%>.class, <%=assocClassFQN%>.class, <%=assocAttrName%>); +}*/ + ); + } + } + } + + //Déclaration des attributs d'une classe d'associations + if (clazz instanceof ObjectModelAssociationClass) { + ObjectModelAssociationClass assoc = (ObjectModelAssociationClass) clazz; + for (ObjectModelAttribute attr : assoc.getParticipantsAttributes()) { + if (attr != null) { + String attrType = TopiaGeneratorUtil.getSimpleName(attr.getType()); + String attrName = attr.getName(); + attrName = GeneratorUtil.toLowerCaseFirstLetter(attrName); + body.append("" +/*{ visitor.visit(this, "<%=attrName%>", <%=attrType%>.class, <%=attrName%>); +}*/ + ); + } + } + } + body.append("" +/*{ visitor.end(this); +}*/ + ); + + setOperationBody(op, body.length() == 0 ? " " : body.toString()); + } + + + private void generateAssociationAccessors(ObjectModelClass result, String name, String type) { + ObjectModelOperation op; + op = addOperation(result, "set" + StringUtils.capitalize(name), "void", ObjectModelModifier.PUBLIC); + ObjectModelParameter param = addParameter(op, type, "value"); + setDocumentation(param, "La valeur de l'attribut " + name + " à positionner."); + setOperationBody(op, "" +/*{ + <%=type%> _oldValue = this.<%=GeneratorUtil.toLowerCaseFirstLetter(name)%>; + fireOnPreWrite("<%=name%>", _oldValue, value); + this.<%=GeneratorUtil.toLowerCaseFirstLetter(name)%> = value; + fireOnPostWrite("<%=name%>", _oldValue, value); +}*/ + ); + + op = addOperation(result, "get" + StringUtils.capitalize(name), type, ObjectModelModifier.PUBLIC); + setOperationBody(op, "" +/*{ + return <%=GeneratorUtil.toLowerCaseFirstLetter(name)%>; +}*/ + ); + + } + + + private void generateI18n(ObjectModelClass result, String i18nPrefix, ObjectModelClass clazz) { + + StringBuilder buffer = new StringBuilder(); + addI18n(buffer, i18nPrefix, java.beans.Introspector.decapitalize(clazz.getName())); + for (ObjectModelAttribute attr : clazz.getAttributes()) { + addI18n(buffer, i18nPrefix, java.beans.Introspector.decapitalize(attr.getName())); + } + + //FIXME : use a block extension for java + } + + private void addI18n(StringBuilder buffer, String i18nPrefix, String suffix) { + buffer.append(" org.nuiton.i18n.I18n.n_(\"").append(i18nPrefix).append(suffix).append("\");\n"); + } +} Property changes on: branches/from2.2.2-eugene2-beta/topia-persistence/src/main/java/org/nuiton/topia/generator/EntityAbstractTransformer.java ___________________________________________________________________ Added: svn:keywords + "Author Date Id Revision HeadURL