Split command reader into separate commands.
[xudocci.git] / src / main / java / net / pterodactylus / xdcc / ui / stdin / Result.java
1 /*
2  * XdccDownloader - Result.java - Copyright © 2013 David Roden
3  *
4  * This program is free software: you can redistribute it and/or modify
5  * it under the terms of the GNU General Public License as published by
6  * the Free Software Foundation, either version 3 of the License, or
7  * (at your option) any later version.
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
16  */
17
18 package net.pterodactylus.xdcc.ui.stdin;
19
20 import java.util.Arrays;
21 import java.util.Comparator;
22 import java.util.List;
23 import java.util.regex.Pattern;
24
25 import net.pterodactylus.xdcc.data.Bot;
26 import net.pterodactylus.xdcc.data.Pack;
27
28 import com.google.common.base.Predicate;
29 import com.google.common.collect.ComparisonChain;
30
31 /**
32  * Container for result information.
33  *
34  * @author <a href="mailto:bombe@pterodactylus.net">David ‘Bombe’ Roden</a>
35  */
36 public class Result implements Comparable<Result> {
37
38         /** {@link Predicate} that matches {@link Result}s that contain an archive. */
39         private static final Predicate<Result> isArchive = new Predicate<Result>() {
40
41                 /** All suffixes that are recognized as archives. */
42                 private final List<String> archiveSuffixes = Arrays.asList("rar", "tar", "zip", "tar.gz", "tar.bz2", "tar.lzma", "7z");
43
44                 @Override
45                 public boolean apply(Result result) {
46                         for (String suffix : archiveSuffixes) {
47                                 if (result.pack().name().toLowerCase().endsWith(suffix)) {
48                                         return true;
49                                 }
50                         }
51                         return false;
52                 }
53         };
54
55         /**
56          * {@link Comparator} for {@link Result}s that sorts archives (as per {@link
57          * #isArchive} to the back of the list.
58          */
59         private static final Comparator<Result> packArchiveComparator = new Comparator<Result>() {
60                 @Override
61                 public int compare(Result leftResult, Result rightResult) {
62                         if (isArchive.apply(leftResult) && !isArchive.apply(rightResult)) {
63                                 return 1;
64                         }
65                         if (!isArchive.apply(leftResult) && isArchive.apply(rightResult)) {
66                                 return -1;
67                         }
68                         return 0;
69                 }
70         };
71
72         /**
73          * {@link Comparator} for bot nicknames. It comprises different strategies: one
74          * name pattern is preferred (and thus listed first), one pattern is disliked
75          * (and thus listed last), the rest is sorted alphabetically.
76          */
77         private static final Comparator<Result> botNameComparator = new Comparator<Result>() {
78
79                 /** Regular expression pattern for preferred names. */
80                 private final Pattern preferredNames = Pattern.compile("(?i)[^\\w]EUR?[^\\w]");
81
82                 /** Regular expression pattern for disliked names. */
83                 private final Pattern dislikedNames = Pattern.compile("(?i)[^\\w]USA?[^\\w]");
84
85                 @Override
86                 public int compare(Result leftResult, Result rightResult) {
87                         String leftBotName = leftResult.bot().name();
88                         String rightBotName = rightResult.bot().name();
89                         /* preferred names to the front! */
90                         if (preferredNames.matcher(leftBotName).find() && !preferredNames.matcher(rightBotName).find()) {
91                                 return -1;
92                         }
93                         if (preferredNames.matcher(rightBotName).find() && !preferredNames.matcher(leftBotName).find()) {
94                                 return 1;
95                         }
96                         /* disliked names to the back. */
97                         if (dislikedNames.matcher(leftBotName).find() && !dislikedNames.matcher(rightBotName).find()) {
98                                 return 1;
99                         }
100                         if (dislikedNames.matcher(rightBotName).find() && !dislikedNames.matcher(leftBotName).find()) {
101                                 return -1;
102                         }
103                         return 0;
104                 }
105         };
106
107         /**
108          * {@link Comparator} for {@link Result}s that sorts them by the name of the
109          * {@link Pack}.
110          */
111         private static final Comparator<Result> packNameComparator = new Comparator<Result>() {
112                 @Override
113                 public int compare(Result leftResult, Result rightResult) {
114                         return leftResult.pack().name().compareToIgnoreCase(rightResult.pack().name());
115                 }
116         };
117
118         /** The bot carrying the pack. */
119         private final Bot bot;
120
121         /** The pack. */
122         private final Pack pack;
123
124         /**
125          * Creates a new result.
126          *
127          * @param bot
128          *              The bot carrying the pack
129          * @param pack
130          *              The pack
131          */
132         Result(Bot bot, Pack pack) {
133                 this.bot = bot;
134                 this.pack = pack;
135         }
136
137         //
138         // ACCESSORS
139         //
140
141         /**
142          * Returns the bot carrying the pack.
143          *
144          * @return The bot carrying the pack
145          */
146         public Bot bot() {
147                 return bot;
148         }
149
150         /**
151          * Returns the pack.
152          *
153          * @return The pack
154          */
155         public Pack pack() {
156                 return pack;
157         }
158
159         //
160         // COMPARABLE METHODS
161         //
162
163         @Override
164         public int compareTo(Result result) {
165                 return ComparisonChain.start()
166                                 .compare(this, result, packArchiveComparator)
167                                 .compare(this, result, botNameComparator)
168                                 .compare(this, result, packNameComparator).result();
169         }
170
171 }