fr.ird.observe.toolkit.templates.dto.DtoTransformer Maven / Gradle / Ivy
package fr.ird.observe.toolkit.templates.dto;
/*-
* #%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.common.collect.ImmutableMap;
import fr.ird.observe.dto.BusinessDto;
import fr.ird.observe.dto.CoordinateHelper;
import fr.ird.observe.dto.DtoToReference;
import fr.ird.observe.dto.ToolkitIdDtoBean;
import fr.ird.observe.dto.data.ContainerChildDto;
import fr.ird.observe.dto.data.ContainerChildWithDataFileDto;
import fr.ird.observe.dto.data.ContainerChildWithIndexDto;
import fr.ird.observe.dto.data.ContainerChildWithOptionalProportionDto;
import fr.ird.observe.dto.data.ContainerChildWithProportionDto;
import fr.ird.observe.dto.data.ContainerDto;
import fr.ird.observe.dto.data.DataGroupByDto;
import fr.ird.observe.dto.data.DataGroupByDtoDefinition;
import fr.ird.observe.dto.data.DataGroupByType;
import fr.ird.observe.dto.data.EditableDto;
import fr.ird.observe.dto.data.InlineDataDto;
import fr.ird.observe.dto.data.LayoutAware;
import fr.ird.observe.dto.data.NoValidationDto;
import fr.ird.observe.dto.data.OpenableDto;
import fr.ird.observe.dto.data.RootOpenableDto;
import fr.ird.observe.dto.data.UsingLayout;
import fr.ird.observe.dto.data.WithIndex;
import fr.ird.observe.dto.form.FormDefinition;
import fr.ird.observe.dto.referential.ReferentialLocale;
import fr.ird.observe.spi.ProjectPackagesDefinition;
import fr.ird.observe.spi.mapping.DataGroupByDtoToDefinitionMapping;
import fr.ird.observe.spi.mapping.DtoToFormDtoMapping;
import fr.ird.observe.spi.mapping.DtoToMainDtoClassMapping;
import fr.ird.observe.spi.navigation.model.tree.TreeProjectModelBuilder;
import fr.ird.observe.toolkit.templates.ConsolidateDtoModel;
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.spi.GenerateJavaBeanDefinition;
import io.ultreia.java4all.classmapping.ImmutableClassMapping;
import io.ultreia.java4all.i18n.spi.bean.RegisterI18nLabel;
import io.ultreia.java4all.lang.Strings;
import io.ultreia.java4all.util.Dates;
import org.apache.commons.lang3.tuple.Pair;
import org.nuiton.eugene.EugeneCoreTagValues;
import org.nuiton.eugene.GeneratorUtil;
import org.nuiton.eugene.java.BeanTransformer;
import org.nuiton.eugene.java.BeanTransformerContext;
import org.nuiton.eugene.java.BeanTransformerTagValues;
import org.nuiton.eugene.java.EugeneJavaTagValues;
import org.nuiton.eugene.java.JavaBuilder;
import org.nuiton.eugene.java.JavaGeneratorUtil;
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.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.ObjectModelClassifierImpl;
import org.nuiton.eugene.models.object.xml.ObjectModelImpl;
import org.nuiton.eugene.models.object.xml.ObjectModelOperationImpl;
import org.nuiton.eugene.models.object.xml.ObjectModelParameterImpl;
import org.nuiton.eugene.models.tagvalue.ObjectModelTagValuesStore;
import org.nuiton.eugene.models.tagvalue.TagValuesStore;
import org.nuiton.topia.templates.TopiaExtensionTagValues;
import java.beans.Introspector;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Date;
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 static fr.ird.observe.toolkit.templates.TemplateContract.isReferentialFromPackageName;
/**
* @author Tony Chemit - [email protected]
* @since ?
*/
@SuppressWarnings({"unused", "StringOperationCanBeSimplified", "UnusedAssignment"})
public class DtoTransformer extends BeanTransformer implements TemplateContract {
private final EugeneCoreTagValues coreTagValues;
private final EugeneJavaTagValues javaTemplatesTagValues;
private final BeanTransformerTagValues beanTagValues;
private final ToolkitTagValues toolkitTagValues;
private final ValidationTagValues validationTagValues;
private final Map dtoFormMapping = new TreeMap<>();
private final Map groupByDtoDefinitionMapping = new LinkedHashMap<>();
private final Map dtoMainMapping = new TreeMap<>();
private final TagValuesStore persistenceTagValues = new TagValuesStore();
private BeanTransformerContext context;
private Map> statistics;
private List decomposeTimestamps;
private Map decomposeTimes;
private Map decomposeDates;
private String currentTimestampPropertyName;
private AutoTrimGenerator autoTrimGenerator;
public static String getCoordinateField(boolean before, String coordinatePrefix, String type) {
return Introspector.decapitalize(before ? (type + coordinatePrefix) : (coordinatePrefix + type));
}
public static Pair getCoordinateMainAndPrefix(boolean before, String coordinatePrefix) {
String main;
if (before) {
coordinatePrefix = coordinatePrefix.substring(1);
}
if (coordinatePrefix.equals("default")) {
coordinatePrefix = "";
main = "coordinate";
} else {
if (before) {
main = "coordinate" + coordinatePrefix;
} else {
main = coordinatePrefix;
}
}
return Pair.of(main, coordinatePrefix);
}
public DtoTransformer() {
coreTagValues = new EugeneCoreTagValues();
javaTemplatesTagValues = new EugeneJavaTagValues();
beanTagValues = new BeanTransformerTagValues();
toolkitTagValues = new ToolkitTagValues();
validationTagValues = new ValidationTagValues();
}
public void addRegisterI18nLabels(boolean inlineDto, boolean containerChildDto, boolean containerChildWithDataFileDto, boolean containerChildWithProportionDto, boolean containerChildWithOptionalProportionDto, ObjectModelClass input, ObjectModelClassifier output, ImportsManager importManager, Set i18nLabelsTagValue, String mainClassName, String i18nOverrideLabelsTagValue) {
ObjectModelAnnotation annotation = addAnnotation(output, output, RegisterI18nLabel.class);
addAnnotationClassParameter(importManager, output, annotation, "target", mainClassName);
StringBuilder content = new StringBuilder("{");
Set i18nProperties = new LinkedHashSet<>(i18nLabelsTagValue);
if (inlineDto) {
String propertiesTagValue = toolkitTagValues.getInlineDataDtoPropertiesTagValue(input);
Arrays.stream(propertiesTagValue.split("\\s*,\\s*")).map(property -> property + ".short").forEach(i18nProperties::add);
}
ConsolidateDtoModel
.loadContainerChildProperties(toolkitTagValues,
input,
containerChildDto,
containerChildWithDataFileDto,
containerChildWithProportionDto,
containerChildWithOptionalProportionDto,
null)
.stream().map(property -> property + ".short").forEach(i18nProperties::add);
Iterator iterator = i18nProperties.stream().sorted().iterator();
while (iterator.hasNext()) {
String value = iterator.next();
content.append("\"").append(value).append("\"");
if (iterator.hasNext()) {
content.append(", ");
}
}
content.append("}");
addAnnotationParameter(output, annotation, "properties", content.toString());
if (i18nOverrideLabelsTagValue != null) {
StringBuilder contentOverride = new StringBuilder("{");
iterator = Arrays.asList(i18nOverrideLabelsTagValue.split("\\s*,\\s*")).iterator();
while (iterator.hasNext()) {
String value = iterator.next();
contentOverride.append("\"").append(value).append("\"");
if (iterator.hasNext()) {
contentOverride.append(", ");
}
}
contentOverride.append("}");
addAnnotationParameter(output, annotation, "overrides", contentOverride.toString());
}
}
@Override
public void transformFromModel(ObjectModel model) {
super.transformFromModel(model);
persistenceTagValues.getStore().putAll(TemplateContract.loadPersistenceTagValues(getClassLoader(), model.getName()));
context = new BeanTransformerContext(model, coreTagValues, javaTemplatesTagValues, beanTagValues, false, false, input -> {
ObjectModelPackage aPackage = model.getPackage(input.getPackageName());
boolean referential = isReferentialFromPackageName(aPackage.getName());
String referencesTagValue = toolkitTagValues.getReferencesTagValue(input);
return referencesTagValue != null || referential;
}, getLog());
context.report();
statistics = StatisticsHelper.toModel(model, ProjectPackagesDefinition.of(getClassLoader()));
}
@Override
protected void generateInitializers() {
// do not generate global model initializer
}
@Override
protected void debugOutputModel() {
super.debugOutputModel();
generateClassMapping(true, DtoToFormDtoMapping.class, "Class extends " + BusinessDto.class.getName() + ">", FormDefinition.class.getName() + ">", ImmutableMap.class, "build", dtoFormMapping);
generateClassMapping(true, DataGroupByDtoToDefinitionMapping.class, "Class extends " + DataGroupByDto.class.getName() + ">>", DataGroupByDtoDefinition.class.getName() + ", ?>", ImmutableMap.class, "build", groupByDtoDefinitionMapping);
generateClassMapping(true, DtoToMainDtoClassMapping.class, BusinessDto.class.getName(), BusinessDto.class.getName(), ImmutableClassMapping.class, "getMappingBuilder", dtoMainMapping);
}
@Override
protected boolean canGenerateAbstractClass(ObjectModelClass aClass, String abstractClassName) {
boolean result = super.canGenerateAbstractClass(aClass, abstractClassName);
if (result) {
result = !EugeneCoreTagValues.isSkip(aClass, model.getPackage(aClass));
}
return result;
}
@Override
protected void addSerializable(ObjectModelClass input,
ObjectModelClass output,
boolean interfaceFound) {
// Nope!
}
public Set getI18nLabelsTagValues(ObjectModelClass input,
boolean referential,
boolean rootOpenableDto,
boolean openableDto,
boolean editableDto,
boolean inlineDto,
boolean containerDto,
boolean containerChildDto,
boolean containerChildWithIndexDto,
boolean containerChildWithDataFileDto,
boolean containerChildWithProportionDto,
boolean containerChildWithOptionalProportionDto,
boolean usingLayout) {
Set result = new LinkedHashSet<>();
String i18nLabelsTagValue = toolkitTagValues.getI18nLabelsTagValue(input);
if (i18nLabelsTagValue != null) {
result.addAll(List.of(i18nLabelsTagValue.split("\\s*,\\s*")));
}
if (referential) {
result.add("label");
}
if (input.isAbstract() || input.isInterface() || input.getName().endsWith("Stub")) {
return result;
}
result.add("type");
if (usingLayout) {
result.add("action.move.all");
result.add("action.move.all.choose.parent.message");
result.add("action.move.all.choose.parent.title");
}
if (containerDto) {
return result;
}
result.add("label");
if (inlineDto) {
return result;
}
if (containerChildWithIndexDto) {
result.add(WithIndex.PROPERTY_INDEX);
result.add(WithIndex.PROPERTY_INDEX + ".short");
}
if (containerChildWithIndexDto || containerChildWithOptionalProportionDto || containerChildWithProportionDto || containerChildDto || containerChildWithDataFileDto) {
result.add("action.create");
result.add("action.save");
result.add("action.save.tip");
if (!input.getName().endsWith("Composition")) {
result.add("title");
}
return result;
}
if (rootOpenableDto) {
result.add("list.title");
result.add("action.create");
result.add("list.navigation.node");
result.add("root.list.message.none");
return result;
}
if (openableDto) {
result.add("action.create");
result.add("action.move");
result.add("action.move.choose.parent.message");
result.add("action.move.choose.parent.title");
result.add("action.move.tip");
result.add("list.message.none");
result.add("list.navigation.node");
result.add("list.title");
result.add("message.not.open");
result.add("navigation.unsaved");
result.add("title");
return result;
}
if (editableDto) {
result.add("action.add");
result.add("action.add.tip");
result.add("navigation.unsaved");
result.add("title");
return result;
}
return result;
}
@Override
protected ObjectModelClass generateGeneratedClass(ObjectModelPackage aPackage, ObjectModelClass input, String className, String mainClassName) {
withIndexProperties.clear();
String decomposeTimestampTagValue = toolkitTagValues.getDecomposeTimestamp(input);
if (decomposeTimestampTagValue != null) {
decomposeTimestamps = new ArrayList<>();
decomposeTimes = new LinkedHashMap<>();
decomposeDates = new LinkedHashMap<>();
for (String timestampPropertyName : decomposeTimestampTagValue.split("\\s*,\\s*")) {
// add timestamp → date
// add timestamp → time
String datePropertyName;
String timePropertyName;
if (timestampPropertyName.equals("timeStamp")) {
datePropertyName = "date";
timePropertyName = "time";
} else {
if (timestampPropertyName.endsWith("TimeStamp")) {
datePropertyName = timestampPropertyName.replace("TimeStamp", "Date");
timePropertyName = timestampPropertyName.replace("TimeStamp", "Time");
} else if (timestampPropertyName.contains(":")) {
String[] split = timestampPropertyName.split("\\s*:\\s*");
timestampPropertyName = split[0];
datePropertyName = split[1];
timePropertyName = split[2];
} else {
throw new IllegalStateException("Can't manage decomposeTimestamp TagValue with value: " + timestampPropertyName);
}
}
decomposeTimestamps.add(timestampPropertyName);
decomposeDates.put(timestampPropertyName, datePropertyName);
decomposeTimes.put(timestampPropertyName, timePropertyName);
}
} else {
decomposeTimestamps = null;
decomposeTimes = decomposeDates = null;
}
ObjectModelClass output = super.generateGeneratedClass(aPackage, input, className, mainClassName);
List statisticDefinitions = statistics.get(input);
StatisticsHelper.addWithStatistics(this, input.getPackageName(), input, output, null, statisticDefinitions);
ObjectModelClass firstSuperClass = output.getSuperclasses().iterator().next();
if (firstSuperClass.getName().equals(ContainerDto.class.getSimpleName())) {
ObjectModelAttribute mainAttribute = input.getAttributes().iterator().next();
if (mainAttribute == null) {
throw new IllegalStateException(String.format("Can't find main attribute on %s", input.getName()));
}
setSuperClass(output, String.format("%s<%sDto>", firstSuperClass.getQualifiedName(), mainAttribute.getType()));
String propertyNameValue = getConstantName(mainAttribute.getName());
if (propertyNameValue != null) {
ObjectModelOperation constructor = addConstructor(output, ObjectModelJavaModifier.PUBLIC);
setOperationBody(constructor, ""+"\n"
+" super("+propertyNameValue+");\n"
+" ");
}
}
boolean referential = TemplateContract.isReferentialFromPackageName(aPackage.getName());
addWithNoCodeInterface(referential, input, output);
boolean notAbstract = !input.isAbstract();
boolean inlineDto = input.getInterfaces().stream().anyMatch(i -> i.getQualifiedName().equals(InlineDataDto.class.getName()));
boolean businessDto = input.getSuperclasses().stream().anyMatch(i -> (i.getQualifiedName() + "Dto").equals(BusinessDto.class.getName()));
boolean containerChildWithIndexDto = input.getSuperclasses().stream().anyMatch(i -> (i.getQualifiedName() + "Dto").equals(ContainerChildWithIndexDto.class.getName()));
boolean containerChildWithDataFileDto = input.getSuperclasses().stream().anyMatch(i -> (i.getQualifiedName() + "Dto").equals(ContainerChildWithDataFileDto.class.getName()));
boolean containerChildWithProportionDto = input.getSuperclasses().stream().anyMatch(i -> (i.getQualifiedName() + "Dto").equals(ContainerChildWithProportionDto.class.getName()));
boolean containerChildWithOptionalProportionDto = input.getSuperclasses().stream().anyMatch(i -> (i.getQualifiedName() + "Dto").equals(ContainerChildWithOptionalProportionDto.class.getName()));
boolean containerChildDto = input.getSuperclasses().stream().anyMatch(i -> (i.getQualifiedName() + "Dto").equals(ContainerChildDto.class.getName()));
boolean containerDto = input.getSuperclasses().stream().anyMatch(i -> (i.getQualifiedName() + "Dto").equals(ContainerDto.class.getName()));
boolean openableDto = input.getSuperclasses().stream().anyMatch(i -> (i.getQualifiedName() + "Dto").equals(OpenableDto.class.getName()));
boolean rootOpenableDto = input.getSuperclasses().stream().anyMatch(i -> (i.getQualifiedName() + "Dto").equals(RootOpenableDto.class.getName()));
boolean editableDto = input.getSuperclasses().stream().anyMatch(i -> (i.getQualifiedName() + "Dto").equals(EditableDto.class.getName()));
boolean usingLayout = input.getInterfaces().stream().anyMatch(i -> (i.getQualifiedName()).equals(UsingLayout.class.getName()))
|| input.getInterfaces().stream().anyMatch(i -> (i.getQualifiedName()).equals(LayoutAware.class.getName()));
String dtoName = TemplateContract.getDtoName(context, input);
Set i18nLabelsTagValues = getI18nLabelsTagValues(input,
referential,
rootOpenableDto,
openableDto,
editableDto,
inlineDto,
containerDto,
containerChildDto,
containerChildWithIndexDto,
containerChildWithDataFileDto,
containerChildWithProportionDto,
containerChildWithOptionalProportionDto,
usingLayout);
String i18nOverrideLabelsTagValue = toolkitTagValues.getI18nOverrideLabelsTagValue(input);
addRegisterI18nLabels(inlineDto, containerChildDto, containerChildWithDataFileDto, containerChildWithProportionDto, containerChildWithOptionalProportionDto, input, output, getImportManager(output), i18nLabelsTagValues, mainClassName, i18nOverrideLabelsTagValue);
if (notAbstract) {
addStaticFactoryMethod(output, mainClassName);
TemplateContract.addToLabel(this, output, dtoName);
}
if (context.selectedClasses.contains(input)) {
String referencesTagValue = toolkitTagValues.getReferencesTagValue(input);
if (referencesTagValue == null && referential) {
referencesTagValue = "code,label,uri";
}
Objects.requireNonNull(referencesTagValue);
Set availableProperties = new LinkedHashSet<>(Arrays.asList(referencesTagValue.split(",")));
Map binderProperties = DtoReferenceTransformer.getReferenceProperties(context.selectedClassesFqn, input, availableProperties, this::getAttributeType);
String referenceName = ProjectPackagesDefinition.cleanType(dtoName) + "Reference";
addInterface(output, String.format("%s<%s>", DtoToReference.class.getName(), referenceName));
addImport(output, ToolkitIdDtoBean.class);
ObjectModelOperation toShortDto = addOperation(output, "toShortDto", ToolkitIdDtoBean.class.getSimpleName(), ObjectModelJavaModifier.PUBLIC);
addAnnotation(output, toShortDto, Override.class);
setOperationBody(toShortDto, ""+"\n"
+" return ToolkitIdDtoBean.of("+dtoName+".class, this);\n"
+" "
);
addToReferenceMethod(output, dtoName, referenceName);
}
if (notAbstract) {
addFormDefinitionAttribute(input, output, referential);
addMainDtoMapping(input, referential);
if (inlineDto) {
addInlineDataDtoMethod(input, output);
}
}
ObjectModelTagValuesStore tagValuesStore = model.getTagValuesStore();
String mandatoryCoordinate = validationTagValues.getNotNullCoordinate(tagValuesStore, input);
String mayNotNullCoordinate = validationTagValues.getMayNotNullCoordinate(tagValuesStore, input);
if (mandatoryCoordinate != null || mayNotNullCoordinate != null) {
StringBuilder postInitContent = new StringBuilder(""+"\n"
+" super.postInit();");
addImport(output, CoordinateHelper.class);
if (mandatoryCoordinate != null) {
String[] split = mandatoryCoordinate.split("\\s*,\\s*");
for (String coordinatePrefix : split) {
boolean before = coordinatePrefix.startsWith(":");
Pair pair = getCoordinateMainAndPrefix(before, coordinatePrefix);
String main = pair.getLeft();
coordinatePrefix = pair.getRight();
String latitude = Strings.capitalize(getCoordinateField(before, coordinatePrefix, "Latitude"));
String longitude = Strings.capitalize(getCoordinateField(before, coordinatePrefix, "Longitude"));
String quadrant = Strings.capitalize(getCoordinateField(before, coordinatePrefix, "Quadrant"));
postInitContent.append(""+"\n"
+" set"+quadrant+"(CoordinateHelper.getQuadrant(get"+longitude+"(), get"+latitude+"()));");
}
}
if (mayNotNullCoordinate != null) {
boolean warning = mayNotNullCoordinate.startsWith("+");
if (warning) {
mayNotNullCoordinate = mayNotNullCoordinate.substring(1);
}
String[] split = mayNotNullCoordinate.split("\\s*,\\s*");
for (String coordinatePrefix : split) {
boolean before = coordinatePrefix.startsWith(":");
Pair pair = getCoordinateMainAndPrefix(before, coordinatePrefix);
String main = pair.getLeft();
coordinatePrefix = pair.getRight();
String latitude = Strings.capitalize(getCoordinateField(before, coordinatePrefix, "Latitude"));
String longitude = Strings.capitalize(getCoordinateField(before, coordinatePrefix, "Longitude"));
String quadrant = Strings.capitalize(getCoordinateField(before, coordinatePrefix, "Quadrant"));
postInitContent.append(""+"\n"
+" set"+quadrant+"(CoordinateHelper.getQuadrant(get"+longitude+"(), get"+latitude+"()));");
}
}
ObjectModelOperation postInit = addOperation(output, "postInit", void.class, ObjectModelJavaModifier.PUBLIC);
addAnnotation(output, postInit, Override.class);
setOperationBody(postInit, postInitContent.append(""+"\n"
+" ").toString());
}
String entryPoint = persistenceTagValues.getClassifierTagValue(input.getQualifiedName().replace("dto", "entities"), TopiaExtensionTagValues.Store.entryPoint.name());
if ("true".equals(entryPoint)) {
String groupByList = persistenceTagValues.getClassifierTagValue(input.getQualifiedName().replace("dto", "entities"), TopiaExtensionTagValues.Store.groupBy.name());
if (groupByList != null) {
addGroupBy(input, groupByList.split("\\s*,\\s*"));
}
}
String atLeastOneSelected = validationTagValues.getAtLeastOneSelected(input);
if (atLeastOneSelected != null) {
if (atLeastOneSelected.startsWith(":")) {
atLeastOneSelected = atLeastOneSelected.substring(1);
}
ObjectModelOperation isAtLeastOneSelectedOperation = addOperation(output, "isAtLeastOneSelected", boolean.class, ObjectModelJavaModifier.PUBLIC, ObjectModelJavaModifier.FINAL);
addAnnotation(output, isAtLeastOneSelectedOperation, Override.class);
List contentBuilder = new LinkedList<>();
String[] split = atLeastOneSelected.split("\\s*,\\s*");
if (split.length == 0) {
throw new IllegalStateException("Can't have a atLeastOneSelected tagValue without value on: " + input);
}
for (String s : split) {
String getterName = getJavaBeanMethodName("is", s);
contentBuilder.add(getterName + "()");
}
String content = String.join(" || ", contentBuilder);
setOperationBody(isAtLeastOneSelectedOperation, ""+"\n"
+" return "+content+";\n"
+" ");
}
if (autoTrimGenerator == null) {
autoTrimGenerator = new AutoTrimGenerator(validationTagValues, this, model, (c, a) -> {
ObjectModelClass aClass = model.getClass(a.getType());
return aClass != null
&& aClass.getSuperclasses().stream().anyMatch(i -> model.getClass(i.getQualifiedName()) != null)
&& aClass.getInterfaces().stream().noneMatch(i -> i.getQualifiedName().equals(NoValidationDto.class.getName()));
});
}
autoTrimGenerator.generate(input, output);
if (!referential && !businessDto && !withIndexProperties.isEmpty()) {
generateInstallIndexMethod(output, withIndexProperties);
}
return output;
}
private void generateInstallIndexMethod(ObjectModelClass output, List withIndexProperties) {
ObjectModelOperation installIndexOperation = addOperation(output, "installIndex", void.class, ObjectModelJavaModifier.PUBLIC, ObjectModelJavaModifier.FINAL);
addAnnotation(output, installIndexOperation, Override.class);
StringBuilder builder = new StringBuilder();
for (String withIndexProperty : withIndexProperties) {
String methodName = getJavaBeanMethodName("get", withIndexProperty);
builder.append(""+"\n"
+" WithIndex.installOrder("+methodName+"());\n"
+" ");
}
if (builder.length() > 0) {
addImport(output, WithIndex.class);
}
setOperationBody(installIndexOperation, builder.toString());
}
void addGroupBy(ObjectModelClass input, String... groupByList) {
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);
}
}
ObjectModelAttribute parentAttribute = Objects.requireNonNull(input.getAttribute(groupBy));
boolean mandatory = validationTagValues.isNotNull(model.getTagValuesStore(), input, parentAttribute);
if (groupBySecond == null) {
addGroupBy(input, groupBy, null, parentAttribute.getType(), mandatory, null);
} else {
ObjectModelClass classifier = model.getClass(parentAttribute.getType().replace("Reference", ""));
model.getClass(classifier.getQualifiedName().replace("Reference", ""));
ObjectModelAttribute secondClassifier = classifier.getAttribute(groupBySecond);
mandatory &= validationTagValues.isNotNull(model.getTagValuesStore(), classifier, secondClassifier);
addGroupBy(input, groupBy, groupBySecond, secondClassifier.getType(), mandatory, classifier);
}
}
}
private void 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() + "Dto";
String formClassName = input.getName() + "GroupBy" + capitalize + "Dto";
String definitionClassName = formClassName + "Definition";
String simplifyGroupType = GeneratorUtil.getSimpleName(type);
String dtoType = input.getQualifiedName() + "Dto";
// generate Definition
ObjectModelClass definitionClass = createClass(definitionClassName, input.getPackageName());
addImport(definitionClass, type);
addImport(definitionClass, dtoType);
addImport(definitionClass, Strings.class);
addImport(definitionClass, dtoType.replace("Dto", "Reference"));
String businessProject = "fr.ird.observe.spi.module.ObserveBusinessProject";
String moduleName = ProjectPackagesDefinition.extractFirstPackage(ProjectPackagesDefinition.removeFirstPackage(dtoType.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>", DataGroupByDtoDefinition.class.getName(), inputName, formClassName));
addImport(definitionClass, DataGroupByType.class);
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.replace("Reference", "")) == null ? DataGroupByType.TEMPORAL : DataGroupByType.QUALITATIVE;
ObjectModelOperation definitionConstructor = addConstructor(definitionClass, ObjectModelJavaModifier.PACKAGE);
String constantName = inputName + "." + getConstantName(groupByPropertyName);
if (groupBySecond != null) {
constantName += " + \".\" + " + secondClassifier.getQualifiedName() + "Dto." + getConstantName(groupBySecond);
}
setOperationBody(definitionConstructor, ""+"\n"
+" super(NAME, DataGroupByType."+groupByType+", "+constantName+", "+mandatory+", "+simplifyGroupType+".class, "+inputName+".class, "+formClassName+".class, "+formClassName+"::new, "+moduleMethodName+");\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 Dto
ObjectModelClass dtoClass = createClass(formClassName, input.getPackageName());
addAnnotation(dtoClass, dtoClass, GenerateJavaBeanDefinition.class);
ObjectModelAnnotation annotation = addAnnotation(dtoClass, dtoClass, RegisterI18nLabel.class);
addAnnotationClassParameter(getImportManager(dtoClass), dtoClass, annotation, "target", formClassName);
StringBuilder content = new StringBuilder("{");
Set i18nProperties = new LinkedHashSet<>(List.of("filterText", "count"));
Iterator iterator = i18nProperties.stream().sorted().iterator();
while (iterator.hasNext()) {
String value = iterator.next();
content.append("\"").append(value).append("\"");
if (iterator.hasNext()) {
content.append(", ");
}
}
content.append("}");
addAnnotationParameter(dtoClass, annotation, "properties", content.toString());
groupByDtoDefinitionMapping.put(dtoClass.getQualifiedName(), dtoClass.getQualifiedName() + ".DEFINITION");
addImport(dtoClass, DataGroupByDtoDefinition.class);
addImport(dtoClass, type);
addImport(dtoClass, dtoType);
addImport(dtoClass, dtoType.replace("Dto", "Reference"));
setSuperClass(dtoClass, String.format("%1$s<%2$s>", DataGroupByDto.class.getName(), inputName));
addConstant(dtoClass, "DEFINITION", definitionClassName, "new " + definitionClassName + "()", ObjectModelJavaModifier.PUBLIC);
ObjectModelOperation definitionOperation = addOperation(dtoClass, "definition", definitionClassName, ObjectModelJavaModifier.PUBLIC, ObjectModelJavaModifier.FINAL);
addAnnotation(dtoClass, definitionOperation, Override.class);
setOperationBody(definitionOperation, ""+"\n"
+" return DEFINITION;\n"
+" ");
}
@Override
protected void generateI18nBlockAndConstants(ObjectModelPackage aPackage, ObjectModelClass input, ObjectModelClassifier output) {
super.generateI18nBlockAndConstants(aPackage, input, output);
if (decomposeDates != null) {
decomposeDates.values().forEach(value -> addConstant(output, getConstantName(value), String.class, "\"" + value + "\"", ObjectModelJavaModifier.PUBLIC));
}
if (decomposeTimes != null) {
decomposeTimes.values().forEach(value -> addConstant(output, getConstantName(value), String.class, "\"" + value + "\"", ObjectModelJavaModifier.PUBLIC));
}
}
private final List withIndexProperties = new LinkedList<>();
@Override
protected void createProperty(ObjectModelClass output,
ObjectModelAttribute attr,
boolean usePCS,
boolean generateBooleanGetMethods,
boolean generateNotEmptyCollections) {
String attrName = getAttributeName(attr);
String attrType = attr.getType();
if (decomposeTimestamps != null && decomposeTimestamps.contains(attrName)) {
// need to add date and time getters
String datePropertyName = Objects.requireNonNull(decomposeDates.get(attrName));
String timePropertyName = Objects.requireNonNull(decomposeTimes.get(attrName));
addImport(output, Dates.class);
currentTimestampPropertyName = attrName;
createDecomposeTimestampAttribute(output, attr, usePCS, generateBooleanGetMethods, generateNotEmptyCollections, datePropertyName, attrType);
createDecomposeTimestampAttribute(output, attr, usePCS, generateBooleanGetMethods, generateNotEmptyCollections, timePropertyName, attrType);
}
super.createProperty(output, attr, usePCS, generateBooleanGetMethods, generateNotEmptyCollections);
boolean multiple = JavaGeneratorUtil.isNMultiplicity(attr);
if (multiple) {
// check out if we are using a WithIndex type
if (attrType.endsWith("Dto")) {
attrType = attrType.substring(0, attrType.length() - "Dto".length());
}
ObjectModelClass classifier = model.getClass(attrType);
if (classifier != null) {
boolean containerChildWithIndexDto = classifier.getSuperclasses().stream().anyMatch(i -> (i.getQualifiedName() + "Dto").equals(ContainerChildWithIndexDto.class.getName()));
if (containerChildWithIndexDto) {
withIndexProperties.add(attrName);
}
}
}
currentTimestampPropertyName = null;
}
private void createDecomposeTimestampAttribute(ObjectModelClass output,
ObjectModelAttribute attr,
boolean usePCS,
boolean generateBooleanGetMethods,
boolean generateNotEmptyCollections,
String attrName, String attrType) {
ObjectModelAttributeImpl dateProperty = new ObjectModelAttributeImpl();
dateProperty.setType(attrType);
dateProperty.setName(attrName);
dateProperty.setObjectModelImpl((ObjectModelImpl) model);
dateProperty.postInit();
super.createProperty(output, dateProperty, usePCS, generateBooleanGetMethods, generateNotEmptyCollections);
}
@Override
protected void createGetMethod(ObjectModelClass output, String attrName, String attrType, String methodPrefix) {
if (currentTimestampPropertyName == null || attrName.equals(currentTimestampPropertyName)) {
// default getter
super.createGetMethod(output, attrName, attrType, methodPrefix);
return;
}
attrType = importAndSimplify(output, attrType);
if (decomposeDates != null && attrName.equals(decomposeDates.get(currentTimestampPropertyName))) {
// date getter
ObjectModelOperation getter = addOperation(output, getJavaBeanMethodName(methodPrefix, attrName), attrType, ObjectModelJavaModifier.PUBLIC);
setOperationBody(getter, ""+"\n"
+" return "+currentTimestampPropertyName+" == null ? null : Dates.getDay("+currentTimestampPropertyName+");\n"
+" ");
return;
}
if (decomposeTimes != null && attrName.equals(decomposeTimes.get(currentTimestampPropertyName))) {
// time getter
ObjectModelOperation getter = addOperation(output, getJavaBeanMethodName(methodPrefix, attrName), attrType, ObjectModelJavaModifier.PUBLIC);
setOperationBody(getter, ""+"\n"
+" return "+currentTimestampPropertyName+" == null ? null : Dates.getTime("+currentTimestampPropertyName+", false, false);\n"
+" ");
}
}
@Override
protected void createSetMethod(ObjectModelClass output, String attrName, String attrType, String simpleType, String constantName, boolean usePCS) {
if (currentTimestampPropertyName == null) {
// default setter
super.createSetMethod(output, attrName, attrType, simpleType, constantName, usePCS);
return;
}
attrType = importAndSimplify(output, attrType);
if (attrName.equals(currentTimestampPropertyName)) {
// timestamp setter
String timestampGetterMethodName = getJavaBeanMethodName("get", attrName);
String datePropertyName = Objects.requireNonNull(decomposeDates.get(attrName));
String dateGetterMethodNameName = getJavaBeanMethodName("get", datePropertyName);
String timePropertyName = Objects.requireNonNull(decomposeTimes.get(attrName));
String timeGetterMethodName = getJavaBeanMethodName("get", timePropertyName);
String dateConstantName = getConstantName(datePropertyName);
String timeConstantName = getConstantName(timePropertyName);
ObjectModelOperation setter = createSetter(output, attrName, attrType);
setOperationBody(setter, ""+"\n"
+" Date oldValue = "+timestampGetterMethodName+"();\n"
+" Date oldDate = "+dateGetterMethodNameName+"();\n"
+" Date oldTime = "+timeGetterMethodName+"();\n"
+" this."+attrName+"= "+attrName+";\n"
+" firePropertyChange("+constantName+", oldValue, "+timestampGetterMethodName+"());\n"
+" firePropertyChange("+dateConstantName+", oldDate, "+dateGetterMethodNameName+"());\n"
+" firePropertyChange("+timeConstantName+", oldTime, "+timeGetterMethodName+"());\n"
+" ");
return;
}
String timestampPropertyName = "set" + Strings.capitalize(currentTimestampPropertyName);
if (decomposeDates != null && attrName.equals(decomposeDates.get(currentTimestampPropertyName))) {
// date setter
ObjectModelOperation setter = createSetter(output, attrName, attrType);
setOperationBody(setter, ""+"\n"
+" if ("+currentTimestampPropertyName+" != null) {\n"
+" Date dateAndTime = "+attrName+" == null ? "+currentTimestampPropertyName+" : Dates.getDateAndTime("+attrName+", "+currentTimestampPropertyName+", true, false);\n"
+" "+timestampPropertyName+"(dateAndTime);\n"
+" }\n"
+" ");
return;
}
if (decomposeTimes != null && attrName.equals(decomposeTimes.get(currentTimestampPropertyName))) {
// time setter
ObjectModelOperation setter = createSetter(output, attrName, attrType);
setOperationBody(setter, ""+"\n"
+" if ("+currentTimestampPropertyName+" != null) {\n"
+" Date dateAndTime = "+attrName+" == null ? "+currentTimestampPropertyName+" : Dates.getDateAndTime("+currentTimestampPropertyName+", "+attrName+", false, false);\n"
+" "+timestampPropertyName+"(dateAndTime);\n"
+" }\n"
+" ");
}
}
@Override
protected void createGetChildMethod(ObjectModelClass output, String attrName, String attrType, String simpleType) {
//super.createGetChildMethod(output, attrName, attrType, simpleType);
}
@Override
protected void createAddChildMethod(ObjectModelClass output,
String attrName,
String attrType,
String constantName,
boolean usePCS) {
}
@Override
protected void createAddAllChildrenMethod(ObjectModelClass output, String attrName, String attrType, String constantName, boolean usePCS) {
//super.createAddAllChildrenMethod(output, attrName, attrType, constantName, usePCS);
}
@Override
protected void createRemoveChildMethod(ObjectModelClass output, String attrName, String attrType, String constantName, boolean usePCS) {
//super.createRemoveChildMethod(output, attrName, attrType, constantName, usePCS);
}
@Override
protected void createRemoveAllChildrenMethod(ObjectModelClass output, String attrName, String attrType, String constantName, boolean usePCS) {
//super.createRemoveAllChildrenMethod(output, attrName, attrType, constantName, usePCS);
}
@Override
protected void createContainsChildMethod(ObjectModelClass output, String attrName, String attrType, String constantName, boolean usePCS) {
//super.createContainsChildMethod(output, attrName, attrType, constantName, usePCS);
}
@Override
protected void createContainsAllChildrenMethod(ObjectModelClass output, String attrName, String attrType, String constantName) {
//super.createContainsAllChildrenMethod(output, attrName, attrType, constantName);
}
private ObjectModelOperation createSetter(ObjectModelClass output, String attrName, String attrType) {
ObjectModelOperation setter = addOperation(output, getJavaBeanMethodName("set", attrName), "void", ObjectModelJavaModifier.PUBLIC);
addParameter(setter, attrType, attrName);
return setter;
}
private void addInlineDataDtoMethod(ObjectModelClass input, ObjectModelClass output) {
//FIXME Generate I18n
List expressions = new LinkedList<>();
String propertiesTagValue = toolkitTagValues.getInlineDataDtoPropertiesTagValue(input);
for (String attributeName : propertiesTagValue.split("\\s*,\\s*")) {
ObjectModelAttribute attribute = input.getAttribute(attributeName);
if (attribute == null) {
addInlineDataDtoExpression(expressions, attributeName, "String");
} else {
addInlineDataDtoExpression(expressions, attributeName, GeneratorUtil.getSimpleName(attribute.getType()));
}
}
if (expressions.isEmpty()) {
return;
}
ObjectModelOperation operation = addOperation(output, "isDataEmpty", boolean.class, ObjectModelJavaModifier.PUBLIC);
addAnnotation(output, operation, Override.class);
String bodyContent = String.join(" && ", expressions);
setOperationBody(operation, ""+"\n"
+" return "+bodyContent+";\n"
+" ");
}
private void addInlineDataDtoExpression(List expressions, String attributeName, String type) {
String methodPrefix = JavaGeneratorUtil.OPERATION_GETTER_DEFAULT_PREFIX;
String getter = getJavaBeanMethodName(methodPrefix, attributeName) + "()";
String expression = getter + " == null";
if (type.equals(String.class.getSimpleName())) {
expression = "(" + expression + " || " + getter + ".trim().isBlank())";
}
expressions.add(expression);
}
private void addStaticFactoryMethod(ObjectModelClass output, String className) {
ObjectModelOperation operation = addOperation(output, "newDto", className, ObjectModelJavaModifier.PUBLIC, ObjectModelJavaModifier.STATIC);
addParameter(operation, importAndSimplify(output, Date.class.getName()), "createDate");
setOperationBody(operation, ""+"\n"
+" return newDto("+className+".class, createDate);\n"
+" ");
}
private void addMainDtoMapping(ObjectModelClass input, boolean referential) {
String mainDtoType = toolkitTagValues.getMainDtoTagValue(input);
if (toolkitTagValues.notSkip(mainDtoType) == null) {
return;
}
String dtoType = input.getPackageName() + "." + context.classesNameTranslation.get(input);
dtoMainMapping.put(dtoType, mainDtoType + ".class");
}
private void addFormDefinitionAttribute(ObjectModelClass input, ObjectModelClass output, boolean referential) {
ObjectModelPackage thisPackage = getPackage(input);
String formTagValue = toolkitTagValues.getFormTagValue(input, thisPackage);
getLog().debug("FormTagValue: " + formTagValue);
ObjectModelPackage defaultPackage = getModel().getPackage(getDefaultPackageName());
String packageName = defaultPackage.getName() + ".";
String formType;
String dtoType = thisPackage.getName() + "." + context.classesNameTranslation.get(input);
String dtoTypeSimpleName = GeneratorUtil.getSimpleName(thisPackage.getName() + "." + context.classesNameTranslation.get(input));
boolean addForm;
Map properties;
if (formTagValue.equals(dtoType)) {
formType = dtoType;
properties = getFormProperties(input, output);
getLog().debug(String.format("form: %s, found %d properties.", formType, properties.size()));
addForm = referential || !properties.isEmpty();
if (addForm) {
StringBuilder bodyBuilder = new StringBuilder();
bodyBuilder.append(""+"\n"
+" new FormDefinition.Builder<>("+dtoTypeSimpleName+".class)");
if (referential) {
String referenceType = dtoTypeSimpleName.replace("Dto", "Reference");
bodyBuilder.append(""+"\n"
+" .addProperty(FormDefinition.REFERENTIAL_LIST_HEADER, "+referenceType+".DEFINITION)");
}
for (Map.Entry entry : properties.entrySet()) {
String propertyName = entry.getKey();
String referenceType = entry.getValue();
propertyName = JavaGeneratorUtil.convertVariableNameToConstantName("property" + JavaGeneratorUtil.capitalizeJavaBeanPropertyName(propertyName));
bodyBuilder.append(""+"\n"
+" .addProperty("+propertyName+", "+referenceType+".DEFINITION)");
}
bodyBuilder.append(""+"\n"
+" .build()");
addImport(output, formType);
addAttribute(output, "FORM_DEFINITION", "FormDefinition<" + GeneratorUtil.getSimpleName(formType) + ">", bodyBuilder.toString(), ObjectModelJavaModifier.STATIC, ObjectModelJavaModifier.FINAL, ObjectModelJavaModifier.PUBLIC);
}
} else {
formType = formTagValue;
addForm = true;
}
if (addForm) {
addImport(output, FormDefinition.class);
dtoFormMapping.put(dtoType, formType + ".FORM_DEFINITION");
}
}
private void addToReferenceMethod(ObjectModelClass output, String dtoName, String referenceName) {
boolean useRelativeName = context.useRelativeName;
ObjectModelOperation operation = addOperation(output, "toReference", referenceName, ObjectModelJavaModifier.PUBLIC);
addAnnotation(output, operation, Override.class);
String importReferentialLocale = importAndSimplify(output, ReferentialLocale.class.getName());
addParameter(operation, importReferentialLocale, "referentialLocale");
setOperationBody(operation, ""+"\n"
+" return "+referenceName+".of(referentialLocale, ("+dtoName+") this);\n"
+" ");
}
@Override
public ObjectModel initOutputModel() {
//FIXME Override builder to avoid bad imports when using synonyms in model...
builder = new JavaBuilder(getModel().getName()) {
@Override
public ObjectModelOperation addOperation(ObjectModelClassifier classifier, String name, String type, ObjectModelModifier... modifiers) {
ObjectModelOperationImpl result = new ObjectModelOperationImpl();
result.setName(name);
if (type != null) {
ObjectModelParameterImpl returnParameter =
new ObjectModelParameterImpl();
returnParameter.setType(type);
result.setReturnParameter(returnParameter);
}
result.addModifier(modifiers);
((ObjectModelClassifierImpl) classifier).addOperation(result);
return result;
}
@Override
public ObjectModelParameter addParameter(ObjectModelOperation operation, String type, String name) {
ObjectModelOperationImpl impl = (ObjectModelOperationImpl) operation;
ObjectModelParameterImpl param = new ObjectModelParameterImpl();
param.setType(type);
param.setName(name);
impl.addParameter(param);
return param;
}
@Override
public ObjectModelAttribute addAttribute(ObjectModelClassifier classifier, String name, String type, String value, ObjectModelModifier... modifiers) {
ObjectModelAttributeImpl attribute = new ObjectModelAttributeImpl();
attribute.setName(name);
attribute.setType(type);
attribute.setDefaultValue(value);
attribute.addModifier(modifiers);
ObjectModelClassifierImpl classifierImpl = (ObjectModelClassifierImpl) classifier;
classifierImpl.addAttribute(attribute);
return attribute;
}
};
setConstantPrefix("");
return builder.getModel();
}
private Map getFormProperties(ObjectModelClass input, ObjectModelClass output) {
Collection attributes = new LinkedList<>(input.getAttributes());
attributes.addAll(input.getAllOtherAttributes());
Map properties = new LinkedHashMap<>();
for (ObjectModelAttribute attr : attributes) {
if (!attr.isNavigable()) {
continue;
}
String type = attr.getType();
if (!type.endsWith("Reference") || !type.contains("referential")) {
continue;
}
addImport(output, type);
properties.put(attr.getName(), JavaGeneratorUtil.getSimpleName(type));
}
return properties;
}
@Override
protected void createSizeMethod(ObjectModelClass output, String attrName) {
ObjectModelOperation operation = addOperation(
output,
getJavaBeanMethodName("get", attrName + "Size"),
int.class,
ObjectModelJavaModifier.PUBLIC
);
setOperationBody(operation, ""+"\n"
+" return "+attrName+" == null ? 0 : "+attrName+".size();\n"
+" "
);
}
@Override
protected void createIsEmptyMethod(ObjectModelClass output, String attrName) {
super.createIsEmptyMethod(output, attrName);
ObjectModelOperation isNotEmptyOperationImpl = addOperation(
output,
getJavaBeanMethodName("isNot", attrName + "Empty"),
boolean.class,
ObjectModelJavaModifier.PUBLIC
);
String isEmptyMethodName = getJavaBeanMethodName("is", attrName + "Empty");
setOperationBody(isNotEmptyOperationImpl, ""+"\n"
+" return !"+isEmptyMethodName+"();\n"
+" "
);
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy