🔥 Replace NOT_EMPTY with Kotlin version
[Sone.git] / src / main / java / net / pterodactylus / sone / data / Album.java
1 /*
2  * Sone - Album.java - Copyright Â© 2011–2020 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 static java.util.Arrays.asList;
21 import static java.util.Collections.emptyList;
22
23 import java.util.ArrayList;
24 import java.util.Collections;
25 import java.util.List;
26 import javax.annotation.Nonnull;
27
28 import com.google.common.base.Function;
29 import com.google.common.base.Predicate;
30 import com.google.common.collect.FluentIterable;
31 import com.google.common.collect.ImmutableList;
32
33 /**
34  * Container for images that can also contain nested {@link Album}s.
35  */
36 public interface Album extends Identified, Fingerprintable {
37
38         /** Function that flattens the given album and all albums beneath it. */
39         Function<Album, List<Album>> FLATTENER = new Function<Album, List<Album>>() {
40
41                 @Override
42                 @Nonnull
43                 public List<Album> apply(Album album) {
44                         if (album == null) {
45                                 return emptyList();
46                         }
47                         List<Album> albums = new ArrayList<>();
48                         albums.add(album);
49                         for (Album subAlbum : album.getAlbums()) {
50                                 albums.addAll(FluentIterable.from(ImmutableList.of(subAlbum)).transformAndConcat(FLATTENER).toList());
51                         }
52                         return albums;
53                 }
54         };
55
56         /** Function that transforms an album into the images it contains. */
57         Function<Album, List<Image>> IMAGES = new Function<Album, List<Image>>() {
58
59                 @Override
60                 @Nonnull
61                 public List<Image> apply(Album album) {
62                         return (album != null) ? album.getImages() : Collections.<Image>emptyList();
63                 }
64         };
65
66         /**
67          * Returns the ID of this album.
68          *
69          * @return The ID of this album
70          */
71         String getId();
72
73         /**
74          * Returns the Sone this album belongs to.
75          *
76          * @return The Sone this album belongs to
77          */
78         Sone getSone();
79
80         /**
81          * Returns the nested albums.
82          *
83          * @return The nested albums
84          */
85         List<Album> getAlbums();
86
87         /**
88          * Adds an album to this album.
89          *
90          * @param album
91          *              The album to add
92          */
93         void addAlbum(Album album);
94
95         /**
96          * Removes an album from this album.
97          *
98          * @param album
99          *              The album to remove
100          */
101         void removeAlbum(Album album);
102
103         /**
104          * Moves the given album up in this album’s albums. If the album is already the
105          * first album, nothing happens.
106          *
107          * @param album
108          *              The album to move up
109          * @return The album that the given album swapped the place with, or
110          *         <code>null</code> if the album did not change its place
111          */
112         Album moveAlbumUp(Album album);
113
114         /**
115          * Moves the given album down in this album’s albums. If the album is already
116          * the last album, nothing happens.
117          *
118          * @param album
119          *              The album to move down
120          * @return The album that the given album swapped the place with, or
121          *         <code>null</code> if the album did not change its place
122          */
123         Album moveAlbumDown(Album album);
124
125         /**
126          * Returns the images in this album.
127          *
128          * @return The images in this album
129          */
130         List<Image> getImages();
131
132         /**
133          * Adds the given image to this album.
134          *
135          * @param image
136          *              The image to add
137          */
138         void addImage(Image image);
139
140         /**
141          * Removes the given image from this album.
142          *
143          * @param image
144          *              The image to remove
145          */
146         void removeImage(Image image);
147
148         /**
149          * Moves the given image up in this album’s images. If the image is already the
150          * first image, nothing happens.
151          *
152          * @param image
153          *              The image to move up
154          * @return The image that the given image swapped the place with, or
155          *         <code>null</code> if the image did not change its place
156          */
157         Image moveImageUp(Image image);
158
159         /**
160          * Moves the given image down in this album’s images. If the image is already
161          * the last image, nothing happens.
162          *
163          * @param image
164          *              The image to move down
165          * @return The image that the given image swapped the place with, or
166          *         <code>null</code> if the image did not change its place
167          */
168         Image moveImageDown(Image image);
169
170         /**
171          * Returns whether this album contains any other albums or images.
172          *
173          * @return {@code true} if this album is empty, {@code false} otherwise
174          */
175         boolean isEmpty();
176
177         /**
178          * Returns whether this album is an identitiy’s root album.
179          *
180          * @return {@code true} if this album is an identity’s root album, {@code
181          *         false} otherwise
182          */
183         boolean isRoot();
184
185         /**
186          * Returns the parent album of this album.
187          *
188          * @return The parent album of this album, or {@code null} if this album does
189          *         not have a parent
190          */
191         Album getParent();
192
193         /**
194          * Sets the parent album of this album.
195          *
196          * @param parent
197          *              The new parent album of this album
198          * @return This album
199          */
200         Album setParent(Album parent);
201
202         /**
203          * Removes the parent album of this album.
204          *
205          * @return This album
206          */
207         Album removeParent();
208
209         /**
210          * Returns the title of this album.
211          *
212          * @return The title of this album
213          */
214         String getTitle();
215
216         /**
217          * Returns the description of this album.
218          *
219          * @return The description of this album
220          */
221         String getDescription();
222
223         /**
224          * Returns a modifier for this album.
225          *
226          * @return A modifier for this album
227          * @throws IllegalStateException
228          *              if this album can not be modified
229          */
230         Modifier modify() throws IllegalStateException;
231
232         /**
233          * Allows modifying an album. Modifications are only performed once {@link
234          * #update()} has succesfully returned a new album with the modifications
235          * made.
236          */
237         interface Modifier {
238
239                 Modifier setTitle(String title);
240
241                 Modifier setDescription(String description);
242
243                 Album update() throws IllegalStateException;
244
245                 class AlbumTitleMustNotBeEmpty extends IllegalStateException { }
246
247         }
248
249 }