Don’t implement equals() without hashCode()!
[Sone.git] / src / main / java / net / pterodactylus / sone / data / Album.java
1 /*
2  * Sone - Album.java - Copyright © 2011 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.sone.data;
19
20 import java.util.ArrayList;
21 import java.util.List;
22 import java.util.UUID;
23
24 import net.pterodactylus.util.validation.Validation;
25
26 /**
27  * Container for images that can also contain nested {@link Album}s.
28  *
29  * @author <a href="mailto:bombe@pterodactylus.net">David ‘Bombe’ Roden</a>
30  */
31 public class Album implements Fingerprintable {
32
33         /** The ID of this album. */
34         private final String id;
35
36         /** The Sone this album belongs to. */
37         private Sone sone;
38
39         /** Nested albums. */
40         private final List<Album> albums = new ArrayList<Album>();
41
42         /** The images in this album. */
43         private final List<Image> images = new ArrayList<Image>();
44
45         /** The parent album. */
46         private Album parent;
47
48         /** The name of this album. */
49         private String name;
50
51         /** The description of this album. */
52         private String description;
53
54         /** The index of the album picture. */
55         private int albumImage = -1;
56
57         /**
58          * Creates a new album with a random ID.
59          */
60         public Album() {
61                 this(UUID.randomUUID().toString());
62         }
63
64         /**
65          * Creates a new album with the given ID.
66          *
67          * @param id
68          *            The ID of the album
69          */
70         public Album(String id) {
71                 Validation.begin().isNotNull("Album ID", id).check();
72                 this.id = id;
73         }
74
75         //
76         // ACCESSORS
77         //
78
79         /**
80          * Returns the ID of this album.
81          *
82          * @return The ID of this album
83          */
84         public String getId() {
85                 return id;
86         }
87
88         /**
89          * Returns the Sone this album belongs to.
90          *
91          * @return The Sone this album belongs to
92          */
93         public Sone getSone() {
94                 return sone;
95         }
96
97         /**
98          * Sets the owner of the album. The owner can only be set as long as the
99          * current owner is {@code null}.
100          *
101          * @param sone
102          *            The album owner
103          * @return This album
104          */
105         public Album setSone(Sone sone) {
106                 Validation.begin().isNull("Current Album Owner", this.sone).isNotNull("New Album Owner", sone).check();
107                 this.sone = sone;
108                 return this;
109         }
110
111         /**
112          * Returns the nested albums.
113          *
114          * @return The nested albums
115          */
116         public List<Album> getAlbums() {
117                 return new ArrayList<Album>(albums);
118         }
119
120         /**
121          * Adds an album to this album.
122          *
123          * @param album
124          *            The album to add
125          */
126         public void addAlbum(Album album) {
127                 Validation.begin().isNotNull("Album", album).check().isEqual("Album Owner", album.sone, sone).isNull("Album Parent", album.parent).check();
128                 albums.add(album);
129                 album.setParent(this);
130         }
131
132         /**
133          * Removes an album from this album.
134          *
135          * @param album
136          *            The album to remove
137          */
138         public void removeAlbum(Album album) {
139                 Validation.begin().isNotNull("Album", album).check().isEqual("Album Owner", album.sone, sone).isEqual("Album Parent", album.parent, this).check();
140                 albums.remove(album);
141                 album.removeParent();
142         }
143
144         /**
145          * Returns the images in this album.
146          *
147          * @return The images in this album
148          */
149         public List<Image> getImages() {
150                 return new ArrayList<Image>(images);
151         }
152
153         /**
154          * Adds the given image to this album.
155          *
156          * @param image
157          *            The image to add
158          */
159         public void addImage(Image image) {
160                 Validation.begin().isNotNull("Image", image).check().isNotNull("Image Owner", image.getSone()).check().isEqual("Image Owner", image.getSone(), sone).check();
161                 images.add(image);
162         }
163
164         /**
165          * Removes the given image from this album.
166          *
167          * @param image
168          *            The image to remove
169          */
170         public void removeImage(Image image) {
171                 Validation.begin().isNotNull("Image", image).check().isEqual("Image Owner", image.getSone(), sone).check();
172                 images.remove(image);
173         }
174
175         /**
176          * Returns the album image of this album, or {@code null} if no album image
177          * has been set.
178          *
179          * @return The image to show when this album is listed
180          */
181         public Image getAlbumImage() {
182                 if (albumImage == -1) {
183                         return null;
184                 }
185                 return images.get(albumImage);
186         }
187
188         /**
189          * Returns the parent album of this album.
190          *
191          * @return The parent album of this album, or {@code null} if this album
192          *         does not have a parent
193          */
194         public Album getParent() {
195                 return parent;
196         }
197
198         /**
199          * Sets the parent album of this album.
200          *
201          * @param parent
202          *            The new parent album of this album
203          * @return This album
204          */
205         protected Album setParent(Album parent) {
206                 Validation.begin().isNotNull("Album Parent", parent).check();
207                 this.parent = parent;
208                 return this;
209         }
210
211         /**
212          * Removes the parent album of this album.
213          *
214          * @return This album
215          */
216         protected Album removeParent() {
217                 Validation.begin().isNotNull("Album Parent", parent).check();
218                 this.parent = null;
219                 return this;
220         }
221
222         /**
223          * Returns the name of this album.
224          *
225          * @return The name of this album
226          */
227         public String getName() {
228                 return name;
229         }
230
231         /**
232          * Sets the name of this album.
233          *
234          * @param name
235          *            The name of this album
236          * @return This album
237          */
238         public Album setName(String name) {
239                 Validation.begin().isNotNull("Album Name", name).check();
240                 this.name = name;
241                 return this;
242         }
243
244         /**
245          * Returns the description of this album.
246          *
247          * @return The description of this album
248          */
249         public String getDescription() {
250                 return description;
251         }
252
253         /**
254          * Sets the description of this album.
255          *
256          * @param description
257          *            The description of this album
258          * @return This album
259          */
260         public Album setDescription(String description) {
261                 Validation.begin().isNotNull("Album Description", description).check();
262                 this.description = description;
263                 return this;
264         }
265
266         //
267         // FINGERPRINTABLE METHODS
268         //
269
270         /**
271          * {@inheritDoc}
272          */
273         @Override
274         public String getFingerprint() {
275                 StringBuilder fingerprint = new StringBuilder();
276                 fingerprint.append("Album(");
277                 fingerprint.append("ID(").append(id).append(')');
278                 fingerprint.append("Name(").append(name).append(')');
279                 fingerprint.append("Description(").append(description).append(')');
280
281                 /* add nested albums. */
282                 fingerprint.append("Albums(");
283                 for (Album album : albums) {
284                         fingerprint.append(album.getFingerprint());
285                 }
286                 fingerprint.append(')');
287
288                 /* add images. */
289                 fingerprint.append("Images(");
290                 for (Image image : images) {
291                         fingerprint.append(image.getFingerprint());
292                 }
293                 fingerprint.append(')');
294
295                 fingerprint.append(')');
296                 return fingerprint.toString();
297         }
298
299         //
300         // OBJECT METHODS
301         //
302
303         /**
304          * {@inheritDoc}
305          */
306         @Override
307         public int hashCode() {
308                 return id.hashCode();
309         }
310
311         /**
312          * {@inheritDoc}
313          */
314         @Override
315         public boolean equals(Object object) {
316                 if (!(object instanceof Album)) {
317                         return false;
318                 }
319                 Album album = (Album) object;
320                 return id.equals(album.id);
321         }
322
323 }