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