1 /***
2 * Ambient - A music player for the Android platform
3 Copyright (C) 2007 Martin Vysny
4
5 This program is free software: you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation, either version 3 of the License, or
8 (at your option) any later version.
9
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
14
15 You should have received a copy of the GNU General Public License
16 along with this program. If not, see <http://www.gnu.org/licenses/>.
17 */
18
19 package sk.baka.ambient.collection;
20
21 import java.io.Serializable;
22
23 import sk.baka.ambient.commons.MiscUtils;
24
25 /***
26 * A single category, may be an artist, an album or a genre.
27 *
28 * @author Martin Vysny
29 */
30 public final class CategoryItem implements Serializable {
31 private static final long serialVersionUID = -6381439171709962868L;
32 /***
33 * The collection-strategy-dependent ID, may be <code>null</code>.
34 */
35 public final Object id;
36 /***
37 * The name of the item, may be <code>null</code> if the name is missing.
38 */
39 public final String name;
40
41 /***
42 * The sort key, used for sorting the items, retrieved from the name by
43 * {@link CollectionUtils#keyFor(String)}.
44 */
45 public final String sortKey;
46
47 /***
48 * Returns displayable name (the "[empty]" string instead of
49 * <code>null</code>).
50 *
51 * @return the displayable name.
52 */
53 public String getDisplayableName() {
54 if (MiscUtils.isEmptyOrWhitespace(name)) {
55 return "[empty]";
56 }
57 return name;
58 }
59
60 /***
61 * Returns displayable year (the "[empty]" string instead of
62 * <code>null</code>).
63 *
64 * @return the displayable year.
65 */
66 public String getDisplayableYear() {
67 if (MiscUtils.isEmptyOrWhitespace(year)) {
68 return "[empty]";
69 }
70 return year;
71 }
72
73 /***
74 * In case of an album the year may be specified. <code>null</code> if not
75 * known.
76 */
77 public final String year;
78
79 /***
80 * The category of this item, must not be <code>null</code>.
81 */
82 public final CategoryEnum category;
83 /***
84 * Contains a number of albums for given artist or genre. Equals to 1 for
85 * {@link CategoryEnum#Title} and {@link CategoryEnum#Album} categories. May
86 * be -1 if not known.
87 */
88 public final int albums;
89 /***
90 * Contains a number of songs for given artist, genre or album. Equals to 1
91 * for {@link CategoryEnum#Title}. May be -1 if not known.
92 */
93 public final int songs;
94
95 /***
96 * Creates new category item instance.
97 *
98 * @param id
99 * the collection-strategy-dependent ID, may be <code>null</code>
100 *
101 * @param name
102 * the name of the item.
103 * @param year
104 * in case of an album the year may be specified.
105 * <code>null</code> if not known.
106 * @param category
107 * The category of this item, must not be <code>null</code>.
108 * @param albums
109 * Contains a number of albums for given artist or genre. Equals
110 * to 1 for {@link CategoryEnum#Title} and
111 * {@link CategoryEnum#Album} categories. May be -1 if not known.
112 * @param songs
113 * Contains a number of songs for given artist, genre or album.
114 * Equals to 1 for {@link CategoryEnum#Title}. May be -1 if not
115 * known.
116 */
117 public CategoryItem(final Object id, final String name, final String year,
118 final CategoryEnum category, final int albums, final int songs) {
119 if (category == null) {
120 throw new IllegalArgumentException("category is null");
121 }
122 this.id = id;
123 this.name = name;
124 this.sortKey = CollectionUtils.keyFor(name);
125 this.year = year;
126 this.category = category;
127 this.albums = albums;
128 this.songs = songs;
129 }
130
131 /***
132 * Builds the {@link CategoryItem}.
133 *
134 * @author Martin Vysny
135 */
136 public static class Builder {
137 /***
138 * The collection-strategy-dependent ID, may be <code>null</code>.
139 */
140 public Object id;
141 /***
142 * The name of the item, may be <code>null</code> if the name is
143 * missing.
144 */
145 public String name;
146 /***
147 * In case of an album the year may be specified. <code>null</code> if
148 * not known.
149 */
150 public String year;
151
152 /***
153 * The category of this item, must not be <code>null</code>.
154 */
155 public CategoryEnum category;
156
157 /***
158 * Contains a number of albums for given artist or genre. Equals to 1
159 * for {@link CategoryEnum#Title} and {@link CategoryEnum#Album}
160 * categories. May be -1 if not known.
161 */
162 public int albums = -1;
163 /***
164 * Contains a number of songs for given artist, genre or album. Equals
165 * to 1 for {@link CategoryEnum#Title}. May be -1 if not known.
166 */
167 public int songs = -1;
168
169 /***
170 * Builds new category item.
171 *
172 * @return the category item instance.
173 */
174 public CategoryItem build() {
175 return new CategoryItem(id, name, year, category, albums, songs);
176 }
177
178 /***
179 * Sets id.
180 *
181 * @param id
182 * The collection-strategy-dependent ID, may be
183 * <code>null</code>.
184 * @return this
185 */
186 public Builder setId(final Object id) {
187 this.id = id;
188 return this;
189 }
190
191 /***
192 * Sets name.
193 *
194 * @param name
195 * The name of the item.
196 * @return this
197 */
198 public Builder setName(final String name) {
199 this.name = name;
200 return this;
201 }
202
203 /***
204 * Sets year.
205 *
206 * @param year
207 * In case of an album the year may be specified.
208 * <code>null</code> if not known.
209 * @return this
210 */
211 public Builder setYear(final String year) {
212 this.year = year;
213 return this;
214 }
215
216 /***
217 * Sets the category.
218 *
219 * @param category
220 * The category of this item, must not be <code>null</code>.
221 * @return this
222 */
223 public Builder setCategory(final CategoryEnum category) {
224 this.category = category;
225 return this;
226 }
227
228 /***
229 * Contains a number of albums for given artist or genre. Equals to 1
230 * for {@link CategoryEnum#Title} and {@link CategoryEnum#Album}
231 * categories. May be -1 if not known.
232 *
233 * @param albums
234 * The number of albums for this item.
235 * @return this
236 */
237 public Builder setAlbums(int albums) {
238 this.albums = albums;
239 return this;
240 }
241
242 /***
243 * Contains a number of songs for given artist, genre or album. Equals
244 * to 1 for {@link CategoryEnum#Title}. May be -1 if not known.
245 *
246 * @param songs
247 * The number of songs for this item.
248 * @return this
249 */
250 public Builder setSongs(int songs) {
251 this.songs = songs;
252 return this;
253 }
254
255 /***
256 * Fills this builder with data from given item.
257 *
258 * @param item
259 * the item to read
260 * @return this
261 */
262 public Builder getData(CategoryItem item) {
263 id = item.id;
264 albums = item.albums;
265 category = item.category;
266 name = item.name;
267 songs = item.songs;
268 year = item.year;
269 return this;
270 }
271 }
272
273 @Override
274 public String toString() {
275 return id + ": " + name + (year == null ? "" : " (" + year + ")");
276 }
277
278 @Override
279 public boolean equals(Object o) {
280 if (o == this) {
281 return true;
282 }
283 if (!(o instanceof CategoryItem)) {
284 return false;
285 }
286 final CategoryItem other = (CategoryItem) o;
287 return (category == other.category)
288 && MiscUtils.nullEquals(year, other.year)
289 && MiscUtils.nullEquals(name, other.name);
290 }
291
292 @Override
293 public int hashCode() {
294 int i = category.hashCode();
295 i = i * 1001 + MiscUtils.hashCode(year);
296 i = i * 1001 + MiscUtils.hashCode(name);
297 return i;
298 }
299 }