All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.nuiton.topia.templates.EntityTransformer Maven / Gradle / Ivy

The newest version!
package org.nuiton.topia.templates;

/*
 * #%L
 * ToPIA :: Templates
 * $Id$
 * $HeadURL$
 * %%
 * Copyright (C) 2004 - 2014 CodeLutin
 * %%
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License as 
 * published by the Free Software Foundation, either version 3 of the 
 * License, or (at your option) any later version.
 * 
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Lesser Public License for more details.
 * 
 * You should have received a copy of the GNU General Lesser Public 
 * License along with this program.  If not, see
 * .
 * #L%
 */

import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.builder.ToStringBuilder;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.codehaus.plexus.component.annotations.Component;
import org.nuiton.eugene.EugeneCoreTagValues;
import org.nuiton.eugene.GeneratorUtil;
import org.nuiton.eugene.Template;
import org.nuiton.eugene.java.JavaGeneratorUtil;
import org.nuiton.eugene.java.ObjectModelTransformerToJava;
import org.nuiton.eugene.models.extension.tagvalue.TagValueUtil;
import org.nuiton.eugene.models.object.ObjectModelAssociationClass;
import org.nuiton.eugene.models.object.ObjectModelAttribute;
import org.nuiton.eugene.models.object.ObjectModelClass;
import org.nuiton.eugene.models.object.ObjectModelClassifier;
import org.nuiton.eugene.models.object.ObjectModelInterface;
import org.nuiton.eugene.models.object.ObjectModelJavaModifier;
import org.nuiton.eugene.models.object.ObjectModelModifier;
import org.nuiton.eugene.models.object.ObjectModelOperation;
import org.nuiton.eugene.models.object.ObjectModelPackage;
import org.nuiton.eugene.models.object.ObjectModelParameter;
import org.nuiton.eugene.models.object.xml.ObjectModelInterfaceImpl;
import org.nuiton.topia.persistence.TopiaDao;
import org.nuiton.topia.persistence.TopiaDaoSupplier;
import org.nuiton.topia.persistence.TopiaEntity;
import org.nuiton.topia.persistence.TopiaEntityContextable;
import org.nuiton.topia.persistence.TopiaEntityVisitor;
import org.nuiton.topia.persistence.TopiaException;
import org.nuiton.topia.persistence.event.ListenableTopiaEntity;
import org.nuiton.topia.persistence.internal.AbstractTopiaEntity;
import org.nuiton.topia.persistence.util.TopiaEntityHelper;

import java.util.Collection;
import java.util.LinkedList;
import java.util.List;
import java.util.Set;




