Merge branch 'release-0.9.7'
[Sone.git] / src / main / java / net / pterodactylus / sone / data / Sone.java
1 /*
2  * Sone - Sone.java - Copyright © 2010–2016 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 com.google.common.collect.FluentIterable.from;
21 import static java.util.Arrays.asList;
22 import static net.pterodactylus.sone.data.Album.FLATTENER;
23 import static net.pterodactylus.sone.data.Album.IMAGES;
24
25 import java.util.Collection;
26 import java.util.Collections;
27 import java.util.Comparator;
28 import java.util.List;
29 import java.util.Set;
30
31 import javax.annotation.Nonnull;
32 import javax.annotation.Nullable;
33
34 import net.pterodactylus.sone.freenet.wot.Identity;
35 import net.pterodactylus.sone.freenet.wot.OwnIdentity;
36 import net.pterodactylus.sone.template.SoneAccessor;
37
38 import freenet.keys.FreenetURI;
39
40 import com.google.common.base.Function;
41 import com.google.common.base.Predicate;
42 import com.google.common.primitives.Ints;
43
44 /**
45  * A Sone defines everything about a user: her profile, her status updates, her
46  * replies, her likes and dislikes, etc.
47  *
48  * @author <a href="mailto:bombe@pterodactylus.net">David ‘Bombe’ Roden</a>
49  */
50 public interface Sone extends Identified, Fingerprintable, Comparable<Sone> {
51
52         /**
53          * Enumeration for the possible states of a {@link Sone}.
54          *
55          * @author <a href="mailto:bombe@pterodactylus.net">David ‘Bombe’ Roden</a>
56          */
57         public enum SoneStatus {
58
59                 /** The Sone is unknown, i.e. not yet downloaded. */
60                 unknown,
61
62                 /** The Sone is idle, i.e. not being downloaded or inserted. */
63                 idle,
64
65                 /** The Sone is currently being inserted. */
66                 inserting,
67
68                 /** The Sone is currently being downloaded. */
69                 downloading,
70         }
71
72         /** comparator that sorts Sones by their nice name. */
73         public static final Comparator<Sone> NICE_NAME_COMPARATOR = new Comparator<Sone>() {
74
75                 @Override
76                 public int compare(Sone leftSone, Sone rightSone) {
77                         int diff = SoneAccessor.getNiceName(leftSone).compareToIgnoreCase(SoneAccessor.getNiceName(rightSone));
78                         if (diff != 0) {
79                                 return diff;
80                         }
81                         return leftSone.getId().compareToIgnoreCase(rightSone.getId());
82                 }
83
84         };
85
86         /** Comparator that sorts Sones by last activity (least recent active first). */
87         public static final Comparator<Sone> LAST_ACTIVITY_COMPARATOR = new Comparator<Sone>() {
88
89                 @Override
90                 public int compare(Sone firstSone, Sone secondSone) {
91                         return (int) Math.min(Integer.MAX_VALUE, Math.max(Integer.MIN_VALUE, secondSone.getTime() - firstSone.getTime()));
92                 }
93         };
94
95         /** Comparator that sorts Sones by numbers of posts (descending). */
96         public static final Comparator<Sone> POST_COUNT_COMPARATOR = new Comparator<Sone>() {
97
98                 /**
99                  * {@inheritDoc}
100                  */
101                 @Override
102                 public int compare(Sone leftSone, Sone rightSone) {
103                         return (leftSone.getPosts().size() != rightSone.getPosts().size()) ? (rightSone.getPosts().size() - leftSone.getPosts().size()) : (rightSone.getReplies().size() - leftSone.getReplies().size());
104                 }
105         };
106
107         /** Comparator that sorts Sones by number of images (descending). */
108         public static final Comparator<Sone> IMAGE_COUNT_COMPARATOR = new Comparator<Sone>() {
109
110                 /**
111                  * {@inheritDoc}
112                  */
113                 @Override
114                 public int compare(Sone leftSone, Sone rightSone) {
115                         int rightSoneImageCount = from(asList(rightSone.getRootAlbum())).transformAndConcat(FLATTENER).transformAndConcat(IMAGES).size();
116                         int leftSoneImageCount = from(asList(leftSone.getRootAlbum())).transformAndConcat(FLATTENER).transformAndConcat(IMAGES).size();
117                         /* sort descending. */
118                         return Ints.compare(rightSoneImageCount, leftSoneImageCount);
119                 }
120         };
121
122         /** Filter to remove Sones that have not been downloaded. */
123         public static final Predicate<Sone> EMPTY_SONE_FILTER = new Predicate<Sone>() {
124
125                 @Override
126                 public boolean apply(Sone sone) {
127                         return (sone != null) && (sone.getTime() != 0);
128                 }
129         };
130
131         /** Filter that matches all {@link Sone#isLocal() local Sones}. */
132         public static final Predicate<Sone> LOCAL_SONE_FILTER = new Predicate<Sone>() {
133
134                 @Override
135                 public boolean apply(Sone sone) {
136                         return (sone != null) && (sone.getIdentity() instanceof OwnIdentity);
137                 }
138
139         };
140
141         /** Filter that matches Sones that have at least one album. */
142         public static final Predicate<Sone> HAS_ALBUM_FILTER = new Predicate<Sone>() {
143
144                 @Override
145                 public boolean apply(Sone sone) {
146                         return (sone != null) && !sone.getRootAlbum().getAlbums().isEmpty();
147                 }
148         };
149
150         public static final Function<Sone, List<Album>> toAllAlbums = new Function<Sone, List<Album>>() {
151                 @Override
152                 public List<Album> apply(@Nullable Sone sone) {
153                         return (sone == null) ? Collections.<Album>emptyList() : FLATTENER.apply(
154                                         sone.getRootAlbum());
155                 }
156         };
157
158         public static final Function<Sone, List<Image>> toAllImages = new Function<Sone, List<Image>>() {
159                 @Override
160                 public List<Image> apply(@Nullable Sone sone) {
161                         return (sone == null) ? Collections.<Image>emptyList() :
162                                         from(FLATTENER.apply(sone.getRootAlbum()))
163                                                         .transformAndConcat(IMAGES).toList();
164                 }
165         };
166
167         /**
168          * Returns the identity of this Sone.
169          *
170          * @return The identity of this Sone
171          */
172         @Nonnull
173         Identity getIdentity();
174
175         /**
176          * Returns the name of this Sone.
177          *
178          * @return The name of this Sone
179          */
180         @Nonnull
181         String getName();
182
183         /**
184          * Returns whether this Sone is a local Sone.
185          *
186          * @return {@code true} if this Sone is a local Sone, {@code false} otherwise
187          */
188         boolean isLocal();
189
190         /**
191          * Returns the request URI of this Sone.
192          *
193          * @return The request URI of this Sone
194          */
195         @Nonnull
196         FreenetURI getRequestUri();
197
198         /**
199          * Returns the insert URI of this Sone.
200          *
201          * @return The insert URI of this Sone
202          */
203         @Nullable
204         FreenetURI getInsertUri();
205
206         /**
207          * Returns the latest edition of this Sone.
208          *
209          * @return The latest edition of this Sone
210          */
211         long getLatestEdition();
212
213         /**
214          * Sets the latest edition of this Sone. If the given latest edition is not
215          * greater than the current latest edition, the latest edition of this Sone is
216          * not changed.
217          *
218          * @param latestEdition
219          *              The latest edition of this Sone
220          */
221         void setLatestEdition(long latestEdition);
222
223         /**
224          * Return the time of the last inserted update of this Sone.
225          *
226          * @return The time of the update (in milliseconds since Jan 1, 1970 UTC)
227          */
228         long getTime();
229
230         /**
231          * Sets the time of the last inserted update of this Sone.
232          *
233          * @param time
234          *              The time of the update (in milliseconds since Jan 1, 1970 UTC)
235          * @return This Sone (for method chaining)
236          */
237         @Nonnull
238         Sone setTime(long time);
239
240         /**
241          * Returns the status of this Sone.
242          *
243          * @return The status of this Sone
244          */
245         @Nonnull
246         SoneStatus getStatus();
247
248         /**
249          * Sets the new status of this Sone.
250          *
251          * @param status
252          *              The new status of this Sone
253          * @return This Sone
254          * @throws IllegalArgumentException
255          *              if {@code status} is {@code null}
256          */
257         @Nonnull
258         Sone setStatus(@Nonnull SoneStatus status);
259
260         /**
261          * Returns a copy of the profile. If you want to update values in the profile
262          * of this Sone, update the values in the returned {@link Profile} and use
263          * {@link #setProfile(Profile)} to change the profile in this Sone.
264          *
265          * @return A copy of the profile
266          */
267         @Nonnull
268         Profile getProfile();
269
270         /**
271          * Sets the profile of this Sone. A copy of the given profile is stored so that
272          * subsequent modifications of the given profile are not reflected in this
273          * Sone!
274          *
275          * @param profile
276          *              The profile to set
277          */
278         void setProfile(@Nonnull Profile profile);
279
280         /**
281          * Returns the client used by this Sone.
282          *
283          * @return The client used by this Sone, or {@code null}
284          */
285         @Nullable
286         Client getClient();
287
288         /**
289          * Sets the client used by this Sone.
290          *
291          * @param client
292          *              The client used by this Sone, or {@code null}
293          * @return This Sone (for method chaining)
294          */
295         @Nonnull
296         Sone setClient(@Nullable Client client);
297
298         /**
299          * Returns whether this Sone is known.
300          *
301          * @return {@code true} if this Sone is known, {@code false} otherwise
302          */
303         boolean isKnown();
304
305         /**
306          * Sets whether this Sone is known.
307          *
308          * @param known
309          *              {@code true} if this Sone is known, {@code false} otherwise
310          * @return This Sone
311          */
312         @Nonnull
313         Sone setKnown(boolean known);
314
315         /**
316          * Returns all friend Sones of this Sone.
317          *
318          * @return The friend Sones of this Sone
319          */
320         @Nonnull
321         Collection<String> getFriends();
322
323         /**
324          * Returns whether this Sone has the given Sone as a friend Sone.
325          *
326          * @param friendSoneId
327          *              The ID of the Sone to check for
328          * @return {@code true} if this Sone has the given Sone as a friend, {@code
329          *         false} otherwise
330          */
331         boolean hasFriend(@Nonnull String friendSoneId);
332
333         /**
334          * Returns the list of posts of this Sone, sorted by time, newest first.
335          *
336          * @return All posts of this Sone
337          */
338         @Nonnull
339         List<Post> getPosts();
340
341         /**
342          * Sets all posts of this Sone at once.
343          *
344          * @param posts
345          *              The new (and only) posts of this Sone
346          * @return This Sone (for method chaining)
347          */
348         @Nonnull
349         Sone setPosts(@Nonnull Collection<Post> posts);
350
351         /**
352          * Adds the given post to this Sone. The post will not be added if its {@link
353          * Post#getSone() Sone} is not this Sone.
354          *
355          * @param post
356          *              The post to add
357          */
358         void addPost(@Nonnull Post post);
359
360         /**
361          * Removes the given post from this Sone.
362          *
363          * @param post
364          *              The post to remove
365          */
366         void removePost(@Nonnull Post post);
367
368         /**
369          * Returns all replies this Sone made.
370          *
371          * @return All replies this Sone made
372          */
373         @Nonnull
374         Set<PostReply> getReplies();
375
376         /**
377          * Sets all replies of this Sone at once.
378          *
379          * @param replies
380          *              The new (and only) replies of this Sone
381          * @return This Sone (for method chaining)
382          */
383         @Nonnull
384         Sone setReplies(@Nonnull Collection<PostReply> replies);
385
386         /**
387          * Adds a reply to this Sone. If the given reply was not made by this Sone,
388          * nothing is added to this Sone.
389          *
390          * @param reply
391          *              The reply to add
392          */
393         void addReply(@Nonnull PostReply reply);
394
395         /**
396          * Removes a reply from this Sone.
397          *
398          * @param reply
399          *              The reply to remove
400          */
401         void removeReply(@Nonnull PostReply reply);
402
403         /**
404          * Returns the IDs of all liked posts.
405          *
406          * @return All liked posts’ IDs
407          */
408         @Nonnull
409         Set<String> getLikedPostIds();
410
411         /**
412          * Sets the IDs of all liked posts.
413          *
414          * @param likedPostIds
415          *              All liked posts’ IDs
416          * @return This Sone (for method chaining)
417          */
418         @Nonnull
419         Sone setLikePostIds(@Nonnull Set<String> likedPostIds);
420
421         /**
422          * Checks whether the given post ID is liked by this Sone.
423          *
424          * @param postId
425          *              The ID of the post
426          * @return {@code true} if this Sone likes the given post, {@code false}
427          *         otherwise
428          */
429         boolean isLikedPostId(@Nonnull String postId);
430
431         /**
432          * Adds the given post ID to the list of posts this Sone likes.
433          *
434          * @param postId
435          *              The ID of the post
436          * @return This Sone (for method chaining)
437          */
438         @Nonnull
439         Sone addLikedPostId(@Nonnull String postId);
440
441         /**
442          * Removes the given post ID from the list of posts this Sone likes.
443          *
444          * @param postId
445          *              The ID of the post
446          */
447         void removeLikedPostId(@Nonnull String postId);
448
449         /**
450          * Returns the IDs of all liked replies.
451          *
452          * @return All liked replies’ IDs
453          */
454         @Nonnull
455         Set<String> getLikedReplyIds();
456
457         /**
458          * Sets the IDs of all liked replies.
459          *
460          * @param likedReplyIds
461          *              All liked replies’ IDs
462          * @return This Sone (for method chaining)
463          */
464         @Nonnull
465         Sone setLikeReplyIds(@Nonnull Set<String> likedReplyIds);
466
467         /**
468          * Checks whether the given reply ID is liked by this Sone.
469          *
470          * @param replyId
471          *              The ID of the reply
472          * @return {@code true} if this Sone likes the given reply, {@code false}
473          *         otherwise
474          */
475         boolean isLikedReplyId(@Nonnull String replyId);
476
477         /**
478          * Adds the given reply ID to the list of replies this Sone likes.
479          *
480          * @param replyId
481          *              The ID of the reply
482          * @return This Sone (for method chaining)
483          */
484         @Nonnull
485         Sone addLikedReplyId(@Nonnull String replyId);
486
487         /**
488          * Removes the given post ID from the list of replies this Sone likes.
489          *
490          * @param replyId
491          *              The ID of the reply
492          */
493         void removeLikedReplyId(@Nonnull String replyId);
494
495         /**
496          * Returns the root album that contains all visible albums of this Sone.
497          *
498          * @return The root album of this Sone
499          */
500         @Nonnull
501         Album getRootAlbum();
502
503         /**
504          * Returns Sone-specific options.
505          *
506          * @return The options of this Sone
507          */
508         @Nonnull
509         SoneOptions getOptions();
510
511         /**
512          * Sets the options of this Sone.
513          *
514          * @param options
515          *              The options of this Sone
516          */
517         /* TODO - remove this method again, maybe add an option provider */
518         void setOptions(@Nonnull SoneOptions options);
519
520 }