Tony CHEMIT pushed to branch develop at ultreiaio / ird-observe Commits: 2462e0f4 by Tony Chemit at 2021-01-14T18:38:54+01:00 Optimisation de l'arbre de sélection et navigation - See #1750 - - - - - 18 changed files: - client/datasource/editor/api/src/main/java/fr/ird/observe/client/datasource/editor/api/content/data/list/ContentListUINavigationInitializer.java - models/persistence/src/main/java/fr/ird/observe/entities/data/TripAwareTopiaDao.java - models/persistence/src/main/java/fr/ird/observe/entities/data/ps/observation/ActivityImpl.java - server/core/src/main/filtered-resources/mapping - services/local-impl/src/main/java/fr/ird/observe/services/local/service/actions/report/ReportServiceLocalSupport.java - services/local-impl/src/main/java/fr/ird/observe/services/local/service/data/EditableDataServiceLocalSupport.java - services/local-impl/src/main/java/fr/ird/observe/services/local/service/data/OpenableDataServiceLocalSupport.java - services/local-impl/src/main/java/fr/ird/observe/services/local/service/data/TripServiceLocalSupport.java - services/local-impl/src/main/java/fr/ird/observe/services/local/service/data/ps/observation/FloatingObjectServiceLocalSupport.java - toolkit/dto/src/main/java/fr/ird/observe/dto/reference/DtoReferenceCollection.java - toolkit/dto/src/main/java/fr/ird/observe/dto/reference/LazyDataDtoReferenceSet.java - + toolkit/dto/src/main/java/fr/ird/observe/dto/reference/UpdatedDataDtoReferenceSet.java - toolkit/persistence/src/main/java/fr/ird/observe/entities/AbstractObserveTopiaDao.java - toolkit/persistence/src/main/java/fr/ird/observe/spi/context/DataDtoEntityContext.java - toolkit/persistence/src/main/java/fr/ird/observe/spi/context/DtoEntityContextSupport.java - toolkit/persistence/src/main/java/fr/ird/observe/spi/context/ReferentialDtoEntityContext.java - toolkit/service/src/main/java/fr/ird/observe/services/service/data/OpenableDataService.java - toolkit/service/src/main/java/fr/ird/observe/spi/context/EmptyChildrenDataReferenceSet.java Changes: ===================================== client/datasource/editor/api/src/main/java/fr/ird/observe/client/datasource/editor/api/content/data/list/ContentListUINavigationInitializer.java ===================================== @@ -70,7 +70,6 @@ public class ContentListUINavigationInitializer extends NavigationInitializer<Co protected void reload(NavigationContext<ContentListUINavigationContext> context) { //FIXME Make sure we need to reload data parentReference = context.reloadReference(parentReference); - //FIXME Make this more performant: only reload references that has changed references.reload(); } ===================================== models/persistence/src/main/java/fr/ird/observe/entities/data/TripAwareTopiaDao.java ===================================== @@ -23,11 +23,15 @@ package fr.ird.observe.entities.data; */ import com.google.common.collect.ArrayListMultimap; +import com.google.common.collect.ImmutableSet; import fr.ird.observe.dto.data.DataDto; import fr.ird.observe.dto.data.TripMapConfigDto; import fr.ird.observe.dto.data.TripMapPoint; import fr.ird.observe.dto.reference.DataDtoReference; +import fr.ird.observe.entities.referential.common.Program; +import org.nuiton.topia.persistence.TopiaDao; import org.nuiton.topia.persistence.TopiaEntityEnum; +import org.nuiton.topia.persistence.TopiaQueryBuilderAddCriteriaOrRunQueryStep; import org.nuiton.topia.persistence.support.SqlFunction; import org.nuiton.topia.persistence.support.TopiaSqlSupport; @@ -35,6 +39,7 @@ import java.sql.ResultSet; import java.util.Date; import java.util.LinkedHashSet; import java.util.List; +import java.util.Map; /** * Created on 14/10/2020. @@ -42,12 +47,16 @@ import java.util.List; * @author Tony Chemit - dev@tchemit.fr * @since 8.0.1 */ -public interface TripAwareTopiaDao<D extends DataDto & fr.ird.observe.dto.data.TripAware, R extends DataDtoReference & fr.ird.observe.dto.data.TripAware, E extends DataEntity<D, R> & TripAware<D, R>> { +public interface TripAwareTopiaDao<D extends DataDto & fr.ird.observe.dto.data.TripAware, R extends DataDtoReference & fr.ird.observe.dto.data.TripAware, E extends DataEntity<D, R> & TripAware<D, R>> extends TopiaDao<E> { String GET_TRIP_IDS_BY_PROGRAM_ID = "SELECT program, topiaId FROM %S.%s t ORDER BY program"; LinkedHashSet<TripMapPoint> extractTripMapActivityPoints(TripMapConfigDto tripMapConfig); + TopiaQueryBuilderAddCriteriaOrRunQueryStep<E> forLastUpdateDateGreaterThan(Date lastUpdateDate); + + <O> List<O> findAll(String hql, Map<String, Object> hqlParameters); + List<E> getMatchingTripsVesselWithinDateRange(String id, String vesselId, Date startDate, Date endDate); void fillTripIdByProgramId(ArrayListMultimap<String, String> map); @@ -59,4 +68,15 @@ public interface TripAwareTopiaDao<D extends DataDto & fr.ird.observe.dto.data.T return null; }); } + + default List<E> getChildren(Program parent, Date lastUpdate) { + if (lastUpdate == null) { + return forProperties(TripAware.PROPERTY_PROGRAM, parent).findAll(); + } + return forLastUpdateDateGreaterThan(lastUpdate).addEquals(TripAware.PROPERTY_PROGRAM, parent).findAll(); + } + + default ImmutableSet<String> getChildrenIds(Program parent) { + return ImmutableSet.copyOf(forProperties(TripAware.PROPERTY_PROGRAM, parent).findAllIds()); + } } ===================================== models/persistence/src/main/java/fr/ird/observe/entities/data/ps/observation/ActivityImpl.java ===================================== @@ -32,6 +32,7 @@ import fr.ird.observe.dto.referential.common.SpeciesReference; import fr.ird.observe.dto.referential.ps.common.VesselActivityReference; import fr.ird.observe.entities.referential.ps.observation.ObservedSystem; +import java.util.Date; import java.util.stream.Collectors; /** @@ -105,7 +106,7 @@ public class ActivityImpl extends ActivityAbstract { public ActivityReference toReference(ReferentialLocale referentialLocale) { ActivityReference reference = super.toReference(referentialLocale); if (isFloatingObjectNotEmpty()) { - reference.setFloatingObject(FloatingObject.SPI.toReferenceSet(referentialLocale, getFloatingObject()).toList()); + reference.setFloatingObject(FloatingObject.SPI.toReferenceSet(referentialLocale, getFloatingObject(), new Date()).toList()); } return reference; } ===================================== server/core/src/main/filtered-resources/mapping ===================================== @@ -102,6 +102,7 @@ GET /api/v1/data/ll/common/TripService/exists GET /api/v1/data/ll/common/TripService/getAllTrip v1.data.ll.common.TripServiceRestApi.getAllTrip GET /api/v1/data/ll/common/TripService/getBrothers v1.data.ll.common.TripServiceRestApi.getBrothers GET /api/v1/data/ll/common/TripService/getChildren v1.data.ll.common.TripServiceRestApi.getChildren +GET /api/v1/data/ll/common/TripService/getChildrenUpdate v1.data.ll.common.TripServiceRestApi.getChildrenUpdate GET /api/v1/data/ll/common/TripService/getMatchingTripsVesselWithinDateRange v1.data.ll.common.TripServiceRestApi.getMatchingTripsVesselWithinDateRange GET /api/v1/data/ll/common/TripService/getParentBrothers v1.data.ll.common.TripServiceRestApi.getParentBrothers GET /api/v1/data/ll/common/TripService/getSpeciesByListAndTrip v1.data.ll.common.TripServiceRestApi.getSpeciesByListAndTrip @@ -116,6 +117,7 @@ DELETE /api/v1/data/ll/landing/LandingService/delete GET /api/v1/data/ll/landing/LandingService/exists v1.data.ll.landing.LandingServiceRestApi.exists GET /api/v1/data/ll/landing/LandingService/getBrothers v1.data.ll.landing.LandingServiceRestApi.getBrothers GET /api/v1/data/ll/landing/LandingService/getChildren v1.data.ll.landing.LandingServiceRestApi.getChildren +GET /api/v1/data/ll/landing/LandingService/getChildrenUpdate v1.data.ll.landing.LandingServiceRestApi.getChildrenUpdate GET /api/v1/data/ll/landing/LandingService/loadDto v1.data.ll.landing.LandingServiceRestApi.loadDto GET /api/v1/data/ll/landing/LandingService/loadForm v1.data.ll.landing.LandingServiceRestApi.loadForm GET /api/v1/data/ll/landing/LandingService/loadReferenceToRead v1.data.ll.landing.LandingServiceRestApi.loadReferenceToRead @@ -135,6 +137,7 @@ DELETE /api/v1/data/ll/logbook/ActivityService/delete GET /api/v1/data/ll/logbook/ActivityService/exists v1.data.ll.logbook.ActivityServiceRestApi.exists GET /api/v1/data/ll/logbook/ActivityService/getBrothers v1.data.ll.logbook.ActivityServiceRestApi.getBrothers GET /api/v1/data/ll/logbook/ActivityService/getChildren v1.data.ll.logbook.ActivityServiceRestApi.getChildren +GET /api/v1/data/ll/logbook/ActivityService/getChildrenUpdate v1.data.ll.logbook.ActivityServiceRestApi.getChildrenUpdate GET /api/v1/data/ll/logbook/ActivityService/loadDto v1.data.ll.logbook.ActivityServiceRestApi.loadDto GET /api/v1/data/ll/logbook/ActivityService/loadForm v1.data.ll.logbook.ActivityServiceRestApi.loadForm GET /api/v1/data/ll/logbook/ActivityService/loadReferenceToRead v1.data.ll.logbook.ActivityServiceRestApi.loadReferenceToRead @@ -145,6 +148,7 @@ DELETE /api/v1/data/ll/logbook/SampleService/delete GET /api/v1/data/ll/logbook/SampleService/exists v1.data.ll.logbook.SampleServiceRestApi.exists GET /api/v1/data/ll/logbook/SampleService/getBrothers v1.data.ll.logbook.SampleServiceRestApi.getBrothers GET /api/v1/data/ll/logbook/SampleService/getChildren v1.data.ll.logbook.SampleServiceRestApi.getChildren +GET /api/v1/data/ll/logbook/SampleService/getChildrenUpdate v1.data.ll.logbook.SampleServiceRestApi.getChildrenUpdate GET /api/v1/data/ll/logbook/SampleService/loadDto v1.data.ll.logbook.SampleServiceRestApi.loadDto GET /api/v1/data/ll/logbook/SampleService/loadForm v1.data.ll.logbook.SampleServiceRestApi.loadForm GET /api/v1/data/ll/logbook/SampleService/loadReferenceToRead v1.data.ll.logbook.SampleServiceRestApi.loadReferenceToRead @@ -171,6 +175,7 @@ DELETE /api/v1/data/ll/observation/ActivityService/delete GET /api/v1/data/ll/observation/ActivityService/exists v1.data.ll.observation.ActivityServiceRestApi.exists GET /api/v1/data/ll/observation/ActivityService/getBrothers v1.data.ll.observation.ActivityServiceRestApi.getBrothers GET /api/v1/data/ll/observation/ActivityService/getChildren v1.data.ll.observation.ActivityServiceRestApi.getChildren +GET /api/v1/data/ll/observation/ActivityService/getChildrenUpdate v1.data.ll.observation.ActivityServiceRestApi.getChildrenUpdate GET /api/v1/data/ll/observation/ActivityService/loadDto v1.data.ll.observation.ActivityServiceRestApi.loadDto GET /api/v1/data/ll/observation/ActivityService/loadForm v1.data.ll.observation.ActivityServiceRestApi.loadForm GET /api/v1/data/ll/observation/ActivityService/loadReferenceToRead v1.data.ll.observation.ActivityServiceRestApi.loadReferenceToRead @@ -204,6 +209,7 @@ GET /api/v1/data/ps/common/TripService/exists GET /api/v1/data/ps/common/TripService/getAllTrip v1.data.ps.common.TripServiceRestApi.getAllTrip GET /api/v1/data/ps/common/TripService/getBrothers v1.data.ps.common.TripServiceRestApi.getBrothers GET /api/v1/data/ps/common/TripService/getChildren v1.data.ps.common.TripServiceRestApi.getChildren +GET /api/v1/data/ps/common/TripService/getChildrenUpdate v1.data.ps.common.TripServiceRestApi.getChildrenUpdate GET /api/v1/data/ps/common/TripService/getMatchingTripsVesselWithinDateRange v1.data.ps.common.TripServiceRestApi.getMatchingTripsVesselWithinDateRange GET /api/v1/data/ps/common/TripService/getParentBrothers v1.data.ps.common.TripServiceRestApi.getParentBrothers GET /api/v1/data/ps/common/TripService/getSpeciesByListAndTrip v1.data.ps.common.TripServiceRestApi.getSpeciesByListAndTrip @@ -218,6 +224,7 @@ DELETE /api/v1/data/ps/observation/ActivityService/delete GET /api/v1/data/ps/observation/ActivityService/exists v1.data.ps.observation.ActivityServiceRestApi.exists GET /api/v1/data/ps/observation/ActivityService/getBrothers v1.data.ps.observation.ActivityServiceRestApi.getBrothers GET /api/v1/data/ps/observation/ActivityService/getChildren v1.data.ps.observation.ActivityServiceRestApi.getChildren +GET /api/v1/data/ps/observation/ActivityService/getChildrenUpdate v1.data.ps.observation.ActivityServiceRestApi.getChildrenUpdate GET /api/v1/data/ps/observation/ActivityService/loadDto v1.data.ps.observation.ActivityServiceRestApi.loadDto GET /api/v1/data/ps/observation/ActivityService/loadForm v1.data.ps.observation.ActivityServiceRestApi.loadForm GET /api/v1/data/ps/observation/ActivityService/loadReferenceToRead v1.data.ps.observation.ActivityServiceRestApi.loadReferenceToRead @@ -248,6 +255,7 @@ DELETE /api/v1/data/ps/observation/RouteService/delete GET /api/v1/data/ps/observation/RouteService/exists v1.data.ps.observation.RouteServiceRestApi.exists GET /api/v1/data/ps/observation/RouteService/getBrothers v1.data.ps.observation.RouteServiceRestApi.getBrothers GET /api/v1/data/ps/observation/RouteService/getChildren v1.data.ps.observation.RouteServiceRestApi.getChildren +GET /api/v1/data/ps/observation/RouteService/getChildrenUpdate v1.data.ps.observation.RouteServiceRestApi.getChildrenUpdate GET /api/v1/data/ps/observation/RouteService/isActivityEndOfSearchFound v1.data.ps.observation.RouteServiceRestApi.isActivityEndOfSearchFound GET /api/v1/data/ps/observation/RouteService/loadDto v1.data.ps.observation.RouteServiceRestApi.loadDto GET /api/v1/data/ps/observation/RouteService/loadForm v1.data.ps.observation.RouteServiceRestApi.loadForm ===================================== services/local-impl/src/main/java/fr/ird/observe/services/local/service/actions/report/ReportServiceLocalSupport.java ===================================== @@ -34,7 +34,7 @@ import fr.ird.observe.dto.report.Report; import fr.ird.observe.dto.report.ReportOperation; import fr.ird.observe.dto.report.ReportRequest; import fr.ird.observe.dto.report.ReportVariable; -import fr.ird.observe.entities.AbstractObserveTopiaDao; +import fr.ird.observe.entities.data.TripAwareTopiaDao; import fr.ird.observe.entities.data.ll.common.GearUseFeatures; import fr.ird.observe.entities.data.ll.common.GearUseFeaturesMeasurement; import fr.ird.observe.entities.data.ps.common.Trip; @@ -485,9 +485,9 @@ public class ReportServiceLocalSupport extends ObserveServiceLocal implements Re paramsFixes.put(name, value); } } - AbstractObserveTopiaDao<?> dao = (AbstractObserveTopiaDao<?>) getTopiaPersistenceContext().getDao(Trip.class); + TripAwareTopiaDao<?, ?, ?> dao = (TripAwareTopiaDao<?, ?, ?>) getTopiaPersistenceContext().getDao(Trip.class); log.debug(String.format("Request: %s, params: %s", request, paramsFixes)); - return dao.findAllFromHql(request, paramsFixes); + return dao.findAll(request, paramsFixes); } private void doPopulateRepeatVariables(Report report, ImmutableSet<String> tripId) { ===================================== services/local-impl/src/main/java/fr/ird/observe/services/local/service/data/EditableDataServiceLocalSupport.java ===================================== @@ -120,10 +120,6 @@ public abstract class EditableDataServiceLocalSupport<PE extends Entity, D exten return spi.newEntity(now()); } - protected DataDtoReferenceSet<R> toReferenceSet(Collection<E> entities) { - return spi.toReferenceSet(getReferentialLocale(), entities); - } - protected DataDtoReferenceSet<R> toReferenceSet(Collection<E> entities, Date now) { return spi.toReferenceSet(getReferentialLocale(), entities, now); } ===================================== services/local-impl/src/main/java/fr/ird/observe/services/local/service/data/OpenableDataServiceLocalSupport.java ===================================== @@ -27,6 +27,7 @@ import fr.ird.observe.dto.data.OpenableDto; import fr.ird.observe.dto.form.Form; import fr.ird.observe.dto.reference.DataDtoReference; import fr.ird.observe.dto.reference.DataDtoReferenceSet; +import fr.ird.observe.dto.reference.UpdatedDataDtoReferenceSet; import fr.ird.observe.dto.result.SaveResultDto; import fr.ird.observe.entities.Entity; import fr.ird.observe.entities.ObserveTopiaPersistenceContext; @@ -36,9 +37,11 @@ import fr.ird.observe.services.service.data.OpenableDataService; import fr.ird.observe.spi.context.DataDtoEntityContext; import fr.ird.observe.spi.context.DtoEntityContext; import org.nuiton.topia.persistence.TopiaDao; +import org.nuiton.topia.persistence.TopiaEntity; import java.util.Collection; import java.util.Date; +import java.util.stream.Collectors; import java.util.stream.Stream; /** @@ -72,6 +75,14 @@ public abstract class OpenableDataServiceLocalSupport<PE extends Entity, D exten return getChildren(parent); } + @Override + public UpdatedDataDtoReferenceSet<R> getChildrenUpdate(String parentId, Date lastUpdate) { + PE parent = loadParentEntity(parentId); + ImmutableSet<String> allIds = getChildrenIds(parent); + Collection<E> children0 = getChildren0(parent, lastUpdate); + return new UpdatedDataDtoReferenceSet<R>(allIds, toReferenceSet(children0, now())); + } + @Override public DataDtoReferenceSet<R> getBrothers(String id) { return getBrothers(parentSpi, propertyName, spi, id); @@ -105,7 +116,7 @@ public abstract class OpenableDataServiceLocalSupport<PE extends Entity, D exten @Override public void move(String newParentId, ImmutableSet<String> ids) { PE parent = loadParentEntity(newParentId); - Collection<E> collection = parent.get(propertyName); + Collection<E> collection = getChildren0(parent, null); for (String id : ids) { E entity = loadEntity(id); collection.add(entity); @@ -142,10 +153,6 @@ public abstract class OpenableDataServiceLocalSupport<PE extends Entity, D exten return spi.newEntity(now()); } - protected DataDtoReferenceSet<R> toReferenceSet(Collection<E> entities) { - return spi.toReferenceSet(getReferentialLocale(), entities); - } - protected DataDtoReferenceSet<R> toReferenceSet(Collection<E> entities, Date now) { return spi.toReferenceSet(getReferentialLocale(), entities, now); } @@ -182,9 +189,22 @@ public abstract class OpenableDataServiceLocalSupport<PE extends Entity, D exten return spi.loadEntity(getApplicationLocale(), getTopiaPersistenceContext(), id); } - protected DataDtoReferenceSet<R> getChildren(PE parent) { - Collection<E> parents = parent.get(propertyName); - return spi.toReferenceSet(getReferentialLocale(), parents); + protected final DataDtoReferenceSet<R> getChildren(PE parent) { + Collection<E> parents = getChildren0(parent, null); + return spi.toReferenceSet(getReferentialLocale(), parents, now()); + } + + protected Collection<E> getChildren0(PE parent, Date lastUpdate) { + Collection<E> collection = parent.get(propertyName); + if (lastUpdate != null) { + collection = collection.stream().filter(e -> e.getLastUpdateDate().after(lastUpdate)).collect(Collectors.toList()); + } + return collection; + } + + protected ImmutableSet<String> getChildrenIds(PE parent) { + Collection<E> collection = getChildren0(parent, null); + return collection.stream().map(TopiaEntity::getTopiaId).collect(ImmutableSet.toImmutableSet()); } protected PE getParent(String id) { ===================================== services/local-impl/src/main/java/fr/ird/observe/services/local/service/data/TripServiceLocalSupport.java ===================================== @@ -50,6 +50,7 @@ import org.nuiton.topia.persistence.script.SqlScriptConsumer; import org.nuiton.topia.persistence.script.TopiaSqlScript; import org.nuiton.util.DateUtil; +import java.util.Collection; import java.util.Comparator; import java.util.Date; import java.util.LinkedHashSet; @@ -71,7 +72,7 @@ public abstract class TripServiceLocalSupport<D extends OpenableDto & fr.ird.obs } @Override - public void setServiceContext(ObserveServiceContextLocal serviceContext) { + public final void setServiceContext(ObserveServiceContextLocal serviceContext) { super.setServiceContext(serviceContext); sqlScriptProducerService = serviceContext.newService(SqlScriptProducerService.class); } @@ -86,16 +87,10 @@ public abstract class TripServiceLocalSupport<D extends OpenableDto & fr.ird.obs return getProgramBrothers(parentSpi, programId); } - @Override - protected DataDtoReferenceSet<R> getChildren(Program parent) { - List<E> entities = getDao().forEquals(TripAware.PROPERTY_PROGRAM, parent).findAll(); - return toReferenceSet(entities); - } - @Override public ImmutableSet<R> getMatchingTripsVesselWithinDateRange(String tripId, String vesselId, Date startDate, Date endDate) { List<E> trips = getDao().getMatchingTripsVesselWithinDateRange(tripId, vesselId, startDate, endDate); - return toReferenceSet(trips).toSet(); + return toReferenceSet(trips, now()).toSet(); } @Override @@ -157,10 +152,20 @@ public abstract class TripServiceLocalSupport<D extends OpenableDto & fr.ird.obs } @Override - protected SaveResultDto onSave(Program parent, E entity, D dto) { + protected final SaveResultDto onSave(Program parent, E entity, D dto) { if (entity.isPersisted()) { entity.updateEndDate(); } return saveEntity(entity); } + + @Override + protected final Collection<E> getChildren0(Program parent, Date lastUpdate) { + return getDao().getChildren(parent, lastUpdate); + } + + @Override + protected final ImmutableSet<String> getChildrenIds(Program parent) { + return getDao().getChildrenIds(parent); + } } ===================================== services/local-impl/src/main/java/fr/ird/observe/services/local/service/data/ps/observation/FloatingObjectServiceLocalSupport.java ===================================== @@ -89,7 +89,7 @@ class FloatingObjectServiceLocalSupport extends EditableDataServiceLocalSupport< @Override public DataDtoReferenceSet<FloatingObjectReference> getChildren(String activityId) { Set<FloatingObject> entities = loadParentEntity(activityId).getFloatingObject(); - return toReferenceSet(entities); + return toReferenceSet(entities, now()); } @Override ===================================== toolkit/dto/src/main/java/fr/ird/observe/dto/reference/DtoReferenceCollection.java ===================================== @@ -102,6 +102,10 @@ public abstract class DtoReferenceCollection<R extends DtoReference> implements return stream().filter(id -> idsList.contains(id.getId())); } + public Stream<R> subSet(Collection<String> ids) { + return stream().filter(id -> ids.contains(id.getId())); + } + public ImmutableSet<R> toSet() { return ImmutableSet.copyOf(references); } ===================================== toolkit/dto/src/main/java/fr/ird/observe/dto/reference/LazyDataDtoReferenceSet.java ===================================== @@ -56,15 +56,15 @@ public abstract class LazyDataDtoReferenceSet<R extends DataDtoReference> implem } public final DataDtoReferenceSet<R> reload() { - clear(); + createDelegate(); return get(); } - public void clear() { - delegate = null; - } - public final Class<R> getReferenceType() { return referenceType; } + + protected DataDtoReferenceSet<R> getDelegate() { + return delegate; + } } ===================================== toolkit/dto/src/main/java/fr/ird/observe/dto/reference/UpdatedDataDtoReferenceSet.java ===================================== @@ -0,0 +1,65 @@ +package fr.ird.observe.dto.reference; + +/*- + * #%L + * ObServe Toolkit :: Dto + * %% + * Copyright (C) 2008 - 2021 IRD, Code Lutin, 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.common.collect.ImmutableSet; +import fr.ird.observe.dto.ObserveDto; + +import java.util.LinkedHashSet; +import java.util.List; +import java.util.Objects; +import java.util.Set; +import java.util.stream.Collectors; + +/** + * Created on 14/01/2021. + * + * @author Tony Chemit - dev@tchemit.fr + * @since 8.0.3 + */ +public class UpdatedDataDtoReferenceSet<R extends DataDtoReference> implements ObserveDto { + + private final ImmutableSet<String> allIds; + private final DataDtoReferenceSet<R> updatedReferences; + + public UpdatedDataDtoReferenceSet(ImmutableSet<String> allIds, DataDtoReferenceSet<R> updatedReferences) { + this.allIds = Objects.requireNonNull(allIds); + this.updatedReferences = Objects.requireNonNull(updatedReferences); + } + + public ImmutableSet<String> getAllIds() { + return allIds; + } + + public DataDtoReferenceSet<R> getUpdatedReferences() { + return updatedReferences; + } + + public DataDtoReferenceSet<R> mergeTo(DataDtoReferenceSet<R> incoming) { + Set<String> previousIdsToKeep = new LinkedHashSet<>(getAllIds()); + previousIdsToKeep.removeAll(updatedReferences.toIds()); + List<R> collect = incoming.subSet(previousIdsToKeep).collect(Collectors.toList()); + collect.addAll(getUpdatedReferences().toArrayList()); + return DataDtoReferenceSet.of(incoming.getType(), collect, getUpdatedReferences().getLastUpdate()); + } +} ===================================== toolkit/persistence/src/main/java/fr/ird/observe/entities/AbstractObserveTopiaDao.java ===================================== @@ -22,50 +22,28 @@ package fr.ird.observe.entities; * #L% */ +import fr.ird.observe.dto.IdDto; +import org.nuiton.topia.persistence.HqlAndParametersBuilder; +import org.nuiton.topia.persistence.TopiaQueryBuilderAddCriteriaOrRunQueryStep; import org.nuiton.topia.persistence.internal.AbstractTopiaDao; -import org.nuiton.topia.persistence.support.TopiaSqlQuery; -import java.sql.Connection; -import java.sql.PreparedStatement; -import java.sql.ResultSet; -import java.sql.SQLException; -import java.sql.Timestamp; +import java.util.Date; import java.util.List; import java.util.Map; public abstract class AbstractObserveTopiaDao<E extends Entity> extends AbstractTopiaDao<E> { - private final GetLastUpdateDateSqlQuery getLastUpdateDateSqlQuery; + public TopiaQueryBuilderAddCriteriaOrRunQueryStep<E> forLastUpdateDateGreaterThan(Date lastUpdateDate) { + HqlAndParametersBuilder<E> hqlAndParametersBuilder = newHqlAndParametersBuilder(); + hqlAndParametersBuilder.addGreaterThan(IdDto.PROPERTY_LAST_UPDATE_DATE, lastUpdateDate); + return new InnerTopiaQueryBuilderAddCriteriaOrRunQueryStep<>(this, hqlAndParametersBuilder) { - protected AbstractObserveTopiaDao() { - String schemaName = getTopiaEntityEnum().dbSchemaName(); - String tableName = getTopiaEntityEnum().dbTableName(); - getLastUpdateDateSqlQuery = new GetLastUpdateDateSqlQuery(schemaName, tableName); + }; } - private static class GetLastUpdateDateSqlQuery extends TopiaSqlQuery<Timestamp> { - - protected final String sql; - - private GetLastUpdateDateSqlQuery(String schemaName, String tableName) { - this.sql = "SELECT max(" + Entity.PROPERTY_LAST_UPDATE_DATE + ") FROM " + schemaName + "." + tableName; - } - - @Override - public PreparedStatement prepareQuery(Connection connection) throws SQLException { - return connection.prepareStatement(sql); - } - - @Override - public Timestamp prepareResult(ResultSet set) throws SQLException { - return set.getTimestamp(1); - } - - } - - public <O> List<O> findAllFromHql(String hql, Map<String, Object> hqlParameters) { - return findAll(hql, hqlParameters); + @Override + public <O> List<O> findAll(String hql, Map<String, Object> hqlParameters) { + return super.findAll(hql, hqlParameters); } - } ===================================== toolkit/persistence/src/main/java/fr/ird/observe/spi/context/DataDtoEntityContext.java ===================================== @@ -51,11 +51,6 @@ public class DataDtoEntityContext<D extends DataDto, R extends DataDtoReference, super(dtoType, referenceType, entityType, entityTypeImpl, daoFunction); } - @Override - public DataDtoReferenceSet<R> toReferenceSet(ReferentialLocale referentialLocale, Collection<E> entities) { - return (DataDtoReferenceSet<R>) super.toReferenceSet(referentialLocale, entities); - } - @Override public DataDtoReferenceSet<R> toReferenceSet(ReferentialLocale referentialLocale, Collection<E> entities, Date now) { return (DataDtoReferenceSet<R>) super.toReferenceSet(referentialLocale, entities.stream(), now); ===================================== toolkit/persistence/src/main/java/fr/ird/observe/spi/context/DtoEntityContextSupport.java ===================================== @@ -75,15 +75,6 @@ public abstract class DtoEntityContextSupport<D extends IdDto, R extends DtoRefe protected abstract void fromDto(ReferentialLocale referentialLocale, E entity, D dto); - protected DtoReferenceCollection<R> toReferenceSet(ReferentialLocale referentialLocale, Collection<E> entities) { - ImmutableSet.Builder<R> references = ImmutableSet.builder(); - for (E entity : entities) { - @SuppressWarnings("unchecked") R reference = ((EntityToDto<?, R>) entity).toReference(referentialLocale); - references.add(reference); - } - return createReferenceSet(referentialLocale, references.build(), null); - } - @Override public UpdateLastUpdateDateFieldScript getUpdateLastUpdateDateFieldScript() { return updateLastUpdateDateFieldScript; ===================================== toolkit/persistence/src/main/java/fr/ird/observe/spi/context/ReferentialDtoEntityContext.java ===================================== @@ -50,11 +50,6 @@ public class ReferentialDtoEntityContext<D extends ReferentialDto, R extends Ref super(dtoType, referenceType, entityType, entityTypeImpl, daoFunction); } - @Override - public ReferentialDtoReferenceSet<R> toReferenceSet(ReferentialLocale referentialLocale, Collection<E> entities) { - return (ReferentialDtoReferenceSet<R>) super.toReferenceSet(referentialLocale, entities); - } - @Override public ReferentialDtoReferenceSet<R> toReferenceSet(ReferentialLocale referentialLocale, Collection<E> entities, Date now) { return (ReferentialDtoReferenceSet<R>) super.toReferenceSet(referentialLocale, entities, now); ===================================== toolkit/service/src/main/java/fr/ird/observe/services/service/data/OpenableDataService.java ===================================== @@ -27,6 +27,7 @@ import fr.ird.observe.dto.data.DataDto; import fr.ird.observe.dto.form.Form; import fr.ird.observe.dto.reference.DataDtoReference; import fr.ird.observe.dto.reference.DataDtoReferenceSet; +import fr.ird.observe.dto.reference.UpdatedDataDtoReferenceSet; import fr.ird.observe.dto.result.SaveResultDto; import fr.ird.observe.security.Permission; import fr.ird.observe.services.service.ObserveService; @@ -37,6 +38,8 @@ import io.ultreia.java4all.http.spi.Get; import io.ultreia.java4all.http.spi.Internal; import io.ultreia.java4all.http.spi.Post; +import java.util.Date; + /** * Created on 13/10/2020. * @@ -50,6 +53,10 @@ public interface OpenableDataService<D extends DataDto, R extends DataDtoReferen @MethodCredential(Permission.READ_DATA) DataDtoReferenceSet<R> getChildren(String parentId); + @Get + @MethodCredential(Permission.READ_DATA) + UpdatedDataDtoReferenceSet<R> getChildrenUpdate(String parentId, Date lastUpdate); + @Get @MethodCredential(Permission.READ_DATA) DataDtoReferenceSet<R> getBrothers(String id); ===================================== toolkit/service/src/main/java/fr/ird/observe/spi/context/EmptyChildrenDataReferenceSet.java ===================================== @@ -26,6 +26,8 @@ import fr.ird.observe.dto.decoration.DecoratorServiceSupport; import fr.ird.observe.dto.reference.DataDtoReference; import fr.ird.observe.dto.reference.DataDtoReferenceSet; import fr.ird.observe.dto.reference.LazyDataDtoReferenceSet; +import fr.ird.observe.dto.reference.UpdatedDataDtoReferenceSet; +import fr.ird.observe.services.service.data.OpenableDataService; import fr.ird.observe.spi.ServicesProvider; import java.util.Comparator; @@ -59,7 +61,18 @@ public class EmptyChildrenDataReferenceSet<R extends DataDtoReference> extends L @Override protected DataDtoReferenceSet<R> createDelegate() { - DataDtoReferenceSet<R> result = spi.getService(servicesProvider).getChildren(parentId); + DataDtoReferenceSet<R> previousResult = getDelegate(); + DataDtoReferenceSet<R> result; + OpenableDataService<?, R> service = spi.getService(servicesProvider); + if (previousResult == null) { + // first time load all data + result = service.getChildren(parentId); + } else { + // ask an update of data + UpdatedDataDtoReferenceSet<R> updateResult = service.getChildrenUpdate(parentId, previousResult.getLastUpdate()); + // merge it with previous data + result = updateResult.mergeTo(previousResult); + } result.sort(spi.getReferenceComparator()); decoratorService.installDecorator(result); return result; View it on GitLab: https://gitlab.com/ultreiaio/ird-observe/-/commit/2462e0f4bd8e53079c81533c85... -- View it on GitLab: https://gitlab.com/ultreiaio/ird-observe/-/commit/2462e0f4bd8e53079c81533c85... You're receiving this email because of your account on gitlab.com.