AssociationSearchHelper.java
package fr.avenirsesr.portfolio.association.domain.service;
import fr.avenirsesr.portfolio.association.domain.data.AssociationSearchResultData;
import fr.avenirsesr.portfolio.association.domain.model.Association;
import fr.avenirsesr.portfolio.association.domain.model.EAssociationType;
import fr.avenirsesr.portfolio.association.domain.port.input.AssociationService;
import fr.avenirsesr.portfolio.common.data.domain.model.PagedResult;
import java.util.List;
import java.util.Set;
import java.util.UUID;
import java.util.function.Function;
import java.util.function.Predicate;
import java.util.stream.Collectors;
import lombok.RequiredArgsConstructor;
@RequiredArgsConstructor
public class AssociationSearchHelper {
private final AssociationService associationService;
/**
* Shared model for searching for entities that are candidates for association
*
* @param sourceEntityId ID of the source entity (e.g., traceId, declaredActivityId)
* @param sourceEntityClass class of the source entity (e.g., Trace.class)
* @param associationType type of association being searched for
* @param associationIdExtractor extractor for the relevant ID from the association (getId1 or
* getId2)
* @param searchResults paginated results of the search for candidate entities
* @param resultIdExtractor extractor for the ID from the search result
* @param resultTitleExtractor extractor for the title from the search result
* @param resultCategoryExtractor extractor for the category (thematic, type, etc.) or null
* @param additionalDisabledCondition additional condition for disabling (e.g., activity
* completed)
* @return paginated results with the disabled flag calculated
*/
public <T> PagedResult<AssociationSearchResultData> searchForAssociation(
UUID sourceEntityId,
Class<?> sourceEntityClass,
EAssociationType associationType,
Function<Association, UUID> associationIdExtractor,
PagedResult<T> searchResults,
Function<T, UUID> resultIdExtractor,
Function<T, String> resultTitleExtractor,
Function<T, String> resultCategoryExtractor,
Predicate<T> additionalDisabledCondition) {
Set<UUID> alreadyAssociatedIds =
sourceEntityId != null
? associationService
.getAllOf(sourceEntityId, sourceEntityClass, List.of(associationType))
.stream()
.map(associationIdExtractor)
.collect(Collectors.toSet())
: Set.of();
var mappedContent =
searchResults.content().stream()
.map(
item ->
new AssociationSearchResultData(
resultIdExtractor.apply(item),
resultTitleExtractor.apply(item),
resultCategoryExtractor != null
? resultCategoryExtractor.apply(item)
: null,
alreadyAssociatedIds.contains(resultIdExtractor.apply(item))
|| additionalDisabledCondition.test(item)))
.toList();
return new PagedResult<>(mappedContent, searchResults.pageInfo());
}
}