Commit | Line | Data |
---|---|---|
fd69647f NR |
1 | package be.nikiroo.fanfix.searchable; |
2 | ||
3 | import java.util.ArrayList; | |
4 | import java.util.List; | |
5 | ||
6 | /** | |
7 | * This class represents a tag that can be searched on a supported website. | |
8 | * | |
9 | * @author niki | |
10 | */ | |
11 | public class SearchableTag { | |
12 | private String id; | |
13 | private String name; | |
14 | private boolean complete; | |
15 | private long count; | |
16 | private List<SearchableTag> children; | |
17 | ||
76ec935e NR |
18 | /** |
19 | * The number of stories result pages this tag can get. | |
20 | * <p> | |
21 | * We keep more information than what the getter/setter returns/accepts. | |
22 | * <ul> | |
23 | * <li>-2: this tag does not support stories results (not a leaf tag)</li> | |
24 | * <li>-1: the number is not yet known, but will be known after a | |
25 | * {@link BasicSearchable#fillTag(SearchableTag)} operation</li> | |
26 | * <li>X: the number of pages</li> | |
27 | * </ul> | |
28 | */ | |
29 | private int pages; | |
30 | ||
fd69647f NR |
31 | /** |
32 | * Create a new {@link SearchableTag}. | |
76ec935e NR |
33 | * <p> |
34 | * Note that tags are complete by default. | |
fd69647f NR |
35 | * |
36 | * @param id | |
37 | * the ID (usually a way to find the linked stories later on) | |
38 | * @param name | |
39 | * the tag name, which can be displayed to the user | |
76ec935e NR |
40 | * @param leaf |
41 | * the tag is a leaf tag, that is, it will not return subtags | |
42 | * with {@link BasicSearchable#fillTag(SearchableTag)} but will | |
43 | * return stories with | |
44 | * {@link BasicSearchable#search(SearchableTag)} | |
45 | */ | |
46 | public SearchableTag(String id, String name, boolean leaf) { | |
47 | this(id, name, leaf, true); | |
48 | } | |
49 | ||
50 | /** | |
51 | * Create a new {@link SearchableTag}. | |
52 | * | |
53 | * @param id | |
54 | * the ID (usually a way to find the linked stories later on) | |
55 | * @param name | |
56 | * the tag name, which can be displayed to the user | |
57 | * @param leaf | |
58 | * the tag is a leaf tag, that is, it will not return subtags | |
59 | * with {@link BasicSearchable#fillTag(SearchableTag)} but will | |
60 | * return stories with | |
61 | * {@link BasicSearchable#search(SearchableTag)} | |
fd69647f | 62 | * @param complete |
76ec935e | 63 | * the tag {@link SearchableTag#isComplete()} or not |
fd69647f | 64 | */ |
76ec935e | 65 | public SearchableTag(String id, String name, boolean leaf, boolean complete) { |
fd69647f NR |
66 | this.id = id; |
67 | this.name = name; | |
68 | this.complete = complete; | |
69 | ||
76ec935e NR |
70 | setLeaf(leaf); |
71 | ||
fd69647f NR |
72 | children = new ArrayList<SearchableTag>(); |
73 | } | |
74 | ||
76ec935e NR |
75 | /** |
76 | * The ID (usually a way to find the linked stories later on). | |
77 | * | |
78 | * @return the ID | |
79 | */ | |
fd69647f NR |
80 | public String getId() { |
81 | return id; | |
82 | } | |
83 | ||
76ec935e NR |
84 | /** |
85 | * The tag name, which can be displayed to the user. | |
86 | * | |
87 | * @return then name | |
88 | */ | |
fd69647f NR |
89 | public String getName() { |
90 | return name; | |
91 | } | |
92 | ||
93 | /** | |
76ec935e NR |
94 | * Non-complete, non-leaf tags can still be completed via a |
95 | * {@link BasicSearchable#fillTag(SearchableTag)} operation from a | |
fd69647f | 96 | * {@link BasicSearchable}, in order to gain (more?) subtag children. |
76ec935e NR |
97 | * <p> |
98 | * This method does not make sense for leaf tags. | |
fd69647f | 99 | * |
76ec935e | 100 | * @return TRUE if it is complete |
fd69647f NR |
101 | */ |
102 | public boolean isComplete() { | |
103 | return complete; | |
104 | } | |
105 | ||
106 | /** | |
76ec935e NR |
107 | * Non-complete, non-leaf tags can still be completed via a |
108 | * {@link BasicSearchable#fillTag(SearchableTag)} operation from a | |
fd69647f | 109 | * {@link BasicSearchable}, in order to gain (more?) subtag children. |
76ec935e NR |
110 | * <p> |
111 | * This method does not make sense for leaf tags. | |
fd69647f NR |
112 | * |
113 | * @param complete | |
76ec935e | 114 | * TRUE if it is complete |
fd69647f NR |
115 | */ |
116 | public void setComplete(boolean complete) { | |
117 | this.complete = complete; | |
118 | } | |
119 | ||
120 | /** | |
121 | * The number of items that can be found with this tag if it is searched. | |
122 | * <p> | |
123 | * Will report the number of subtags by default. | |
124 | * | |
125 | * @return the number of items | |
126 | */ | |
127 | public long getCount() { | |
128 | long count = this.count; | |
129 | if (count <= 0) { | |
130 | count = children.size(); | |
131 | } | |
132 | ||
133 | return count; | |
134 | } | |
135 | ||
136 | /** | |
137 | * The number of items that can be found with this tag if it is searched, | |
138 | * displayable format. | |
139 | * <p> | |
140 | * Will report the number of subtags by default. | |
141 | * | |
142 | * @return the number of items | |
143 | */ | |
144 | public String getCountDisplay() { | |
145 | long count = this.count; | |
146 | if (count <= 0) { | |
147 | count = children.size(); | |
148 | } | |
149 | ||
150 | if (count > 999999) { | |
151 | return count / 1000000 + "M"; | |
152 | } | |
153 | ||
154 | if (count > 2000) { | |
155 | return count / 1000 + "k"; | |
156 | } | |
157 | ||
158 | return Long.toString(count); | |
159 | } | |
160 | ||
161 | /** | |
162 | * The number of items that can be found with this tag if it is searched. | |
163 | * | |
164 | * @param count | |
165 | * the new count | |
166 | */ | |
167 | public void setCount(long count) { | |
168 | this.count = count; | |
169 | } | |
170 | ||
76ec935e NR |
171 | /** |
172 | * The number of stories result pages this tag contains, only make sense if | |
173 | * {@link SearchableTag#isLeaf()} returns TRUE. | |
174 | * <p> | |
175 | * Will return -1 if the number is not yet known. | |
176 | * | |
177 | * @return the number of pages, or -1 | |
178 | */ | |
179 | public int getPages() { | |
180 | return Math.max(-1, pages); | |
181 | } | |
182 | ||
183 | /** | |
184 | * The number of stories result pages this tag contains, only make sense if | |
185 | * {@link SearchableTag#isLeaf()} returns TRUE. | |
186 | * | |
187 | * @param pages | |
188 | * the (positive or 0) number of pages | |
189 | */ | |
190 | public void setPages(int pages) { | |
191 | this.pages = Math.max(-1, pages); | |
192 | } | |
193 | ||
194 | /** | |
195 | * This tag is a leaf tag, that is, it will not return other subtags with | |
196 | * {@link BasicSearchable#fillTag(SearchableTag)} but will return stories | |
197 | * with {@link BasicSearchable#search(SearchableTag)}. | |
198 | * | |
199 | * @return TRUE if it is | |
200 | */ | |
201 | public boolean isLeaf() { | |
202 | return pages > -2; | |
203 | } | |
204 | ||
205 | /** | |
206 | * This tag is a leaf tag, that is, it will not return other subtags with | |
207 | * {@link BasicSearchable#fillTag(SearchableTag)} but will return stories | |
208 | * with {@link BasicSearchable#search(SearchableTag)}. | |
209 | * <p> | |
210 | * Will reset the number of pages to -1. | |
211 | * | |
212 | * @param leaf | |
213 | * TRUE if it is | |
214 | */ | |
215 | public void setLeaf(boolean leaf) { | |
216 | pages = leaf ? -1 : -2; | |
217 | } | |
218 | ||
fd69647f NR |
219 | /** |
220 | * The subtag children of this {@link SearchableTag}. | |
221 | * <p> | |
222 | * Never NULL. | |
223 | * <p> | |
224 | * Note that if {@link SearchableTag#isComplete()} returns false, you can | |
225 | * still fill (more?) subtag children with a {@link BasicSearchable}. | |
226 | * | |
227 | * @return the subtag children, never NULL | |
228 | */ | |
229 | public List<SearchableTag> getChildren() { | |
230 | return children; | |
231 | } | |
232 | ||
233 | /** | |
234 | * Add the given {@link SearchableTag} as a subtag child. | |
235 | * | |
236 | * @param tag | |
237 | * the tag to add | |
238 | */ | |
239 | public void add(SearchableTag tag) { | |
240 | children.add(tag); | |
241 | } | |
242 | ||
243 | /** | |
244 | * Display a DEBUG {@link String} representation of this object. | |
245 | */ | |
246 | @Override | |
247 | public String toString() { | |
248 | String rep = name + " [" + id + "]"; | |
249 | if (!complete) { | |
250 | rep += "*"; | |
251 | } | |
252 | ||
253 | if (getCount() > 0) { | |
254 | rep += " (" + getCountDisplay() + ")"; | |
255 | } | |
256 | ||
257 | if (!children.isEmpty()) { | |
258 | String tags = ""; | |
259 | int i = 1; | |
260 | for (SearchableTag tag : children) { | |
261 | if (!tags.isEmpty()) { | |
262 | tags += ", "; | |
263 | } | |
264 | ||
265 | if (i > 10) { | |
266 | tags += "..."; | |
267 | break; | |
268 | } | |
269 | ||
270 | tags += tag; | |
271 | i++; | |
272 | } | |
273 | ||
274 | rep += ": " + tags; | |
275 | } | |
276 | ||
277 | return rep; | |
278 | } | |
279 | } |