Extract superclass out of default Sone implementation.
[Sone.git] / src / main / java / net / pterodactylus / sone / data / impl / DefaultSone.java
1 /*
2  * Sone - SoneImpl.java - Copyright © 2010–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 java.util.ArrayList;
21 import java.util.Collection;
22 import java.util.Collections;
23 import java.util.List;
24 import java.util.Set;
25 import java.util.concurrent.CopyOnWriteArraySet;
26 import java.util.logging.Level;
27
28 import net.pterodactylus.sone.data.Post;
29 import net.pterodactylus.sone.data.PostReply;
30 import net.pterodactylus.sone.data.Sone;
31 import net.pterodactylus.sone.database.AlbumBuilder;
32
33 /**
34  * Dumb, store-everything-in-memory {@link Sone} implementation.
35  *
36  * @author <a href="mailto:bombe@pterodactylus.net">David ‘Bombe’ Roden</a>
37  */
38 public class DefaultSone extends AbstractSone {
39
40         /** All posts. */
41         private final Set<Post> posts = new CopyOnWriteArraySet<Post>();
42
43         /** All replies. */
44         private final Set<PostReply> replies = new CopyOnWriteArraySet<PostReply>();
45
46         /** The IDs of all liked posts. */
47         private final Set<String> likedPostIds = new CopyOnWriteArraySet<String>();
48
49         /** The IDs of all liked replies. */
50         private final Set<String> likedReplyIds = new CopyOnWriteArraySet<String>();
51
52         /**
53          * Creates a new Sone.
54          *
55          * @param id
56          *              The ID of the Sone
57          * @param local
58          *              {@code true} if the Sone is a local Sone, {@code false} otherwise
59          */
60         public DefaultSone(String id, boolean local) {
61                 super(id, local);
62         }
63
64         //
65         // ACCESSORS
66         //
67
68         /**
69          * Returns whether this Sone is known.
70          *
71          * @return {@code true} if this Sone is known, {@code false} otherwise
72          */
73         public boolean isKnown() {
74                 return known;
75         }
76
77         /**
78          * Sets whether this Sone is known.
79          *
80          * @param known
81          *              {@code true} if this Sone is known, {@code false} otherwise
82          * @return This Sone
83          */
84         public Sone setKnown(boolean known) {
85                 this.known = known;
86                 return this;
87         }
88
89         /**
90          * Returns all friend Sones of this Sone.
91          *
92          * @return The friend Sones of this Sone
93          */
94         public List<String> getFriends() {
95                 List<String> friends = new ArrayList<String>(friendSones);
96                 return friends;
97         }
98
99         /**
100          * Returns whether this Sone has the given Sone as a friend Sone.
101          *
102          * @param friendSoneId
103          *              The ID of the Sone to check for
104          * @return {@code true} if this Sone has the given Sone as a friend, {@code
105          *         false} otherwise
106          */
107         public boolean hasFriend(String friendSoneId) {
108                 return friendSones.contains(friendSoneId);
109         }
110
111         /**
112          * Adds the given Sone as a friend Sone.
113          *
114          * @param friendSone
115          *              The friend Sone to add
116          * @return This Sone (for method chaining)
117          */
118         public Sone addFriend(String friendSone) {
119                 if (!friendSone.equals(id)) {
120                         friendSones.add(friendSone);
121                 }
122                 return this;
123         }
124
125         /**
126          * Removes the given Sone as a friend Sone.
127          *
128          * @param friendSoneId
129          *              The ID of the friend Sone to remove
130          * @return This Sone (for method chaining)
131          */
132         public Sone removeFriend(String friendSoneId) {
133                 friendSones.remove(friendSoneId);
134                 return this;
135         }
136
137         /**
138          * Returns the list of posts of this Sone, sorted by time, newest first.
139          *
140          * @return All posts of this Sone
141          */
142         public List<Post> getPosts() {
143                 List<Post> sortedPosts;
144                 synchronized (this) {
145                         sortedPosts = new ArrayList<Post>(posts);
146                 }
147                 Collections.sort(sortedPosts, Post.TIME_COMPARATOR);
148                 return sortedPosts;
149         }
150
151         /**
152          * Sets all posts of this Sone at once.
153          *
154          * @param posts
155          *              The new (and only) posts of this Sone
156          * @return This Sone (for method chaining)
157          */
158         public Sone setPosts(Collection<Post> posts) {
159                 synchronized (this) {
160                         this.posts.clear();
161                         this.posts.addAll(posts);
162                 }
163                 return this;
164         }
165
166         /**
167          * Adds the given post to this Sone. The post will not be added if its {@link
168          * Post#getSone() Sone} is not this Sone.
169          *
170          * @param post
171          *              The post to add
172          */
173         public void addPost(Post post) {
174                 if (post.getSone().equals(this) && posts.add(post)) {
175                         logger.log(Level.FINEST, String.format("Adding %s to “%s”.", post, getName()));
176                 }
177         }
178
179         /**
180          * Removes the given post from this Sone.
181          *
182          * @param post
183          *              The post to remove
184          */
185         public void removePost(Post post) {
186                 if (post.getSone().equals(this)) {
187                         posts.remove(post);
188                 }
189         }
190
191         /**
192          * Returns all replies this Sone made.
193          *
194          * @return All replies this Sone made
195          */
196         public Set<PostReply> getReplies() {
197                 return Collections.unmodifiableSet(replies);
198         }
199
200         /**
201          * Sets all replies of this Sone at once.
202          *
203          * @param replies
204          *              The new (and only) replies of this Sone
205          * @return This Sone (for method chaining)
206          */
207         public Sone setReplies(Collection<PostReply> replies) {
208                 this.replies.clear();
209                 this.replies.addAll(replies);
210                 return this;
211         }
212
213         /**
214          * Adds a reply to this Sone. If the given reply was not made by this Sone,
215          * nothing is added to this Sone.
216          *
217          * @param reply
218          *              The reply to add
219          */
220         public void addReply(PostReply reply) {
221                 if (reply.getSone().equals(this)) {
222                         replies.add(reply);
223                 }
224         }
225
226         /**
227          * Removes a reply from this Sone.
228          *
229          * @param reply
230          *              The reply to remove
231          */
232         public void removeReply(PostReply reply) {
233                 if (reply.getSone().equals(this)) {
234                         replies.remove(reply);
235                 }
236         }
237
238         /**
239          * Returns the IDs of all liked posts.
240          *
241          * @return All liked posts’ IDs
242          */
243         public Set<String> getLikedPostIds() {
244                 return Collections.unmodifiableSet(likedPostIds);
245         }
246
247         /**
248          * Sets the IDs of all liked posts.
249          *
250          * @param likedPostIds
251          *              All liked posts’ IDs
252          * @return This Sone (for method chaining)
253          */
254         public Sone setLikePostIds(Set<String> likedPostIds) {
255                 this.likedPostIds.clear();
256                 this.likedPostIds.addAll(likedPostIds);
257                 return this;
258         }
259
260         public boolean isLikedPostId(String postId) {
261                 return likedPostIds.contains(postId);
262         }
263
264         public Sone addLikedPostId(String postId) {
265                 likedPostIds.add(postId);
266                 return this;
267         }
268
269         public Sone removeLikedPostId(String postId) {
270                 likedPostIds.remove(postId);
271                 return this;
272         }
273
274         public Set<String> getLikedReplyIds() {
275                 return Collections.unmodifiableSet(likedReplyIds);
276         }
277
278         public Sone setLikeReplyIds(Set<String> likedReplyIds) {
279                 this.likedReplyIds.clear();
280                 this.likedReplyIds.addAll(likedReplyIds);
281                 return this;
282         }
283
284         public boolean isLikedReplyId(String replyId) {
285                 return likedReplyIds.contains(replyId);
286         }
287
288         public Sone addLikedReplyId(String replyId) {
289                 likedReplyIds.add(replyId);
290                 return this;
291         }
292
293         public Sone removeLikedReplyId(String replyId) {
294                 likedReplyIds.remove(replyId);
295                 return this;
296         }
297
298         @Override
299         public AlbumBuilder newAlbumBuilder() {
300                 return new DefaultAlbumBuilder(this, rootAlbum);
301         }
302
303 }