diff --git a/src/main/java/com/xpandit/raven/reports/traceability/bulk/BulkTraceabilityCalculatorImpl.java b/src/main/java/com/xpandit/raven/reports/traceability/bulk/BulkTraceabilityCalculatorImpl.java index ed457610b3..4d218a1c3c 100644 --- a/src/main/java/com/xpandit/raven/reports/traceability/bulk/BulkTraceabilityCalculatorImpl.java +++ b/src/main/java/com/xpandit/raven/reports/traceability/bulk/BulkTraceabilityCalculatorImpl.java @@ -211,15 +211,23 @@ public class BulkTraceabilityCalculatorImpl implements BulkTraceabilityCalculato String scopeName = params.getExecutionScope().getScopeName(); //Step 1: if hierarchical transform whole hierarchy into flat mode - Set collapsedRequirements = getAllLevelRequirements(stopWatchManager, requirements); - loadedDataStatistics.updateTotalRequirements(collapsedRequirements.size()); + Map> parentReqsSubReqsMap = getAllLevelRequirements(stopWatchManager, requirements); + Collection> values = parentReqsSubReqsMap.values(); + Set totalReqIds = + values.stream() + .flatMap(Collection::stream) + .flatMap(this::getSubReqBean) + .collect(toSet()); + + totalReqIds.addAll(parentReqsSubReqsMap.keySet()); + loadedDataStatistics.updateTotalRequirements(totalReqIds.size()); //Step 2: Create beans for each requirement, if user has permission a not allowed bean is created Map requirementBeans - = createRequirementBeans(stopWatchManager, params, collapsedRequirements, scopeName); + = createRequirementBeans(stopWatchManager, params, totalReqIds, scopeName); //Step 3: Get requirements by test - TestRequirements testRequirements = getTestsForRequirements(stopWatchManager, collapsedRequirements, params); + TestRequirements testRequirements = getTestsForRequirements(stopWatchManager, totalReqIds, params); loadedDataStatistics.updateTotalTests(testRequirements.getTests().size()); @@ -229,9 +237,8 @@ public class BulkTraceabilityCalculatorImpl implements BulkTraceabilityCalculato //Step 5: transform flat data into hierarchy again //this hierarchical processing is needed even for flat mode because, regardless of the mode, we have some hierarchy stuff to consider //namely the requirement status counts... these need to take into account the tests of the child sub-requirements - List parentRequirementIds = requirements.stream().map(Issue::getId).collect(toList()); List hierarchy = createHierarchy(stopWatchManager, - parentRequirementIds, + parentReqsSubReqsMap, requirementBeans, new HashSet<>()); @@ -635,27 +642,24 @@ public class BulkTraceabilityCalculatorImpl implements BulkTraceabilityCalculato return testRunBeanFactory.createSimplifiedTestRunTraceabilityBean(testRunAdapter, preloaded); } - private Set getAllLevelRequirements(StopWatchManager stopWatchManager, + private Map> getAllLevelRequirements(StopWatchManager stopWatchManager, Collection parentRequirements) { stopWatchManager.startStopWatchOfStep(ProcessingStep.FETCHING_REQUIREMENTS); - Map> requirementSubReqs = parentRequirements.stream() + Set parentReqIds = parentRequirements.stream() .map(Issue::getId) - .collect( - Collectors.toMap( - r -> r, - requirementService::getAllLevelSubRequirements, - (r1, r2) -> r1) - ); + .collect(toSet()); - Set reqs = requirementSubReqs.entrySet() - .stream() - .flatMap(e -> Stream.concat(Stream.of(e.getKey()), e.getValue().stream())) - .collect(Collectors.toSet()); + Set subRequirements = getSubRequirements(parentReqIds, MAX_DEFECT_TRACEABILITY_REQUIREMENT_DEPTH); + + Map> parentReqSubReqsMap = + parentReqIds.stream() + .map(parentReqId -> Pair.of(parentReqId, subRequirements.stream().filter(subReq -> subReq.getParentReqId().equals(parentReqId)).collect(toSet()))) + .collect(toMap(Pair::getLeft, Pair::getRight)); stopWatchManager.stopStopWatchOfStep(ProcessingStep.FETCHING_REQUIREMENTS); - return reqs; + return parentReqSubReqsMap; } private Map createRequirementBeans( @@ -817,12 +821,16 @@ public class BulkTraceabilityCalculatorImpl implements BulkTraceabilityCalculato private List createHierarchy( StopWatchManager stopWatchManager, - List parentRequirements, + Map> parentReqsSubReqsMap, Map requirementBeans, Set visited ) { stopWatchManager.startStopWatchOfStep(ProcessingStep.CREATING_HIERARCHY); - List hierarchy = createHierarchy(parentRequirements, + Set subRequirements = parentReqsSubReqsMap.values() + .stream() + .flatMap(Collection::stream) + .collect(toSet()); + List hierarchy = createHierarchy(parentReqsSubReqsMap.keySet(), subRequirements, requirementBeans, visited, true); @@ -831,7 +839,8 @@ public class BulkTraceabilityCalculatorImpl implements BulkTraceabilityCalculato } private List createHierarchy( - List parentRequirements, + Set parentRequirements, + Set subRequirements, Map requirementBeans, Set visited, boolean isFirstLevel @@ -855,10 +864,21 @@ public class BulkTraceabilityCalculatorImpl implements BulkTraceabilityCalculato visited.add(parent); - List subRequirements = getSubRequirements(requirementBeans, visited, parent); + Set filteredSubReqs = + subRequirements.stream() + .filter(subReq -> subReq.getParentReqId().equals(parent)) + .collect(toSet()); - List subRequirementBeans - = createHierarchy(subRequirements, requirementBeans, visited, false); + List subRequirementBeans = createHierarchy( + filteredSubReqs.stream().map(LightRequirementHelperBean::getReqId).collect(toSet()), + filteredSubReqs.stream() + .map(LightRequirementHelperBean::getSubRequirements) + .flatMap(Collection::stream) + .collect(toSet()), + requirementBeans, + visited, + false + ); parentBean.setSubRequirementsStatusBean(subRequirementBeans);