/**
 * A template to generate all the {@link TopiaEntity} api for all classifier
 * with a {@code entity} stereotype.
 *
 * For example, given a {@code House} entity, it will generates :
 * 
    *
  • {@code House} : contract of entity
  • *
  • {@code AbstractHouse} : default abstract implementation of entity
  • *
  • {@code HouseImpl} : default impl of abstract entity
  • *
* * Note: The impl will ony be generated in these cases : *
    *
  • There is no abstract method
  • *
  • There is no already defined such class in class-path
  • *
* * @author Tony Chemit - [email protected] * @since 2.3.4 */ @Component( role = Template.class, hint="org.nuiton.topia.templates.EntityTransformer") public class EntityTransformer extends ObjectModelTransformerToJava { /** Logger */ private static final Log log = LogFactory.getLog(EntityTransformer.class); protected ObjectModelInterface outputInterface; protected ObjectModelClass outputAbstract; protected ObjectModelClass outputImpl; private boolean associationClass; protected boolean generateInterface; protected boolean generateAbstract; protected boolean generateImpl; protected boolean generateBooleanGetMethods; protected boolean generatePropertyChangeSupport; protected TopiaTemplateHelper templateHelper; protected final TopiaCoreTagValues topiaCoreTagValues; protected final TopiaHibernateTagValues topiaHibernateTagValues; public EntityTransformer() { this.topiaCoreTagValues = new TopiaCoreTagValues(); this.topiaHibernateTagValues = new TopiaHibernateTagValues(); } protected void clean() { outputInterface = null; outputAbstract = null; outputImpl = null; } @Override public void transformFromClass(ObjectModelClass input) { if (templateHelper == null) { templateHelper = new TopiaTemplateHelper(model); } if (!templateHelper.isEntity(input)) { // not an entity, skip class. return; } if (log.isDebugEnabled()) { log.debug("for entity : " + input.getQualifiedName()); log.debug("Will use classLoader " + getClassLoader()); } ObjectModelPackage aPackage = getPackage(input); // fix once for all the constant prefix to use String prefix = getConstantPrefix(input); if (StringUtils.isEmpty(prefix)) { // no specific prefix, so no prefix if (log.isWarnEnabled()) { log.warn("[" + input.getName() + "] Will generate constants with NO prefix, not a good idea... \n" + "Use '" + EugeneCoreTagValues.Store.constantPrefix + "' tagvalue in your xmi properties. For example " + "for all the model : model.tagvalue." + EugeneCoreTagValues.Store.constantPrefix + "=PROPERTY_"); } } setConstantPrefix(prefix); generateInterface = isGenerateInterface(input); generateAbstract = isGenerateAbstract(input); generateImpl = isGenerateImpl(input); generateBooleanGetMethods = eugeneTagValues.isGenerateBooleanGetMethods(input, aPackage, model); generatePropertyChangeSupport = topiaCoreTagValues.isGeneratePropertyChangeSupport(input, model); if (generateInterface) { // Create Entity Interface and its header createEntityInterface(aPackage, input); } else { // mock it outputInterface = new ObjectModelInterfaceImpl(); ((ObjectModelInterfaceImpl) outputInterface).setName(input.getName()); } if (generateAbstract) { // Create Entity Abstract class and its header createEntityAbstractClass(aPackage, input); } // Generate i18n block String i18nPrefix = eugeneTagValues.getI18nPrefixTagValue(input, aPackage, model); if (!StringUtils.isEmpty(i18nPrefix)) { generateI18nBlock(input, outputAbstract, i18nPrefix); } // Create accept operation, will be updated during property generation createAcceptOperation(); createAcceptInternalOperation(input); // Add constant, attribute and operations for each property generateProperties(input.getAttributes(), input, aPackage); // Case of association class : properties from participants/extremities // of the association class. if (input instanceof ObjectModelAssociationClass) { ObjectModelAssociationClass association = (ObjectModelAssociationClass) input; associationClass = true; generateProperties(association.getParticipantsAttributes(), input, aPackage); associationClass = false; } closeAcceptInternalOperation(); // Add extra constants (from uml dependency) generateExtraConstants(input); // Add extra operations (defined on the entity) generateExtraOperations(input); // Implement toString operation if (!topiaCoreTagValues.getNotGenerateToStringTagValue(input, aPackage, model)) { generateToStringOperation(input); } // Generate serialVersionUID on abstract class generateSerialVersionUID(input, outputAbstract); // Generate Entity Implementation class if (generateImpl) { generateImpl(input); generateSerialVersionUID(input, outputImpl); } // Clean data output after transformation clean(); } protected void generateSerialVersionUID(ObjectModelClass input, ObjectModelClass ouput) { // serialVersionUID String svUID = TagValueUtil.findTagValue(TopiaCoreTagValues.Store.serialVersionUID, input); if (svUID == null) { // use a default one svUID = GeneratorUtil.generateSerialVersionUID(ouput) + "L"; } addConstant(ouput, GeneratorUtil.SERIAL_VERSION_UID, long.class, svUID, ObjectModelJavaModifier.PRIVATE); } protected void createEntityInterface(ObjectModelPackage aPackage, ObjectModelClass input) { outputInterface = createInterface(input.getName(), input.getPackageName()); // Documentation if (GeneratorUtil.hasDocumentation(input)) { setDocumentation(outputInterface, input.getDocumentation()); } if (log.isTraceEnabled()) { log.trace("Will add interfaces on " + outputInterface.getQualifiedName()); } List interfaceAlreadyDone = new LinkedList<>(); // Extends for (ObjectModelClassifier parent : input.getInterfaces()) { addInterface(interfaceAlreadyDone, outputInterface, parent); } // Extends from inheritance boolean needTopiaEntity = true; for (ObjectModelClassifier parent : input.getSuperclasses()) { if (templateHelper.isEntity(parent)) { addInterface(interfaceAlreadyDone, outputInterface, parent); needTopiaEntity = false; } } // Extends TopiaEntity (only if hasn't parent entity) if (needTopiaEntity) { Class interfaze = TopiaEntity.class; if (topiaCoreTagValues.getContextableTagValue(input, aPackage, model)) { interfaze = TopiaEntityContextable.class; } addInterface(interfaceAlreadyDone, outputInterface, interfaze); } else if (topiaCoreTagValues.getContextableTagValue(input, aPackage, model)) { // Even if there is no need to implement TopiaEntity, it might be // necessary to implement TopiaEntityContextable addInterface(interfaceAlreadyDone, outputInterface, TopiaEntityContextable.class); } if (generatePropertyChangeSupport) { addInterface(interfaceAlreadyDone, outputInterface, ListenableTopiaEntity.class); } } protected void createEntityAbstractClass(ObjectModelPackage aPackage, ObjectModelClass input) { outputAbstract = createAbstractClass(input.getName() + "Abstract", input.getPackageName()); // Documentation StringBuilder doc = new StringBuilder(); doc.append("Implantation POJO pour l'entité {@link "); doc.append(StringUtils.capitalize(outputInterface.getName())); doc.append("}\n"); String dbName = templateHelper.getDbName(input); if (dbName != null) { doc.append("

Nom de l'entité en BD : "); doc.append(dbName); doc.append(".

"); } setDocumentation(outputAbstract, doc.toString()); // Implements addInterface(outputAbstract, outputInterface.getName()); // Extends for (ObjectModelClass parent : input.getSuperclasses()) { //tchemit-2011-09-12 What ever abstract or not, we alwyas use an Impl, moreover use the util method instead String extendClass = templateHelper.getDOType(parent, model); // String extendClass = parent.getQualifiedName(); // //Si une des classes parentes définies des méthodes abstraites, son // // impl ne sera pas créé // boolean abstractParent = templateHelper.shouldBeAbstract(parent); // if (templateHelper.isEntity(parent)) { // if (abstractParent) { // extendClass += "Abstract"; // } else { // extendClass += "Impl"; // } // } setSuperClass(outputAbstract, extendClass); } // Extends AbstractTopiaEntity (only if hasn't parent entity) if (outputAbstract.getSuperclasses().isEmpty()) { String superClassName = topiaCoreTagValues.getEntitySuperClassTagValue(input, aPackage, model); if (superClassName == null) { superClassName = AbstractTopiaEntity.class.getName(); } setSuperClass(outputAbstract, superClassName); } if (topiaCoreTagValues.getContextableTagValue(input, aPackage, model)) { addContextableMethods(input, outputAbstract); } } /** * Ajout les methodes necessaire à l'interface {@link TopiaEntityContextable} * si le tagValue {@link TopiaCoreTagValues.Store#contextable} est renseigné. * * @param input FIXME * @param outputAbstract FIXME */ protected void addContextableMethods(ObjectModelClass input, ObjectModelClass outputAbstract) { addImport(outputAbstract, TopiaDaoSupplier.class); addImport(outputAbstract, TopiaDao.class); // topiaContext attribute ObjectModelAttribute topiaContextAttribute = addAttribute( outputAbstract, "topiaDaoSupplier", TopiaDaoSupplier.class, null, ObjectModelJavaModifier.PROTECTED, ObjectModelJavaModifier.TRANSIENT); setDocumentation(topiaContextAttribute, "TopiaDAO instance associated with the current \n" + "instance. For internal usage only"); ObjectModelOperation op; op = addOperation(outputAbstract, "getTopiaDaoSupplier", TopiaDaoSupplier.class, ObjectModelJavaModifier.PUBLIC); setDocumentation(op, "@since 3.0"); addAnnotation(outputAbstract, op, Override.class); setOperationBody(op, "" +"\n" +" return topiaDaoSupplier;\n" +" " ); op = addOperation(outputAbstract, "setTopiaDaoSupplier", "void", ObjectModelJavaModifier.PUBLIC); addException(op, TopiaException.class); addParameter(op, TopiaDaoSupplier.class, "topiaDaoSupplier"); setDocumentation(op, "@since 3.0"); addAnnotation(outputAbstract, op, Override.class); setOperationBody(op, "" +"\n" +" if (this.topiaDaoSupplier == null) {\n" +" this.topiaDaoSupplier = topiaDaoSupplier;\n" +" }\n" +" " ); String daoClassName = templateHelper.getConcreteDaoName(input); op = addOperation(outputAbstract, "getInternalDao", daoClassName, ObjectModelJavaModifier.PROTECTED); setDocumentation(op, "@since 3.0"); setOperationBody(op, "" +"\n" +" TopiaDaoSupplier daoSupplier = getTopiaDaoSupplier();\n" +" "+daoClassName+" result = null;\n" +" if (daoSupplier != null) { // This may happend when entity is created manually\n" +" result = daoSupplier.getDao("+input.getName()+".class, "+daoClassName+".class);\n" +" }\n" +" return result;\n" +" " ); op = addOperation(outputAbstract, "getGenericEntityDao", "TopiaDao", ObjectModelJavaModifier.PUBLIC); addAnnotation(outputAbstract, op, Override.class); setDocumentation(op, "@since 3.0"); setOperationBody(op, "" +"\n" +" return getInternalDao();\n" +" " ); op = addOperation(outputAbstract, "update", "void", ObjectModelJavaModifier.PUBLIC); addException(op, TopiaException.class); addAnnotation(outputAbstract, op, Override.class); setOperationBody(op, "" +"\n" +" getInternalDao().update(this);\n" +" " ); op = addOperation(outputAbstract, "delete", "void", ObjectModelJavaModifier.PUBLIC); addException(op, TopiaException.class); addAnnotation(outputAbstract, op, Override.class); setOperationBody(op, "" +"\n" +" getInternalDao().delete(this);\n" +" " ); op = addOperation(outputAbstract, "getComposite", List.class.getName() + '<' + TopiaEntity.class.getName() + '>', ObjectModelJavaModifier.PUBLIC); addException(op, TopiaException.class); addAnnotation(outputAbstract, op, Override.class); setOperationBody(op, "" +"\n" +" List result = getInternalDao().getComposite(this);\n" +" return result;\n" +" " ); op = addOperation(outputAbstract, "getAggregate", List.class.getName() + '<' + TopiaEntity.class.getName() + '>', ObjectModelJavaModifier.PUBLIC); addException(op, TopiaException.class); addAnnotation(outputAbstract, op, Override.class); setOperationBody(op, "" +"\n" +" List result = getInternalDao().getAggregate(this);\n" +" return result;\n" +" " ); } protected boolean isGenerateInterface(ObjectModelClass input) { return !getResourcesHelper().isJavaFileInClassPath(input.getQualifiedName()); } protected boolean isGenerateAbstract(ObjectModelClass input) { String fqn = input.getQualifiedName() + " Abstract"; return !getResourcesHelper().isJavaFileInClassPath(fqn); } protected boolean isGenerateImpl(ObjectModelClass input) { Collection operations = input.getOperations(); String fqn = input.getQualifiedName() + "Impl"; boolean alreadyInClassPath = getResourcesHelper().isJavaFileInClassPath(fqn); if (alreadyInClassPath) { return false; } // On ne génère pas le impl si l'entité a des opérations if (!operations.isEmpty()) { log.info("Will not generate [" + fqn + "], there is some operations to manually implement"); 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()) { log.info("Will not generate [" + fqn + "], there is an abstract operation [" + otherOp.getName() + "] in allOtherOperations."); return false; } } return true; } protected void generateImpl(ObjectModelClass input) { String implName = input.getName() + "Impl"; String packageName = input.getPackageName(); if (isVerbose()) { log.info("Will generate [" + implName + "]"); } if (isAbstract(input)) { outputImpl = createAbstractClass(implName, packageName); } else { outputImpl = createClass(implName, packageName); } setDocumentation(outputImpl, "Implantation des operations pour l'entité " + input.getName() + "."); setSuperClass(outputImpl, input.getQualifiedName() + "Abstract"); } /** * 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 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 opName = operation.getName(); String opType = operation.getReturnType(); ObjectModelModifier visibility = ObjectModelJavaModifier.fromVisibility(operation.getVisibility()); if (log.isDebugEnabled()) { log.debug("Extra operation for : " + input.getQualifiedName() + " - method : " + opName + " - returnType : " + opType + " - visibility : " + visibility); } // Generate entity methods which have not a public visibility. // Only in abstract entity class as abstract operation. if (!visibility.equals(ObjectModelJavaModifier.PUBLIC)) { addOperation(outputAbstract, opName, opType, visibility, ObjectModelJavaModifier.ABSTRACT); // Other operations, only in entity interface, implementations // need to be done in implementation class created by developper } else { cloneOperationSignature(operation, outputInterface, true); } } } /** * Generate properties from {@code attributes}. Generate * constant, attribute and operations for each property. * * @param attributes Input attributes * @param aClass FIXME * @param aPackage FIXME */ protected void generateProperties(Collection attributes, ObjectModelClassifier aClass, ObjectModelPackage aPackage) { for (ObjectModelAttribute attribute : attributes) { if (!associationClass) { // FIXME-fdesbois-2010-06-25 : Strange behavior to keep those links, will break hibernate, may be a problem in mapping if (!attribute.isNavigable() && attribute.hasAssociationClass()) { generatePropertyConstant(attribute); generatePropertyAttribute(attribute, aClass, aPackage); updateAcceptOperation(attribute, aClass, aPackage); } if (!attribute.isNavigable() && !templateHelper.hasUnidirectionalRelationOnAbstractType( attribute.getReverseAttribute(), model)) { continue; } } // constant generatePropertyConstant(attribute); // attribute generatePropertyAttribute(attribute, aClass, aPackage); // operations generatePropertyOperations(attribute, aClass, aPackage); // update accept body updateAcceptOperation(attribute, aClass, aPackage); } } // ------------------------------------------------------------------------- // Generate for property // ------------------------------------------------------------------------- /** * 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 (log.isDebugEnabled()) { log.debug("Generate constant for property : " + attrName); } addAttribute(outputInterface, getConstantName(attrName), String.class, "\"" + attrName + "\""); } protected void generatePropertyAttribute(ObjectModelAttribute attribute, ObjectModelClassifier aClass, ObjectModelPackage aPackage) { String attrName = getPropertyName(attribute); String attrType = getPropertyType(attribute, aClass, aPackage); String collectionType = getCollectionType(attribute); if (collectionType != null) { attrType = collectionType + "<" + attrType + ">"; } //String attrVisibility = attr.getVisibility(); // Declaration ObjectModelAttribute property = addAttribute(outputAbstract, attrName, attrType, null, //ObjectModelJavaModifier.toValue(attrVisibility), ObjectModelJavaModifier.PROTECTED ); // Documentation StringBuilder buffer = new StringBuilder(); if (GeneratorUtil.hasDocumentation(attribute)) { String attrDocumentation = attribute.getDocumentation(); buffer.append(attrDocumentation).append('\n'); } String dbName = templateHelper.getDbName(attribute); if (!StringUtils.isEmpty(dbName)) { buffer.append("Nom de l'attribut en BD : ").append(dbName).append('\n'); } setDocumentation(property, buffer.toString()); // Annotation String annotation = new TopiaCoreTagValues().getAnnotationTagValue(attribute); if (!StringUtils.isEmpty(annotation)) { //FIXME Make annotation works... //TODO tchemit 20100513 Test it still works addAnnotation(outputAbstract, property, annotation); } } /** * 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 attribute Input attribute to treate * @param aClass Input class * @param aPackage Input package * @see #addSingleGetOperation(ObjectModelAttribute, String, String) * @see #addSingleSetOperation(ObjectModelAttribute, ObjectModelClassifier, ObjectModelPackage) * @see #addMultipleAddOperation(ObjectModelAttribute, ObjectModelClassifier, ObjectModelPackage, String) * @see #addMultipleAddAllOperation(ObjectModelAttribute, ObjectModelClassifier, ObjectModelPackage) * @see #addMultipleSetOperation(ObjectModelAttribute, ObjectModelClassifier, ObjectModelPackage, String, String) * @see #addMultipleRemoveOperation(ObjectModelAttribute, ObjectModelClassifier, ObjectModelPackage) * @see #addMultipleClearOperation(ObjectModelAttribute, ObjectModelClassifier, ObjectModelPackage, String, String) * @see #addMultipleGetOperation(ObjectModelAttribute, ObjectModelClassifier, ObjectModelPackage, String) * @see #addMultipleGetByTopiaIdOperation(ObjectModelAttribute, ObjectModelClassifier, ObjectModelPackage) * @see #addMultipleGetOperationFromEntity(ObjectModelAttribute, ObjectModelClassifier, ObjectModelPackage) * @see #addMultipleSizeOperation(ObjectModelAttribute) * @see #addMultipleIsEmptyOperations(ObjectModelAttribute) * @see #addMultipleGetByIndexOperation(ObjectModelAttribute, ObjectModelClassifier, ObjectModelPackage) */ protected void generatePropertyOperations(ObjectModelAttribute attribute, ObjectModelClassifier aClass, ObjectModelPackage aPackage) { if (attribute.getMaxMultiplicity() == 1 || associationClass) { // setXXX addSingleSetOperation(attribute, aClass, aPackage); boolean booleanProperty = GeneratorUtil.isBooleanPrimitive(attribute); String attrType = getPropertyType(attribute, aClass, aPackage); if (booleanProperty) { // isXXX addSingleGetOperation( attribute, attrType, JavaGeneratorUtil.OPERATION_GETTER_BOOLEAN_PREFIX); } if (!booleanProperty || generateBooleanGetMethods) { // getXXX addSingleGetOperation( attribute, attrType, JavaGeneratorUtil.OPERATION_GETTER_DEFAULT_PREFIX); } } else { // List, Set or Collection ? String collectionInterface = templateHelper.getCollectionType(attribute).getName(); String collectionImpl = templateHelper.getCollectionInstanceType(attribute).getName(); addImport(outputInterface, collectionInterface); addImport(outputAbstract, collectionInterface); addImport(outputAbstract, collectionImpl); collectionInterface = GeneratorUtil.getSimpleName(collectionInterface); collectionImpl = GeneratorUtil.getSimpleName(collectionImpl); boolean ordered = JavaGeneratorUtil.isOrdered(attribute); boolean unique = EugeneCoreTagValues.isUnique(attribute); boolean entity = templateHelper.isEntity(attribute, model); // addXXX addMultipleAddOperation(attribute, aClass, aPackage, collectionImpl); if (ordered && !unique) { // addXXX(index) addMultipleAddAtIndexOperation(attribute, aClass, aPackage, collectionImpl); } // addAllXXX addMultipleAddAllOperation(attribute, aClass, aPackage); // setXXX addMultipleSetOperation(attribute, aClass, aPackage, collectionInterface, collectionImpl); // removeXXX addMultipleRemoveOperation(attribute, aClass, aPackage); if (ordered && !unique) { // removeXXX(index) addMultipleRemoveAtIndexOperation(attribute, aClass, aPackage); } // clearXXX addMultipleClearOperation(attribute, aClass, aPackage, collectionInterface, collectionImpl); // getXXX addMultipleGetOperation(attribute, aClass, aPackage, collectionInterface); if (ordered) { // getXXX(index) addMultipleGetByIndexOperation(attribute, aClass, aPackage); } if (entity) { // getXXXByTopiaId addMultipleGetByTopiaIdOperation(attribute, aClass, aPackage); // getXXXTopiaIds addMultipleGetTopiaIdsOperation(attribute, aClass, aPackage, collectionInterface, collectionImpl); } // sizeXXX addMultipleSizeOperation(attribute); // isXXXEmpty addMultipleIsEmptyOperations(attribute); // containsXXX addMultipleContainsOperation(attribute, aClass, aPackage); } } protected void addSingleSetOperation(ObjectModelAttribute attribute, ObjectModelClassifier aClass, ObjectModelPackage aPackage) { String attrName = getPropertyName(attribute); String attrType = getPropertyType(attribute, aClass, aPackage); if (log.isDebugEnabled()) { log.debug("Generate single 'set' operation for property : " + attrName + " [" + attrType + "]"); } // Interface operation ObjectModelOperation interfaceOperation = createPropertySetterSignature(outputInterface, attrType, attrName, ""); // Implementation ObjectModelOperation implOperation = createImplOperation(interfaceOperation); attrType = GeneratorUtil.getSimpleName(attrType); String constantName = getConstantName(attrName); StringBuilder body = new StringBuilder(); if (generatePropertyChangeSupport) { body.append("" +"\n" +" "+attrType+" oldValue = this."+attrName+";\n" +" fireOnPreWrite("+constantName+", oldValue, "+attrName+");" ); } body.append("" +"\n" +" this."+attrName+" = "+attrName+";\n" +" " ); if (generatePropertyChangeSupport) { body.append("" +" fireOnPostWrite("+constantName+", oldValue, "+attrName+");\n" +" " ); } setOperationBody(implOperation, body.toString()); } /** * Add getter for simple property (neither association nor multiple). * Will add two different operations for boolean case ('is' method and * 'get' method). This method add the operation in both {@code * outputAbstract} and {@code outputInterface}. * * @param attribute ObjectModelAttribute for getter operation * @param attrType type of the attribute * @param operationPrefix Operation prefix : 'get' by default, if prefix * is null */ protected void addSingleGetOperation(ObjectModelAttribute attribute, String attrType, String operationPrefix) { String attrName = getPropertyName(attribute); if (log.isDebugEnabled()) { log.debug("Generate single '" + operationPrefix + "' operation for property : " + attrName + " [" + attrType + "]"); } String constantName = getConstantName(attrName); // Interface operation ObjectModelOperation interfaceOperation = addOperation(outputInterface, getJavaBeanMethodName(operationPrefix, attrName), attrType, ObjectModelJavaModifier.PACKAGE); // Implementation ObjectModelOperation implOperation = createImplOperation(interfaceOperation); attrType = GeneratorUtil.getSimpleName(attrType); StringBuilder body = new StringBuilder(); if (generatePropertyChangeSupport) { body.append("" +"\n" +" fireOnPreRead("+constantName+", "+attrName+");" ); } body.append("" +"\n" +" "+attrType+" result = this."+attrName+";\n" +"" ); if (generatePropertyChangeSupport) { body.append("" +" fireOnPostRead("+constantName+", "+attrName+");\n" +"" ); } body.append("" +" return result;\n" +" " ); setOperationBody(implOperation, body.toString()); } protected void addMultipleAddOperation(ObjectModelAttribute attribute, ObjectModelClassifier aClass, ObjectModelPackage aPackage, String collectionImpl) { String attrName = getPropertyName(attribute); String attrType = getPropertyType(attribute, aClass, aPackage); ObjectModelAttribute reverse = attribute.getReverseAttribute(); if (log.isDebugEnabled()) { log.debug("Generate multiple 'add' operation for property : " + attrName + " [" + attrType + "]"); } String constantName = getConstantName(attrName); // Interface operation ObjectModelOperation interfaceOperation = addOperation(outputInterface, getJavaBeanMethodName("add", attrName), void.class, ObjectModelJavaModifier.PACKAGE); ObjectModelParameter param = addParameter(interfaceOperation, attrType, attrName); // Implementation ObjectModelOperation implOperation = createImplOperation(interfaceOperation); attrType = GeneratorUtil.getSimpleName(attrType); StringBuilder body = new StringBuilder(); if (generatePropertyChangeSupport) { body.append("" +"\n" +" fireOnPreWrite("+constantName+", null, "+attrName+");" ); } body.append("" +"\n" +" if (this."+attrName+" == null) {\n" +" this."+attrName+" = new "+collectionImpl+"<"+attrType+">();\n" +" }\n" +"" ); if (reverse != null && (reverse.isNavigable() || templateHelper.hasUnidirectionalRelationOnAbstractType(attribute, model))) { String getterName = getJavaBeanMethodName("get", reverse.getName()); String setterName = getJavaBeanMethodName("set", reverse.getName()); // TODO brendan 15/04/14 remove FQN String reverseAttrType = JavaGeneratorUtil.getAttributeImplementationType(reverse, true); if (!GeneratorUtil.isNMultiplicity(reverse)) { body.append("" +" "+attrName+"."+setterName+"(this);\n" +"" ); // Don't manage reverse attribute add if attribute has associationClass } else if (!attribute.hasAssociationClass()) { body.append("" +" if ("+attrName+"."+getterName+"() == null) {\n" +" "+attrName+"."+setterName+"(new "+reverseAttrType+"());\n" +" }\n" +" "+attrName+"."+getterName+"().add(this);\n" +"" ); } } body.append("" +" this."+attrName+".add("+attrName+");\n" +" " ); if (generatePropertyChangeSupport) { body.append("" +" fireOnPostWrite("+constantName+", this."+attrName+".size(), null, "+attrName+");\n" +" " ); } setOperationBody(implOperation, body.toString()); } protected void addMultipleAddAtIndexOperation(ObjectModelAttribute attribute, ObjectModelClassifier aClass, ObjectModelPackage aPackage, String collectionImpl) { String attrName = getPropertyName(attribute); String attrType = getPropertyType(attribute, aClass, aPackage); ObjectModelAttribute reverse = attribute.getReverseAttribute(); if (log.isDebugEnabled()) { log.debug("Generate multiple 'add' operation for property : " + attrName + " [" + attrType + "]"); } String constantName = getConstantName(attrName); // Interface operation ObjectModelOperation interfaceOperation = addOperation(outputInterface, getJavaBeanMethodName("add", attrName), void.class, ObjectModelJavaModifier.PACKAGE); addParameter(interfaceOperation, int.class, "index"); ObjectModelParameter param = addParameter(interfaceOperation, attrType, attrName); // Implementation ObjectModelOperation implOperation = createImplOperation(interfaceOperation); attrType = GeneratorUtil.getSimpleName(attrType); StringBuilder body = new StringBuilder(); if (generatePropertyChangeSupport) { body.append("" +"\n" +" fireOnPreWrite("+constantName+", null, "+attrName+");" ); } body.append("" +"\n" +" if (this."+attrName+" == null) {\n" +" this."+attrName+" = new "+collectionImpl+"<"+attrType+">();\n" +" }\n" +"" ); if (reverse != null && (reverse.isNavigable() || templateHelper.hasUnidirectionalRelationOnAbstractType(attribute, model))) { String getterName = getJavaBeanMethodName("get", reverse.getName()); String setterName = getJavaBeanMethodName("set", reverse.getName()); // TODO brendan 15/04/14 remove FQN String reverseAttrType = JavaGeneratorUtil.getAttributeImplementationType(reverse, true); if (!GeneratorUtil.isNMultiplicity(reverse)) { body.append("" +" "+attrName+"."+setterName+"(this);\n" +"" ); // Don't manage reverse attribute add if attribute has associationClass } else if (!attribute.hasAssociationClass()) { body.append("" +" if ("+attrName+"."+getterName+"() == null) {\n" +" "+attrName+"."+setterName+"(new "+reverseAttrType+"());\n" +" }\n" +" "+attrName+"."+getterName+"().add(index, this);\n" +"" ); } } body.append("" +" this."+attrName+".add(index, "+attrName+");\n" +" " ); if (generatePropertyChangeSupport) { body.append("" +" fireOnPostWrite("+constantName+", index, null, "+attrName+");\n" +" " ); } setOperationBody(implOperation, body.toString()); } protected void addMultipleAddAllOperation(ObjectModelAttribute attribute, ObjectModelClassifier aClass, ObjectModelPackage aPackage) { String attrName = getPropertyName(attribute); String attrType = getPropertyType(attribute, aClass, aPackage); if (log.isDebugEnabled()) { log.debug("Generate multiple 'addAll' operation for property : " + attrName + " [" + attrType + "]"); } // Interface operation ObjectModelOperation interfaceOperation = addOperation(outputInterface, getJavaBeanMethodName("addAll", attrName), void.class, ObjectModelJavaModifier.PACKAGE); ObjectModelParameter param = addParameter(interfaceOperation, "Iterable<" + attrType + ">", attrName); // Implementation ObjectModelOperation implOperation = createImplOperation(interfaceOperation); attrType = GeneratorUtil.getSimpleName(attrType); String addMethodName = getJavaBeanMethodName("add", attrName); setOperationBody(implOperation, "" +"\n" +" if ("+attrName+" == null) {\n" +" return;\n" +" }\n" +" for ("+attrType+" item : "+attrName+") {\n" +" "+addMethodName+"(item);\n" +" }\n" +" " ); } protected void addMultipleSetOperation(ObjectModelAttribute attribute, ObjectModelClassifier aClass, ObjectModelPackage aPackage, String collectionInterface, String collectionImpl) { String attrName = getPropertyName(attribute); String referenceType = getPropertyType(attribute, aClass, aPackage); String attrType = collectionInterface + "<" + referenceType + ">"; String constantName = getConstantName(attrName); if (log.isDebugEnabled()) { log.debug("Generate multiple 'set' operation for property : " + attrName + " [" + attrType + "]"); } // Interface operation ObjectModelOperation interfaceOperation = createPropertySetterSignature(outputInterface, attrType, attrName, ""); ObjectModelOperation implOperation = createImplOperation(interfaceOperation); attrType = GeneratorUtil.getSimpleName(attrType); referenceType = GeneratorUtil.getSimpleName(referenceType); StringBuilder body = new StringBuilder(); if (generatePropertyChangeSupport) { body.append("" +"\n" +" // Copy elements to keep data for fire with new reference\n" +" "+attrType+" oldValue = this."+attrName+" != null ? new "+collectionImpl+"<"+referenceType+">(this."+attrName+") : null;\n" +" fireOnPreWrite("+constantName+", oldValue, "+attrName+");" ); } body.append("" +"\n" +" this."+attrName+" = "+attrName+";\n" +" " ); if (generatePropertyChangeSupport) { body.append("" +" fireOnPostWrite("+constantName+", oldValue, "+attrName+");\n" +" " ); } setOperationBody(implOperation, body.toString()); } protected void addMultipleRemoveOperation(ObjectModelAttribute attribute, ObjectModelClassifier aClass, ObjectModelPackage aPackage) { String attrName = getPropertyName(attribute); String attrType = getPropertyType(attribute, aClass, aPackage); ObjectModelAttribute reverse = attribute.getReverseAttribute(); String constantName = getConstantName(attrName); if (log.isDebugEnabled()) { log.debug("Generate 'remove' operation for property : " + attrName + " [" + attrType + "]"); } // Interface operation ObjectModelOperation interfaceOperation = addOperation(outputInterface, getJavaBeanMethodName("remove", attrName), void.class, ObjectModelJavaModifier.PACKAGE); ObjectModelParameter param = addParameter(interfaceOperation, attrType, attrName); // Implementation ObjectModelOperation implOperation = createImplOperation(interfaceOperation); attrType = GeneratorUtil.getSimpleName(attrType); StringBuilder body = new StringBuilder(); if (generatePropertyChangeSupport) { body.append("" +"\n" +" fireOnPreWrite("+constantName+", "+attrName+", null);" ); } body.append("" +"\n" +" if (this."+attrName+" == null || !this."+attrName+".remove("+attrName+")) {\n" +" throw new IllegalArgumentException(\"List does not contain given element\");\n" +" }\n" +" " ); if (reverse != null && (reverse.isNavigable() || templateHelper.hasUnidirectionalRelationOnAbstractType(attribute, model))) { String getterName = getJavaBeanMethodName("get", reverse.getName()); String setterName = getJavaBeanMethodName("set", reverse.getName()); if (!GeneratorUtil.isNMultiplicity(reverse)) { body.append("" +" "+attrName+"."+setterName+"(null);\n" +" " ); // Don't manage reverse attribute remove if attribute has associationClass } else if (!attribute.hasAssociationClass()) { body.append("" +" "+attrName+"."+getterName+"().remove(this);\n" +" " ); } } if (generatePropertyChangeSupport) { body.append("" +" fireOnPostWrite("+constantName+", this."+attrName+".size() + 1, "+attrName+", null);\n" +" " ); } setOperationBody(implOperation, body.toString()); } protected void addMultipleRemoveAtIndexOperation(ObjectModelAttribute attribute, ObjectModelClassifier aClass, ObjectModelPackage aPackage) { String attrName = getPropertyName(attribute); String attrType = getPropertyType(attribute, aClass, aPackage); ObjectModelAttribute reverse = attribute.getReverseAttribute(); String constantName = getConstantName(attrName); if (log.isDebugEnabled()) { log.debug("Generate 'remove' operation for property : " + attrName + " [" + attrType + "]"); } // Interface operation ObjectModelOperation interfaceOperation = addOperation(outputInterface, getJavaBeanMethodName("remove", attrName), void.class, ObjectModelJavaModifier.PACKAGE); addParameter(interfaceOperation, int.class, "index"); // Implementation ObjectModelOperation implOperation = createImplOperation(interfaceOperation); attrType = GeneratorUtil.getSimpleName(attrType); StringBuilder body = new StringBuilder(); if (generatePropertyChangeSupport) { body.append("" +"\n" +" fireOnPreWrite("+constantName+", "+attrName+", null);" ); } body.append("" +"\n" +" if (this."+attrName+" == null) {\n" +" throw new IllegalArgumentException(\"List does not contain given element\");\n" +" }\n" +" "+attrType+" oldValue = this."+attrName+".remove(index);\n" +" if (oldValue == null) {\n" +" throw new IllegalArgumentException(\"List does not contain given element\");\n" +" }\n" +" " ); if (reverse != null && (reverse.isNavigable() || templateHelper.hasUnidirectionalRelationOnAbstractType(attribute, model))) { String getterName = getJavaBeanMethodName("get", reverse.getName()); String setterName = getJavaBeanMethodName("set", reverse.getName()); if (!GeneratorUtil.isNMultiplicity(reverse)) { body.append("" +" oldValue."+setterName+"(null);\n" +" " ); // Don't manage reverse attribute remove if attribute has associationClass } else if (!attribute.hasAssociationClass()) { body.append("" +" "+attrName+"."+getterName+"().remove(this);\n" +" " ); } } if (generatePropertyChangeSupport) { body.append("" +" fireOnPostWrite("+constantName+", index, oldValue, null);\n" +" " ); } setOperationBody(implOperation, body.toString()); } protected void addMultipleClearOperation(ObjectModelAttribute attribute, ObjectModelClassifier aClass, ObjectModelPackage aPackage, String collectionInterface, String collectionImpl) { String attrName = getPropertyName(attribute); String attrType = getPropertyType(attribute, aClass, aPackage); ObjectModelAttribute reverse = attribute.getReverseAttribute(); String constantName = getConstantName(attrName); if (log.isDebugEnabled()) { log.debug("Generate multiple 'clear' operation for property : " + attrName + " [" + attrType + "]"); } // Interface operation ObjectModelOperation interfaceOperation = addOperation(outputInterface, getJavaBeanMethodName("clear", attrName), void.class, ObjectModelJavaModifier.PACKAGE); // Implementation ObjectModelOperation implOperation = createImplOperation(interfaceOperation); attrType = GeneratorUtil.getSimpleName(attrType); StringBuilder body = new StringBuilder("" +"\n" +" if (this."+attrName+" == null) {\n" +" return;\n" +" }\n" +"" ); if (reverse != null && (reverse.isNavigable() || templateHelper.hasUnidirectionalRelationOnAbstractType(attribute, model))) { String getterName = getJavaBeanMethodName("get", reverse.getName()); String setterName = getJavaBeanMethodName("set", reverse.getName()); body.append("" +" for ("+attrType+" item : this."+attrName+") {\n" +"" ); if (!GeneratorUtil.isNMultiplicity(reverse)) { body.append("" +" item."+setterName+"(null);\n" +"" ); // Don't manage reverse attribute remove if attribute has associationClass } else if (!attribute.hasAssociationClass()) { body.append("" +" item."+getterName+"().remove(this);\n" +"" ); } body.append("" +" }\n" +"" ); } if (generatePropertyChangeSupport) { body.append("" +" "+collectionInterface+"<"+attrType+"> oldValue = new "+collectionImpl+"<"+attrType+">(this."+attrName+");\n" +" fireOnPreWrite("+constantName+", oldValue, this."+attrName+");\n" +"" ); } body.append("" +" this."+attrName+".clear();\n" +" " ); if (generatePropertyChangeSupport) { body.append("" +" fireOnPostWrite("+constantName+", oldValue, this."+attrName+");\n" +" " ); } setOperationBody(implOperation, body.toString()); } protected void addMultipleGetOperation(ObjectModelAttribute attribute, ObjectModelClassifier aClass, ObjectModelPackage aPackage, String collectionInterface) { String attrName = getPropertyName(attribute); String attrType = collectionInterface + "<" + getPropertyType(attribute, aClass, aPackage) + ">"; if (log.isDebugEnabled()) { log.debug("Generate multiple 'get' operation for property : " + attrName + " [" + attrType + "]"); } // Interface operation ObjectModelOperation interfaceOperation = addOperation(outputInterface, getJavaBeanMethodName("get", attrName), attrType, ObjectModelJavaModifier.PACKAGE); // Implementation ObjectModelOperation implOperation = createImplOperation(interfaceOperation); setOperationBody(implOperation, "" +"\n" +" return "+attrName+";\n" +" " ); } protected void addMultipleGetByIndexOperation(ObjectModelAttribute attribute, ObjectModelClassifier aClass, ObjectModelPackage aPackage) { String attrName = getPropertyName(attribute); String attrType = getPropertyType(attribute, aClass, aPackage); if (log.isDebugEnabled()) { log.debug("Generate multiple 'getByTopiaId' operation for property : " + attrName + " [" + attrType + "]"); } // Interface operation ObjectModelOperation interfaceOperation = addOperation(outputInterface, getJavaBeanMethodName("get", attrName), attrType, ObjectModelJavaModifier.PACKAGE); ObjectModelParameter param = addParameter(interfaceOperation, int.class, "index"); // Implementation ObjectModelOperation implOperation = createImplOperation(interfaceOperation); addImport(outputAbstract, TopiaEntityHelper.class); setOperationBody(implOperation, "" +"\n" +" return TopiaEntityHelper.getEntityByIndex("+attrName+", index);\n" +" " ); } protected void addMultipleGetByTopiaIdOperation(ObjectModelAttribute attribute, ObjectModelClassifier aClass, ObjectModelPackage aPackage) { String attrName = getPropertyName(attribute); String attrType = getPropertyType(attribute, aClass, aPackage); if (log.isDebugEnabled()) { log.debug("Generate multiple 'getByTopiaId' operation for property : " + attrName + " [" + attrType + "]"); } // Interface operation ObjectModelOperation interfaceOperation = addOperation(outputInterface, getJavaBeanMethodName("get", attrName) + "ByTopiaId", attrType, ObjectModelJavaModifier.PACKAGE); ObjectModelParameter param = addParameter(interfaceOperation, String.class, "topiaId"); // Implementation ObjectModelOperation implOperation = createImplOperation(interfaceOperation); addImport(outputAbstract, TopiaEntityHelper.class); setOperationBody(implOperation, "" +"\n" +" return TopiaEntityHelper.getEntityByTopiaId("+attrName+", topiaId);\n" +" " ); } protected void addMultipleGetTopiaIdsOperation(ObjectModelAttribute attribute, ObjectModelClassifier aClass, ObjectModelPackage aPackage, String collectionInterface, String collectionImpl) { String attrName = getPropertyName(attribute); String attrType = getPropertyType(attribute, aClass, aPackage); String getterName = getJavaBeanMethodName("get", attrName); if (log.isDebugEnabled()) { log.debug("Generate multiple 'getTopiaIds' operation for property : " + attrName + " [" + attrType + "]"); } // Interface operation ObjectModelOperation interfaceOperation = addOperation(outputInterface, getJavaBeanMethodName("get", attrName) + "TopiaIds", collectionInterface + "", ObjectModelJavaModifier.PACKAGE); addImport(outputAbstract, TopiaEntity.class); // Implementation ObjectModelOperation implOperation = createImplOperation(interfaceOperation); setOperationBody(implOperation, "" +"\n" +" "+collectionInterface+" topiaIds = new "+collectionImpl+"();\n" +" "+collectionInterface+"<"+attrType+"> tmp = "+getterName+"();\n" +" if (tmp != null) {\n" +" for (TopiaEntity topiaEntity : tmp) {\n" +" topiaIds.add(topiaEntity.getTopiaId());\n" +" }\n" +" }\n" +" return topiaIds;\n" +" " ); } protected void addMultipleGetOperationFromEntity(ObjectModelAttribute attribute, ObjectModelClassifier aClass, ObjectModelPackage aPackage) { // reference to the real attribute name String referenceName = attribute.getName(); String referenceType = attribute.getType(); String referenceGetterName = getJavaBeanMethodName("get", referenceName); // association attribute name String attrName = getPropertyName(attribute); String attrType = getPropertyType(attribute, aClass, aPackage); if (log.isDebugEnabled()) { log.debug("Generate multiple 'getFromEntity' operation for property : " + attrName + " [" + attrType + "]"); } // Interface operation ObjectModelOperation interfaceOperation = addOperation(outputInterface, getJavaBeanMethodName("get", attrName), attrType); addParameter(interfaceOperation, referenceType, referenceName); // Implementation ObjectModelOperation implOperation = createImplOperation(interfaceOperation); attrType = GeneratorUtil.getSimpleName(attrType); setOperationBody(implOperation, "" +"\n" +" if ("+referenceName+" == null || this."+attrName+" == null) {\n" +" return null;\n" +" }\n" +" for ("+attrType+" item : this."+attrName+") {\n" +" if ("+referenceName+".equals(item."+referenceGetterName+"())) {\n" +" return item;\n" +" }\n" +" }\n" +" return null;\n" +" " ); } protected void addMultipleSizeOperation(ObjectModelAttribute attribute) { String attrName = getPropertyName(attribute); if (log.isDebugEnabled()) { log.debug("Generate multiple 'size' operation for property : " + attrName); } // Interface operation ObjectModelOperation interfaceOperation = addOperation(outputInterface, getJavaBeanMethodName("size", attrName), int.class, ObjectModelJavaModifier.PACKAGE); // Implementation ObjectModelOperation implOperation = createImplOperation(interfaceOperation); setOperationBody(implOperation, "" +"\n" +" if ("+attrName+" == null) {\n" +" return 0;\n" +" }\n" +" return "+attrName+".size();\n" +" " ); } protected void addMultipleIsEmptyOperations(ObjectModelAttribute attribute) { String attrName = getPropertyName(attribute); if (log.isDebugEnabled()) { log.debug("Generate multiple 'isEmpty' operation for property : " + attrName); } String sizeMethodName = getJavaBeanMethodName("size", attrName); // isEmpty Interface operation String isEmptyMethodName = getJavaBeanMethodName("is", attrName) + "Empty"; ObjectModelOperation isEmptyInterfaceOperation = addOperation(outputInterface, isEmptyMethodName, boolean.class, ObjectModelJavaModifier.PACKAGE); // Implementation ObjectModelOperation isEmptyOperationImpl = createImplOperation(isEmptyInterfaceOperation); setOperationBody(isEmptyOperationImpl, "" +"\n" +" int size = "+sizeMethodName+"();\n" +" return size == 0;\n" +" " ); // isNotEmpty Interface operation ObjectModelOperation isNotEmptyInterfaceOperation = addOperation(outputInterface, getJavaBeanMethodName("is", attrName) + "NotEmpty", boolean.class, ObjectModelJavaModifier.PACKAGE); // Implementation ObjectModelOperation isNotEmptyOperationImpl = createImplOperation(isNotEmptyInterfaceOperation); setOperationBody(isNotEmptyOperationImpl, "" +"\n" +" boolean empty = "+isEmptyMethodName+"();\n" +" return ! empty;\n" +" " ); } protected void addMultipleContainsOperation(ObjectModelAttribute attribute, ObjectModelClassifier aClass, ObjectModelPackage aPackage) { String attrName = getPropertyName(attribute); String attrType = getPropertyType(attribute, aClass, aPackage); if (log.isDebugEnabled()) { log.debug("Generate multiple 'contains' operation for property : " + attrName); } String methodName = getJavaBeanMethodName("contains", attrName); ObjectModelOperation isEmptyInterfaceOperation = addOperation(outputInterface, methodName, boolean.class, ObjectModelJavaModifier.PACKAGE); addParameter(isEmptyInterfaceOperation, attrType, attrName); // Implementation ObjectModelOperation isEmptyOperationImpl = createImplOperation(isEmptyInterfaceOperation); setOperationBody(isEmptyOperationImpl, "" +"\n" +" boolean contains = this."+attrName+" !=null && this."+attrName+".contains("+attrName+");\n" +" return contains;\n" +" " ); } // ------------------------------------------------------------------------- // Generate util operations // ------------------------------------------------------------------------- private ObjectModelOperation internalAcceptOperation; private StringBuilder internalAcceptOperationBody; protected void createAcceptOperation() { ObjectModelOperation acceptOperation = addOperation(outputAbstract, "accept", void.class); addAnnotation(outputAbstract, acceptOperation, Override.class); addParameter(acceptOperation, TopiaEntityVisitor.class, "visitor"); addException(acceptOperation, TopiaException.class); setOperationBody(acceptOperation, "" +"\n" +" visitor.start(this);\n" +" accept0(visitor);\n" +" visitor.end(this);\n" +" " ); } protected void createAcceptInternalOperation(ObjectModelClass input) { boolean withSuperEntity = false; for (ObjectModelClassifier parent : input.getSuperclasses()) { if (templateHelper.isEntity(parent)) { withSuperEntity = true; break; } } internalAcceptOperation = addOperation(outputAbstract, "accept0", void.class, ObjectModelJavaModifier.PROTECTED); addParameter(internalAcceptOperation, TopiaEntityVisitor.class, "visitor"); addException(internalAcceptOperation, TopiaException.class); if (withSuperEntity) { addAnnotation(outputAbstract, internalAcceptOperation, Override.class); internalAcceptOperationBody = new StringBuilder("" +"\n" +" super.accept0(visitor);\n" +"" ); } else { internalAcceptOperationBody = new StringBuilder("" +"\n" +"" ); } } protected void updateAcceptOperation(ObjectModelAttribute attribute, ObjectModelClassifier aClass, ObjectModelPackage aPackage) { String attrName = GeneratorUtil.getSimpleName(getPropertyName(attribute)); String attrType = GeneratorUtil.getSimpleName(getPropertyType(attribute, aClass, aPackage)); // remove custom generics http://nuiton.org/issues/3453 attrType = GeneratorUtil.removeAnyGenericDefinition(attrType); String collectionType = getCollectionType(attribute); String constantName = getConstantName(attrName); if (collectionType != null) { collectionType = GeneratorUtil.getSimpleName(collectionType); internalAcceptOperationBody.append("" +" visitor.visit(this, "+constantName+", "+collectionType+".class, "+attrType+".class, "+attrName+");\n" +"" ); } else { internalAcceptOperationBody.append("" +" visitor.visit(this, "+constantName+", "+attrType+".class, "+attrName+");\n" +"" ); } } protected void closeAcceptInternalOperation() { setOperationBody(internalAcceptOperation, internalAcceptOperationBody.toString() + "" +" " ); } protected void generateToStringOperation(ObjectModelClass input) { if (log.isDebugEnabled()) { log.debug("generate toString method for entity " + outputInterface.getQualifiedName()); } ObjectModelOperation operation = addOperation(outputAbstract, "toString", String.class); addAnnotation(outputAbstract, operation, Override.class); addImport(outputAbstract, ToStringBuilder.class); StringBuilder body = new StringBuilder("" +"\n" +" String result = new ToStringBuilder(this).\n" +"" ); for (ObjectModelAttribute attr : input.getAttributes()) { //FIXME possibilité de boucles (non directes) ObjectModelClass attrEntity = null; if (model.hasClass(attr.getType())) { attrEntity = model.getClass(attr.getType()); } boolean isEntity = attrEntity != null && templateHelper.isEntity(attrEntity); ObjectModelAttribute reverse = attr.getReverseAttribute(); if (isEntity && (reverse == null || !reverse.isNavigable()) && !attr.hasAssociationClass() || !isEntity) { String attrName = attr.getName(); String constantName = getConstantName(attrName); body.append("" +" append("+constantName+", this."+attrName+").\n" +"" ); } } body.append("" +" toString();\n" +" return result;\n" +" " ); setOperationBody(operation, body.length() == 0 ? " " : body.toString()); } // ------------------------------------------------------------------------- // Helpers // ------------------------------------------------------------------------- protected boolean isAbstract(ObjectModelClass clazz) { if (clazz.isAbstract()) { return true; } //Une classe peut être abstraite si elle a des méthodes définies dans // ses superinterface et non implantées dans ses superclasses Collection allInterfaceOperations = clazz.getAllInterfaceOperations(true); allInterfaceOperations.removeAll(clazz.getAllOtherOperations(true)); for (ObjectModelOperation op : allInterfaceOperations) { boolean implementationFound = false; for (ObjectModelClass superClazz : clazz.getSuperclasses()) { for (ObjectModelOperation matchingOp : superClazz.getOperations(op.getName())) { implementationFound = op.equals(matchingOp) && !matchingOp.isAbstract(); if (implementationFound) { break; } } if (implementationFound) { break; } } if (!implementationFound) { if (log.isDebugEnabled()) { log.debug(clazz.getName() + " : abstract operation " + op); } return true; } } return false; } protected String getCollectionType(ObjectModelAttribute attribute) { String result = null; if (!associationClass && GeneratorUtil.isNMultiplicity(attribute)) { result = templateHelper.getCollectionType(attribute).getName(); } return result; } protected String getPropertyName(ObjectModelAttribute attribute) { String propertyName = attribute.getName(); if (!associationClass && attribute.hasAssociationClass()) { propertyName = GeneratorUtil.getAssocAttrName(attribute); } return propertyName; } protected String getPropertyType(ObjectModelAttribute attribute, ObjectModelClassifier aClass, ObjectModelPackage aPackage) { String propertyType = topiaHibernateTagValues.getAttributeType(attribute, aClass, aPackage, model); if (propertyType == null) { propertyType = attribute.getType(); } if (!associationClass && attribute.hasAssociationClass()) { propertyType = attribute.getAssociationClass().getQualifiedName(); } return propertyType; } protected ObjectModelOperation createImplOperation(ObjectModelOperation interfaceOperation) { ObjectModelOperation implOperation = cloneOperationSignature(interfaceOperation, outputAbstract, false); addAnnotation(outputAbstract, implOperation, Override.class); return implOperation; } /** * TODO-fdesbois-2010-06-25 : This method can be put in JavaBuilder or ObjectModelTransformerToJava * * This method create an set operation in {@code classifier} with * {@code propertyType} as return type and {@code propertyName} used for * operation name ('set[propertyName]'). {@code operationDocument} can * also be added to the operation created. Only signature with default * visibility will be added. * * @param classifier Classifier where the operation will be added * @param propertyType Type of the property (better if qualified name) * @param propertyName Name of the property to set * @param operationDocumentation Documentation for the operation * @return the created operation */ protected ObjectModelOperation createPropertySetterSignature(ObjectModelClassifier classifier, String propertyType, String propertyName, String operationDocumentation) { // Operation ObjectModelOperation operation = addOperation(classifier, getJavaBeanMethodName("set", propertyName), void.class); ObjectModelParameter param = addParameter(operation, propertyType, propertyName); // Documentation if (StringUtils.isNotEmpty(operationDocumentation)) { setDocumentation(operation, operationDocumentation); setDocumentation(param, "La valeur de l'attribut à positionner."); } return operation; } protected void addInterface(List interfaceAlreadyDone, ObjectModelClassifier output, ObjectModelClassifier interfaze) { String qualifiedName = interfaze.getQualifiedName(); if (!interfaceAlreadyDone.contains(qualifiedName)) { interfaceAlreadyDone.add(qualifiedName); if (output != null) { // add it to output addInterface(output, qualifiedName); if (log.isTraceEnabled()) { log.trace("Add interface " + qualifiedName + " on " + output.getQualifiedName()); } } else { if (log.isTraceEnabled()) { log.trace("Skip included interface " + qualifiedName); } } // scan also all interfaces or super-classes of it for (ObjectModelClassifier parent : interfaze.getInterfaces()) { addInterface(interfaceAlreadyDone, null, parent); } } } protected void addInterface(List interfaceAlreadyDone, ObjectModelClassifier output, Class clazz) { String qualifiedName = clazz.getName(); if (!interfaceAlreadyDone.contains(qualifiedName)) { // add it to output addInterface(output, qualifiedName); } } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy