Rework bot sorting logic.
authorDavid ‘Bombe’ Roden <bombe@pterodactylus.net>
Tue, 21 Jan 2014 07:02:14 +0000 (08:02 +0100)
committerDavid ‘Bombe’ Roden <bombe@pterodactylus.net>
Tue, 21 Jan 2014 07:02:14 +0000 (08:02 +0100)
src/main/java/net/pterodactylus/xdcc/ui/stdin/Result.java

index b09b061..0107c6c 100644 (file)
 package net.pterodactylus.xdcc.ui.stdin;
 
 import static com.google.common.collect.FluentIterable.from;
+import static java.util.regex.Pattern.compile;
 
-import java.util.Arrays;
 import java.util.Collection;
 import java.util.Comparator;
-import java.util.List;
 import java.util.function.Predicate;
 import java.util.regex.Pattern;
 
@@ -41,74 +40,50 @@ import com.google.common.collect.ComparisonChain;
  */
 public class Result implements Comparable<Result> {
 
-       /** {@link Predicate} that matches {@link Result}s that contain an archive. */
-       private static final Predicate<Result> isArchive = new Predicate<Result>() {
-
-               /** All suffixes that are recognized as archives. */
-               private final List<String> archiveSuffixes = Arrays.asList("rar", "tar", "zip", "tar.gz", "tar.bz2", "tar.lzma", "7z");
+       private static Predicate<String> matches(String regex) {
+               Pattern pattern = compile(regex);
+               return new Predicate<String>() {
+                       @Override
+                       public boolean test(String input) {
+                               return pattern.matcher(input).find();
+                       }
+               };
+       }
 
-               @Override
-               public boolean test(Result result) {
-                       for (String suffix : archiveSuffixes) {
-                               if (result.pack().name().toLowerCase().endsWith(suffix)) {
-                                       return true;
+       private static Comparator<Result> preferredComparator(Predicate<String> preferredName, Function<Result, String> stringExtractor) {
+               return new Comparator<Result>() {
+                       @Override
+                       public int compare(Result leftResult, Result rightResult) {
+                               boolean leftStringMatches = preferredName.test(stringExtractor.apply(leftResult));
+                               boolean rightStringMatches = preferredName.test(stringExtractor.apply(rightResult));
+                               if (leftStringMatches && !rightStringMatches) {
+                                       return -1;
+                               } else if (rightStringMatches && !leftStringMatches) {
+                                       return 1;
                                }
+                               return 0;
                        }
-                       return false;
-               }
-       };
+               };
+       }
 
-       /**
-        * {@link Comparator} for {@link Result}s that sorts archives (as per {@link
-        * #isArchive} to the back of the list.
-        */
-       private static final Comparator<Result> packArchiveComparator = new Comparator<Result>() {
-               @Override
-               public int compare(Result leftResult, Result rightResult) {
-                       if (isArchive.test(leftResult) && !isArchive.test(rightResult)) {
-                               return 1;
-                       }
-                       if (!isArchive.test(leftResult) && isArchive.test(rightResult)) {
-                               return -1;
-                       }
-                       return 0;
-               }
-       };
+       /** {@link Comparator} for {@link Result}s that sorts archives to the back of the list. */
+       private static final Comparator<Result> packArchiveComparator = preferredComparator(matches("(rar|tar|zip|tar\\.(gz|bz2|lzma)|7z)$").negate(), (result) -> result.pack().name());
 
-       /**
-        * {@link Comparator} for bot nicknames. It comprises different strategies: one
-        * name pattern is preferred (and thus listed first), one pattern is disliked
-        * (and thus listed last), the rest is sorted alphabetically.
-        */
-       private static final Comparator<Result> botNameComparator = new Comparator<Result>() {
+       /** {@link Comparator} for bot nicknames. */
+       private static final Comparator<Result> botNameComparator =
+                       sortEuropeanBotsToTheFront().thenComparing(sortAmericanBotsToTheBack()).thenComparing(sortPassiveBotsToTheBack());
 
-               /** Regular expression pattern for preferred names. */
-               private final Pattern preferredNames = Pattern.compile("(?i)[^\\w]EUR?[^\\w]");
+       private static Comparator<Result> sortEuropeanBotsToTheFront() {
+               return preferredComparator(matches("(?i)[^\\w]EUR?[^\\w]"), (result) -> result.bot().name());
+       }
 
-               /** Regular expression pattern for disliked names. */
-               private final Pattern dislikedNames = Pattern.compile("(?i)[^\\w]USA?[^\\w]");
+       private static Comparator<Result> sortAmericanBotsToTheBack() {
+               return preferredComparator(matches("(?i)[^\\w]USA?[^\\w]").negate(), (result) -> result.bot().name());
+       }
 
-               @Override
-               public int compare(Result leftResult, Result rightResult) {
-                       String leftBotName = leftResult.bot().name();
-                       String rightBotName = rightResult.bot().name();
-                       /* preferred names to the front! */
-                       if (preferredNames.matcher(leftBotName).find() && !preferredNames.matcher(rightBotName).find()) {
-                               return -1;
-                       }
-                       if (preferredNames.matcher(rightBotName).find() && !preferredNames.matcher(leftBotName).find()) {
-                               return 1;
-                       }
-                       /* disliked names to the back. */
-                       if (dislikedNames.matcher(leftBotName).find() && !dislikedNames.matcher(rightBotName).find()) {
-                               return 1;
-                       }
-                       if (dislikedNames.matcher(rightBotName).find() && !dislikedNames.matcher(leftBotName).find()) {
-                               return -1;
-                       }
-                       return 0;
-               }
-       };
+       private static Comparator<Result> sortPassiveBotsToTheBack() {
+               return preferredComparator(matches("[-|]P[-|]").negate(), (result) -> result.bot().name());
+       }
 
        /**
         * {@link Comparator} for {@link Result}s that sorts them by the name of the