74b66e795e934ed4c7b23d6d5267c0deefa13c45
[Sone.git] / src / main / java / net / pterodactylus / sone / data / impl / DefaultAlbum.java
1 /*
2  * Sone - Album.java - Copyright © 2011–2013 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.impl;
19
20 import static com.google.common.base.Preconditions.checkArgument;
21 import static com.google.common.base.Preconditions.checkNotNull;
22
23 import java.util.ArrayList;
24 import java.util.HashMap;
25 import java.util.List;
26 import java.util.Map;
27 import java.util.UUID;
28
29 import net.pterodactylus.sone.data.Album;
30 import net.pterodactylus.sone.data.Image;
31 import net.pterodactylus.sone.data.Sone;
32 import net.pterodactylus.sone.database.AlbumBuilder;
33 import net.pterodactylus.sone.database.ImageBuilder;
34
35 import com.google.common.base.Function;
36 import com.google.common.base.Optional;
37 import com.google.common.base.Predicates;
38 import com.google.common.collect.Collections2;
39
40 /**
41  * Dumb, store-everything-in-memory implementation of an {@link Album}.
42  *
43  * @author <a href="mailto:bombe@pterodactylus.net">David ‘Bombe’ Roden</a>
44  */
45 public class DefaultAlbum extends AbstractAlbum {
46
47         /** The Sone this album belongs to. */
48         private Sone sone;
49
50         /** Nested albums. */
51         private final List<Album> albums = new ArrayList<Album>();
52
53         /** The image IDs in order. */
54         final List<String> imageIds = new ArrayList<String>();
55
56         /** The images in this album. */
57         final Map<String, Image> images = new HashMap<String, Image>();
58
59         /** The parent album. */
60         private Album parent;
61
62         /** Creates a new album with a random ID. */
63         public DefaultAlbum(Sone sone) {
64                 this(UUID.randomUUID().toString(), sone);
65         }
66
67         /**
68          * Creates a new album with the given ID.
69          *
70          * @param id
71          *              The ID of the album
72          */
73         public DefaultAlbum(String id, Sone sone) {
74                 super(id);
75                 this.sone = sone;
76         }
77
78         //
79         // ACCESSORS
80         //
81
82         @Override
83         public Sone getSone() {
84                 return sone;
85         }
86
87         @Override
88         public List<Album> getAlbums() {
89                 return new ArrayList<Album>(albums);
90         }
91
92         @Override
93         public void removeAlbum(Album album) {
94                 checkNotNull(album, "album must not be null");
95                 checkArgument(album.getSone().equals(sone), "album must belong this album’s Sone");
96                 checkArgument(equals(album.getParent()), "album must belong to this album");
97                 albums.remove(album);
98                 album.removeParent();
99         }
100
101         @Override
102         public Album moveAlbumUp(Album album) {
103                 checkNotNull(album, "album must not be null");
104                 checkArgument(album.getSone().equals(sone), "album must belong to the same Sone as this album");
105                 checkArgument(equals(album.getParent()), "album must belong to this album");
106                 int oldIndex = albums.indexOf(album);
107                 if (oldIndex <= 0) {
108                         return null;
109                 }
110                 albums.remove(oldIndex);
111                 albums.add(oldIndex - 1, album);
112                 return albums.get(oldIndex);
113         }
114
115         @Override
116         public Album moveAlbumDown(Album album) {
117                 checkNotNull(album, "album must not be null");
118                 checkArgument(album.getSone().equals(sone), "album must belong to the same Sone as this album");
119                 checkArgument(equals(album.getParent()), "album must belong to this album");
120                 int oldIndex = albums.indexOf(album);
121                 if ((oldIndex < 0) || (oldIndex >= (albums.size() - 1))) {
122                         return null;
123                 }
124                 albums.remove(oldIndex);
125                 albums.add(oldIndex + 1, album);
126                 return albums.get(oldIndex);
127         }
128
129         @Override
130         public List<Image> getImages() {
131                 return new ArrayList<Image>(Collections2.filter(Collections2.transform(imageIds, new Function<String, Image>() {
132
133                         @Override
134                         @SuppressWarnings("synthetic-access")
135                         public Image apply(String imageId) {
136                                 return images.get(imageId);
137                         }
138                 }), Predicates.notNull()));
139         }
140
141         @Override
142         public Image moveImageUp(Image image) {
143                 checkNotNull(image, "image must not be null");
144                 checkNotNull(image.getSone(), "image must have an owner");
145                 checkArgument(image.getSone().equals(sone), "image must belong to the same Sone as this album");
146                 checkArgument(image.getAlbum().equals(this), "image must belong to this album");
147                 int oldIndex = imageIds.indexOf(image.getId());
148                 if (oldIndex <= 0) {
149                         return null;
150                 }
151                 imageIds.remove(image.getId());
152                 imageIds.add(oldIndex - 1, image.getId());
153                 return images.get(imageIds.get(oldIndex));
154         }
155
156         @Override
157         public Image moveImageDown(Image image) {
158                 checkNotNull(image, "image must not be null");
159                 checkNotNull(image.getSone(), "image must have an owner");
160                 checkArgument(image.getSone().equals(sone), "image must belong to the same Sone as this album");
161                 checkArgument(image.getAlbum().equals(this), "image must belong to this album");
162                 int oldIndex = imageIds.indexOf(image.getId());
163                 if ((oldIndex == -1) || (oldIndex >= (imageIds.size() - 1))) {
164                         return null;
165                 }
166                 imageIds.remove(image.getId());
167                 imageIds.add(oldIndex + 1, image.getId());
168                 return images.get(imageIds.get(oldIndex));
169         }
170
171         @Override
172         public Image getAlbumImage() {
173                 if (albumImage == null) {
174                         return null;
175                 }
176                 return Optional.fromNullable(images.get(albumImage)).or(images.values().iterator().next());
177         }
178
179         @Override
180         public Album getParent() {
181                 return parent;
182         }
183
184         @Override
185         public Album setParent(Album parent) {
186                 this.parent = checkNotNull(parent, "parent must not be null");
187                 return this;
188         }
189
190         @Override
191         public Album removeParent() {
192                 this.parent = null;
193                 return this;
194         }
195
196         @Override
197         public AlbumBuilder newAlbumBuilder() {
198                 return new DefaultAlbumBuilder(sone) {
199                         @Override
200                         public Album build() throws IllegalStateException {
201                                 Album album = super.build();
202                                 albums.add(album);
203                                 return album;
204                         }
205                 };
206         }
207
208         @Override
209         public ImageBuilder newImageBuilder() throws IllegalStateException {
210                 return new DefaultImageBuilder(sone, this) {
211                         @Override
212                         public Image build() throws IllegalStateException {
213                                 Image image = super.build();
214                                 if (images.isEmpty() && (albumImage == null)) {
215                                         albumImage = image.getId();
216                                 }
217                                 images.put(image.getId(), image);
218                                 imageIds.add(image.getId());
219                                 return image;
220                         }
221                 };
222         }
223
224 }