Turn Sone into an interface, add in-memory implementation of Sone.
[Sone.git] / src / main / java / net / pterodactylus / sone / data / Sone.java
1 /*
2  * Sone - Sone.java - Copyright © 2010–2012 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.Collection;
21 import java.util.Comparator;
22 import java.util.List;
23 import java.util.Set;
24
25 import net.pterodactylus.sone.core.Core;
26 import net.pterodactylus.sone.core.Options;
27 import net.pterodactylus.sone.freenet.wot.Identity;
28 import net.pterodactylus.sone.freenet.wot.OwnIdentity;
29 import net.pterodactylus.sone.template.SoneAccessor;
30 import net.pterodactylus.util.collection.filter.Filter;
31 import freenet.keys.FreenetURI;
32
33 /**
34  * A Sone defines everything about a user: her profile, her status updates, her
35  * replies, her likes and dislikes, etc.
36  * <p>
37  * Operations that modify the Sone need to synchronize on the Sone in question.
38  *
39  * @author <a href="mailto:bombe@pterodactylus.net">David ‘Bombe’ Roden</a>
40  */
41 public interface Sone extends Fingerprintable, Comparable<Sone> {
42
43         /**
44          * Enumeration for the possible states of a {@link Sone}.
45          *
46          * @author <a href="mailto:bombe@pterodactylus.net">David ‘Bombe’ Roden</a>
47          */
48         public enum SoneStatus {
49
50                 /** The Sone is unknown, i.e. not yet downloaded. */
51                 unknown,
52
53                 /** The Sone is idle, i.e. not being downloaded or inserted. */
54                 idle,
55
56                 /** The Sone is currently being inserted. */
57                 inserting,
58
59                 /** The Sone is currently being downloaded. */
60                 downloading,
61         }
62
63         /**
64          * The possible values for the “show custom avatars” option.
65          *
66          * @author <a href="mailto:bombe@pterodactylus.net">David ‘Bombe’ Roden</a>
67          */
68         public static enum ShowCustomAvatars {
69
70                 /** Never show custom avatars. */
71                 NEVER,
72
73                 /** Only show custom avatars of followed Sones. */
74                 FOLLOWED,
75
76                 /** Only show custom avatars of Sones you manually trust. */
77                 MANUALLY_TRUSTED,
78
79                 /** Only show custom avatars of automatically trusted Sones. */
80                 TRUSTED,
81
82                 /** Always show custom avatars. */
83                 ALWAYS,
84
85         }
86
87         /** comparator that sorts Sones by their nice name. */
88         public static final Comparator<Sone> NICE_NAME_COMPARATOR = new Comparator<Sone>() {
89
90                 @Override
91                 public int compare(Sone leftSone, Sone rightSone) {
92                         int diff = SoneAccessor.getNiceName(leftSone).compareToIgnoreCase(SoneAccessor.getNiceName(rightSone));
93                         if (diff != 0) {
94                                 return diff;
95                         }
96                         return leftSone.getId().compareToIgnoreCase(rightSone.getId());
97                 }
98
99         };
100
101         /**
102          * Comparator that sorts Sones by last activity (least recent active first).
103          */
104         public static final Comparator<Sone> LAST_ACTIVITY_COMPARATOR = new Comparator<Sone>() {
105
106                 @Override
107                 public int compare(Sone firstSone, Sone secondSone) {
108                         return (int) Math.min(Integer.MAX_VALUE, Math.max(Integer.MIN_VALUE, secondSone.getTime() - firstSone.getTime()));
109                 }
110         };
111
112         /** Comparator that sorts Sones by numbers of posts (descending). */
113         public static final Comparator<Sone> POST_COUNT_COMPARATOR = new Comparator<Sone>() {
114
115                 /**
116                  * {@inheritDoc}
117                  */
118                 @Override
119                 public int compare(Sone leftSone, Sone rightSone) {
120                         return (leftSone.getPosts().size() != rightSone.getPosts().size()) ? (rightSone.getPosts().size() - leftSone.getPosts().size()) : (rightSone.getReplies().size() - leftSone.getReplies().size());
121                 }
122         };
123
124         /** Comparator that sorts Sones by number of images (descending). */
125         public static final Comparator<Sone> IMAGE_COUNT_COMPARATOR = new Comparator<Sone>() {
126
127                 /**
128                  * {@inheritDoc}
129                  */
130                 @Override
131                 public int compare(Sone leftSone, Sone rightSone) {
132                         return rightSone.getAllImages().size() - leftSone.getAllImages().size();
133                 }
134         };
135
136         /** Filter to remove Sones that have not been downloaded. */
137         public static final Filter<Sone> EMPTY_SONE_FILTER = new Filter<Sone>() {
138
139                 @Override
140                 public boolean filterObject(Sone sone) {
141                         return sone.getTime() != 0;
142                 }
143         };
144
145         /** Filter that matches all {@link Core#getLocalSones() local Sones}. */
146         public static final Filter<Sone> LOCAL_SONE_FILTER = new Filter<Sone>() {
147
148                 @Override
149                 public boolean filterObject(Sone sone) {
150                         return sone.getIdentity() instanceof OwnIdentity;
151                 }
152
153         };
154
155         /** Filter that matches Sones that have at least one album. */
156         public static final Filter<Sone> HAS_ALBUM_FILTER = new Filter<Sone>() {
157
158                 @Override
159                 public boolean filterObject(Sone sone) {
160                         return !sone.getAlbums().isEmpty();
161                 }
162         };
163
164         //
165         // ACCESSORS
166         //
167
168         /**
169          * Returns the identity of this Sone.
170          *
171          * @return The identity of this Sone
172          */
173         public String getId();
174
175         /**
176          * Returns the identity of this Sone.
177          *
178          * @return The identity of this Sone
179          */
180         public Identity getIdentity();
181
182         /**
183          * Sets the identity of this Sone. The {@link Identity#getId() ID} of the
184          * identity has to match this Sone’s {@link #getId()}.
185          *
186          * @param identity
187          *            The identity of this Sone
188          * @return This Sone (for method chaining)
189          * @throws IllegalArgumentException
190          *             if the ID of the identity does not match this Sone’s ID
191          */
192         public Sone setIdentity(Identity identity) throws IllegalArgumentException;
193
194         /**
195          * Returns whether this Sone is local.
196          *
197          * @return {@code true} if this Sone is local, {@code false} otherwise
198          */
199         public boolean isLocal();
200
201         /**
202          * Returns the name of this Sone.
203          *
204          * @return The name of this Sone
205          */
206         public String getName();
207
208         /**
209          * Returns the request URI of this Sone.
210          *
211          * @return The request URI of this Sone
212          */
213         public FreenetURI getRequestUri();
214
215         /**
216          * Sets the request URI of this Sone.
217          *
218          * @param requestUri
219          *            The request URI of this Sone
220          * @return This Sone (for method chaining)
221          */
222         public Sone setRequestUri(FreenetURI requestUri);
223
224         /**
225          * Returns the insert URI of this Sone.
226          *
227          * @return The insert URI of this Sone
228          */
229         public FreenetURI getInsertUri();
230
231         /**
232          * Sets the insert URI of this Sone.
233          *
234          * @param insertUri
235          *            The insert URI of this Sone
236          * @return This Sone (for method chaining)
237          */
238         public Sone setInsertUri(FreenetURI insertUri);
239
240         /**
241          * Returns the latest edition of this Sone.
242          *
243          * @return The latest edition of this Sone
244          */
245         public long getLatestEdition();
246
247         /**
248          * Sets the latest edition of this Sone. If the given latest edition is not
249          * greater than the current latest edition, the latest edition of this Sone
250          * is not changed.
251          *
252          * @param latestEdition
253          *            The latest edition of this Sone
254          */
255         public void setLatestEdition(long latestEdition);
256
257         /**
258          * Return the time of the last inserted update of this Sone.
259          *
260          * @return The time of the update (in milliseconds since Jan 1, 1970 UTC)
261          */
262         public long getTime();
263
264         /**
265          * Sets the time of the last inserted update of this Sone.
266          *
267          * @param time
268          *            The time of the update (in milliseconds since Jan 1, 1970 UTC)
269          * @return This Sone (for method chaining)
270          */
271         public Sone setTime(long time);
272
273         /**
274          * Returns the status of this Sone.
275          *
276          * @return The status of this Sone
277          */
278         public SoneStatus getStatus();
279
280         /**
281          * Sets the new status of this Sone.
282          *
283          * @param status
284          *            The new status of this Sone
285          * @return This Sone
286          * @throws IllegalArgumentException
287          *             if {@code status} is {@code null}
288          */
289         public Sone setStatus(SoneStatus status);
290
291         /**
292          * Returns a copy of the profile. If you want to update values in the
293          * profile of this Sone, update the values in the returned {@link Profile}
294          * and use {@link #setProfile(Profile)} to change the profile in this Sone.
295          *
296          * @return A copy of the profile
297          */
298         public Profile getProfile();
299
300         /**
301          * Sets the profile of this Sone. A copy of the given profile is stored so
302          * that subsequent modifications of the given profile are not reflected in
303          * this Sone!
304          *
305          * @param profile
306          *            The profile to set
307          */
308         public void setProfile(Profile profile);
309
310         /**
311          * Returns the client used by this Sone.
312          *
313          * @return The client used by this Sone, or {@code null}
314          */
315         public Client getClient();
316
317         /**
318          * Sets the client used by this Sone.
319          *
320          * @param client
321          *            The client used by this Sone, or {@code null}
322          * @return This Sone (for method chaining)
323          */
324         public Sone setClient(Client client);
325
326         /**
327          * Returns whether this Sone is known.
328          *
329          * @return {@code true} if this Sone is known, {@code false} otherwise
330          */
331         public boolean isKnown();
332
333         /**
334          * Sets whether this Sone is known.
335          *
336          * @param known
337          *            {@code true} if this Sone is known, {@code false} otherwise
338          * @return This Sone
339          */
340         public Sone setKnown(boolean known);
341
342         /**
343          * Returns all friend Sones of this Sone.
344          *
345          * @return The friend Sones of this Sone
346          */
347         public Collection<String> getFriends();
348
349         /**
350          * Returns whether this Sone has the given Sone as a friend Sone.
351          *
352          * @param friendSoneId
353          *            The ID of the Sone to check for
354          * @return {@code true} if this Sone has the given Sone as a friend,
355          *         {@code false} otherwise
356          */
357         public boolean hasFriend(String friendSoneId);
358
359         /**
360          * Adds the given Sone as a friend Sone.
361          *
362          * @param friendSone
363          *            The friend Sone to add
364          * @return This Sone (for method chaining)
365          */
366         public Sone addFriend(String friendSone);
367
368         /**
369          * Removes the given Sone as a friend Sone.
370          *
371          * @param friendSoneId
372          *            The ID of the friend Sone to remove
373          * @return This Sone (for method chaining)
374          */
375         public Sone removeFriend(String friendSoneId);
376
377         /**
378          * Returns the list of posts of this Sone, sorted by time, newest first.
379          *
380          * @return All posts of this Sone
381          */
382         public List<Post> getPosts();
383
384         /**
385          * Sets all posts of this Sone at once.
386          *
387          * @param posts
388          *            The new (and only) posts of this Sone
389          * @return This Sone (for method chaining)
390          */
391         public Sone setPosts(Collection<Post> posts);
392
393         /**
394          * Adds the given post to this Sone. The post will not be added if its
395          * {@link Post#getSone() Sone} is not this Sone.
396          *
397          * @param post
398          *            The post to add
399          */
400         public void addPost(Post post);
401
402         /**
403          * Removes the given post from this Sone.
404          *
405          * @param post
406          *            The post to remove
407          */
408         public void removePost(Post post);
409
410         /**
411          * Returns all replies this Sone made.
412          *
413          * @return All replies this Sone made
414          */
415         public Set<PostReply> getReplies();
416
417         /**
418          * Sets all replies of this Sone at once.
419          *
420          * @param replies
421          *            The new (and only) replies of this Sone
422          * @return This Sone (for method chaining)
423          */
424         public Sone setReplies(Collection<PostReply> replies);
425
426         /**
427          * Adds a reply to this Sone. If the given reply was not made by this Sone,
428          * nothing is added to this Sone.
429          *
430          * @param reply
431          *            The reply to add
432          */
433         public void addReply(PostReply reply);
434
435         /**
436          * Removes a reply from this Sone.
437          *
438          * @param reply
439          *            The reply to remove
440          */
441         public void removeReply(PostReply reply);
442
443         /**
444          * Returns the IDs of all liked posts.
445          *
446          * @return All liked posts’ IDs
447          */
448         public Set<String> getLikedPostIds();
449
450         /**
451          * Sets the IDs of all liked posts.
452          *
453          * @param likedPostIds
454          *            All liked posts’ IDs
455          * @return This Sone (for method chaining)
456          */
457         public Sone setLikePostIds(Set<String> likedPostIds);
458
459         /**
460          * Checks whether the given post ID is liked by this Sone.
461          *
462          * @param postId
463          *            The ID of the post
464          * @return {@code true} if this Sone likes the given post, {@code false}
465          *         otherwise
466          */
467         public boolean isLikedPostId(String postId);
468
469         /**
470          * Adds the given post ID to the list of posts this Sone likes.
471          *
472          * @param postId
473          *            The ID of the post
474          * @return This Sone (for method chaining)
475          */
476         public Sone addLikedPostId(String postId);
477
478         /**
479          * Removes the given post ID from the list of posts this Sone likes.
480          *
481          * @param postId
482          *            The ID of the post
483          * @return This Sone (for method chaining)
484          */
485         public Sone removeLikedPostId(String postId);
486
487         /**
488          * Returns the IDs of all liked replies.
489          *
490          * @return All liked replies’ IDs
491          */
492         public Set<String> getLikedReplyIds();
493
494         /**
495          * Sets the IDs of all liked replies.
496          *
497          * @param likedReplyIds
498          *            All liked replies’ IDs
499          * @return This Sone (for method chaining)
500          */
501         public Sone setLikeReplyIds(Set<String> likedReplyIds);
502
503         /**
504          * Checks whether the given reply ID is liked by this Sone.
505          *
506          * @param replyId
507          *            The ID of the reply
508          * @return {@code true} if this Sone likes the given reply, {@code false}
509          *         otherwise
510          */
511         public boolean isLikedReplyId(String replyId);
512
513         /**
514          * Adds the given reply ID to the list of replies this Sone likes.
515          *
516          * @param replyId
517          *            The ID of the reply
518          * @return This Sone (for method chaining)
519          */
520         public Sone addLikedReplyId(String replyId);
521
522         /**
523          * Removes the given post ID from the list of replies this Sone likes.
524          *
525          * @param replyId
526          *            The ID of the reply
527          * @return This Sone (for method chaining)
528          */
529         public Sone removeLikedReplyId(String replyId);
530
531         /**
532          * Returns the albums of this Sone.
533          *
534          * @return The albums of this Sone
535          */
536         public List<Album> getAlbums();
537
538         /**
539          * Returns a flattened list of all albums of this Sone. The resulting list
540          * contains parent albums before child albums so that the resulting list can
541          * be parsed in a single pass.
542          *
543          * @return The flattened albums
544          */
545         public List<Album> getAllAlbums();
546
547         /**
548          * Returns all images of a Sone. Images of a album are inserted into this
549          * list before images of all child albums.
550          *
551          * @return The list of all images
552          */
553         public List<Image> getAllImages();
554
555         /**
556          * Adds an album to this Sone.
557          *
558          * @param album
559          *            The album to add
560          */
561         public void addAlbum(Album album);
562
563         /**
564          * Sets the albums of this Sone.
565          *
566          * @param albums
567          *            The albums of this Sone
568          */
569         public void setAlbums(Collection<? extends Album> albums);
570
571         /**
572          * Removes an album from this Sone.
573          *
574          * @param album
575          *            The album to remove
576          */
577         public void removeAlbum(Album album);
578
579         /**
580          * Moves the given album up in this album’s albums. If the album is already
581          * the first album, nothing happens.
582          *
583          * @param album
584          *            The album to move up
585          * @return The album that the given album swapped the place with, or
586          *         <code>null</code> if the album did not change its place
587          */
588         public Album moveAlbumUp(Album album);
589
590         /**
591          * Moves the given album down in this album’s albums. If the album is
592          * already the last album, nothing happens.
593          *
594          * @param album
595          *            The album to move down
596          * @return The album that the given album swapped the place with, or
597          *         <code>null</code> if the album did not change its place
598          */
599         public Album moveAlbumDown(Album album);
600
601         /**
602          * Returns Sone-specific options.
603          *
604          * @return The options of this Sone
605          */
606         public Options getOptions();
607
608 }