diff --git a/lib/taskana-core/src/main/java/pro/taskana/task/internal/AttachmentMapper.java b/lib/taskana-core/src/main/java/pro/taskana/task/internal/AttachmentMapper.java index 96dffac09..241ed53b7 100644 --- a/lib/taskana-core/src/main/java/pro/taskana/task/internal/AttachmentMapper.java +++ b/lib/taskana-core/src/main/java/pro/taskana/task/internal/AttachmentMapper.java @@ -1,6 +1,7 @@ package pro.taskana.task.internal; import java.time.Instant; +import java.util.Collection; import java.util.List; import java.util.Map; import org.apache.ibatis.annotations.Delete; @@ -81,7 +82,7 @@ public interface AttachmentMapper { @Result(property = "channel", column = "CHANNEL") @Result(property = "received", column = "RECEIVED") List findAttachmentSummariesByTaskIds( - @Param("taskIds") List taskIds); + @Param("taskIds") Collection taskIds); @Delete("DELETE FROM ATTACHMENT WHERE ID=#{attachmentId}") void delete(@Param("attachmentId") String attachmentId); diff --git a/lib/taskana-core/src/main/java/pro/taskana/task/internal/TaskServiceImpl.java b/lib/taskana-core/src/main/java/pro/taskana/task/internal/TaskServiceImpl.java index 05b64fb2b..f67093918 100644 --- a/lib/taskana-core/src/main/java/pro/taskana/task/internal/TaskServiceImpl.java +++ b/lib/taskana-core/src/main/java/pro/taskana/task/internal/TaskServiceImpl.java @@ -14,6 +14,7 @@ import java.util.Map; import java.util.Objects; import java.util.Optional; import java.util.Set; +import java.util.function.Function; import java.util.function.Predicate; import java.util.stream.Collectors; import java.util.stream.Stream; @@ -312,18 +313,13 @@ public class TaskServiceImpl implements TaskService { attachmentImpls = new ArrayList<>(); } - List classifications; - classifications = findClassificationForTaskImplAndAttachments(resultTask, attachmentImpls); - List attachments = - addClassificationSummariesToAttachments(attachmentImpls, classifications); - resultTask.setAttachments(attachments); + Map classificationSummariesById = + findClassificationForTaskImplAndAttachments(resultTask, attachmentImpls); + addClassificationSummariesToAttachments(attachmentImpls, classificationSummariesById); + resultTask.setAttachments(new ArrayList<>(attachmentImpls)); String classificationId = resultTask.getClassificationSummary().getId(); - ClassificationSummary classification = - classifications.stream() - .filter(c -> c.getId().equals(classificationId)) - .findFirst() - .orElse(null); + ClassificationSummary classification = classificationSummariesById.get(classificationId); if (classification == null) { throw new SystemException( "Could not find a Classification for task " + resultTask.getId()); @@ -969,8 +965,8 @@ public class TaskServiceImpl implements TaskService { private List augmentTaskSummariesByContainedSummariesWithoutPartitioning( List taskSummaries) { - List taskIds = - taskSummaries.stream().map(TaskSummaryImpl::getId).distinct().collect(Collectors.toList()); + Set taskIds = + taskSummaries.stream().map(TaskSummaryImpl::getId).collect(Collectors.toSet()); if (taskIds.isEmpty()) { taskIds = null; @@ -982,15 +978,17 @@ public class TaskServiceImpl implements TaskService { + "about to query for attachmentSummaries ", taskSummaries); } + List attachmentSummaries = attachmentMapper.findAttachmentSummariesByTaskIds(taskIds); - - List classifications = + Map classificationSummariesById = findClassificationsForTasksAndAttachments(taskSummaries, attachmentSummaries); + Map workbasketSummariesById = findWorkbasketsForTasks(taskSummaries); - addClassificationSummariesToTaskSummaries(taskSummaries, classifications); - addWorkbasketSummariesToTaskSummaries(taskSummaries); - addAttachmentSummariesToTaskSummaries(taskSummaries, attachmentSummaries, classifications); + addClassificationSummariesToAttachments(attachmentSummaries, classificationSummariesById); + addClassificationSummariesToTaskSummaries(taskSummaries, classificationSummariesById); + addWorkbasketSummariesToTaskSummaries(taskSummaries, workbasketSummariesById); + addAttachmentSummariesToTaskSummaries(taskSummaries, attachmentSummaries); return taskSummaries; } @@ -1541,184 +1539,159 @@ public class TaskServiceImpl implements TaskService { } } - private void addClassificationSummariesToTaskSummaries( - List tasks, List classifications) { + private Map findWorkbasketsForTasks( + List taskSummaries) { + if (taskSummaries == null || taskSummaries.isEmpty()) { + return Collections.emptyMap(); + } - if (tasks == null || tasks.isEmpty()) { - return; - } - // assign query results to appropriate tasks. - for (TaskSummaryImpl task : tasks) { - String classificationId = task.getClassificationSummary().getId(); - ClassificationSummary classificationSummary = - classifications.stream() - .filter(c -> c.getId().equals(classificationId)) - .findFirst() - .orElse(null); - if (classificationSummary == null) { - throw new SystemException( - "Did not find a Classification for task (Id=" - + task.getId() - + ",classification=" - + task.getClassificationSummary().getId() - + ")"); - } - // set the classification on the task object - task.setClassificationSummary(classificationSummary); - } + Set workbasketIds = + taskSummaries.stream() + .map(TaskSummary::getWorkbasketSummary) + .map(WorkbasketSummary::getId) + .collect(Collectors.toSet()); + + return queryWorkbasketsForTasks(workbasketIds).stream() + .collect(Collectors.toMap(WorkbasketSummary::getId, Function.identity())); } - private List findClassificationsForTasksAndAttachments( - List taskSummaries, + private Map findClassificationsForTasksAndAttachments( + List taskSummaries, List attachmentSummaries) { if (taskSummaries == null || taskSummaries.isEmpty()) { - return new ArrayList<>(); + return Collections.emptyMap(); } - Set classificationIdSet = + Set classificationIds = Stream.concat( taskSummaries.stream().map(TaskSummary::getClassificationSummary), attachmentSummaries.stream().map(AttachmentSummary::getClassificationSummary)) .map(ClassificationSummary::getId) .collect(Collectors.toSet()); - return queryClassificationsForTasksAndAttachments(classificationIdSet); + return queryClassificationsForTasksAndAttachments(classificationIds).stream() + .collect(Collectors.toMap(ClassificationSummary::getId, Function.identity())); } - private List findClassificationForTaskImplAndAttachments( + private Map findClassificationForTaskImplAndAttachments( TaskImpl task, List attachmentImpls) { return findClassificationsForTasksAndAttachments( Collections.singletonList(task), attachmentImpls); } private List queryClassificationsForTasksAndAttachments( - Set classificationIdSet) { - - String[] classificationIdArray = classificationIdSet.toArray(new String[0]); + Set classificationIds) { if (LOGGER.isDebugEnabled()) { LOGGER.debug( - "getClassificationsForTasksAndAttachments() about to query classifications and exit"); + "queryClassificationsForTasksAndAttachments() about to query classifications and exit"); } - // perform classification query return this.classificationService .createClassificationQuery() - .idIn(classificationIdArray) + .idIn(classificationIds.toArray(new String[0])) .list(); } - private void addWorkbasketSummariesToTaskSummaries(List taskSummaries) { - if (taskSummaries == null || taskSummaries.isEmpty()) { + private List queryWorkbasketsForTasks(Set workbasketIds) { + + if (LOGGER.isDebugEnabled()) { + LOGGER.debug("queryWorkbasketsForTasks() about to query workbaskets and exit"); + } + // perform classification query + return this.workbasketService + .createWorkbasketQuery() + .idIn(workbasketIds.toArray(new String[0])) + .list(); + } + + private void addClassificationSummariesToTaskSummaries( + List tasks, Map classificationSummaryById) { + + if (tasks == null || tasks.isEmpty()) { return; } - // calculate parameters for workbasket query: workbasket keys - String[] workbasketIdArray = - taskSummaries.stream() - .map(t -> t.getWorkbasketSummary().getId()) - .distinct() - .toArray(String[]::new); - if (LOGGER.isDebugEnabled()) { - LOGGER.debug("addWorkbasketSummariesToTaskSummaries() about to query workbaskets"); - } - WorkbasketQueryImpl query = (WorkbasketQueryImpl) workbasketService.createWorkbasketQuery(); - query.setUsedToAugmentTasks(true); - List workbaskets = query.idIn(workbasketIdArray).list(); - Iterator taskIterator = taskSummaries.iterator(); - while (taskIterator.hasNext()) { - TaskSummaryImpl task = taskIterator.next(); - String workbasketId = task.getWorkbasketSummaryImpl().getId(); - - WorkbasketSummary workbasketSummary = - workbaskets.stream() - .filter(x -> workbasketId != null && workbasketId.equals(x.getId())) - .findFirst() - .orElse(null); - if (workbasketSummary == null) { - LOGGER.warn("Could not find a Workbasket for task {}.", task.getId()); - taskIterator.remove(); - continue; + for (TaskSummaryImpl task : tasks) { + String classificationId = task.getClassificationSummary().getId(); + ClassificationSummary classificationSummary = classificationSummaryById.get(classificationId); + if (classificationSummary == null) { + throw new SystemException( + "Did not find a Classification for task (Id=" + + task.getId() + + ",Classification=" + + task.getClassificationSummary().getId() + + ")"); } + task.setClassificationSummary(classificationSummary); + } + } + private void addWorkbasketSummariesToTaskSummaries( + List tasks, Map workbasketSummaryById) { + if (tasks == null || tasks.isEmpty()) { + return; + } + + for (TaskSummaryImpl task : tasks) { + String workbasketId = task.getWorkbasketSummary().getId(); + WorkbasketSummary workbasketSummary = workbasketSummaryById.get(workbasketId); + if (workbasketSummary == null) { + throw new SystemException( + "Did not find a Workbasket for task (Id=" + + task.getId() + + ",Workbasket=" + + task.getWorkbasketSummary().getId() + + ")"); + } task.setWorkbasketSummary(workbasketSummary); } } private void addAttachmentSummariesToTaskSummaries( - List taskSummaries, - List attachmentSummaries, - List classifications) { + List taskSummaries, List attachmentSummaries) { if (taskSummaries == null || taskSummaries.isEmpty()) { return; } - // augment attachment summaries by classification summaries - // Note: - // the mapper sets for each Attachment summary the property classificationSummary.key from the - // CLASSIFICATION_KEY property in the DB - addClassificationSummariesToAttachmentSummaries( - attachmentSummaries, taskSummaries, classifications); - // assign attachment summaries to task summaries - for (TaskSummaryImpl task : taskSummaries) { - for (AttachmentSummaryImpl attachment : attachmentSummaries) { - if (attachment.getTaskId() != null && attachment.getTaskId().equals(task.getId())) { - task.addAttachmentSummary(attachment); - } + Map taskSummariesById = + taskSummaries.stream() + .collect( + Collectors.toMap( + TaskSummary::getId, + Function.identity(), + // Currently, we still have a bug (TSK-1204), where the TaskQuery#list function + // returns the same task multiple times when that task has more than one + // attachment...Therefore, this MergeFunction is necessary. + (a, b) -> b)); + + for (AttachmentSummaryImpl attachmentSummary : attachmentSummaries) { + String taskId = attachmentSummary.getTaskId(); + TaskSummaryImpl taskSummary = taskSummariesById.get(taskId); + if (taskSummary != null) { + taskSummary.addAttachmentSummary(attachmentSummary); } } } - private void addClassificationSummariesToAttachmentSummaries( - List attachmentSummaries, - List taskSummaries, - List classifications) { - // prereq: in each attachmentSummary, the classificationSummary.key property is set. - if (attachmentSummaries == null - || attachmentSummaries.isEmpty() - || taskSummaries == null - || taskSummaries.isEmpty()) { + private void addClassificationSummariesToAttachments( + List attachments, + Map classificationSummariesById) { + + if (attachments == null || attachments.isEmpty()) { return; } - // iterate over all attachment summaries an add the appropriate classification summary to each - for (AttachmentSummaryImpl att : attachmentSummaries) { - String classificationId = att.getClassificationSummary().getId(); + + for (AttachmentSummaryImpl attachment : attachments) { + String classificationId = attachment.getClassificationSummary().getId(); ClassificationSummary classificationSummary = - classifications.stream() - .filter(x -> classificationId != null && classificationId.equals(x.getId())) - .findFirst() - .orElse(null); - if (classificationSummary == null) { - throw new SystemException("Could not find a Classification for attachment " + att); - } - att.setClassificationSummary(classificationSummary); - } - } - - private List addClassificationSummariesToAttachments( - List attachmentImpls, List classifications) { - - if (attachmentImpls == null || attachmentImpls.isEmpty()) { - return new ArrayList<>(); - } - - List result = new ArrayList<>(); - for (AttachmentImpl att : attachmentImpls) { - // find the associated task to use the correct domain - ClassificationSummary classificationSummary = - classifications.stream() - .filter(c -> c != null && c.getId().equals(att.getClassificationSummary().getId())) - .findFirst() - .orElse(null); + classificationSummariesById.get(classificationId); if (classificationSummary == null) { - throw new SystemException("Could not find a Classification for attachment " + att); + throw new SystemException("Could not find a Classification for attachment " + attachment); } - att.setClassificationSummary(classificationSummary); - result.add(att); + attachment.setClassificationSummary(classificationSummary); } - - return result; } private TaskImpl initUpdatedTask(