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

fr.ird.observe.toolkit.templates.entity.ToolkitEntityTransformer Maven / Gradle / Ivy

There is a newer version: 10.0.1
Show newest version
package fr.ird.observe.toolkit.templates.entity;

/*-
 * #%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 com.google.auto.service.AutoService;
import com.google.common.collect.ImmutableMap;
import fr.ird.observe.dto.BusinessDto;
import fr.ird.observe.dto.DtoParentAware;
import fr.ird.observe.dto.data.ContainerDto;
import fr.ird.observe.dto.data.DataDto;
import fr.ird.observe.dto.data.DataGroupByType;
import fr.ird.observe.dto.data.EditableDto;
import fr.ird.observe.dto.data.OpenableDto;
import fr.ird.observe.dto.data.SimpleDto;
import fr.ird.observe.dto.reference.DtoReference;
import fr.ird.observe.dto.referential.ReferentialLocale;
import fr.ird.observe.entities.Entity;
import fr.ird.observe.entities.data.DataEntity;
import fr.ird.observe.entities.data.DataGroupByEntityAbstract;
import fr.ird.observe.entities.data.DataGroupByEntityDefinition;
import fr.ird.observe.entities.referential.I18nReferentialEntity;
import fr.ird.observe.entities.referential.ReferentialEntity;
import fr.ird.observe.spi.PersistenceBusinessProject;
import fr.ird.observe.spi.ProjectPackagesDefinition;
import fr.ird.observe.spi.context.ContainerDtoEntityContext;
import fr.ird.observe.spi.context.DataDtoEntityContext;
import fr.ird.observe.spi.context.DtoEntityContext;
import fr.ird.observe.spi.context.EditableDtoEntityContext;
import fr.ird.observe.spi.context.OpenableDtoEntityContext;
import fr.ird.observe.spi.context.ReferentialDtoEntityContext;
import fr.ird.observe.spi.context.RootOpenableDtoEntityContext;
import fr.ird.observe.spi.context.SimpleDtoEntityContext;
import fr.ird.observe.spi.mapping.DtoToEntityContextMapping;
import fr.ird.observe.spi.mapping.EntityToDtoClassMapping;
import fr.ird.observe.spi.module.BusinessModule;
import fr.ird.observe.spi.navigation.model.MetaModelSupport;
import fr.ird.observe.spi.navigation.model.tree.TreeNodeModel;
import fr.ird.observe.spi.navigation.model.tree.TreeProjectModel;
import fr.ird.observe.spi.navigation.model.tree.TreeProjectModelBuilder;
import fr.ird.observe.spi.navigation.parent.ParentLink;
import fr.ird.observe.spi.navigation.parent.ParentProjectModel;
import fr.ird.observe.spi.relation.MultipleDtoEntityRelation;
import fr.ird.observe.spi.relation.SingleDtoEntityRelation;
import fr.ird.observe.spi.relation.WithDtoEntityRelation;
import fr.ird.observe.spi.result.AddEntityToUpdateStep;
import fr.ird.observe.toolkit.templates.TemplateContract;
import fr.ird.observe.toolkit.templates.ToolkitTagValues;
import fr.ird.observe.toolkit.templates.dto.stats.StatisticDefinitionModel;
import fr.ird.observe.toolkit.templates.dto.stats.StatisticsHelper;
import fr.ird.observe.toolkit.templates.validation.ValidationTagValues;
import io.ultreia.java4all.bean.definition.JavaBeanDefinition;
import io.ultreia.java4all.bean.definition.JavaBeanDefinitionStore;
import io.ultreia.java4all.bean.spi.GenerateJavaBeanDefinition;
import io.ultreia.java4all.classmapping.ImmutableClassMapping;
import io.ultreia.java4all.lang.Strings;
import org.apache.commons.lang3.tuple.Pair;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.nuiton.eugene.EugeneCoreTagValues;
import org.nuiton.eugene.GeneratorUtil;
import org.nuiton.eugene.java.extension.ImportsManager;
import org.nuiton.eugene.java.extension.ObjectModelAnnotation;
import org.nuiton.eugene.models.object.ObjectModel;
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.ObjectModelElement;
import org.nuiton.eugene.models.object.ObjectModelEnumeration;
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.ObjectModelAttributeImpl;
import org.nuiton.eugene.models.object.xml.ObjectModelImpl;
import org.nuiton.eugene.models.object.xml.ObjectModelInterfaceImpl;
import org.nuiton.topia.persistence.TopiaEntity;
import org.nuiton.topia.persistence.TopiaPersistenceContext;
import org.nuiton.topia.persistence.filter.EntityFilterConsumer;
import org.nuiton.topia.persistence.filter.EntityFilterProperty;
import org.nuiton.topia.persistence.filter.property.BooleanFilterProperty;
import org.nuiton.topia.persistence.filter.property.DateFilterProperty;
import org.nuiton.topia.persistence.filter.property.DoubleFilterProperty;
import org.nuiton.topia.persistence.filter.property.EnumFilterProperty;
import org.nuiton.topia.persistence.filter.property.FloatFilterProperty;
import org.nuiton.topia.persistence.filter.property.IdFilterProperty;
import org.nuiton.topia.persistence.filter.property.IntegerFilterProperty;
import org.nuiton.topia.persistence.filter.property.LongFilterProperty;
import org.nuiton.topia.persistence.filter.property.StringFilterProperty;
import org.nuiton.topia.persistence.filter.property.TimeFilterProperty;
import org.nuiton.topia.persistence.filter.property.TimestampFilterProperty;
import org.nuiton.topia.persistence.internal.AbstractTopiaEntity;
import org.nuiton.topia.service.sql.TopiaEntitySqlModelResource;
import org.nuiton.topia.service.sql.metadata.TopiaMetadataEntity;
import org.nuiton.topia.service.sql.model.TopiaEntitySqlDescriptor;
import org.nuiton.topia.service.sql.script.TopiaEntitySqlScript;
import org.nuiton.topia.templates.EntityTransformer;

import java.beans.Introspector;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.lang.reflect.Parameter;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.lang.reflect.TypeVariable;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Comparator;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.LinkedHashSet;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Set;
import java.util.TreeMap;
import java.util.TreeSet;
import java.util.function.Function;
import java.util.stream.Collectors;




/**
 * 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", "CommentedOutCode", "unused"}) public class ToolkitEntityTransformer extends EntityTransformer implements TemplateContract { private static final Logger log = LogManager.getLogger(ToolkitEntityTransformer.class); private final Set spiMethodNames; private final Map dtoToEntityContextMapping = new TreeMap<>(); private final Map entityToDtoClassMapping = new TreeMap<>(); private final List groupByDtoDefinitionMapping = new LinkedList<>(); private final ToolkitTagValues toolkitTagValues; private final ValidationTagValues validationTagValues; protected boolean doReference; private Class referenceContractType; private Class dtoContractType; private Class dtoType; private Class referenceType; private String parentWithGeneric; private String[] relativeNameExcludes; private List entityClasses; private List entityClassesFully; private ProjectPackagesDefinition def; private List entityClassesEntryPoints; private ParentProjectModel parentProjectModel; private TreeProjectModel navigationProjectModel; private List statisticDefinitions; public ToolkitEntityTransformer() { this.toolkitTagValues = new ToolkitTagValues(); spiMethodNames = new LinkedHashSet<>(); spiMethodNames.add("fromDto"); spiMethodNames.add("getDao"); spiMethodNames.add("entityToForm"); spiMethodNames.add("loadEntityToReferenceDto"); spiMethodNames.add("loadEntityToDto"); spiMethodNames.add("loadEntities"); spiMethodNames.add("loadOrCreateEntity"); spiMethodNames.add("loadEntity"); spiMethodNames.add("loadEntitiesToDto"); spiMethodNames.add("loadReference"); spiMethodNames.add("loadOrCreateEntityFromDto"); spiMethodNames.add("loadNullableEntity"); spiMethodNames.add("newEntity"); spiMethodNames.add("newDto"); spiMethodNames.add("toReferenceSet"); spiMethodNames.add("toDto"); spiMethodNames.add("toReference"); spiMethodNames.add("toReferenceType"); spiMethodNames.add("toEntity"); spiMethodNames.add("toDtoSet"); spiMethodNames.add("toDtoList"); spiMethodNames.add("toLabelList"); spiMethodNames.add("toReferenceLabelList"); spiMethodNames.add("toDtoType"); spiMethodNames.add("usageModel"); validationTagValues = new ValidationTagValues(); } @SuppressWarnings({"unchecked", "rawtypes"}) @Override protected void setDoDto(ObjectModelClass input) { super.setDoDto(input); boolean isAbstract = input.isAbstract() && !input.isStatic(); doReference = doDto && !isAbstract && entityToDtoMapping.acceptReference(input); if (doDto) { dtoContractType = ((ToolkitEntityToDtoMapping) entityToDtoMapping).getDtoContract2(); referenceContractType = ((ToolkitEntityToDtoMapping) entityToDtoMapping).getReferenceType(dtoContractType); dtoType = (Class) entityToDtoMapping.getDtoType(); Collection classifiersToTest = new LinkedList<>(input.getInterfaces()); classifiersToTest.addAll((Collection) input.getSuperclasses()); for (ObjectModelClassifier parent : classifiersToTest) { ObjectModelClass parent1 = model.getClass(parent.getQualifiedName()); if (parent1 != null && templateHelper.isEntity(parent1)) { parentWithGeneric = parent.getQualifiedName(); break; } } } if (doReference) { referenceType = ((ToolkitEntityToDtoMapping) entityToDtoMapping).getReferenceType(dtoType); } } @Override public void transformFromModel(ObjectModel model) { def = ProjectPackagesDefinition.of(getClassLoader()); EugeneCoreTagValues coreTagValues = new EugeneCoreTagValues(); Set relativeNameExcludes = coreTagValues.getRelativeNameExcludes(model); this.relativeNameExcludes = relativeNameExcludes == null ? new String[0] : relativeNameExcludes.toArray(new String[0]); MetaModelSupport metaModelSupport = new MetaModelSupport(model.getName()); navigationProjectModel = metaModelSupport.getTreeNavigationProjectModel(); parentProjectModel = metaModelSupport.getParentProjectModel(); List entityClasses = templateHelper.getEntityClasses(model, false); this.entityClasses = entityClasses.stream().map(ObjectModelClass::getName).collect(Collectors.toList()); entityClassesFully = entityClasses.stream().map(ObjectModelClass::getQualifiedName).collect(Collectors.toList()); this.entityClassesEntryPoints = entityClasses.stream().filter(topiaExtensionTagValues::isEntryPoint).map(ObjectModelClass::getQualifiedName).collect(Collectors.toCollection(LinkedList::new)); super.transformFromModel(model); } @Override protected void debugOutputModel() { super.debugOutputModel(); generateClassMapping(true, DtoToEntityContextMapping.class, "Class", DtoEntityContext.class.getName() + "", ImmutableMap.class, "build", dtoToEntityContextMapping); generateClassMapping(true, EntityToDtoClassMapping.class, Entity.class.getName(), BusinessDto.class.getName(), ImmutableClassMapping.class, "getMappingBuilder", entityToDtoClassMapping); String businessProjectClassName = generateBusinessProject(model.getName()); if (isVerbose()) { getLog().info("Generated: " + businessProjectClassName); } } @Override protected boolean isGenerateAbstract(ObjectModelClass input) { if (Entity.class.getName().equals(input.getQualifiedName())) { return false; } return super.isGenerateAbstract(input); } @Override protected boolean isGenerateImpl(ObjectModelClass input) { if (ReferentialEntity.class.getName().equals(input.getQualifiedName())) { return true; } if (I18nReferentialEntity.class.getName().equals(input.getQualifiedName())) { return true; } if (DataEntity.class.getName().equals(input.getQualifiedName())) { return true; } return super.isGenerateImpl(input); } @SuppressWarnings("unused") private String generateBusinessProject(String name) { String className = String.format("%s%s", name, PersistenceBusinessProject.class.getSimpleName()); ObjectModelClass aClass = createClass(className, PersistenceBusinessProject.class.getPackage().getName()); ObjectModelAnnotation annotation = addAnnotation(aClass, aClass, AutoService.class); ImportsManager importManager = getImportManager(aClass); addAnnotationClassParameter(importManager, aClass, annotation, "value", PersistenceBusinessProject.class); setSuperClass(aClass, PersistenceBusinessProject.class); addImport(aClass, List.class); addImport(aClass, BusinessModule.class); ObjectModelOperation getOperation = addOperation(aClass, "get", className, ObjectModelJavaModifier.PUBLIC, ObjectModelJavaModifier.STATIC); setOperationBody(getOperation, ""+"\n" +" return ("+className+") PersistenceBusinessProject.get();\n" +" "); ObjectModelOperation constructor = addConstructor(aClass, ObjectModelJavaModifier.PUBLIC); String entityToDtoMapping = EntityToDtoClassMapping.class.getPackage().getName() + "." + name + EntityToDtoClassMapping.class.getSimpleName(); String dtoToEntityContextMapping = DtoToEntityContextMapping.class.getPackage().getName() + "." + name + DtoToEntityContextMapping.class.getSimpleName(); List tmp = new LinkedList<>(); for (String groupBy : groupByDtoDefinitionMapping) { tmp.add(",\n " + groupBy); } String groupByDtoDefinition = String.join("", tmp).substring(1); setOperationBody(constructor, ""+"\n" +" super("+entityToDtoMapping+".get(), "+dtoToEntityContextMapping+".get(),"+groupByDtoDefinition+");\n" +" "); return aClass.getQualifiedName(); } @Override protected void createEntityInterface(ObjectModelPackage aPackage, ObjectModelClass input) { statisticDefinitions = null; if (doDto && dtoType != null) { String[] statisticsTagValue = ((ToolkitEntityToDtoMapping) entityToDtoMapping).getStatisticsTagValue(dtoType); statisticDefinitions = statisticsTagValue == null ? null : StatisticsHelper.toModel(model, input, def, Objects.requireNonNull(statisticsTagValue)); } boolean isAbstract = input.isAbstract() && !input.isStatic(); if (isAbstract && doDto) { String name = input.getName(); if (generateInterface) { outputInterface = createInterface(name, input.getPackageName()); } else { outputInterface = new ObjectModelInterfaceImpl(); ((ObjectModelInterfaceImpl) outputInterface).setName(name); } } else { if (generateInterface) { outputInterface = createInterface(input.getName(), input.getPackageName()); } else { outputInterface = new ObjectModelInterfaceImpl(); ((ObjectModelInterfaceImpl) outputInterface).setName(input.getName()); } } addImport(outputInterface, outputInterface.getQualifiedName()); if (!generateInterface) { return; } // Documentation if (GeneratorUtil.hasDocumentation(input)) { setDocumentation(outputInterface, input.getDocumentation()); } addAnnotation(outputInterface, outputInterface, GenerateJavaBeanDefinition.class); boolean oneParentContainsEntity = false; List interfaceAlreadyDone = new LinkedList<>(); for (ObjectModelClassifier parent : input.getInterfaces()) { if (doDto) { Set parents = collectAllInterfaces(parent); oneParentContainsEntity = parents.contains(Entity.class.getName()); if (parent.getQualifiedName().equals(parentWithGeneric)) { addImport(outputInterface, parentWithGeneric); addInterface(interfaceAlreadyDone, outputInterface, parentWithGeneric); continue; } if (oneParentContainsEntity) { addImport(outputInterface, parent.getQualifiedName()); addInterface(interfaceAlreadyDone, outputInterface, parent.getQualifiedName()); continue; } } addInterface(interfaceAlreadyDone, outputInterface, parent); } for (ObjectModelClassifier parent : input.getSuperclasses()) { if (templateHelper.isEntity(parent)) { if (doDto) { if (isAbstract) { addInterface(interfaceAlreadyDone, outputInterface, parent.getQualifiedName()); } else { if (oneParentContainsEntity) { continue; } addInterface(interfaceAlreadyDone, outputInterface, parent.getQualifiedName()); } } else { addInterface(interfaceAlreadyDone, outputInterface, parent); } } } if (generateInterface && doDto && !isAbstract) { String persistenceContext = getDefaultPackageName() + "." + templateHelper.getPersistenceContextConcreteName(model); addImport(outputInterface, persistenceContext); boolean referential = TemplateContract.isReferentialFromPackageName(aPackage.getName()); addWithNoCodeInterface(referential, input, outputInterface); } if (!isAbstract) { generateJavaBeanMethods(); } addContractTypeMethod(input, outputInterface); } @SuppressWarnings("UnusedAssignment") @Override protected void closeAcceptInternalOperation() { super.closeAcceptInternalOperation(); boolean isAbstract = input.isAbstract() && !input.isStatic(); if (generateInterface && doDto && !isAbstract) { String daoMethodName = Strings.getRelativeCamelCaseName(getDefaultPackageName(), def.getRelativeEntityPackage(input.getQualifiedName() + "Dao"), relativeNameExcludes); String entityName = input.getName(); String entityPackageName = input.getPackageName(); String daoName = entityName + "TopiaDao"; boolean referential = TemplateContract.isReferentialFromPackageName(entityPackageName); boolean entryPoint = topiaExtensionTagValues.isEntryPoint(input); String persistenceContext = getDefaultPackageName() + "." + templateHelper.getPersistenceContextConcreteName(model); for (Class dtoDtoType : entityToDtoMapping.getDtoTypes(input)) { boolean mainSpi = dtoDtoType.getSimpleName().equals(entityName + "Dto"); boolean dtoEntryPoint = mainSpi && entryPoint; boolean container = false; String dtoTypeName = dtoDtoType.getSimpleName(); String spiClassName = dtoTypeName.replace("Dto", "Spi"); String generatedSpiClassName = "Generated" + spiClassName; ObjectModelClass generatedSpi = createAbstractClass(generatedSpiClassName, entityPackageName); addImport(generatedSpi, dtoDtoType); addImport(generatedSpi, ReferentialLocale.class); ToolkitEntityToDtoMapping entityToDtoMapping = (ToolkitEntityToDtoMapping) this.entityToDtoMapping; @SuppressWarnings("unchecked") Class referenceType = entityToDtoMapping.getReferenceType((Class) dtoDtoType); boolean noReference = referenceType == null; String referencesTagValue = null; if (referenceType == null) { referenceType = entityToDtoMapping.getReferenceType(dtoType); } addImport(generatedSpi, referenceType); String resourceClassName = model.getName() + TopiaEntitySqlModelResource.class.getSimpleName(); { addImport(generatedSpi, getDefaultPackageName() + "." + resourceClassName); ObjectModelOperation operation = addOperation(generatedSpi, "loadEntitySqlDescriptor", TopiaEntitySqlDescriptor.class, ObjectModelJavaModifier.PROTECTED, ObjectModelJavaModifier.FINAL); addAnnotation(generatedSpi, operation, Override.class); setOperationBody(operation, ""+"\n" +" return "+resourceClassName+".get().getModel().getDescriptor(toEntityType());\n" +" "); operation = addOperation(generatedSpi, "loadSqlScript", TopiaEntitySqlScript.class, ObjectModelJavaModifier.PROTECTED, ObjectModelJavaModifier.FINAL); addAnnotation(generatedSpi, operation, Override.class); setOperationBody(operation, ""+"\n" +" return "+resourceClassName+".get().getScriptModel().getScript(toEntityType().getName());\n" +" "); } if (referential) { String updateClassName = entityName + "ExtraScripts"; ObjectModelOperation operation = addOperation(generatedSpi, "loadExtraScripts", updateClassName, ObjectModelJavaModifier.PROTECTED, ObjectModelJavaModifier.FINAL); addAnnotation(generatedSpi, operation, Override.class); setOperationBody(operation, ""+"\n" +" return new "+updateClassName+"();\n" +" "); generateReferentialSpi( dtoTypeName, generatedSpi, referenceType, entityName, daoName ); } else if (dtoEntryPoint) { referencesTagValue = toolkitTagValues.getReferencesTagValue(input); generateEntryPointSpi( dtoTypeName, generatedSpi, referenceType, entityName, daoName ); } else { // any of data must have at least one default parent TopiaMetadataEntity entity = metadataModel.getEntity(templateHelper.getEntityEnumLiteralName(input)); Pair pair = getParent(entityToDtoMapping, input, entity, dtoDtoType, entryPoint); String parentType = pair == null ? null : pair.getValue(); @SuppressWarnings("unused") String parentPropertyName = pair == null ? null : pair.getKey(); String parentDtoTypeName = null; String parentTypeName = null; @SuppressWarnings("unused") boolean multiple = false; if (parentType != null) { if (!entityClassesFully.contains(parentType)) { parentType = input.getQualifiedName(); } parentDtoTypeName = importAndSimplify(generatedSpi, parentType.replace(".entities.", ".dto.") + "Dto"); parentTypeName = importAndSimplify(generatedSpi, parentType); ObjectModelClass parentTypeClass = model.getClass(parentType); TopiaMetadataEntity parentEntity = metadataModel.getEntity(templateHelper.getEntityEnumLiteralName(parentTypeClass)); //noinspection multiple = parentEntity.getOneToManyAssociations().containsKey(parentPropertyName); } Class superClass = guessSpiSuperClass(dtoDtoType); container = ContainerDtoEntityContext.class.equals(superClass); generateSpi( dtoTypeName, generatedSpi, referenceType, entityName, daoName, parentType, superClass); boolean editable = EditableDtoEntityContext.class.isAssignableFrom(superClass); if (!entryPoint && parentType != null) { String type; if (multiple) { type = importAndSimplify(generatedSpi, MultipleDtoEntityRelation.class.getName()); } else { type = importAndSimplify(generatedSpi, SingleDtoEntityRelation.class.getName()); } String relationPrototype; String relationType; String relationRef = null; if (mainSpi || editable) { relationRef = "RELATION"; relationPrototype = String.format("<%s, %s, %s, %s>", parentDtoTypeName, dtoTypeName, parentTypeName, entityName); relationType = String.format("%s%s", type, relationPrototype); @SuppressWarnings("unused") String constantName = getConstantName(parentPropertyName); addConstant(generatedSpi, "RELATION", relationType, ""+" "+type+".create(\n" +" "+parentDtoTypeName+".class,\n" +" "+dtoTypeName+".class,\n" +" "+parentTypeName+".class,\n" +" "+entityName+".class,\n" +" "+parentTypeName+"."+constantName+")", ObjectModelJavaModifier.PUBLIC); } else { relationRef = entityName + ".SPI.relation()"; relationPrototype = String.format("<%s, %s, %s, %s>", parentDtoTypeName, importAndSimplify(generatedSpi, dtoType.getName()), parentTypeName, entityName); relationType = String.format("%s%s", type, relationPrototype); } addInterface(generatedSpi, String.format("%s%s", WithDtoEntityRelation.class.getName(), relationPrototype)); { ObjectModelOperation relationOperation = addOperation(generatedSpi, "relation", relationType, ObjectModelJavaModifier.PUBLIC, ObjectModelJavaModifier.FINAL); addAnnotation(generatedSpi, relationOperation, Override.class); setOperationBody(relationOperation, ""+"\n" +" return "+relationRef+";\n" +" "); } if (editable) { { ObjectModelOperation parentSpiOperation = addOperation(generatedSpi, "parentSpi", parentType + "Spi", ObjectModelJavaModifier.PUBLIC, ObjectModelJavaModifier.FINAL); addAnnotation(generatedSpi, parentSpiOperation, Override.class); setOperationBody(parentSpiOperation, ""+"\n" +" return "+parentTypeName+".SPI;\n" +" "); } { ObjectModelOperation setNotPersistedEntityOperation = addOperation(generatedSpi, "setNotPersistedEntity", "void", ObjectModelJavaModifier.PUBLIC); addAnnotation(generatedSpi, setNotPersistedEntityOperation, Override.class); addParameter(setNotPersistedEntityOperation, parentTypeName, "parent"); addParameter(setNotPersistedEntityOperation, entityName, "entity"); @SuppressWarnings("unused") String methodName = (multiple ? "add" : "set") + Strings.capitalize(parentPropertyName); setOperationBody(setNotPersistedEntityOperation, ""+"\n" +" parent."+methodName+"(entity);\n" +" "); } } if (OpenableDtoEntityContext.class.isAssignableFrom(superClass)) { { ObjectModelOperation parentSpiOperation = addOperation(generatedSpi, "parentSpi", parentType + "Spi", ObjectModelJavaModifier.PUBLIC, ObjectModelJavaModifier.FINAL); addAnnotation(generatedSpi, parentSpiOperation, Override.class); setOperationBody(parentSpiOperation, ""+"\n" +" return "+parentTypeName+".SPI;\n" +" "); } { ObjectModelOperation getChildrenFromParentOperation = addOperation(generatedSpi, "getChildrenFromParent", Collection.class.getName() + "<" + entityName + ">", ObjectModelJavaModifier.PUBLIC); addAnnotation(generatedSpi, getChildrenFromParentOperation, Override.class); addParameter(getChildrenFromParentOperation, parentTypeName, "parent"); @SuppressWarnings("unused") String methodName = getJavaBeanMethodName("get", parentPropertyName); setOperationBody(getChildrenFromParentOperation, ""+"\n" +" return parent."+methodName+"();\n" +" "); } { ObjectModelOperation addChildrenToParentOperation = addOperation(generatedSpi, "addChildrenToParent", void.class, ObjectModelJavaModifier.PUBLIC); addAnnotation(generatedSpi, addChildrenToParentOperation, Override.class); addParameter(addChildrenToParentOperation, parentTypeName, "parent"); addParameter(addChildrenToParentOperation, entityName, "entity"); @SuppressWarnings("unused") String methodName = getJavaBeanMethodName("add", parentPropertyName); setOperationBody(addChildrenToParentOperation, ""+"\n" +" parent."+methodName+"(entity);\n" +" "); } } } } String fqn; if (mainSpi) { // generate main spi fqn = generateMainSpi(dtoDtoType, entityPackageName, entityName, spiClassName); // generate delegate methods generateSpiDelegateMethods(referential, daoName); // add filter methods on generated spi addFilterMethods(input, generatedSpi, referential, entryPoint); } else { // generate not main spi fqn = generateSubSpi(dtoDtoType, entityPackageName, entityName, spiClassName); { ObjectModelOperation newFilterConsumer = addOperation(generatedSpi, "newFilterConsumer", "EntityFilterConsumer<" + entityName + ">", ObjectModelJavaModifier.PUBLIC, ObjectModelJavaModifier.FINAL); addParameter(newFilterConsumer, ReferentialLocale.class, "referentialLocale"); addAnnotation(generatedSpi, newFilterConsumer, Override.class); addImport(generatedSpi, EntityFilterConsumer.class); String mainSpiClassName = entityName + ".SPI"; setOperationBody(newFilterConsumer, ""+"\n" +" return "+mainSpiClassName+".newFilterConsumer(referentialLocale);\n" +" "); } } dtoToEntityContextMapping.put(dtoDtoType.getName(), fqn); generateSpiCommonMethods(input, persistenceContext, entityName, daoName, daoMethodName, dtoDtoType, dtoTypeName, noReference, referenceType, generatedSpi, referencesTagValue, mainSpi, container); generateConcreteSpi(entityPackageName, spiClassName, generatedSpi); List operations = generatedSpi.getOperations().stream().sorted(Comparator.comparing(ObjectModelElement::getName)).collect(Collectors.toList()); generatedSpi.getOperations().clear(); generatedSpi.getOperations().addAll(operations); } TemplateContract.addToLabel(this, outputAbstract, dtoType.getName()); } } protected void generateSpi(String dtoTypeName, ObjectModelClass generatedSpi, Class referenceType, String entityName, String daoName, String parentType, Class superClass) { String referenceTypeName = Objects.requireNonNull(referenceType).getSimpleName(); String spiClassPrototype; if (EditableDtoEntityContext.class.isAssignableFrom(superClass) || OpenableDtoEntityContext.class.isAssignableFrom(superClass)) { spiClassPrototype = String.format("<%s, %s, %s, %s, %s>", parentType, dtoTypeName, referenceTypeName, entityName, daoName); } else { spiClassPrototype = String.format("<%s, %s, %s, %s>", dtoTypeName, referenceTypeName, entityName, daoName); } String generatedSpiSuperClass = String.format("%s%s", superClass.getName(), spiClassPrototype); setSuperClass(generatedSpi, generatedSpiSuperClass); } protected void generateEntryPointSpi(String dtoTypeName, ObjectModelClass generatedSpi, Class referenceType, String entityName, String daoName) { String referenceTypeName = Objects.requireNonNull(referenceType).getSimpleName(); String spiClassPrototype = String.format("<%s, %s, %s, %s, %s>", dtoTypeName, referenceTypeName, entityName, daoName, entityName + "GroupByReferentialHelper"); String generatedSpiSuperClass = String.format("%s%s", RootOpenableDtoEntityContext.class.getName(), spiClassPrototype); setSuperClass(generatedSpi, generatedSpiSuperClass); } protected void generateReferentialSpi(String dtoTypeName, ObjectModelClass generatedSpi, Class referenceType, String entityName, String daoName) { String referenceTypeName = Objects.requireNonNull(referenceType).getSimpleName(); String spiClassPrototype = String.format("<%s, %s, %s, %s>", dtoTypeName, referenceTypeName, entityName, daoName); String generatedSpiSuperClass = String.format("%s%s", ReferentialDtoEntityContext.class.getName(), spiClassPrototype); setSuperClass(generatedSpi, generatedSpiSuperClass); } private void generateSpiCommonMethods(ObjectModelClass input, @SuppressWarnings("unused") String persistenceContext, String entityName, String daoName, @SuppressWarnings("unused") String daoMethodName, Class dtoDtoType, String dtoTypeName, boolean noReference, Class referenceType, ObjectModelClass generatedSpi, String referencesTagValue, boolean mainSpi, boolean container) { TopiaMetadataEntity table = metadataModel.getEntity(templateHelper.getEntityEnumLiteralName(input)); { ObjectModelOperation toEntityTypeOperation = addOperation(generatedSpi, "toEntityType", "Class<" + entityName + ">", ObjectModelJavaModifier.PUBLIC, ObjectModelJavaModifier.FINAL); addAnnotation(generatedSpi, toEntityTypeOperation, Override.class); setOperationBody(toEntityTypeOperation, ""+"\n" +" return "+entityName+".class;\n" +" "); } { ObjectModelOperation newEntityOperation = addOperation(generatedSpi, "newEntity", entityName, ObjectModelJavaModifier.PUBLIC, ObjectModelJavaModifier.FINAL); addAnnotation(generatedSpi, newEntityOperation, Override.class); setOperationBody(newEntityOperation, ""+"\n" +" return new "+entityName+"Impl();\n" +" "); } { ObjectModelOperation getDaoOperation = addOperation(generatedSpi, "getDao", daoName, ObjectModelJavaModifier.PUBLIC, ObjectModelJavaModifier.FINAL); addAnnotation(generatedSpi, getDaoOperation, Override.class); addParameter(getDaoOperation, TopiaPersistenceContext.class, "persistenceContext"); setOperationBody(getDaoOperation, ""+"\n" +" return (("+persistenceContext+") persistenceContext).get"+daoMethodName+"();\n" +" "); } { ObjectModelOperation toDtoTypeOperation = addOperation(generatedSpi, "toDtoType", "Class<" + dtoTypeName + ">", ObjectModelJavaModifier.PUBLIC, ObjectModelJavaModifier.FINAL); addAnnotation(generatedSpi, toDtoTypeOperation, Override.class); setOperationBody(toDtoTypeOperation, ""+"\n" +" return "+dtoTypeName+".class;\n" +" "); } ObjectModelOperation spiToDtoOperation = addOperation(generatedSpi, "toDto", "void", ObjectModelJavaModifier.PUBLIC); addAnnotation(generatedSpi, spiToDtoOperation, Override.class); addParameter(spiToDtoOperation, ReferentialLocale.class, "referentialLocale"); addParameter(spiToDtoOperation, entityName, "entity"); addParameter(spiToDtoOperation, dtoTypeName, "dto"); setOperationBody(spiToDtoOperation, ""+"\n" +" " + generateToDtoOperation(dtoDtoType).trim() + ""+"\n" +" "); ObjectModelOperation spiFromDtoOperation = addOperation(generatedSpi, "fromDto", "void", ObjectModelJavaModifier.PUBLIC); addAnnotation(generatedSpi, spiFromDtoOperation, Override.class); addParameter(spiFromDtoOperation, ReferentialLocale.class, "referentialLocale"); addParameter(spiFromDtoOperation, entityName, "entity"); addParameter(spiFromDtoOperation, dtoTypeName, "dto"); setOperationBody(spiFromDtoOperation, ""+"\n" +" " + generateFromDtoOperation(dtoDtoType).trim() + ""+"\n" +" "); if (container) { ObjectModelOperation saveCallbackOperation = addOperation(generatedSpi, "saveCallback", "void", ObjectModelJavaModifier.PUBLIC); addAnnotation(generatedSpi, saveCallbackOperation, Override.class); addParameter(saveCallbackOperation, AddEntityToUpdateStep.class, "saveHelper"); addParameter(saveCallbackOperation, entityName, "entity"); ObjectModelAttribute attribute; if (mainSpi) { // special cas, input is container also, we need to find out the unique association from table attribute = input.getAttributes().stream().filter(e -> ((ToolkitEntityToDtoMapping) entityToDtoMapping).containerChildDataTypes(e.getType())).findFirst().orElse(null); } else { String childEntityName = dtoDtoType.getPackageName().replace("dto.", "entities.") + "." + dtoTypeName.substring(entityName.length(), dtoTypeName.length() - 3); attribute = input.getAttributes().stream().filter(e -> e.getType().equals(childEntityName)).findFirst().orElse(null); } Objects.requireNonNull(attribute, "Can't find attribute for type: " + dtoDtoType.getName()); String spi = importAndSimplify(generatedSpi, attribute.getType()) + ".SPI"; String methodName = getJavaBeanMethodName("get", attribute.getName()); setOperationBody(saveCallbackOperation, ""+"\n" +" saveHelper.updateCollection("+spi+", entity."+methodName+"());\n" +" "); } if (!noReference) { String referenceTypeSimpleName = referenceType.getSimpleName(); { ObjectModelOperation spiToReferenceOperation = addOperation(generatedSpi, "toReference", referenceTypeSimpleName, ObjectModelJavaModifier.PUBLIC); addAnnotation(generatedSpi, spiToReferenceOperation, Override.class); addParameter(spiToReferenceOperation, ReferentialLocale.class, "referentialLocale"); addParameter(spiToReferenceOperation, dtoTypeName, "dto"); setOperationBody(spiToReferenceOperation, ""+"\n" +" return "+referenceTypeSimpleName+".of(referentialLocale, dto);\n" +" "); } { ObjectModelOperation toReferenceTypeOperation = addOperation(generatedSpi, "toReferenceType", "Class<" + referenceTypeSimpleName + ">", ObjectModelJavaModifier.PUBLIC, ObjectModelJavaModifier.FINAL); addAnnotation(generatedSpi, toReferenceTypeOperation, Override.class); setOperationBody(toReferenceTypeOperation, ""+"\n" +" return "+referenceTypeSimpleName+".class;\n" +" "); } } if (referencesTagValue != null) { String query = ToolkitEntityHibernateMappingTransformer.getReferenceQuery(table, referencesTagValue); addConstant(generatedSpi, "REFERENCES_QUERY", String.class, "\"" + query + "\"", ObjectModelJavaModifier.PRIVATE); ObjectModelOperation getReferenceQueryOperation = addOperation(generatedSpi, "getReferenceQuery", String.class, ObjectModelJavaModifier.PUBLIC, ObjectModelJavaModifier.FINAL); addAnnotation(generatedSpi, getReferenceQueryOperation, Override.class); setOperationBody(getReferenceQueryOperation, ""+"\n" +" return REFERENCES_QUERY;\n" +" "); } } private void generateConcreteSpi(String entityPackageName, String spiClassName, ObjectModelClass generatedSpi) { if (getResourcesHelper().isJavaFileInClassPath(entityPackageName + "." + spiClassName)) { return; } ObjectModelClass spi = createClass(spiClassName, entityPackageName); setSuperClass(spi, generatedSpi.getQualifiedName()); } protected Pair getParent(ToolkitEntityToDtoMapping entityToDtoMapping, ObjectModelClass input, TopiaMetadataEntity entity, Class dtoDtoType, boolean entryPoint) { if (entryPoint) { return null; } String dtoTypeName = dtoDtoType.getName().replace("fr.ird.observe.dto.", "").replace("Dto", ""); for (ParentLink entry : parentProjectModel.getLinks()) { String type = entry.getClassName(); if (dtoTypeName.equals(type)) { TreeNodeModel node = navigationProjectModel.getNode(type).orElse(null); if (node == null) { break; } return Pair.of(entry.getPropertyName(), "fr.ird.observe.entities." + entry.getParentClassName()); } } // parent not found from navigation parent model // possible since not all data are in navigation model // must be DataDto, InlineDto, SimpleDto or ContainerDto @SuppressWarnings("unchecked") Class mainDtoType = entityToDtoMapping.getMainDtoType((Class) dtoDtoType); if (!Objects.equals(mainDtoType, dtoDtoType)) { Pair parent = getParent(entityToDtoMapping, input, entity, mainDtoType, false); if (parent != null) { return parent; } } Set oneToManyAssociationInverses = entity.getOneToManyAssociationInverses(); if (oneToManyAssociationInverses.size() == 1) { String parent = oneToManyAssociationInverses.iterator().next(); TopiaMetadataEntity parentEntity = metadataModel.getEntity(parent); Map manyToOneAssociations = parentEntity.getManyToOneAssociations(); Map oneToManyAssociations = parentEntity.getOneToManyAssociations(); String parentPropertyName = null; if (manyToOneAssociations.containsValue(entity.getType())) { parentPropertyName = manyToOneAssociations.entrySet().stream().filter(e -> entity.getType().equals(e.getValue())).findFirst().map(Map.Entry::getKey).orElse(null); } else if (oneToManyAssociations.containsValue(entity.getType())) { parentPropertyName = oneToManyAssociations.entrySet().stream().filter(e -> entity.getType().equals(e.getValue())).findFirst().map(Map.Entry::getKey).orElse(null); } return Pair.of(parentPropertyName, parentEntity.getFullyQualifiedName()); } throw new IllegalStateException("Need to find parent for: " + dtoDtoType.getName()); } private Class guessSpiSuperClass(Class dtoDtoType) { if (OpenableDto.class.isAssignableFrom(dtoDtoType)) { return OpenableDtoEntityContext.class; } if (EditableDto.class.isAssignableFrom(dtoDtoType)) { return EditableDtoEntityContext.class; } if (SimpleDto.class.isAssignableFrom(dtoDtoType)) { return SimpleDtoEntityContext.class; } if (ContainerDto.class.isAssignableFrom(dtoDtoType)) { return ContainerDtoEntityContext.class; } return DataDtoEntityContext.class; } @SuppressWarnings("unused") private void addFilterMethods(ObjectModelClass input, ObjectModelClass generatedSpi, boolean referential, boolean addGroupBy) { ImportsManager importManager = getImportManager(generatedSpi); ObjectModelPackage aPackage = model.getPackage(input); String inputSimpleName = input.getName(); importManager.addExcludedPattern(".+\\." + inputSimpleName); addImport(generatedSpi, IdFilterProperty.class); addImport(generatedSpi, LongFilterProperty.class); addImport(generatedSpi, TimestampFilterProperty.class); StringBuilder filterContent = new StringBuilder(""+"\n" +" List.of(\n" +" IdFilterProperty.create(),\n" +" LongFilterProperty.createPrimitive("+inputSimpleName+".PROPERTY_TOPIA_VERSION),\n" +" TimestampFilterProperty.create("+inputSimpleName+".PROPERTY_TOPIA_CREATE_DATE),"); StringBuilder naturalOrderContent = new StringBuilder(""+"\n" +" List.of(\n" +""); String[] naturalOrder = toolkitTagValues.getNaturalOrderTagValue(input); if (naturalOrder == null) { if (referential) { naturalOrder = new String[]{ReferentialEntity.PROPERTY_CODE}; } else { naturalOrder = new String[]{TopiaEntity.PROPERTY_TOPIA_CREATE_DATE}; } } List order = new LinkedList<>(); for (String s : naturalOrder) { String constantName = getConstantName(s); order.add(" " + inputSimpleName + "." + constantName); } naturalOrderContent.append(String.join(",\n", order)).append(""+"\n" +" )"); Collection attributes = new LinkedList<>(input.getAttributes()); attributes.addAll(input.getAllOtherAttributes()); attributes.removeIf(a -> !a.isNavigable()); attributes.removeIf(GeneratorUtil::isNMultiplicity); Map orderedAttributes = new TreeMap<>(); for (ObjectModelAttribute attribute : attributes) { String attrName = GeneratorUtil.getSimpleName(getPropertyName(attribute)); orderedAttributes.put(attrName, attribute); } for (Map.Entry entry : orderedAttributes.entrySet()) { String attrName = entry.getKey(); ObjectModelAttribute attribute = entry.getValue(); String attrType = getPropertyType(attribute, input, aPackage); attrType = GeneratorUtil.removeAnyGenericDefinition(attrType); if (entityClassesFully.contains(attrType)) { if (attrType.contains(".referential.")) { addReferentialFilterProperty(inputSimpleName, filterContent, attrName); continue; } addDataFilterProperty(inputSimpleName, filterContent, attrName); continue; } ObjectModelEnumeration enumeration = model.getEnumeration(attrType); if (enumeration != null) { addImport(generatedSpi, EnumFilterProperty.class); addEnumFilterProperty(generatedSpi, inputSimpleName, filterContent, attrName, enumeration); continue; } attrType = GeneratorUtil.getSimpleName(attrType); switch (attrType) { case "String": addImport(generatedSpi, StringFilterProperty.class); addStringFilterProperty(inputSimpleName, filterContent, attrName); continue; case "boolean": addImport(generatedSpi, BooleanFilterProperty.class); addPrimitiveBooleanFilterProperty(inputSimpleName, filterContent, attrName); continue; case "Boolean": addImport(generatedSpi, BooleanFilterProperty.class); addBooleanFilterProperty(inputSimpleName, filterContent, attrName); continue; case "int": addImport(generatedSpi, IntegerFilterProperty.class); addPrimitiveIntegerFilterProperty(inputSimpleName, filterContent, attrName); continue; case "long": addPrimitiveLongFilterProperty(inputSimpleName, filterContent, attrName); continue; case "float": addImport(generatedSpi, FloatFilterProperty.class); addPrimitiveFloatFilterProperty(inputSimpleName, filterContent, attrName); continue; case "double": addImport(generatedSpi, IntegerFilterProperty.class); addPrimitiveDoubleFilterProperty(inputSimpleName, filterContent, attrName); continue; case "Integer": addImport(generatedSpi, IntegerFilterProperty.class); addIntegerFilterProperty(inputSimpleName, filterContent, attrName); continue; case "Long": addLongFilterProperty(inputSimpleName, filterContent, attrName); continue; case "Float": addImport(generatedSpi, FloatFilterProperty.class); addFloatFilterProperty(inputSimpleName, filterContent, attrName); continue; case "Double": addImport(generatedSpi, DoubleFilterProperty.class); addDoubleFilterProperty(inputSimpleName, filterContent, attrName); continue; case "Date": String type = topiaHibernateTagValues.getHibernateAttributeType(attribute, input, aPackage, model); if (type == null) { type = "timestamp"; } switch (type) { case "date": addImport(generatedSpi, DateFilterProperty.class); addDateFilterProperty(inputSimpleName, filterContent, attrName); break; case "time": addImport(generatedSpi, TimeFilterProperty.class); addTimeFilterProperty(inputSimpleName, filterContent, attrName); break; case "timestamp": addTimestampFilterProperty(inputSimpleName, filterContent, attrName); break; } continue; } getLog().warn(String.format("No filter on %s.%s", inputSimpleName, attrName)); } String content = filterContent.toString(); if (content.endsWith(",")) { content = content.substring(0, content.length() - 1); } content += ""+"\n" +" )"; addImport(generatedSpi, List.class); addImport(generatedSpi, ImmutableMap.class); addImport(generatedSpi, Map.class); addImport(generatedSpi, Set.class); addImport(generatedSpi, EntityFilterProperty.class); addImport(generatedSpi, EntityFilterConsumer.class); addAttribute(generatedSpi, "FILTER_PROPERTIES", "java.util.List>", content, ObjectModelJavaModifier.FINAL, ObjectModelJavaModifier.PRIVATE, ObjectModelJavaModifier.STATIC); if (addGroupBy) { if (entityClassesEntryPoints.contains(input.getQualifiedName())) { String[] groupByList = topiaExtensionTagValues.getGroupBy(input); if (groupByList != null) { StringBuilder groupByContent = new StringBuilder(""+"\n" +" List.>of("); List tmp = new LinkedList<>(); for (String groupByPattern : groupByList) { String groupBy = groupByPattern; String groupBySecond = null; int index = groupByPattern.indexOf(":"); if (index > -1) { groupBy = groupByPattern.substring(0, index); } else { index = groupByPattern.indexOf("."); if (index > -1) { groupBy = groupByPattern.substring(0, index); groupBySecond = groupByPattern.substring(index + 1); } } String pair = addGroupBy(input, groupBy, groupBySecond); tmp.add(",\n " + pair); } groupByContent.append(String.join("", tmp).substring(1)).append(""+"\n" +" ).stream().collect(Collectors.toMap(DataGroupByEntityDefinition::getName, definition -> definition, (a, b) -> b, LinkedHashMap::new))"); addImport(generatedSpi, DataGroupByEntityDefinition.class); addImport(generatedSpi, List.class); addImport(generatedSpi, LinkedHashMap.class); addImport(generatedSpi, Collectors.class); addImport(generatedSpi, Function.class); String type = String.format("Map>", inputSimpleName); addAttribute(generatedSpi, "FILTER_GROUP_BY", type, groupByContent.toString(), ObjectModelJavaModifier.FINAL, ObjectModelJavaModifier.PRIVATE, ObjectModelJavaModifier.STATIC); ObjectModelOperation getGroupBy = addOperation(generatedSpi, "getGroupBy", type, ObjectModelJavaModifier.PUBLIC, ObjectModelJavaModifier.FINAL); addAnnotation(generatedSpi, getGroupBy, Override.class); setOperationBody(getGroupBy, ""+"\n" +" return FILTER_GROUP_BY;\n" +" "); groupByDtoDefinitionMapping.add(input.getQualifiedName() + ".SPI"); } } } addAttribute(generatedSpi, "FILTER_AUTHORIZED_PROPERTIES", "java.util.Set", "EntityFilterConsumer.getAuthorizedPropertyNames(FILTER_PROPERTIES)", ObjectModelJavaModifier.FINAL, ObjectModelJavaModifier.PRIVATE, ObjectModelJavaModifier.STATIC); addAttribute(generatedSpi, "FILTER_AUTHORIZED_ORDERS", "java.util.Set", "EntityFilterConsumer.getAuthorizedOrders(FILTER_PROPERTIES)", ObjectModelJavaModifier.FINAL, ObjectModelJavaModifier.PRIVATE, ObjectModelJavaModifier.STATIC); addAttribute(generatedSpi, "FILTER_PROPERTIES_CONSUMERS", "Map>", "EntityFilterConsumer.getPropertyConsumers(FILTER_PROPERTIES)", ObjectModelJavaModifier.FINAL, ObjectModelJavaModifier.PRIVATE, ObjectModelJavaModifier.STATIC); addAttribute(generatedSpi, "FILTER_NATURAL_ORDERS", "java.util.List", naturalOrderContent.toString(), ObjectModelJavaModifier.FINAL, ObjectModelJavaModifier.PRIVATE, ObjectModelJavaModifier.STATIC); { ObjectModelOperation newFilterConsumer = addOperation(generatedSpi, "newFilterConsumer", "EntityFilterConsumer<" + inputSimpleName + ">", ObjectModelJavaModifier.PUBLIC, ObjectModelJavaModifier.FINAL); addParameter(newFilterConsumer, ReferentialLocale.class, "referentialLocale"); addAnnotation(generatedSpi, newFilterConsumer, Override.class); addImport(generatedSpi, Objects.class); setOperationBody(newFilterConsumer, ""+"\n" +" return new EntityFilterConsumer<>(Objects.requireNonNull(referentialLocale.getColumnName()), FILTER_PROPERTIES, FILTER_AUTHORIZED_PROPERTIES, FILTER_AUTHORIZED_ORDERS, FILTER_NATURAL_ORDERS, FILTER_PROPERTIES_CONSUMERS);\n" +" "); } ObjectModelOperation getNaturalOrder = addOperation(generatedSpi, "getNaturalOrder", "List", ObjectModelJavaModifier.PUBLIC, ObjectModelJavaModifier.FINAL); addAnnotation(generatedSpi, getNaturalOrder, Override.class); setOperationBody(getNaturalOrder, ""+"\n" +" return FILTER_NATURAL_ORDERS;\n" +" "); } private void addEnumFilterProperty(ObjectModelClass generatedSpi, String inputSimpleName, StringBuilder filterContent, String attrName, ObjectModelEnumeration attrType) { addImport(generatedSpi, attrType.getQualifiedName()); String constantName = getConstantName(attrName); String propertyName = inputSimpleName + "." + constantName; filterContent.append(""+"\n" +" EnumFilterProperty.create("+propertyName+", "+attrType.getName()+".class),"); } private void addIntegerFilterProperty(String inputSimpleName, StringBuilder filterContent, String attrName) { String constantName = getConstantName(attrName); String propertyName = inputSimpleName + "." + constantName; filterContent.append(""+"\n" +" IntegerFilterProperty.create("+propertyName+"),"); } private void addLongFilterProperty(String inputSimpleName, StringBuilder filterContent, String attrName) { String constantName = getConstantName(attrName); String propertyName = inputSimpleName + "." + constantName; filterContent.append(""+"\n" +" LongFilterProperty.create("+propertyName+"),"); } private void addFloatFilterProperty(String inputSimpleName, StringBuilder filterContent, String attrName) { String constantName = getConstantName(attrName); String propertyName = inputSimpleName + "." + constantName; filterContent.append(""+"\n" +" FloatFilterProperty.create("+propertyName+"),"); } private void addDoubleFilterProperty(String inputSimpleName, StringBuilder filterContent, String attrName) { String constantName = getConstantName(attrName); String propertyName = inputSimpleName + "." + constantName; filterContent.append(""+"\n" +" DoubleFilterProperty.create("+propertyName+"),"); } private void addPrimitiveIntegerFilterProperty(String inputSimpleName, StringBuilder filterContent, String attrName) { String constantName = getConstantName(attrName); String propertyName = inputSimpleName + "." + constantName; filterContent.append(""+"\n" +" IntegerFilterProperty.createPrimitive("+propertyName+"),"); } private void addPrimitiveLongFilterProperty(String inputSimpleName, StringBuilder filterContent, String attrName) { String constantName = getConstantName(attrName); String propertyName = inputSimpleName + "." + constantName; filterContent.append(""+"\n" +" LongFilterProperty.createPrimitive("+propertyName+"),"); } private void addPrimitiveFloatFilterProperty(String inputSimpleName, StringBuilder filterContent, String attrName) { String constantName = getConstantName(attrName); String propertyName = inputSimpleName + "." + constantName; filterContent.append(""+"\n" +" FloatFilterProperty.createPrimitive("+propertyName+"),"); } private void addPrimitiveDoubleFilterProperty(String inputSimpleName, StringBuilder filterContent, String attrName) { String constantName = getConstantName(attrName); String propertyName = inputSimpleName + "." + constantName; filterContent.append(""+"\n" +" FilterProperty.createPrimitive("+propertyName+"),"); } private void addStringFilterProperty(String inputSimpleName, StringBuilder filterContent, String attrName) { String constantName = getConstantName(attrName); String propertyName = inputSimpleName + "." + constantName; filterContent.append(""+"\n" +" StringFilterProperty.create("+propertyName+"),"); } private void addPrimitiveBooleanFilterProperty(String inputSimpleName, StringBuilder filterContent, String attrName) { String constantName = getConstantName(attrName); String propertyName = inputSimpleName + "." + constantName; filterContent.append(""+"\n" +" BooleanFilterProperty.createPrimitive("+propertyName+"),"); } private void addBooleanFilterProperty(String inputSimpleName, StringBuilder filterContent, String attrName) { String constantName = getConstantName(attrName); String propertyName = inputSimpleName + "." + constantName; filterContent.append(""+"\n" +" BooleanFilterProperty.create("+propertyName+"),"); } private void addDateFilterProperty(String inputSimpleName, StringBuilder filterContent, String attrName) { String constantName = getConstantName(attrName); String propertyName = inputSimpleName + "." + constantName; filterContent.append(""+"\n" +" DateFilterProperty.create("+propertyName+"),"); } private void addTimeFilterProperty(String inputSimpleName, StringBuilder filterContent, String attrName) { String constantName = getConstantName(attrName); String propertyName = inputSimpleName + "." + constantName; filterContent.append(""+"\n" +" TimeFilterProperty.create("+propertyName+"),"); } private void addTimestampFilterProperty(String inputSimpleName, StringBuilder filterContent, String attrName) { String constantName = getConstantName(attrName); String propertyName = inputSimpleName + "." + constantName; filterContent.append(""+"\n" +" TimestampFilterProperty.create("+propertyName+"),"); } private void addReferentialFilterProperty(String inputSimpleName, StringBuilder filterContent, String attrName) { String constantName = getConstantName(attrName); String propertyName = inputSimpleName + "." + constantName; filterContent.append(""+"\n" +" IdFilterProperty.create("+propertyName+"),\n" +" StringFilterProperty.createCode("+propertyName+"),\n" +" StringFilterProperty.createLabel("+propertyName+"),"); } private void addDataFilterProperty(String inputSimpleName, StringBuilder filterContent, String attrName) { String constantName = getConstantName(attrName); String propertyName = inputSimpleName + "." + constantName; filterContent.append(""+"\n" +" IdFilterProperty.create("+propertyName+"),"); } protected String generateMainSpi(Class dtoDtoType, String entityPackageName, String entityName, String constantType) { String constantName = "SPI"; addAttribute(outputInterface, constantName, constantType, "new " + constantType + "()"); entityToDtoClassMapping.put(entityPackageName + "." + entityName, dtoDtoType.getName() + ".class"); entityToDtoClassMapping.put(entityPackageName + "." + entityName + "Impl", dtoDtoType.getName() + ".class"); return entityPackageName + "." + entityName + "." + constantName; } protected String generateSubSpi(Class dtoDtoType, String entityPackageName, String entityName, String constantType) { String constantName = builder.getConstantName(ProjectPackagesDefinition.cleanType(dtoDtoType.getSimpleName()).replaceAll("\\.", "_") + "_spi"); addAttribute(outputInterface, constantName, constantType, "new " + constantType + "()"); return entityPackageName + "." + entityName + "." + constantName; } @SuppressWarnings({"unused"}) @Override protected void createEntityAbstractClass(ObjectModelPackage aPackage, ObjectModelClass input) { boolean isAbstract = input.isAbstract() && !input.isStatic(); if (doDto && isAbstract) { outputAbstract = createAbstractClass(String.format("%s
", input.getName() + "Abstract", dtoContractType.getName(), referenceContractType.getName()), input.getPackageName()); addImport(outputAbstract, dtoContractType); addImport(outputAbstract, referenceContractType); } else { outputAbstract = createAbstractClass(input.getName() + "Abstract", input.getPackageName()); } addImport(outputAbstract, input.getQualifiedName()); // Documentation StringBuilder doc = new StringBuilder(); doc.append("Implantation POJO pour l'entité {@link "); doc.append(Strings.capitalize(input.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()); boolean isDataEntity = DataEntity.class.getSimpleName().equals(input.getName()) || ReferentialEntity.class.getSimpleName().equals(input.getName()); if (doDto) { if (isAbstract) { addImport(outputAbstract, parentWithGeneric + "Impl"); addImport(outputAbstract, parentWithGeneric); setSuperClass(outputAbstract, parentWithGeneric + "Impl"); addInterface(outputAbstract, input.getQualifiedName()); } else { addImport(outputAbstract, parentWithGeneric); setSuperClass(outputAbstract, parentWithGeneric + "Impl"); addInterface(outputAbstract, parentWithGeneric); addInterface(outputAbstract, input.getQualifiedName()); } } else { // Implements addInterface(outputAbstract, input.getQualifiedName()); // 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); } } // add statistics if (doDto && statisticDefinitions != null) { String packageName = dtoType.getPackageName(); StatisticsHelper.addWithStatistics(this, packageName, input, outputAbstract, outputInterface, statisticDefinitions); } } @Override protected void generateImpl(ObjectModelClass input) { String implName = input.getName() + "Impl"; String packageName = input.getPackageName(); if (isVerbose()) { log.info("Will generate [" + implName + "]"); } boolean isAbstract = isAbstract(input) && !input.isStatic(); if (isAbstract) { outputImpl = createAbstractClass(implName, packageName); setSuperClass(outputImpl, input.getQualifiedName() + "Abstract"); } else { outputImpl = createClass(implName, packageName); setSuperClass(outputImpl, input.getQualifiedName() + "Abstract"); } setDocumentation(outputImpl, String.format("Implantation des operations pour l'entité %s.", input.getName())); } @Override protected void generateProperties(Collection attributes, ObjectModelClassifier aClass, ObjectModelPackage aPackage) { boolean withParentId = aClass.getInterfaces().stream().anyMatch(i -> i.getQualifiedName().equals(DtoParentAware.class.getName())); if (withParentId) { ObjectModelAttributeImpl e = new ObjectModelAttributeImpl(); e.setName("parentId"); e.setType(String.class.getName()); e.setObjectModelImpl((ObjectModelImpl) model); e.setReverseAttributeName("nope"); e.postInit(); attributes = new LinkedList<>(attributes); attributes.add(e); } super.generateProperties(attributes, aClass, aPackage); } @Override protected void addSingleGetOperation(ObjectModelClass input, ObjectModelAttribute attribute, String attrType, String operationPrefix) { super.addSingleGetOperation(input, attribute, attrType, operationPrefix); boolean entity = templateHelper.isEntity(attribute, model); if (entity) { // add getXXXSize method (return 0 if no value, 1 if with value) addSingleSizeOperation(attribute); } } protected void addSingleSizeOperation(ObjectModelAttribute attribute) { String attrName = getPropertyName(attribute); log.debug(String.format("Generate single '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); String getter = getJavaBeanMethodName("get", attrName); setOperationBody(implOperation, ""+"\n" +" return "+getter+"() == null ? 0 : 1;\n" +" "); } @Override public ObjectModelOperation addOperation(ObjectModelClassifier classifier, String name, String type, ObjectModelModifier... modifiers) { if (entityClasses != null && !type.startsWith(getDefaultPackageName())) { String type1 = GeneratorUtil.removeAnyGenericDefinition(GeneratorUtil.getSimpleName(type, true)); if (!entityClasses.contains(type1)) { Set types = GeneratorUtil.getTypesList(type); boolean doIt = true; for (String s : types) { String s1 = GeneratorUtil.getSimpleName(s); if (entityClasses.contains(s1)) { doIt = false; break; } } if (doIt) { addImport(classifier, type); type = GeneratorUtil.getSimpleName(type); } } } return super.addOperation(classifier, name, type, modifiers); } @Override public ObjectModelParameter addParameter(ObjectModelOperation operation, String type, String name) { if (!type.startsWith(getDefaultPackageName())) { String type1 = GeneratorUtil.removeAnyGenericDefinition(GeneratorUtil.getSimpleName(type, true)); ObjectModelClassifier declaringElement = (ObjectModelClassifier) operation.getDeclaringElement(); if (!entityClasses.contains(type1)) { Set types = GeneratorUtil.getTypesList(type); boolean doIt = true; for (String s : types) { String s1 = GeneratorUtil.getSimpleName(s); if (entityClasses.contains(s1)) { doIt = false; break; } } if (doIt) { addImport(declaringElement, type); type = GeneratorUtil.getSimpleName(type); } } } return super.addParameter(operation, type, name); } String addGroupBy(ObjectModelClass input, String groupBy, String groupBySecond) { ObjectModelAttribute parentAttribute = Objects.requireNonNull(input.getAttribute(groupBy)); boolean mandatory = validationTagValues.isNotNull(model.getTagValuesStore(), input, parentAttribute); ObjectModelClassifier classifier = parentAttribute.getClassifier(); if (classifier instanceof ObjectModelClass && entityClassesFully.contains(classifier.getQualifiedName())) { if (groupBySecond == null) { return addGroupBy(input, groupBy, null, classifier.getQualifiedName(), mandatory, null); } else { ObjectModelAttribute secondClassifierAttribute = classifier.getAttribute(groupBySecond); ObjectModelClass secondClassifier = model.getClass(classifier.getQualifiedName()); return addGroupBy(input, groupBy, groupBySecond, secondClassifierAttribute.getClassifier().getQualifiedName(), mandatory, secondClassifier); } } return addGroupBy(input, groupBy, null, parentAttribute.getType(), mandatory, null); } private String addGroupBy(ObjectModelClass input, String groupByPropertyName, String groupBySecond, String type, boolean mandatory, ObjectModelClass secondClassifier) { String capitalize = Strings.capitalize(groupByPropertyName); if (groupBySecond != null) { capitalize += Strings.capitalize(groupBySecond); } String inputName = input.getName(); String formClassName = inputName + "GroupBy" + capitalize; String definitionClassName = formClassName + "Definition"; String spiClassName = formClassName + "Spi"; String dtoType = entityToDtoClassMapping.get(input.getQualifiedName()).replace(".class", ""); String dtoDefinitionClassName = dtoType.replace("." + GeneratorUtil.getSimpleName(dtoType), "." + formClassName + "DtoDefinition"); String dtoFormClassName = dtoType.replace("." + GeneratorUtil.getSimpleName(dtoType), "." + formClassName + "Dto"); String simplifyGroupType = GeneratorUtil.getSimpleName(type); // generate Definition ObjectModelClass definitionClass = createClass(definitionClassName, input.getPackageName()); addImport(definitionClass, type); addImport(definitionClass, dtoType); addImport(definitionClass, Strings.class); addImport(definitionClass, dtoFormClassName); addImport(definitionClass, dtoType.replace("Dto", "Reference")); String businessProject = "fr.ird.observe.spi.module.ObserveBusinessProject"; String moduleName = ProjectPackagesDefinition.extractFirstPackage(ProjectPackagesDefinition.removeFirstPackage(input.getPackageName().replace(getDefaultPackageName() + ".", ""))); String moduleMethodName = String.format("() -> %s.get().get%sBusinessModule()", importAndSimplify(definitionClass, businessProject), Strings.capitalize(moduleName)); setSuperClass(definitionClass, String.format("%1$s<%2$s, %3$s, %4$s, %5$s>", DataGroupByEntityDefinition.class.getName(), inputName, formClassName, dtoType, dtoFormClassName)); String definitionId = Introspector.decapitalize(TreeProjectModelBuilder.toCamelCase(input.getQualifiedName().substring(getDefaultPackageName().length()) + ".groupBy." + groupByPropertyName)); if (groupBySecond != null) { definitionId += Strings.capitalize(groupBySecond); } addConstant(definitionClass, "NAME", "String", "\"" + definitionId + "\"", ObjectModelJavaModifier.PUBLIC); DataGroupByType groupByType = model.getClassifier(type) == null ? DataGroupByType.TEMPORAL : DataGroupByType.QUALITATIVE; addImport(definitionClass, DataGroupByType.class); ObjectModelOperation definitionConstructor = addConstructor(definitionClass, ObjectModelJavaModifier.PACKAGE); String constantName = inputName + "." + getConstantName(groupByPropertyName); String groupBySecondTable = null; if (groupBySecond != null) { constantName += " + \".\" + " + secondClassifier.getQualifiedName() + "." + getConstantName(groupBySecond); groupBySecondTable = "\"" + metadataModel.getEntity(templateHelper.getEntityEnumLiteralName(secondClassifier)).getSchemaAndTableName() + "\""; } setOperationBody(definitionConstructor, ""+"\n" +" super(NAME, DataGroupByType."+groupByType+", "+constantName+", "+mandatory+", "+simplifyGroupType+".class, "+inputName+".class, "+formClassName+".class, "+formClassName+"::new, "+moduleMethodName+", "+groupBySecondTable+");\n" +" "); ObjectModelOperation dtoDefinitionOperation = addOperation(definitionClass, "dtoDefinition", dtoDefinitionClassName, ObjectModelJavaModifier.PUBLIC, ObjectModelJavaModifier.FINAL); addAnnotation(definitionClass, dtoDefinitionOperation, Override.class); setOperationBody(dtoDefinitionOperation, ""+"\n" +" return "+dtoFormClassName+".DEFINITION;\n" +" "); ObjectModelOperation toGroupByValueOperation = addOperation(definitionClass, "toGroupByObjectValue", type, ObjectModelJavaModifier.PUBLIC, ObjectModelJavaModifier.FINAL); addParameter(toGroupByValueOperation, inputName, "data"); addAnnotation(definitionClass, toGroupByValueOperation, Override.class); String getterName = getJavaBeanMethodName("get", groupByPropertyName); if (groupBySecond != null) { getterName += "()." + getJavaBeanMethodName("get", groupBySecond); } setOperationBody(toGroupByValueOperation, ""+"\n" +" return data."+getterName+"();\n" +" "); ObjectModelOperation setGroupByValueOperation = addOperation(definitionClass, "setGroupByValue", void.class, ObjectModelJavaModifier.PUBLIC, ObjectModelJavaModifier.FINAL); addParameter(setGroupByValueOperation, inputName, "data"); addParameter(setGroupByValueOperation, Object.class, "value"); addAnnotation(definitionClass, setGroupByValueOperation, Override.class); if (groupBySecond == null) { String setterName = getJavaBeanMethodName("set", groupByPropertyName); setOperationBody(setGroupByValueOperation, ""+"\n" +" data."+setterName+"(("+type+") value);\n" +" "); } else { setOperationBody(setGroupByValueOperation, ""+"\n" +" "); } // generate Entity ObjectModelClass entityClass = createClass(formClassName, input.getPackageName()); { addImport(entityClass, DataGroupByEntityDefinition.class); addImport(entityClass, type); addImport(entityClass, dtoType); addImport(entityClass, dtoType.replace("Dto", "Reference")); setSuperClass(entityClass, String.format("%1$s<%2$s>", DataGroupByEntityAbstract.class.getName(), inputName)); addConstant(entityClass, "DEFINITION", definitionClassName, String.format("new %1$s()", definitionClassName), ObjectModelJavaModifier.PUBLIC); ObjectModelOperation definitionOperation = addOperation(entityClass, "definition", definitionClassName, ObjectModelJavaModifier.PUBLIC, ObjectModelJavaModifier.FINAL); addAnnotation(entityClass, definitionOperation, Override.class); setOperationBody(definitionOperation, ""+"\n" +" return DEFINITION;\n" +" "); addContractTypeMethod(input, entityClass); } return entityClass.getQualifiedName() + ".DEFINITION"; } @Override protected void clean() { super.clean(); dtoContractType = dtoType = null; referenceContractType = referenceType = null; parentWithGeneric = null; doDto = doReference = false; } private String getTypeGenericBounds(Type type, String daoName) { Set typeVariables = null; if (type instanceof TypeVariable) { TypeVariable type1 = (TypeVariable) type; typeVariables = Arrays.stream(type1.getGenericDeclaration().getTypeParameters()).map(TypeVariable::getName).collect(Collectors.toCollection(TreeSet::new)); } else if (type instanceof ParameterizedType) { ParameterizedType type1 = (ParameterizedType) type; typeVariables = Arrays.stream(type1.getActualTypeArguments()).map(Type::getTypeName).collect(Collectors.toCollection(TreeSet::new)); } String returnType = type.getTypeName(); if (typeVariables != null) { List typesList = new ArrayList<>(GeneratorUtil.getTypesList(returnType)); for (String typeVariable : typeVariables) { if (Objects.equals(returnType, typeVariable.trim())) { switch (typeVariable) { case "D": return dtoType.getName(); case "R": return referenceType.getName(); case "T": return daoName; case "E": return outputInterface.getQualifiedName(); } } if (typesList.contains(typeVariable)) { switch (typeVariable) { case "D": returnType = replaceType(returnType, typesList, typeVariable, dtoType.getName()); break; case "R": returnType = replaceType(returnType, typesList, typeVariable, (doReference ? referenceType.getName() : "?")); break; case "T": returnType = replaceType(returnType, typesList, typeVariable, daoName); break; case "E": returnType = replaceType(returnType, typesList, typeVariable, outputInterface.getQualifiedName()); break; } } } } return returnType; } private String replaceType(String returnType, List typesList, String typeVariable, String name) { StringBuilder result = new StringBuilder(returnType.substring(0, returnType.indexOf('<') + 1)); Iterator restingParts = Arrays.asList(returnType.trim().substring(result.length(), returnType.length() - 1).split("\\s*,\\s*")).iterator(); while (restingParts.hasNext()) { String restingPart = restingParts.next(); if (restingPart.trim().equals(typeVariable)) { result.append(name); typesList.remove(typeVariable); } else { result.append(restingPart); } if (restingParts.hasNext()) { result.append(" ,"); } } result.append(">"); return result.toString(); } private void generateJavaBeanMethods() { // add JavaBeanDefinition constant addImport(outputInterface, JavaBeanDefinition.class); addImport(outputInterface, JavaBeanDefinitionStore.class); addImport(outputInterface, IllegalStateException.class); addConstant(outputInterface, "JAVA_BEAN_DEFINITION", JavaBeanDefinition.class.getSimpleName(), String.format("JavaBeanDefinitionStore.getDefinition(%s.class).orElseThrow(IllegalStateException::new)", outputInterface.getName()), ObjectModelJavaModifier.PUBLIC); // add JavaBean method ObjectModelOperation operation = addOperation(outputInterface, "javaBeanDefinition", JavaBeanDefinition.class.getSimpleName(), ObjectModelJavaModifier.DEFAULT); setOperationBody(operation, ""+"\n" +" return JAVA_BEAN_DEFINITION;\n" +" "); addAnnotation(outputInterface, operation, Override.class); } private void generateSpiDelegateMethods(boolean referential, String daoName) { List methods = Arrays.stream((referential ? ReferentialDtoEntityContext.class : DataDtoEntityContext.class).getMethods()).filter(method -> { int modifiers = method.getModifiers(); if (Modifier.isStatic(modifiers) || method.isSynthetic()) { return false; } String methodName = method.getName(); return spiMethodNames.contains(methodName); }).collect(Collectors.toList()); for (Method method : methods) { String methodName = method.getName(); String returnType = getTypeGenericBounds(method.getGenericReturnType(), daoName); addImport(outputInterface, returnType); ObjectModelOperation operation = addOperation(outputInterface, methodName, returnType, ObjectModelJavaModifier.STATIC); for (Parameter parameter : method.getParameters()) { String parameterName = parameter.getName(); String parameterType = getTypeGenericBounds(parameter.getParameterizedType(), daoName); addImport(outputInterface, parameterType); addParameter(operation, parameterType, parameterName); } StringBuilder content = new StringBuilder(); if (void.class.equals(method.getReturnType())) { content.append(""+"\n" +" " ); } else { content.append(""+"\n" +" return" ); } content.append(""+" SPI."+methodName+"(" ); Iterator iterator = Arrays.asList(method.getParameters()).iterator(); while (iterator.hasNext()) { Parameter parameter = iterator.next(); @SuppressWarnings("unused") String parameterName = parameter.getName(); content.append(""+""+parameterName+"" ); if (iterator.hasNext()) { content.append(""+", " ); } } content.append(""+");\n" +" " ); setOperationBody(operation, content.toString()); } } private Set collectAllInterfaces(ObjectModelClassifier classifier) { Set result = new LinkedHashSet<>(); collectAllInterfaces(classifier, false, result); return result; } private void collectAllInterfaces(ObjectModelClassifier classifier, boolean collectSuperClasses, Set result) { if (collectSuperClasses && classifier instanceof ObjectModelClass) { ObjectModelClass classifier1 = (ObjectModelClass) classifier; for (ObjectModelClass superclass : classifier1.getSuperclasses()) { result.add(superclass.getQualifiedName()); collectAllInterfaces(superclass, true, result); } } for (ObjectModelInterface anInterface : classifier.getInterfaces()) { result.add(anInterface.getQualifiedName()); ObjectModelClassifier classifier1 = model.getClassifier(anInterface.getQualifiedName()); if (classifier1 != null) { collectAllInterfaces(classifier1, true, result); } } } protected void addInterface(List interfaceAlreadyDone, ObjectModelClassifier output, String qualifiedName) { if (!interfaceAlreadyDone.contains(qualifiedName)) { // add it to output addInterface(output, qualifiedName); } } }




© 2015 - 2025 Weber Informatics LLC | Privacy Policy