cleanup
[cdmlib.git] / cdmlib-services / src / main / java / eu / etaxonomy / cdm / api / service / geo / DistributionServiceUtilities.java
index 377caf8294b8d1050d0319b551e26e900b5ae260..5bb0a8a87f19d2b4960f63a89af2cada4c5137cc 100644 (file)
@@ -142,12 +142,12 @@ public class DistributionServiceUtilities {
      *            and a {@link TaggedText} representation of the condensed distribution string.
      */
     public static CondensedDistribution getCondensedDistribution(Collection<Distribution> filteredDistributions,
-            SetMap<NamedArea, NamedArea> parentAreaMap, CondensedDistributionConfiguration config, List<Language> languages) {
+            SetMap<NamedArea,TermNode<NamedArea>> area2TermNodesMap, CondensedDistributionConfiguration config, List<Language> languages) {
 
         CondensedDistributionComposer composer = new CondensedDistributionComposer();
 
         CondensedDistribution condensedDistribution = composer.createCondensedDistribution(
-                filteredDistributions, parentAreaMap, languages, config);
+                filteredDistributions, area2TermNodesMap, languages, config);
         return condensedDistribution;
     }
 
@@ -378,8 +378,8 @@ public class DistributionServiceUtilities {
      * @param distribution
      * @param area
      */
-    private static void addAreaToLayerMap(Map<String, Map<Integer,
-            Set<Distribution>>> layerMap,
+    private static void addAreaToLayerMap(Map<String,
+            Map<Integer,Set<Distribution>>> layerMap,
             List<PresenceAbsenceTerm> statusList,
             Distribution distribution,
             NamedArea area,
@@ -541,12 +541,13 @@ public class DistributionServiceUtilities {
 
     private static void addDistributionToStyleMap(Distribution distribution, Map<Integer, Set<Distribution>> styleMap,
             List<PresenceAbsenceTerm> statusList) {
+
         PresenceAbsenceTerm status = distribution.getStatus();
         if (status != null) {
             int style = statusList.indexOf(status);
             Set<Distribution> distributionSet = styleMap.get(style);
             if (distributionSet == null) {
-                distributionSet = new HashSet<Distribution>();
+                distributionSet = new HashSet<>();
                 styleMap.put(style, distributionSet);
             }
             distributionSet.add(distribution);
@@ -701,24 +702,32 @@ public class DistributionServiceUtilities {
      * @return the filtered collection of distribution elements.
      */
     public static Set<Distribution> filterDistributions(Collection<Distribution> distributions,
-            TermTree<NamedArea> areaTree, Set<MarkerType> fallbackAreaMarkerTypes,
+            TermTree<NamedArea> areaTree, TermTree<PresenceAbsenceTerm> statusTree,
+            Set<MarkerType> fallbackAreaMarkerTypes,
             boolean preferAggregated, boolean statusOrderPreference,
-            boolean subAreaPreference, boolean keepFallBackOnlyIfNoSubareaDataExists,
-            boolean ignoreDistributionStatusUndefined) {
-
-        SetMap<NamedArea, Distribution> filteredDistributions = new SetMap<>(distributions.size());
+            boolean subAreaPreference, boolean keepFallBackOnlyIfNoSubareaDataExists) {
+
+        SetMap<NamedArea, Distribution> filteredDistributionsPerArea = new SetMap<>(distributions.size());
+        Set<UUID> statusPositiveSet = null;
+        if (statusTree != null) {
+            statusPositiveSet = new HashSet<>();
+            for (PresenceAbsenceTerm status : statusTree.asTermList()) {
+                statusPositiveSet.add(status.getUuid());
+            }
+        }
 
-        // assign distributions to the area and filter undefinedStatus
+        // assign distributions to the area and filter undefined status
         for(Distribution distribution : distributions){
             NamedArea area = distribution.getArea();
             if(area == null) {
                 logger.debug("skipping distribution with NULL area");
                 continue;
             }
-            boolean filterUndefined = ignoreDistributionStatusUndefined && distribution.getStatus() != null
-                    && distribution.getStatus().getUuid().equals(PresenceAbsenceTerm.uuidUndefined);
-            if (!filterUndefined){
-                filteredDistributions.putItem(area, distribution);
+            boolean filterOutStatus = statusPositiveSet != null &&
+                    (distribution.getStatus() == null
+                      || !statusPositiveSet.contains(distribution.getStatus().getUuid()));
+            if (!filterOutStatus){
+                filteredDistributionsPerArea.putItem(area, distribution);
             }
         }
 
@@ -732,33 +741,33 @@ public class DistributionServiceUtilities {
         //TODO since using area tree this is only relevant if keepFallBackOnlyIfNoSubareaDataExists = true
         //     as the area tree should also exclude real hidden areas
 //        if(!CdmUtils.isNullSafeEmpty(fallbackAreaMarkerTypes)) {
-            removeHiddenAndKeepFallbackAreas(areaTree, fallbackAreaMarkerTypes, filteredDistributions, keepFallBackOnlyIfNoSubareaDataExists);
+            removeHiddenAndKeepFallbackAreas(areaTree, fallbackAreaMarkerTypes, filteredDistributionsPerArea, keepFallBackOnlyIfNoSubareaDataExists);
 //        }
 
         // -------------------------------------------------------------------
         // 2) remove not computed distributions for areas for which computed
         //    distributions exists
         if(preferAggregated) {
-            handlePreferAggregated(filteredDistributions);
+            handlePreferAggregated(filteredDistributionsPerArea);
         }
 
         // -------------------------------------------------------------------
         // 3) status order preference rule
         if (statusOrderPreference) {
-            SetMap<NamedArea, Distribution> tmpMap = new SetMap<>(filteredDistributions.size());
-            for(NamedArea key : filteredDistributions.keySet()){
-                tmpMap.put(key, filterByHighestDistributionStatusForArea(filteredDistributions.get(key)));
+            SetMap<NamedArea, Distribution> tmpMap = new SetMap<>(filteredDistributionsPerArea.size());
+            for(NamedArea key : filteredDistributionsPerArea.keySet()){
+                tmpMap.put(key, filterByHighestDistributionStatusForArea(filteredDistributionsPerArea.get(key)));
             }
-            filteredDistributions = tmpMap;
+            filteredDistributionsPerArea = tmpMap;
         }
 
         // -------------------------------------------------------------------
         // 4) Sub area preference rule
         if(subAreaPreference){
-            handleSubAreaPreferenceRule(filteredDistributions, areaTree);
+            handleSubAreaPreferenceRule(filteredDistributionsPerArea, areaTree);
         }
 
-        return valuesOfAllInnerSets(filteredDistributions.values());
+        return valuesOfAllInnerSets(filteredDistributionsPerArea.values());
     }
 
     static TermTree<NamedArea> getAreaTree(Collection<Distribution> distributions,
@@ -870,21 +879,26 @@ public class DistributionServiceUtilities {
         return result;
     }
 
-
+    /**
+     * Removes all distributions that have an area being a parent of
+     * another distribution area. E.g. removes distribution for "Europe"
+     * if a distribution for "France" exists in the list, where Europe
+     * is a direct parent for France.
+     */
     private static void handleSubAreaPreferenceRule(SetMap<NamedArea, Distribution> filteredDistributions,
             TermTree<NamedArea> areaTree) {
 
-        SetMap<NamedArea, NamedArea> parentMap = areaTree.getParentMap();
+        SetMap<NamedArea, NamedArea> childToParentsMap = areaTree.getParentMap();
         Set<NamedArea> removeCandidatesArea = new HashSet<>();
         for(NamedArea area : filteredDistributions.keySet()){
             if(removeCandidatesArea.contains(area)){
                 continue;
             }
-            //xx;
-            NamedArea parent = parentMap.getFirstValue(area);
-            if(parent != null && filteredDistributions.containsKey(parent)){
-                removeCandidatesArea.add(parent);
-            }
+            childToParentsMap.get(area).forEach(parent->{
+                if(parent != null && filteredDistributions.containsKey(parent)){
+                    removeCandidatesArea.add(parent);
+                }
+            });
         }
         for(NamedArea removeKey : removeCandidatesArea){
             filteredDistributions.remove(removeKey);
@@ -1057,24 +1071,32 @@ public class DistributionServiceUtilities {
     public static DistributionTreeDto buildOrderedTreeDto(Set<NamedAreaLevel> omitLevels,
             Collection<DistributionDto> distributions,
             SetMap<NamedArea, NamedArea> parentAreaMap,
-            Set<MarkerType> fallbackAreaMarkerTypes,
+            TermTree<NamedArea> areaTree, Set<MarkerType> fallbackAreaMarkerTypes,
             Set<MarkerType> alternativeRootAreaMarkerType,
             boolean neverUseFallbackAreaAsParent,
             DistributionOrder distributionOrder,
-            IDefinedTermDao termDao) {
+            IDefinedTermDao termDao,
+            boolean useSecondMethod) {
 
         //TODO loader needed?
         DistributionTreeDtoLoader loader = new DistributionTreeDtoLoader(termDao);
-        DistributionTreeDto dto = loader.load();
+        DistributionTreeDto distributionTreeDto = loader.load();
 
         if (logger.isDebugEnabled()){logger.debug("order tree ...");}
+
         //order by areas
-        loader.orderAsTree(dto, distributions, parentAreaMap, omitLevels,
-                fallbackAreaMarkerTypes, neverUseFallbackAreaAsParent);
-        loader.handleAlternativeRootArea(dto, alternativeRootAreaMarkerType);
-        loader.recursiveSortChildren(dto, distributionOrder); // TODO respect current locale for sorting
+        if (!useSecondMethod) {
+            loader.orderAsTree(distributionTreeDto, distributions, parentAreaMap, omitLevels,
+                    fallbackAreaMarkerTypes, neverUseFallbackAreaAsParent);
+        }else {
+            loader.orderAsTree2(distributionTreeDto, distributions, areaTree, omitLevels,
+                    fallbackAreaMarkerTypes, neverUseFallbackAreaAsParent);
+        }
+        loader.handleAlternativeRootArea(distributionTreeDto, alternativeRootAreaMarkerType);
+        loader.recursiveSortChildren(distributionTreeDto, distributionOrder); // TODO respect current locale for sorting
+
         if (logger.isDebugEnabled()){logger.debug("create tree - DONE");}
-        return dto;
+        return distributionTreeDto;
     }
 
     /**