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

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

There is a newer version: 10.0.1
Show newest version
package org.nuiton.topia.templates;

/*
 * #%L
 * Toolkit :: Templates
 * %%
 * Copyright (C) 2017 - 2024 Ultreia.io
 * %%
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU 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 Public License for more details.
 *
 * You should have received a copy of the GNU General Public
 * License along with this program.  If not, see
 * .
 * #L%
 */

import io.ultreia.java4all.classmapping.ImmutableClassMapping;
import io.ultreia.java4all.lang.Numbers;
import org.apache.commons.lang3.StringUtils;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
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.object.ObjectModel;
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.TopiaEntity;
import org.nuiton.topia.persistence.TopiaEntityVisitor;
import org.nuiton.topia.persistence.TopiaException;
import org.nuiton.topia.persistence.internal.AbstractTopiaEntity;
import org.nuiton.topia.service.sql.metadata.TopiaMetadataEntity;
import org.nuiton.topia.service.sql.metadata.TopiaMetadataModel;
import org.nuiton.topia.service.sql.metadata.TopiaMetadataOneToOneComposition;
import org.nuiton.topia.templates.sql.TopiaMetadataModelBuilder;

import java.io.File;
import java.io.IOException;
import java.util.Collection;
import java.util.LinkedHashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.ServiceLoader;
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 */ @SuppressWarnings({"StringOperationCanBeSimplified", "unused", "UnusedAssignment", "SameParameterValue"}) @Component(role = Template.class, hint = "org.nuiton.topia.templates.EntityTransformer") public class EntityTransformer extends ObjectModelTransformerToJava { private static final Logger log = LogManager.getLogger(EntityTransformer.class); protected final TopiaCoreTagValues topiaCoreTagValues; protected final TopiaExtensionTagValues topiaExtensionTagValues; protected final TopiaHibernateTagValues topiaHibernateTagValues; protected ObjectModelInterface outputInterface; protected ObjectModelClass outputAbstract; protected ObjectModelClass outputImpl; protected boolean generateInterface; protected boolean generateAbstract; protected boolean generateImpl; protected boolean generateBooleanGetMethods; protected boolean generatePropertyChangeSupport; protected TopiaTemplateHelper templateHelper; protected EntityToDtoMapping entityToDtoMapping; protected boolean doDto; protected ObjectModelClass input; private boolean associationClass; private boolean useRelativeName; private ObjectModelOperation internalAcceptOperation; private Set> dtoTypes; private StringBuilder internalAcceptOperationBody; private Map, StringBuilder> spiToDtoOperationBody; private Map, StringBuilder> spiFromDtoOperationBody; protected TopiaMetadataModel metadataModel; protected TopiaMetadataOneToOneComposition oneToOneComposition; protected ObjectModelAttribute reverseOneToOneAttribute; public EntityTransformer() { this.topiaCoreTagValues = new TopiaCoreTagValues(); this.topiaHibernateTagValues = new TopiaHibernateTagValues(); this.topiaExtensionTagValues = new TopiaExtensionTagValues(); } protected void clean() { outputInterface = null; outputAbstract = null; outputImpl = null; spiToDtoOperationBody = null; spiFromDtoOperationBody = null; input = null; dtoTypes = null; } @Override public void applyTemplate(ObjectModel model, File destDir) throws IOException { templateHelper = new TopiaTemplateHelper(model); metadataModel = TopiaMetadataModelBuilder.buildFull(isVerbose(), model, templateHelper); super.applyTemplate(model, destDir); } @Override public void transformFromModel(ObjectModel model) { for (EntityToDtoMapping toDtoMapping : ServiceLoader.load(EntityToDtoMapping.class, getClassLoader())) { this.entityToDtoMapping = toDtoMapping; this.entityToDtoMapping.init(this); break; } List entityClasses = templateHelper.getEntityClasses(model, true); EugeneCoreTagValues coreTagValues = new EugeneCoreTagValues(); useRelativeName = coreTagValues.isUseRelativeName(model); Set relativeNameExcludes = coreTagValues.getRelativeNameExcludes(model); String[] relativeNameExcludes1 = relativeNameExcludes == null ? new String[0] : relativeNameExcludes.toArray(new String[0]); super.transformFromModel(model); } @Override protected void debugOutputModel() { super.debugOutputModel(); if (entityToDtoMapping != null) { entityToDtoMapping.close(); } } @Override public void transformFromClass(ObjectModelClass input) { 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()); } setDoDto(input); 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); if (generateAbstract) { // Generate serialVersionUID on abstract class generateSerialVersionUID(input, outputAbstract); } if (generateImpl) { // Generate Entity Implementation class generateImpl(input); generateSerialVersionUID(input, outputImpl); } // Clean data output after transformation clean(); } protected void setDoDto(ObjectModelClass input) { this.input = input; doDto = entityToDtoMapping != null && entityToDtoMapping.accept(input); String literalName = templateHelper.getEntityEnumLiteralName(input); TopiaMetadataEntity metadataEntity = metadataModel.getEntity(literalName); Set oneToOneCompositions = metadataModel.getReverseOneToOneAssociations(literalName); if (oneToOneCompositions != null && !oneToOneCompositions.isEmpty()) { oneToOneComposition = oneToOneCompositions.iterator().next(); String oneToOneAttributeName = oneToOneComposition.getTargetPropertyName(); ObjectModelAttribute reverseOneToOneAttribute = null; for (ObjectModelAttribute attribute : input.getAttributes()) { if (!attribute.isNavigable()) { reverseOneToOneAttribute = attribute.getReverseAttribute(); if (oneToOneAttributeName == null || reverseOneToOneAttribute == null || !Objects.equals(oneToOneAttributeName, reverseOneToOneAttribute.getName())) { continue; } break; } } this.reverseOneToOneAttribute = Objects.requireNonNull(reverseOneToOneAttribute); } else { oneToOneComposition = null; this.reverseOneToOneAttribute = null; } } protected void generateSerialVersionUID(ObjectModelClass input, ObjectModelClass output) { addConstant(output, GeneratorUtil.SERIAL_VERSION_UID, long.class, "1L", ObjectModelJavaModifier.PRIVATE); } protected void createEntityInterface(ObjectModelPackage aPackage, ObjectModelClass input) { outputInterface = createInterface(input.getName(), input.getPackageName()); addImport(outputInterface, outputInterface.getQualifiedName()); // Documentation if (GeneratorUtil.hasDocumentation(input)) { setDocumentation(outputInterface, input.getDocumentation()); } 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) { addInterface(interfaceAlreadyDone, outputInterface, TopiaEntity.class); } addContractTypeMethod(input, outputInterface); } protected void createEntityAbstractClass(ObjectModelPackage aPackage, ObjectModelClass input) { outputAbstract = createAbstractClass(input.getName() + "Abstract", input.getPackageName()); addImport(outputAbstract, outputInterface.getQualifiedName()); // 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 always use an Impl, moreover use the util method instead String extendClass = templateHelper.getDOType(parent, model); 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); } } 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); } if (reverseOneToOneAttribute != null) { ObjectModelAttribute attribute = reverseOneToOneAttribute.getReverseAttribute(); generatePropertyConstant(attribute); generatePropertyAttribute(attribute, aClass, aPackage); generatePropertyOperations(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) { if (outputAbstract == null) { return; } 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(ObjectModelClass, ObjectModelAttribute, String, String) * @see #addSingleSetOperation(ObjectModelAttribute, ObjectModelClassifier, ObjectModelPackage) * @see #addMultipleAddOperation(ObjectModelAttribute, ObjectModelClassifier, ObjectModelPackage, String) * @see #addMultipleAddAllOperation(ObjectModelAttribute, ObjectModelClassifier, ObjectModelPackage, String) * @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, Class) * @see #addMultipleSizeOperation(ObjectModelAttribute) * @see #addMultipleIsEmptyOperations(ObjectModelAttribute) */ 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( (ObjectModelClass) aClass, attribute, attrType, JavaGeneratorUtil.OPERATION_GETTER_BOOLEAN_PREFIX); } if (!booleanProperty || generateBooleanGetMethods) { // getXXX addSingleGetOperation( (ObjectModelClass) aClass, attribute, attrType, JavaGeneratorUtil.OPERATION_GETTER_DEFAULT_PREFIX); } } else { // List, Set or Collection ? Class collectionInterfaceType = templateHelper.getCollectionType(attribute); String collectionInterface = collectionInterfaceType.getName(); String collectionImpl = templateHelper.getCollectionInstanceType(attribute).getName(); if (!useRelativeName) { addImport(outputInterface, collectionInterface); addImport(outputAbstract, collectionInterface); addImport(outputAbstract, collectionImpl); if (!GeneratorUtil.getSimpleName(collectionInterface).equals(outputInterface.getName()) && !GeneratorUtil.getSimpleName(collectionInterface).equals(outputAbstract.getName()) ) { collectionInterface = GeneratorUtil.getSimpleName(collectionInterface); } if (!GeneratorUtil.getSimpleName(collectionImpl).equals(outputInterface.getName()) && !GeneratorUtil.getSimpleName(collectionImpl).equals(outputAbstract.getName())) { 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); // addAllXXX addMultipleAddAllOperation(attribute, aClass, aPackage, collectionImpl); // setXXX addMultipleSetOperation(attribute, aClass, aPackage, collectionInterface, collectionImpl); // removeXXX addMultipleRemoveOperation(attribute, aClass, aPackage); // clearXXX addMultipleClearOperation(attribute, aClass, aPackage, collectionInterface, collectionImpl); // getXXX addMultipleGetOperation(attribute, aClass, aPackage, collectionInterface, collectionInterfaceType); if (entity) { // 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, ""); if (outputAbstract == null) { return; } // Implementation ObjectModelOperation implOperation = createImplOperation(interfaceOperation); if (!useRelativeName) { attrType = GeneratorUtil.getSimpleName(attrType); } String constantName = getConstantName(attrName); StringBuilder body = new StringBuilder(); Integer digits = topiaExtensionTagValues.getDigits(aPackage, aClass, attribute); if (digits != null) { addImport(outputAbstract, Numbers.class); body.append("" +"\n" +" if ("+attrName+" != null) {\n" +" // round to "+digits+" digit(s)\n" +" "+attrName+" = Numbers.roundNDigits("+attrName+", "+digits+");\n" +" }\n" +" " ); } if (generatePropertyChangeSupport) { body.append("" +"\n" +" "+attrType+" oldValue = this."+attrName+";" ); } body.append("" +"\n" +" this."+attrName+" = "+attrName+";\n" +" " ); if (generatePropertyChangeSupport) { body.append("" +" firePropertyChange("+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 input input class * @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(ObjectModelClass input, 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); if (outputAbstract == null) { return; } // Implementation ObjectModelOperation implOperation = createImplOperation(interfaceOperation); if (!useRelativeName) { attrType = GeneratorUtil.getSimpleName(attrType); } StringBuilder body = new StringBuilder(); body.append("" +"\n" +" return this."+attrName+";\n" +"" ); setOperationBody(implOperation, body.toString()); if (doDto) { boolean isEntity = attribute.getClassifier() != null && templateHelper.isEntity(attribute.getClassifier()); for (Class dtoType : dtoTypes) { if (entityToDtoMapping.acceptToDtoProperty(dtoType, attrName)) { String toDtoGetterName = entityToDtoMapping.getToDtoSimpleMethod(dtoType, attribute, operationPrefix, isEntity); String toDtoSetterName = getJavaBeanMethodName("set", attrName); spiToDtoOperationBody.get(dtoType).append(""+"\n" +" dto."+toDtoSetterName+"("+toDtoGetterName+");"); if (entityToDtoMapping.acceptFromDtoProperty(dtoType, attrName, isEntity, false)) { String fromDtoGetterName = entityToDtoMapping.getFromDtoSimpleMethod(dtoType, attribute, operationPrefix, isEntity); if (fromDtoGetterName != null) { String fromDtoSetterName = getJavaBeanMethodName("set", attrName); spiFromDtoOperationBody.get(dtoType).append(""+"\n" +" entity."+fromDtoSetterName+"("+fromDtoGetterName+");"); } } } } } } public String getJavaBeanMethodName(String methodPrefix, String propertyName) { return super.getJavaBeanMethodName(methodPrefix, propertyName); } 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); if (outputAbstract == null) { return; } // Implementation ObjectModelOperation implOperation = createImplOperation(interfaceOperation); if (!useRelativeName) { attrType = GeneratorUtil.getSimpleName(attrType); } StringBuilder body = new StringBuilder(); 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("" +" firePropertyChange("+constantName+", null, "+attrName+");\n" +" " ); } setOperationBody(implOperation, body.toString()); } protected void addMultipleAddAllOperation(ObjectModelAttribute attribute, ObjectModelClassifier aClass, ObjectModelPackage aPackage, String collectionImpl) { 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, "java.util.Collection<" + attrType + ">", attrName); if (outputAbstract == null) { return; } // Implementation ObjectModelOperation implOperation = createImplOperation(interfaceOperation); String constantName = getConstantName(attrName); if (!useRelativeName) { attrType = GeneratorUtil.getSimpleName(attrType); } StringBuilder body = new StringBuilder(); body.append("" +"\n" +" if ("+attrName+" == null) {\n" +" return;\n" +" }\n" +" if (this."+attrName+" == null) {\n" +" this."+attrName+" = new "+collectionImpl+"<"+attrType+">();\n" +" }\n" +" this."+attrName+".addAll("+attrName+");\n" +"" ); if (generatePropertyChangeSupport) { body.append("" +" firePropertyChange("+constantName+", null, "+attrName+");\n" +" " ); } setOperationBody(implOperation, body.toString()); } 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, ""); if (outputAbstract == null) { return; } ObjectModelOperation implOperation = createImplOperation(interfaceOperation); if (!useRelativeName) { 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;" ); } body.append("" +"\n" +" this."+attrName+" = "+attrName+";\n" +" " ); if (generatePropertyChangeSupport) { body.append("" +" firePropertyChange("+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); if (outputAbstract == null) { return; } // Implementation ObjectModelOperation implOperation = createImplOperation(interfaceOperation); if (!useRelativeName) { attrType = GeneratorUtil.getSimpleName(attrType); } StringBuilder body = new StringBuilder(); 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("" +" firePropertyChange("+constantName+", null, "+attrName+");\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); if (outputAbstract == null) { return; } // Implementation ObjectModelOperation implOperation = createImplOperation(interfaceOperation); if (!useRelativeName) { 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+"<>(this."+attrName+");\n" +"" ); } body.append("" +" this."+attrName+".clear();\n" +" " ); if (generatePropertyChangeSupport) { body.append("" +" firePropertyChange("+constantName+", oldValue, this."+attrName+");\n" +" " ); } setOperationBody(implOperation, body.toString()); } protected void addMultipleGetOperation(ObjectModelAttribute attribute, ObjectModelClassifier aClass, ObjectModelPackage aPackage, String collectionInterface, Class collectionInterfaceType) { 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); if (outputAbstract == null) { return; } // Implementation ObjectModelOperation implOperation = createImplOperation(interfaceOperation); setOperationBody(implOperation, "" +"\n" +" return "+attrName+";\n" +" " ); if (doDto) { boolean isEntity = attribute.getClassifier() != null && templateHelper.isEntity(attribute.getClassifier()); for (Class dtoType : dtoTypes) { if (entityToDtoMapping.acceptToDtoProperty(dtoType, attrName)) { String toDtoGetterName = entityToDtoMapping.getToDtoMultipleMethod(dtoType, attribute, isEntity); String toDtoSetterName = getJavaBeanMethodName("set", attrName); spiToDtoOperationBody.get(dtoType).append(""+"\n" +" dto."+toDtoSetterName+"("+toDtoGetterName+");" ); if (entityToDtoMapping.acceptFromDtoProperty(dtoType, attrName, isEntity, true)) { String fromDtoGetterName = entityToDtoMapping.getFromDtoMultipleMethod(dtoType, attribute, collectionInterfaceType, isEntity); if (fromDtoGetterName != null) { String fromDtoSetterName = getJavaBeanMethodName("set", attrName); spiFromDtoOperationBody.get(dtoType).append(""+"\n" +" entity."+fromDtoSetterName+"("+fromDtoGetterName+");" ); } } } if (entityToDtoMapping.acceptToDtoProperty(dtoType, attrName + "Size")) { String toDtoSetterName = getJavaBeanMethodName("set", attrName + "Size"); String toDtoGetterName = getJavaBeanMethodName("get", attrName + "Size"); spiToDtoOperationBody.get(dtoType).append(""+"\n" +" dto."+toDtoSetterName+"(entity."+toDtoGetterName+"());" ); } if (entityToDtoMapping.acceptToDtoProperty(dtoType, attrName + "Empty")) { String toDtoSetterName = getJavaBeanMethodName("set", attrName + "Empty"); String toDtoGetterName = getJavaBeanMethodName("is", attrName + "Empty"); spiToDtoOperationBody.get(dtoType).append(""+"\n" +" dto."+toDtoSetterName+"(entity."+toDtoGetterName+"());" ); } } } } 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); if (outputAbstract == null) { return; } 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 addMultipleSizeOperation(ObjectModelAttribute attribute) { String attrName = getPropertyName(attribute); log.debug(String.format("Generate multiple 'getSize' operation for property : %s", attrName)); // Interface operation ObjectModelOperation interfaceOperation = addOperation(outputInterface, getJavaBeanMethodName("get", attrName + "Size"), int.class, ObjectModelJavaModifier.PACKAGE); if (outputAbstract == null) { return; } // 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); log.debug(String.format("Generate multiple 'isEmpty' operation for property : %s", attrName)); String sizeMethodName = getJavaBeanMethodName("get", attrName + "Size"); // isEmpty Interface operation String isEmptyMethodName = getJavaBeanMethodName("is", attrName) + "Empty"; ObjectModelOperation isEmptyInterfaceOperation = addOperation(outputInterface, isEmptyMethodName, boolean.class, ObjectModelJavaModifier.PACKAGE); // isNotEmpty Interface operation ObjectModelOperation isNotEmptyInterfaceOperation = addOperation(outputInterface, getJavaBeanMethodName("is", attrName) + "NotEmpty", boolean.class, ObjectModelJavaModifier.PACKAGE); if (outputAbstract == null) { return; } // Implementation ObjectModelOperation isEmptyOperationImpl = createImplOperation(isEmptyInterfaceOperation); setOperationBody(isEmptyOperationImpl, ""+"\n" +" int size = "+sizeMethodName+"();\n" +" return size == 0;\n" +" " ); // 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); if (outputAbstract == null) { return; } // Implementation ObjectModelOperation isEmptyOperationImpl = createImplOperation(isEmptyInterfaceOperation); setOperationBody(isEmptyOperationImpl, "" +"\n" +" boolean contains = this."+attrName+" !=null && this."+attrName+".contains("+attrName+");\n" +" return contains;\n" +" " ); } // ------------------------------------------------------------------------- // Generate util operations // ------------------------------------------------------------------------- protected void createAcceptOperation() { if (outputAbstract == null) { return; } 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) { if (outputAbstract == null) { return; } boolean withSuperEntity = false; for (ObjectModelClassifier parent : input.getSuperclasses()) { if (templateHelper.isEntity(parent)) { withSuperEntity = true; break; } } if (doDto) { Class dtoTypeContract = entityToDtoMapping.getDtoContract(input); dtoTypes = entityToDtoMapping.getDtoTypes(input); spiToDtoOperationBody = new LinkedHashMap<>(); spiFromDtoOperationBody = new LinkedHashMap<>(); addImport(outputAbstract, dtoTypeContract); for (Class dtoType : dtoTypes) { String dtoTypeName = dtoType.getName(); spiToDtoOperationBody.put(dtoType, new StringBuilder("")); spiFromDtoOperationBody.put(dtoType, new StringBuilder("")); } } 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) { if (outputAbstract == null) { return; } String attrName = GeneratorUtil.getSimpleName(getPropertyName(attribute)); String attrType = importAndSimplify(outputAbstract, 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) { 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() { if (outputAbstract == null) { return; } setOperationBody(internalAcceptOperation, internalAcceptOperationBody.toString() + "" +" " ); } protected String generateToDtoOperation(Class dtoType) { String content = spiToDtoOperationBody.get(dtoType).toString().trim(); return ""+"\n" +" super.toDto(referentialLocale, entity, dto);\n" +" "+content+"\n" +" dto.postInit();"; } protected String generateFromDtoOperation(Class dtoType) { String content = spiFromDtoOperationBody.get(dtoType).toString().trim(); return ""+"\n" +" super.fromDto(referentialLocale, entity, dto);\n" +" "+content+""; } // ------------------------------------------------------------------------- // 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); } } protected void generateSimpleClassMapping(String className, boolean useSimpleName, Class superClass, String sourceType, String targetType, Class builderType, String buildMethod, Map mapping) { ObjectModelClass output = createClass(className, getDefaultPackageName()); addImport(output, ImmutableClassMapping.class); String initMethod = builderType.getName(); if (useSimpleName) { addImport(output, builderType); addImport(output, sourceType); addImport(output, targetType); sourceType = GeneratorUtil.getSimpleName(sourceType); targetType = GeneratorUtil.getSimpleName(targetType); initMethod = GeneratorUtil.getSimpleName(initMethod); } setSuperClass(output, superClass); StringBuilder body = new StringBuilder(""+"\n" +" super(" ); body.append(""+""+initMethod+".<"+sourceType+", "+targetType+">builder()" ); mapping.forEach((source, target) -> body.append(""+"\n" +" .put("+source+".class, "+target+")" )); body.append(""+"\n" +" ."+buildMethod+"());\n" +" " ); ObjectModelOperation constructor = addConstructor(output, ObjectModelJavaModifier.PUBLIC); setOperationBody(constructor, body.toString()); } protected void addContractTypeMethod(ObjectModelClass input, ObjectModelClassifier output) { ObjectModelJavaModifier[] modifier = output instanceof ObjectModelInterface ? new ObjectModelJavaModifier[]{ObjectModelJavaModifier.DEFAULT} : new ObjectModelJavaModifier[]{ObjectModelJavaModifier.PUBLIC, ObjectModelJavaModifier.FINAL}; String type = output instanceof ObjectModelInterface ? input.getName() : output.getName(); ObjectModelOperation contractType = addOperation(output, "contractType", String.format("Class<%s>", type), modifier); addAnnotation(output, contractType, Override.class); setOperationBody(contractType, ""+"\n" +" return "+type+".class;\n" +" "); } }





© 2015 - 2025 Weber Informatics LLC | Privacy Policy