[Git][ultreiaio/ird-observe][feature/issue-2846] 14 commits: [ui] fix Logger name
Tony CHEMIT pushed to branch feature/issue-2846 at ultreiaio / ird-observe Commits: 519d78f9 by Tony Chemit at 2024-09-30T15:59:51+02:00 [ui] fix Logger name - - - - - d5112573 by Tony Chemit at 2024-09-30T16:00:12+02:00 [toolkit-api-services] Introduce ReferentialSecondLevelDeepBehaviourModel - - - - - e3a9e816 by Tony Chemit at 2024-09-30T16:00:12+02:00 [toolkit-templates] Introduce referentialSecondLevelDeepBehaviour tagValue - - - - - d73e9c61 by Tony Chemit at 2024-09-30T16:00:12+02:00 [toolkit-templates] Introduce new generators to produce ReferentialSecondLevelDeepBehaviourModel.json and his associated model class file ReferentialSecondLevelDeepBehaviourModel - - - - - 7c55ec38 by Tony Chemit at 2024-09-30T16:00:12+02:00 [model] use referentialSecondLevelDeepBehaviour tagValue - - - - - 14bedb12 by Tony Chemit at 2024-09-30T16:00:12+02:00 [core-api-services] generate ReferentialSecondLevelDeepBehaviourModel.json model file - - - - - cfb14bc2 by Tony Chemit at 2024-09-30T16:00:12+02:00 [core-api-services] test the generated ObserveReferentialSecondLevelDeepBehaviourModel - - - - - bf6a14a2 by Tony Chemit at 2024-09-30T16:00:12+02:00 [toolkit-api-services] Introduce ExtraSaveRequest for ReferentialService.save method - - - - - ac66dc3d by Tony Chemit at 2024-09-30T16:05:43+02:00 [toolkit-persistence] Introduce AddExtraSqlScripts and implements it to PersistenceResultBuilder - - - - - 73e16a66 by Tony Chemit at 2024-09-30T16:06:25+02:00 [core-services-local] implements ReferentialService.save new method - - - - - 824a3395 by Tony Chemit at 2024-09-30T16:06:39+02:00 [core-services-tests] adapt tests - - - - - f231c455 by Tony Chemit at 2024-09-30T16:54:09+02:00 [ui] Introduce ContentReferentialUIModelStates.secondLevelUsages to keep second level usages - - - - - 9dcbee37 by Tony Chemit at 2024-09-30T17:02:54+02:00 [ui] Fill ContentReferentialUIModelStates.secondLevelUsages from ReferentialSavePredicate (to be used in the deactivate process) - - - - - a04f842e by Tony Chemit at 2024-09-30T17:02:54+02:00 [ui] Review save action (using now the ExtraSaveRequest) - - - - - 24 changed files: - client/datasource/editor/api/src/main/java/fr/ird/observe/client/datasource/editor/api/content/referential/ContentReferentialUIHandler.java - client/datasource/editor/api/src/main/java/fr/ird/observe/client/datasource/editor/api/content/referential/ContentReferentialUIModelStates.java - client/datasource/editor/api/src/main/java/fr/ird/observe/client/datasource/editor/api/content/referential/ReferentialSavePredicate.java - client/datasource/editor/api/src/main/java/fr/ird/observe/client/datasource/editor/api/content/referential/actions/ReplaceReferentialUsages.java - client/datasource/editor/api/src/main/java/fr/ird/observe/client/datasource/editor/api/content/referential/usage/UsageForDesactivateUIHandler.java - core/api/services/pom.xml - + core/api/services/src/main/resources/META-INF/services/Observe/ReferentialSecondLevelDeepBehaviourModel.json - + core/api/services/src/test/java/fr/ird/observe/services/service/referential/ObserveReferentialSecondLevelDeepBehaviourModelTest.java - core/persistence/java/src/main/java/fr/ird/observe/entities/referential/common/OceanSpi.java - core/services/local/src/main/java/fr/ird/observe/services/local/service/referential/ReferentialServiceLocalSupport.java - core/services/local/src/test/java/fr/ird/observe/services/local/service/referential/UnidirectionalResultIssue2208Test.java - core/services/test/src/main/java/fr/ird/observe/services/service/referential/ReferentialServiceFixtures.java - + model/src/main/models/Observe/dto/class/referentialSecondLevelDeepBehaviour.properties - + toolkit/api-services/src/main/java/fr/ird/observe/services/service/referential/ExtraSaveRequest.java - + toolkit/api-services/src/main/java/fr/ird/observe/services/service/referential/ReferentialSecondLevelDeepBehaviourModel.java - toolkit/api-services/src/main/java/fr/ird/observe/services/service/referential/ReferentialService.java - toolkit/persistence/src/main/java/fr/ird/observe/spi/context/ReferentialDtoEntityContext.java - + toolkit/persistence/src/main/java/fr/ird/observe/spi/result/AddExtraSqlScripts.java - toolkit/persistence/src/main/java/fr/ird/observe/spi/result/AddUpdateLastUpdateDateTableStep.java - toolkit/persistence/src/main/java/fr/ird/observe/spi/result/PersistenceResultBuilder.java - toolkit/templates/src/main/java/fr/ird/observe/toolkit/templates/GenerateServices.java - toolkit/templates/src/main/java/fr/ird/observe/toolkit/templates/ToolkitTagValues.java - + toolkit/templates/src/main/java/fr/ird/observe/toolkit/templates/services/GenerateReferentialSecondLevelDeepBehaviourClass.java - + toolkit/templates/src/main/java/fr/ird/observe/toolkit/templates/services/GenerateReferentialSecondLevelDeepBehaviourFile.java Changes: ===================================== client/datasource/editor/api/src/main/java/fr/ird/observe/client/datasource/editor/api/content/referential/ContentReferentialUIHandler.java ===================================== @@ -44,11 +44,11 @@ import fr.ird.observe.client.datasource.editor.api.content.referential.actions.S import fr.ird.observe.client.datasource.editor.api.content.referential.actions.ShowUsagesReferential; import fr.ird.observe.client.util.UIHelper; import fr.ird.observe.datasource.security.ConcurrentModificationException; -import fr.ird.observe.dto.ToolkitIdLabel; import fr.ird.observe.dto.reference.ReferentialDtoReference; import fr.ird.observe.dto.referential.ReferentialDto; import fr.ird.observe.dto.referential.ReferentialDtoReferenceWithNoCodeAware; import fr.ird.observe.services.service.SaveResultDto; +import fr.ird.observe.services.service.referential.ExtraSaveRequest; import io.ultreia.java4all.i18n.I18n; import io.ultreia.java4all.jaxx.widgets.list.ListHeader; import org.apache.logging.log4j.LogManager; @@ -284,14 +284,8 @@ public class ContentReferentialUIHandler<D extends ReferentialDto, R extends Ref } protected SaveResultDto doSave(D bean) throws ConcurrentModificationException { - ToolkitIdLabel replaceReference = getModel().getStates().getReplaceReference(); - if (replaceReference != null) { - String id = bean.getId(); - String replaceId = replaceReference.getId(); - log.info(String.format("Do replace reference before save (%s → %s)", id, replaceId)); - getReferentialService().replaceReference(getModel().getSource().getScope().getMainType(), id, replaceId); - } - SaveResultDto result = getReferentialService().save(bean); + ExtraSaveRequest request = getModel().getStates().toExtraSaveRequest(); + SaveResultDto result = getReferentialService().save(bean, request); bean.copy(getModel().getStates().getForm().getObject()); return result; } ===================================== client/datasource/editor/api/src/main/java/fr/ird/observe/client/datasource/editor/api/content/referential/ContentReferentialUIModelStates.java ===================================== @@ -30,6 +30,7 @@ import fr.ird.observe.client.datasource.editor.api.content.ContentUIModel; import fr.ird.observe.client.datasource.editor.api.content.ContentUIModelStates; import fr.ird.observe.client.datasource.editor.api.content.actions.save.SavePredicate; import fr.ird.observe.client.util.init.DefaultUIInitializerResult; +import fr.ird.observe.dto.ToolkitIdBean; import fr.ird.observe.dto.ToolkitIdDtoBean; import fr.ird.observe.dto.ToolkitIdLabel; import fr.ird.observe.dto.form.Form; @@ -38,11 +39,20 @@ import fr.ird.observe.dto.referential.ReferentialDto; import fr.ird.observe.dto.referential.ReferentialLocale; import fr.ird.observe.navigation.id.Project; import fr.ird.observe.services.ObserveServicesProvider; +import fr.ird.observe.services.service.referential.ExtraSaveRequest; +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; import javax.swing.ListModel; +import java.util.Collection; +import java.util.LinkedHashMap; import java.util.LinkedList; import java.util.List; +import java.util.Map; import java.util.Objects; +import java.util.Optional; +import java.util.Set; +import java.util.stream.Collectors; /** * Created on 30/10/2020. @@ -52,6 +62,7 @@ import java.util.Objects; */ public abstract class ContentReferentialUIModelStates<D extends ReferentialDto, R extends ReferentialDtoReference> extends ContentUIModelStates { public static final String PROPERTY_SELECTED_BEAN_REFERENCE = "selectedBeanReference"; + private static final Logger log = LogManager.getLogger(ContentReferentialUIModelStates.class); /** * Reference cache. */ @@ -67,6 +78,12 @@ public abstract class ContentReferentialUIModelStates<D extends ReferentialDto, private Form<D> form; private ToolkitIdLabel replaceReference; private ContentReferentialUI<D, R, ?> ui; + /** + * To keep the second level usages when necessary). + * + * @since 9.4.0 + */ + private Map<Class<? extends ReferentialDto>, Collection<ToolkitIdLabel>> secondLevelUsages; public ContentReferentialUIModelStates(ContentReferentialUIModel<D, R> model, D bean) { source = Objects.requireNonNull(model).getSource(); @@ -194,7 +211,45 @@ public abstract class ContentReferentialUIModelStates<D extends ReferentialDto, return mainType; } + public ExtraSaveRequest toExtraSaveRequest() { + ToolkitIdLabel replaceReference = getReplaceReference(); + if (replaceReference != null) { + String id = bean.getId(); + String replaceId = replaceReference.getId(); + log.info("Do replace reference before save ({} → {})", id, replaceId); + } + Map<Class<? extends ReferentialDto>, Set<String>> toDisableIds = getToDisableIds(); + if (toDisableIds != null) { + toDisableIds.forEach((k, v) -> log.info("Do disable references before save of type {} → {} id(s)", k, v.size())); + } + String replaceId = Optional.ofNullable(replaceReference).map(ToolkitIdBean::getId).orElse(null); + if (replaceId == null && toDisableIds == null) { + return null; + } + return new ExtraSaveRequest(replaceId, toDisableIds); + } + + private Map<Class<? extends ReferentialDto>, Set<String>> getToDisableIds() { + Map<Class<? extends ReferentialDto>, Collection<ToolkitIdLabel>> secondLevelUsages = getSecondLevelUsages(); + Map<Class<? extends ReferentialDto>, Set<String>> toDisableIds; + if (secondLevelUsages == null) { + toDisableIds = null; + } else { + toDisableIds = new LinkedHashMap<>(secondLevelUsages.size()); + secondLevelUsages.forEach((k, v) -> toDisableIds.put(k, v.stream().map(ToolkitIdBean::getId).collect(Collectors.toSet()))); + } + return toDisableIds; + } + public Class<R> mainReferenceType() { return mainReferenceType; } + + public Map<Class<? extends ReferentialDto>, Collection<ToolkitIdLabel>> getSecondLevelUsages() { + return secondLevelUsages; + } + + public void setSecondLevelUsages(Map<Class<? extends ReferentialDto>, Collection<ToolkitIdLabel>> secondLevelUsages) { + this.secondLevelUsages = secondLevelUsages; + } } ===================================== client/datasource/editor/api/src/main/java/fr/ird/observe/client/datasource/editor/api/content/referential/ReferentialSavePredicate.java ===================================== @@ -24,16 +24,28 @@ package fr.ird.observe.client.datasource.editor.api.content.referential; import fr.ird.observe.client.datasource.editor.api.content.actions.save.SavePredicateSupport; import fr.ird.observe.client.datasource.editor.api.content.referential.usage.UsageForDesactivateUIHandler; +import fr.ird.observe.dto.BusinessDto; import fr.ird.observe.dto.ToolkitIdDtoBean; import fr.ird.observe.dto.ToolkitIdLabel; import fr.ird.observe.dto.reference.ReferentialDtoReference; import fr.ird.observe.dto.referential.ReferenceStatus; import fr.ird.observe.dto.referential.ReferentialDto; import fr.ird.observe.services.service.UsageCount; +import fr.ird.observe.services.service.UsageCountWithLabel; import fr.ird.observe.services.service.UsageService; +import fr.ird.observe.services.service.referential.ObserveReferentialSecondLevelDeepBehaviourModel; +import fr.ird.observe.spi.module.ObserveBusinessProject; +import io.ultreia.java4all.i18n.I18n; import org.apache.commons.lang3.tuple.Pair; +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; +import java.util.Collection; +import java.util.LinkedHashMap; import java.util.List; +import java.util.Map; +import java.util.Objects; +import java.util.Set; import java.util.stream.Collectors; /** @@ -43,7 +55,7 @@ import java.util.stream.Collectors; * @since 9.0.0 */ public class ReferentialSavePredicate<D extends ReferentialDto, R extends ReferentialDtoReference, S extends ContentReferentialUIModelStates<D, R>> extends SavePredicateSupport<S,D> { - + private static final Logger log = LogManager.getLogger(ReferentialSavePredicate.class); public ReferentialSavePredicate(S states) { super(states); } @@ -66,26 +78,51 @@ public class ReferentialSavePredicate<D extends ReferentialDto, R extends Refere ToolkitIdDtoBean request = states.toUsageRequest(bean.getId()); UsageCount usages = usageService.countReferential(request); - if (!usages.isEmpty()) { - // some usages were found + if (usages.isEmpty()) { + return true; + } - // get replacements - List<R> referentialReferences = states.getReferentialReferences(); - List<R> referenceList = referentialReferences - .stream() - .filter(ReferentialDtoReference::isEnabled) - .filter(r -> !bean.getId().equals(r.getId())) - .collect(Collectors.toList()); + // some usages were found + UsageCountWithLabel realUsages = new UsageCountWithLabel(I18n.getDefaultLocale(), ObserveBusinessProject.get(), usages); + UsageForDesactivateUIHandler.DisableReferentialUsagesGetter getter = new UsageForDesactivateUIHandler.DisableReferentialUsagesGetter(realUsages, usageService, request); - ToolkitIdLabel dtoLabel = bean.toLabel(); - states.getDecoratorService().installToolkitIdLabelDecorator(bean.getClass(), dtoLabel); - Pair<Boolean, ToolkitIdLabel> result = UsageForDesactivateUIHandler.showUsages(usageService, dtoLabel, request, usages, referenceList.stream().map(ReferentialDtoReference::toLabel).collect(Collectors.toList())); - boolean willSave = result.getLeft(); - if (!willSave) { - return false; + ObserveReferentialSecondLevelDeepBehaviourModel referentialSecondLevelDeepBehaviourModel = ObserveReferentialSecondLevelDeepBehaviourModel.get(); + Map<Class<? extends ReferentialDto>, Collection<ToolkitIdLabel>> secondLevelUsages = new LinkedHashMap<>(); + Set<Class<? extends BusinessDto>> typesFound = usages.keySet(); + for (Class<? extends BusinessDto> type : typesFound) { + if (!ReferentialDto.class.isAssignableFrom(type) ) { + continue; } - states.setReplaceReference(result.getRight()); + @SuppressWarnings("unchecked") Class<? extends ReferentialDto> referentialType = (Class<? extends ReferentialDto>) type; + if (referentialSecondLevelDeepBehaviourModel.useSecondLevelDeepBehaviour(referentialType)) { + Collection<ToolkitIdLabel> toolkitIdLabels = getter.getUsages(type).get(); + log.info("Found second level type: {} - {} occurrence(s).", referentialType, toolkitIdLabels.size()); + secondLevelUsages.put(referentialType,toolkitIdLabels); + } + } + if (!secondLevelUsages.isEmpty()) { + states.setSecondLevelUsages(secondLevelUsages); + } + + // get replacements + List<R> referentialReferences = states.getReferentialReferences(); + List<ToolkitIdLabel> referenceList = referentialReferences + .stream() + .filter(ReferentialDtoReference::isEnabled) + .filter(r -> !Objects.equals(bean.getId(), r.getId())) + .map(ReferentialDtoReference::toLabel) + .collect(Collectors.toList()); + + ToolkitIdLabel dtoLabel = bean.toLabel(); + states.getDecoratorService().installToolkitIdLabelDecorator(bean.getClass(), dtoLabel); + Pair<Boolean, ToolkitIdLabel> result = UsageForDesactivateUIHandler.showUsages(dtoLabel, + getter, + referenceList); + boolean willSave = result.getLeft(); + if (!willSave) { + return false; } + states.setReplaceReference(result.getRight()); } return true; } ===================================== client/datasource/editor/api/src/main/java/fr/ird/observe/client/datasource/editor/api/content/referential/actions/ReplaceReferentialUsages.java ===================================== @@ -57,7 +57,7 @@ import static io.ultreia.java4all.i18n.I18n.n; */ public class ReplaceReferentialUsages<D extends ReferentialDto, R extends ReferentialDtoReference, U extends ContentReferentialUI<D, R, U>> extends ContentReferentialUIActionSupport<D, R, U> implements ConfigureMenuAction<U> { - private static final Logger log = LogManager.getLogger(DeleteReferential.class); + private static final Logger log = LogManager.getLogger(ReplaceReferentialUsages.class); private ToolkitIdLabel replaceReference; ===================================== client/datasource/editor/api/src/main/java/fr/ird/observe/client/datasource/editor/api/content/referential/usage/UsageForDesactivateUIHandler.java ===================================== @@ -29,12 +29,10 @@ import fr.ird.observe.client.util.init.UIInitHelper; import fr.ird.observe.dto.BusinessDto; import fr.ird.observe.dto.ToolkitIdDtoBean; import fr.ird.observe.dto.ToolkitIdLabel; -import fr.ird.observe.services.service.UsageCount; import fr.ird.observe.services.service.UsageCountWithLabel; import fr.ird.observe.services.service.UsageService; import fr.ird.observe.spi.module.ObserveBusinessProject; import io.ultreia.java4all.application.template.spi.GenerateTemplate; -import io.ultreia.java4all.i18n.I18n; import io.ultreia.java4all.jaxx.widgets.combobox.FilterableComboBox; import io.ultreia.java4all.jaxx.widgets.combobox.FilterableComboBoxModel; import io.ultreia.java4all.util.SingletonSupplier; @@ -85,15 +83,10 @@ public class UsageForDesactivateUIHandler extends UsageUIHandlerSupport<UsageFor } } - public static Pair<Boolean, ToolkitIdLabel> showUsages(UsageService usageService, - ToolkitIdLabel dto, - ToolkitIdDtoBean request, - UsageCount usages, + public static Pair<Boolean, ToolkitIdLabel> showUsages(ToolkitIdLabel dto, + DisableReferentialUsagesGetter getter, List<ToolkitIdLabel> referenceList) { ObserveBusinessProject businessProject = ObserveBusinessProject.get(); - UsageCountWithLabel realUsages = new UsageCountWithLabel(I18n.getDefaultLocale(), businessProject, usages); - DisableReferentialUsagesGetter getter = new DisableReferentialUsagesGetter(realUsages, usageService, request); - Class<? extends BusinessDto> dtoType = dto.getType(); String type = businessProject.getLongTitle(dtoType); String message = t("observe.ui.message.show.usage.referential.disabled", type, dto); ===================================== core/api/services/pom.xml ===================================== @@ -84,6 +84,11 @@ <groupId>io.ultreia.java4all.http</groupId> <artifactId>http-api</artifactId> </dependency> + <dependency> + <groupId>junit</groupId> + <artifactId>junit</artifactId> + <scope>test</scope> + </dependency> <dependency> <groupId>io.ultreia.java4all.http</groupId> <artifactId>http-spi-processor</artifactId> ===================================== core/api/services/src/main/resources/META-INF/services/Observe/ReferentialSecondLevelDeepBehaviourModel.json ===================================== @@ -0,0 +1,5 @@ +[ + "fr.ird.observe.dto.referential.common.LengthLengthParameterDto", + "fr.ird.observe.dto.referential.common.LengthWeightParameterDto", + "fr.ird.observe.dto.referential.ps.common.WeightCategoryDto" +] \ No newline at end of file ===================================== core/api/services/src/test/java/fr/ird/observe/services/service/referential/ObserveReferentialSecondLevelDeepBehaviourModelTest.java ===================================== @@ -0,0 +1,69 @@ +package fr.ird.observe.services.service.referential; + +/*- + * #%L + * ObServe Core :: API :: Services + * %% + * Copyright (C) 2008 - 2024 IRD, 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 + * <http://www.gnu.org/licenses/gpl-3.0.html>. + * #L% + */ + +import fr.ird.observe.dto.referential.ReferentialDto; +import fr.ird.observe.dto.referential.common.LengthLengthParameterDto; +import fr.ird.observe.dto.referential.common.LengthWeightParameterDto; +import fr.ird.observe.dto.referential.common.SpeciesDto; +import fr.ird.observe.dto.referential.ps.common.WeightCategoryDto; +import org.junit.Test; + +import java.util.Iterator; +import java.util.Set; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertTrue; + +/** + * Created at 30/09/2024. + * + * @author Tony Chemit - dev@tchemit.fr + * @since 9.4.0 + */ +public class ObserveReferentialSecondLevelDeepBehaviourModelTest { + + @Test + public void get() { + ObserveReferentialSecondLevelDeepBehaviourModel model = ObserveReferentialSecondLevelDeepBehaviourModel.get(); + assertNotNull(model); + Set<Class<? extends ReferentialDto>> entries = model.entries(); + assertEquals(3, entries.size()); + Iterator<Class<? extends ReferentialDto>> iterator = entries.iterator(); + assertEquals(LengthLengthParameterDto.class, iterator.next()); + assertEquals(LengthWeightParameterDto.class, iterator.next()); + assertEquals(WeightCategoryDto.class, iterator.next()); + } + + @Test + public void useSecondLevelDeepBehaviour() { + ObserveReferentialSecondLevelDeepBehaviourModel model = ObserveReferentialSecondLevelDeepBehaviourModel.get(); + assertNotNull(model); + assertTrue(model.useSecondLevelDeepBehaviour(LengthLengthParameterDto.class)); + assertTrue(model.useSecondLevelDeepBehaviour(LengthWeightParameterDto.class)); + assertTrue(model.useSecondLevelDeepBehaviour(WeightCategoryDto.class)); + assertFalse(model.useSecondLevelDeepBehaviour(SpeciesDto.class)); + } +} ===================================== core/persistence/java/src/main/java/fr/ird/observe/entities/referential/common/OceanSpi.java ===================================== @@ -28,6 +28,7 @@ import fr.ird.observe.dto.referential.common.SpeciesReference; import fr.ird.observe.services.service.SaveResultDto; import fr.ird.observe.spi.result.AddEntityToUpdateStep; import fr.ird.observe.spi.service.ServiceContext; +import io.ultreia.java4all.util.sql.SqlScript; import java.util.LinkedHashSet; import java.util.List; @@ -54,7 +55,7 @@ public class OceanSpi extends GeneratedOceanSpi { } @Override - public SaveResultDto saveEntity(ServiceContext context, Ocean entity, OceanDto dto) { + public SaveResultDto saveEntity(ServiceContext context, Ocean entity, OceanDto dto, List<SqlScript> extraScripts) { Set<Species> speciesToUpdate = new LinkedHashSet<>(); Set<String> newSpeciesWithThisOceanIds = dto.getSpecies().stream().map(SpeciesReference::getId).collect(Collectors.toSet()); if (dto.isPersisted()) { @@ -87,6 +88,6 @@ public class OceanSpi extends GeneratedOceanSpi { for (Species species : speciesToUpdate) { update.update(Species.SPI, species); } - return update.build(entity); + return update.addExtraSqlScripts(extraScripts).build(entity); } -} //OceanSpi +} ===================================== core/services/local/src/main/java/fr/ird/observe/services/local/service/referential/ReferentialServiceLocalSupport.java ===================================== @@ -31,6 +31,7 @@ import fr.ird.observe.dto.reference.ReferentialDtoReferenceSet; import fr.ird.observe.dto.referential.ReferentialDto; import fr.ird.observe.services.local.service.ObserveServiceLocal; import fr.ird.observe.services.service.SaveResultDto; +import fr.ird.observe.services.service.referential.ExtraSaveRequest; import fr.ird.observe.services.service.referential.ReferentialIds; import fr.ird.observe.services.service.referential.ReferentialService; import fr.ird.observe.spi.context.ReferentialDtoEntityContext; @@ -85,10 +86,10 @@ class ReferentialServiceLocalSupport extends ObserveServiceLocal implements Refe } @Override - public <D extends ReferentialDto> SaveResultDto save(D bean) throws ConcurrentModificationException { + public <D extends ReferentialDto> SaveResultDto save(D bean, ExtraSaveRequest extraSaveRequest) throws ConcurrentModificationException { @SuppressWarnings("unchecked") Class<D> type = (Class<D>) bean.getClass(); ReferentialDtoEntityContext<D, ?, ?, ?> spi = fromReferentialDto(type); - return spi.save(this, bean); + return spi.save(this, bean, extraSaveRequest); } @Override ===================================== core/services/local/src/test/java/fr/ird/observe/services/local/service/referential/UnidirectionalResultIssue2208Test.java ===================================== @@ -31,6 +31,7 @@ import fr.ird.observe.dto.referential.common.SpeciesDto; import fr.ird.observe.services.local.LocalTestClassResource; import fr.ird.observe.services.local.LocalTestMethodResourceWrite; import fr.ird.observe.services.local.service.ServiceLocalTestSupportWrite; +import fr.ird.observe.services.service.referential.ExtraSaveRequest; import fr.ird.observe.services.service.referential.ReferentialService; import fr.ird.observe.services.service.referential.ReferentialServiceFixtures; import fr.ird.observe.services.service.referential.SynchronizeEngine; @@ -121,7 +122,7 @@ public class UnidirectionalResultIssue2208Test extends ServiceLocalTestSupportWr centralSpecies.getOcean().add(ocean); TOPIA_TEST_CLASS_RESOURCE_CENTRAL.setGenerateNow(true); try { - centralReferentialService.save(centralSpecies); + centralReferentialService.save(centralSpecies, null); } finally { TOPIA_TEST_CLASS_RESOURCE_CENTRAL.setGenerateNow(false); } ===================================== core/services/test/src/main/java/fr/ird/observe/services/service/referential/ReferentialServiceFixtures.java ===================================== @@ -189,7 +189,7 @@ public class ReferentialServiceFixtures extends GeneratedReferentialServiceFixtu fr.ird.observe.dto.referential.ps.common.ProgramDto actual = service.loadDto(fr.ird.observe.dto.referential.ps.common.ProgramDto.class, getProperty("loadDto.id")); Assert.assertNotNull(actual); try { - SaveResultDto actualResult = service.save(actual); + SaveResultDto actualResult = service.save(actual, null); Assert.assertNotNull(actualResult); } catch (ConcurrentModificationException e) { throw new RuntimeException(e); ===================================== model/src/main/models/Observe/dto/class/referentialSecondLevelDeepBehaviour.properties ===================================== @@ -0,0 +1,24 @@ +### +# #%L +# ObServe :: Model +# %% +# Copyright (C) 2008 - 2024 IRD, 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 +# <http://www.gnu.org/licenses/gpl-3.0.html>. +# #L% +### +referential.common.LengthLengthParameter=true +referential.common.LengthWeightParameter=true +referential.ps.common.WeightCategory=true ===================================== toolkit/api-services/src/main/java/fr/ird/observe/services/service/referential/ExtraSaveRequest.java ===================================== @@ -0,0 +1,62 @@ +package fr.ird.observe.services.service.referential; + +/*- + * #%L + * ObServe Toolkit :: API :: Services + * %% + * Copyright (C) 2008 - 2024 IRD, 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 + * <http://www.gnu.org/licenses/gpl-3.0.html>. + * #L% + */ + +import fr.ird.observe.dto.referential.ReferentialDto; +import io.ultreia.java4all.util.json.JsonAware; + +import java.util.Map; +import java.util.Optional; +import java.util.Set; + +/** + * An object to define all extra actions that can be done while trying to save a referential. + * <p> + * Created at 30/09/2024. + * + * @author Tony Chemit - dev@tchemit.fr + * @since 9.4.0 + */ +public class ExtraSaveRequest implements JsonAware { + /** + * Optional replace id to perform before save. + */ + private final String replaceId; + /** + * Optional disable id to perform before save. + */ + private final Map<Class<? extends ReferentialDto>, Set<String>> toDisableIds; + + public ExtraSaveRequest(String replaceId, Map<Class<? extends ReferentialDto>, Set<String>> toDisableIds) { + this.replaceId = replaceId; + this.toDisableIds = toDisableIds; + } + + public Optional<String> getReplaceId() { + return Optional.ofNullable(replaceId); + } + + public Optional<Map<Class<? extends ReferentialDto>, Set<String>>> getToDisableIds() { + return Optional.ofNullable(toDisableIds); + } +} ===================================== toolkit/api-services/src/main/java/fr/ird/observe/services/service/referential/ReferentialSecondLevelDeepBehaviourModel.java ===================================== @@ -0,0 +1,84 @@ +package fr.ird.observe.services.service.referential; + +/*- + * #%L + * ObServe Toolkit :: API :: Services + * %% + * Copyright (C) 2008 - 2024 IRD, 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 + * <http://www.gnu.org/licenses/gpl-3.0.html>. + * #L% + */ + +import com.google.gson.Gson; +import com.google.gson.GsonBuilder; +import com.google.gson.reflect.TypeToken; +import fr.ird.observe.dto.referential.ReferentialDto; +import io.ultreia.java4all.util.json.JsonAware; +import io.ultreia.java4all.util.json.adapters.ClassAdapter; + +import java.io.BufferedReader; +import java.io.IOException; +import java.io.InputStreamReader; +import java.io.Reader; +import java.net.URL; +import java.nio.charset.StandardCharsets; +import java.util.Collections; +import java.util.LinkedHashSet; +import java.util.Objects; +import java.util.Set; + +/** + * Created at 30/09/2024. + * + * @author Tony Chemit - dev@tchemit.fr + * @since 9.4.0 + */ +public class ReferentialSecondLevelDeepBehaviourModel implements JsonAware { + + public static String toLocation(String modelName) { + return String.format("META-INF/services/%s/%s.json", Objects.requireNonNull(modelName), ReferentialSecondLevelDeepBehaviourModel.class.getSimpleName()); + } + + public static Gson newGson() { + return new GsonBuilder() + .disableHtmlEscaping() + .setPrettyPrinting() + .enableComplexMapKeySerialization() + .registerTypeAdapter(Class.class, new ClassAdapter()) + .create(); + } + + private final Set<Class<? extends ReferentialDto>> entries; + + public ReferentialSecondLevelDeepBehaviourModel(String modelName) { + String location = toLocation(Objects.requireNonNull(modelName)); + URL resource = Objects.requireNonNull(ReferentialSecondLevelDeepBehaviourModel.class).getClassLoader().getResource(Objects.requireNonNull(location)); + try (Reader reader = new BufferedReader(new InputStreamReader(Objects.requireNonNull(resource).openStream(), StandardCharsets.UTF_8))) { + this.entries = Collections.unmodifiableSet(newGson().fromJson(reader, new TypeToken<LinkedHashSet<Class<? extends ReferentialDto>>>() { + }.getType())); + } catch (IOException e) { + throw new IllegalStateException(String.format("Could not load resource: %s (for type: %s)", resource, getClass().getName()), e); + } + } + + public Set<Class<? extends ReferentialDto>> entries() { + return entries; + } + + public boolean useSecondLevelDeepBehaviour(Class<? extends ReferentialDto> type) { + return entries().contains(type); + } +} ===================================== toolkit/api-services/src/main/java/fr/ird/observe/services/service/referential/ReferentialService.java ===================================== @@ -96,9 +96,9 @@ public interface ReferentialService extends ObserveService { <D extends ReferentialDto> Form<D> preCreate(Class<D> type); @Write - @Post + @Post(useMultiPartForm = true) @MethodCredential(Permission.WRITE_REFERENTIAL) - <D extends ReferentialDto> SaveResultDto save(D bean) throws ConcurrentModificationException; + <D extends ReferentialDto> SaveResultDto save(D bean, @Nullable ExtraSaveRequest extraSaveRequest) throws ConcurrentModificationException; @Write @Delete ===================================== toolkit/persistence/src/main/java/fr/ird/observe/spi/context/ReferentialDtoEntityContext.java ===================================== @@ -40,6 +40,7 @@ import fr.ird.observe.entities.referential.I18nReferentialEntity; import fr.ird.observe.entities.referential.ReferentialEntity; import fr.ird.observe.services.service.SaveResultDto; import fr.ird.observe.services.service.UsageCount; +import fr.ird.observe.services.service.referential.ExtraSaveRequest; import fr.ird.observe.spi.referential.ReferentialExtraScripts; import fr.ird.observe.spi.service.ServiceContext; import fr.ird.observe.spi.usage.UsageHelper; @@ -52,10 +53,11 @@ import org.nuiton.topia.persistence.TopiaEntity; import org.nuiton.topia.persistence.TopiaException; import org.nuiton.topia.service.sql.script.DeleteReferentialScript; import org.nuiton.topia.service.sql.script.DisableReferentialScript; -import org.nuiton.topia.service.sql.script.ReplaceReferentialInReferentialScript; import org.nuiton.topia.service.sql.script.ReplaceReferentialInDataScript; +import org.nuiton.topia.service.sql.script.ReplaceReferentialInReferentialScript; import org.nuiton.topia.service.sql.script.TopiaEntitySqlScript; +import java.sql.Timestamp; import java.util.ArrayList; import java.util.Collection; import java.util.Comparator; @@ -83,23 +85,22 @@ public abstract class ReferentialDtoEntityContext< private final SingletonSupplier<ReferentialExtraScripts<E>> extraScripts; - protected abstract TopiaEntitySqlScript loadSqlScript(); - - - protected abstract ReferentialExtraScripts<E> loadExtraScripts(); - public ReferentialDtoEntityContext() { this.extraScripts = SingletonSupplier.of(this::loadExtraScripts); } + protected abstract TopiaEntitySqlScript loadSqlScript(); + + protected abstract ReferentialExtraScripts<E> loadExtraScripts(); + @Override public Form<D> loadForm(ServiceContext context, String id) { E entity = loadEntity(context, id); return referentialEntityToForm(context.getReferentialLocale(), entity); } - public SaveResultDto saveEntity(ServiceContext context, E entity, D dto) { - return saveEntity(context, entity); + public SaveResultDto saveEntity(ServiceContext context, E entity, D dto, List<SqlScript> extraScripts) { + return newSaveHelper(context).update(this, entity).addExtraSqlScripts(extraScripts).build(entity); } public Optional<ReplaceReferentialInDataScript> getReplaceInDataScript() { @@ -261,6 +262,15 @@ public abstract class ReferentialDtoEntityContext< sqlScript.ifPresent(s -> context.getTopiaPersistenceContext().executeSqlScript(s)); } + public final Optional<SqlScript> replaceReferenceScript(ServiceContext context, String idToReplace, String replaceId, boolean replaceInReferential, boolean replaceInData) { + if (!replaceInReferential && !replaceInData) { + throw new IllegalStateException("Need at least one of the parameters *replaceInReferential* or *replaceInData* to be on."); + } + checkEntityExists(context, idToReplace); + checkEntityExists(context, replaceId); + return generateReplaceScript(idToReplace, replaceId, context.now(), replaceInReferential, replaceInData); + } + public final void changeId(ServiceContext context, String id, String newId) { checkEntityExists(context, id); log.info(String.format("will change id from %s to %s", id, newId)); @@ -284,11 +294,31 @@ public abstract class ReferentialDtoEntityContext< // delete(context, id); } - public final SaveResultDto save(ServiceContext context, D dto) throws ConcurrentModificationException { + public final SaveResultDto save(ServiceContext context, D dto, ExtraSaveRequest extraSaveRequest) throws ConcurrentModificationException { E entity = loadOrCreateEntityFromReferentialDto(context, dto); checkLastUpdateDate(context, entity, dto); + // if replace id is here, let's do the replacement in data (never replace in referential) + List<SqlScript> extraScripts = new ArrayList<>(); + extraSaveRequest.getReplaceId().ifPresent(replaceId -> { + Optional<SqlScript> sqlScript = replaceReferenceScript(context, dto.getId(), replaceId, false, true); + sqlScript.ifPresent(extraScripts::add); + }); + Timestamp timestamp = context.timestampNow(); + extraSaveRequest.getToDisableIds().ifPresent(toDisableIds -> { + // if toDisableIds is here, let's do the disable actions + List<String> sqlStatements = new ArrayList<>(); + toDisableIds.forEach((k, v) -> { + ReferentialDtoEntityContext<? extends ReferentialDto, ?, ?, ?> spi2 = context.fromReferentialDto(k); + DisableReferentialScript disableScript = spi2.getDisableScript(); + v.forEach(id -> sqlStatements.addAll(disableScript.generate(id, timestamp))); + sqlStatements.addAll(spi2.updateLastUpdateDateTable(context.getTopiaPersistenceContext(), timestamp)); + }); + if (!sqlStatements.isEmpty()) { + extraScripts.add(SqlScript.of(String.join("\n", sqlStatements))); + } + }); fromDto(context.getReferentialLocale(), entity, dto); - return saveEntity(context, entity, dto); + return saveEntity(context, entity, dto, extraScripts); } private SqlScript generateDuplicateScript(ServiceContext context, String id, String newId) { @@ -357,10 +387,6 @@ public abstract class ReferentialDtoEntityContext< return toReference(context.getReferentialLocale(), entity); } - public final SaveResultDto saveEntity(ServiceContext context, E entity) { - return newSaveHelper(context).update(this, entity).build(entity); - } - public final UsageCount count(ServiceContext context, ToolkitIdDtoBean request) { ReferentialEntity entity = loadEntity(context, request.getId()); return newUsageHelper(context).count(entity); ===================================== toolkit/persistence/src/main/java/fr/ird/observe/spi/result/AddExtraSqlScripts.java ===================================== @@ -0,0 +1,43 @@ +package fr.ird.observe.spi.result; + +/*- + * #%L + * ObServe Toolkit :: Persistence + * %% + * Copyright (C) 2008 - 2023 IRD, 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 + * <http://www.gnu.org/licenses/gpl-3.0.html>. + * #L% + */ + +import io.ultreia.java4all.util.sql.SqlScript; + +import java.util.List; + +/** + * Created at 30/09/2024. + * + * @author Tony Chemit - dev@tchemit.fr + * @since 9.4.0 + */ +public interface AddExtraSqlScripts extends BuildStep { + + default AddExtraSqlScripts addExtraSqlScripts(List<SqlScript> sqlScripts) { + sqlScripts.forEach(this::addExtraSqlScript); + return this; + } + + AddExtraSqlScripts addExtraSqlScript(SqlScript sqlScript); +} ===================================== toolkit/persistence/src/main/java/fr/ird/observe/spi/result/AddUpdateLastUpdateDateTableStep.java ===================================== @@ -30,7 +30,7 @@ import fr.ird.observe.spi.context.DtoEntityContext; * @author Tony Chemit - dev@tchemit.fr * @since 6.0.4 */ -public interface AddUpdateLastUpdateDateTableStep extends BuildStep { +public interface AddUpdateLastUpdateDateTableStep extends AddExtraSqlScripts { AddUpdateLastUpdateDateTableStep updateLastUpdateDateTable(DtoEntityContext<?, ?, ?, ?> spi); } ===================================== toolkit/persistence/src/main/java/fr/ird/observe/spi/result/PersistenceResultBuilder.java ===================================== @@ -26,6 +26,7 @@ import fr.ird.observe.entities.Entity; import fr.ird.observe.entities.ToolkitTopiaPersistenceContextSupport; import fr.ird.observe.services.service.SaveResultDto; import fr.ird.observe.spi.context.DtoEntityContext; +import io.ultreia.java4all.util.sql.SqlScript; import java.util.Date; import java.util.LinkedList; @@ -41,12 +42,13 @@ import java.util.function.Supplier; * @author Tony Chemit - dev@tchemit.fr * @since 5.0.10 */ -public class PersistenceResultBuilder implements AddEntityToUpdateStep, AddUpdateLastUpdateDateFieldStep, AddUpdateLastUpdateDateTableStep, BuildStep { +public class PersistenceResultBuilder implements AddEntityToUpdateStep, AddUpdateLastUpdateDateFieldStep, AddUpdateLastUpdateDateTableStep, AddExtraSqlScripts, BuildStep { private final List<EntityContext<?>> updates; private final List<EntityContext<?>> creates; private final List<EntityContext<?>> createsReal; private final List<EntityContext<?>> lastUpdateDateFields; private final List<DtoEntityContext<?, ?, ?, ?>> lastUpdateDateTables; + private final List<SqlScript> extraScriptScripts; private final ToolkitTopiaPersistenceContextSupport persistenceContext; private final Supplier<Date> lastUpdateDateSupplier; @@ -62,6 +64,7 @@ public class PersistenceResultBuilder implements AddEntityToUpdateStep, AddUpdat this.createsReal = new LinkedList<>(); this.lastUpdateDateFields = new LinkedList<>(); this.lastUpdateDateTables = new LinkedList<>(); + this.extraScriptScripts = new LinkedList<>(); } @Override @@ -111,6 +114,12 @@ public class PersistenceResultBuilder implements AddEntityToUpdateStep, AddUpdat return this; } + @Override + public AddExtraSqlScripts addExtraSqlScript(SqlScript sqlScript) { + extraScriptScripts.add(Objects.requireNonNull(sqlScript)); + return this; + } + @Override public Date build() { Date lastUpdateDate = lastUpdateDateSupplier.get(); @@ -137,6 +146,7 @@ public class PersistenceResultBuilder implements AddEntityToUpdateStep, AddUpdat for (DtoEntityContext<?, ?, ?, ?> spi : lastUpdateDateTables) { spi.updateLastUpdateDateTable(persistenceContext, lastUpdateDate); } + extraScriptScripts.forEach(persistenceContext::executeSqlScript); return lastUpdateDate; } ===================================== toolkit/templates/src/main/java/fr/ird/observe/toolkit/templates/GenerateServices.java ===================================== @@ -24,6 +24,8 @@ package fr.ird.observe.toolkit.templates; import fr.ird.observe.toolkit.templates.services.GenerateDifferentialMetaModelClass; import fr.ird.observe.toolkit.templates.services.GenerateDifferentialMetaModelFile; +import fr.ird.observe.toolkit.templates.services.GenerateReferentialSecondLevelDeepBehaviourClass; +import fr.ird.observe.toolkit.templates.services.GenerateReferentialSecondLevelDeepBehaviourFile; import org.codehaus.plexus.component.annotations.Component; import org.nuiton.eugene.Template; @@ -38,7 +40,9 @@ public class GenerateServices extends DtoMetaTransformer { public GenerateServices() { setTemplateTypes( GenerateDifferentialMetaModelFile.class, - GenerateDifferentialMetaModelClass.class + GenerateDifferentialMetaModelClass.class, + GenerateReferentialSecondLevelDeepBehaviourFile.class, + GenerateReferentialSecondLevelDeepBehaviourClass.class ); } } ===================================== toolkit/templates/src/main/java/fr/ird/observe/toolkit/templates/ToolkitTagValues.java ===================================== @@ -145,6 +145,19 @@ public class ToolkitTagValues extends DefaultTagValueMetadatasProvider { return store.findAttributeBooleanTagValue(Store.skipCopyToEntity, clazz, attribute); } + /** + * Obtain the value of the {@link Store#referentialSecondLevelDeepBehaviour} tag value on the given classifier. + * + * @param store tag-values store + * @param clazz attribute classifier + * @return the none empty value of the found tag value or {@code null} if not found nor empty. + * @see Store#referentialSecondLevelDeepBehaviour + * @see <a href="https://gitlab.com/ultreiaio/ird-observe/-/issues/2846">issue 2846</a> + */ + public boolean isReferentialSecondLevelDeepBehaviour(ObjectModelTagValuesStore store, ObjectModelClass clazz) { + return store.findClassifierBooleanTagValue(Store.referentialSecondLevelDeepBehaviour, clazz); + } + public String notSkip(String tagValue) { return Objects.equals("skip", tagValue) ? null : tagValue; } @@ -174,6 +187,11 @@ public class ToolkitTagValues extends DefaultTagValueMetadatasProvider { form("Pour qualifier les propriétés à générer", String.class, null, ObjectModelClassifier.class, ObjectModelPackage.class), + /** + * @see <a href="https://gitlab.com/ultreiaio/ird-observe/-/issues/2846">issue 2846</a> + */ + referentialSecondLevelDeepBehaviour("Pour qualifier le comportement à utiliser pour les référentiels lors d'une suppression, désactivation ou remplacement (false = comportement par défaut, true = pour effectuer une opération en profondeur sur les référentiels utilisés de second niveau", boolean.class, "false", ObjectModelClassifier.class), + packagePriority("Pour prioriser les paquetages", int.class, null, ObjectModelPackage.class); private final Set<Class<?>> targets; ===================================== toolkit/templates/src/main/java/fr/ird/observe/toolkit/templates/services/GenerateReferentialSecondLevelDeepBehaviourClass.java ===================================== @@ -0,0 +1,54 @@ +package fr.ird.observe.toolkit.templates.services; + +/*- + * #%L + * ObServe Toolkit :: Templates + * %% + * Copyright (C) 2008 - 2024 IRD, 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 + * <http://www.gnu.org/licenses/gpl-3.0.html>. + * #L% + */ + +import fr.ird.observe.services.service.referential.ReferentialSecondLevelDeepBehaviourModel; +import fr.ird.observe.toolkit.templates.TemplateContract; +import org.nuiton.eugene.java.ObjectModelTransformerToJava; +import org.nuiton.eugene.models.object.ObjectModel; +import org.nuiton.eugene.models.object.ObjectModelClass; +import org.nuiton.eugene.models.object.ObjectModelJavaModifier; +import org.nuiton.eugene.models.object.ObjectModelOperation; + +/** + * Created at 30/09/2024. + * + * @author Tony Chemit - dev@tchemit.fr + * @since 9.4.0 + */ +public class GenerateReferentialSecondLevelDeepBehaviourClass extends ObjectModelTransformerToJava implements TemplateContract { + + @Override + public void transformFromModel(ObjectModel model) { + String packageName = getDefaultPackageName().replace(".dto", ".services.service.referential"); + String modelName = model.getName(); + ObjectModelClass modelSupport = createClass(modelName + ReferentialSecondLevelDeepBehaviourModel.class.getSimpleName(), packageName); + setSuperClass(modelSupport, ReferentialSecondLevelDeepBehaviourModel.class); + addStaticFactory(modelSupport, modelSupport.getQualifiedName()); + ObjectModelOperation constructor = addConstructor(modelSupport, ObjectModelJavaModifier.PUBLIC); + setOperationBody(constructor, ""/*{ + super("<%=modelName%>"); + }*/); + } + +} ===================================== toolkit/templates/src/main/java/fr/ird/observe/toolkit/templates/services/GenerateReferentialSecondLevelDeepBehaviourFile.java ===================================== @@ -0,0 +1,88 @@ +package fr.ird.observe.toolkit.templates.services; + +/*- + * #%L + * ObServe Toolkit :: Templates + * %% + * Copyright (C) 2008 - 2024 IRD, 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 + * <http://www.gnu.org/licenses/gpl-3.0.html>. + * #L% + */ + +import fr.ird.observe.services.service.referential.ReferentialSecondLevelDeepBehaviourModel; +import fr.ird.observe.toolkit.templates.ToolkitTagValues; +import org.nuiton.eugene.models.object.ObjectModel; +import org.nuiton.eugene.models.object.ObjectModelClass; +import org.nuiton.eugene.models.object.ObjectModelGenerator; +import org.nuiton.eugene.models.object.ObjectModelType; +import org.nuiton.topia.templates.sql.TopiaMetadataModelGeneratorSupport; + +import java.io.File; +import java.io.Writer; +import java.util.Collections; +import java.util.LinkedList; +import java.util.List; + +/** + * Created at 30/09/2024. + * + * @author Tony Chemit - dev@tchemit.fr + * @since 9.4.0 + */ +public class GenerateReferentialSecondLevelDeepBehaviourFile extends ObjectModelGenerator { + + @Override + public void applyTemplate(ObjectModel model, File destDir) { + this.model = model; + + File realTarget = TopiaMetadataModelGeneratorSupport.getNotGeneratedResourceDirector(destDir); + String filename = getFilenameForModel(model); + generateFromElement(model, realTarget, filename, ObjectModelType.OBJECT_MODEL); + } + + @Override + public String getFilenameForModel(ObjectModel model) { + return ReferentialSecondLevelDeepBehaviourModel.toLocation(super.getFilenameForModel(model)); + } + + @Override + protected void generateFromElement(Object element, File destDir, String filename, ObjectModelType type) { + if (ObjectModelType.OBJECT_MODEL != type) { + // only generate on model + return; + } + super.generateFromElement(element, destDir, filename, type); + } + + @Override + public void generateFromModel(Writer output, ObjectModel input) { + List<String> referentialTypes = new LinkedList<>(); + + ToolkitTagValues tagValues = new ToolkitTagValues(); + for (ObjectModelClass classifier : model.getClasses()) { + if (tagValues.isReferentialSecondLevelDeepBehaviour(model.getTagValuesStore(), classifier)) { + referentialTypes.add(classifier.getQualifiedName() + "Dto"); + } + } + Collections.sort(referentialTypes); + ReferentialSecondLevelDeepBehaviourModel.newGson().toJson(referentialTypes, output); + } + + @Override + protected File getDestinationFile(File destDir, String filename) { + return destDir.toPath().resolve(filename).toFile(); + } +} View it on GitLab: https://gitlab.com/ultreiaio/ird-observe/-/compare/e266bc57ca9b66cfbff708bae... -- View it on GitLab: https://gitlab.com/ultreiaio/ird-observe/-/compare/e266bc57ca9b66cfbff708bae... You're receiving this email because of your account on gitlab.com.
participants (1)
-
Tony CHEMIT (@tchemit)