Store posts and replies in immutable sets.
[Sone.git] / src / main / java / net / pterodactylus / sone / data / impl / SoneImpl.java
index b895304..2ca73a2 100644 (file)
@@ -33,6 +33,7 @@ import java.util.logging.Logger;
 
 import net.pterodactylus.sone.data.Album;
 import net.pterodactylus.sone.data.Client;
+import net.pterodactylus.sone.data.LocalSone;
 import net.pterodactylus.sone.data.Post;
 import net.pterodactylus.sone.data.PostReply;
 import net.pterodactylus.sone.data.Profile;
@@ -40,11 +41,14 @@ import net.pterodactylus.sone.data.Reply;
 import net.pterodactylus.sone.data.Sone;
 import net.pterodactylus.sone.data.SoneOptions;
 import net.pterodactylus.sone.data.SoneOptions.DefaultSoneOptions;
+import net.pterodactylus.sone.database.Database;
 import net.pterodactylus.sone.freenet.wot.Identity;
 import net.pterodactylus.sone.freenet.wot.OwnIdentity;
 
 import freenet.keys.FreenetURI;
 
+import com.google.common.collect.FluentIterable;
+import com.google.common.collect.ImmutableSet;
 import com.google.common.hash.Hasher;
 import com.google.common.hash.Hashing;
 
@@ -55,11 +59,14 @@ import com.google.common.hash.Hashing;
  *
  * @author <a href="mailto:bombe@pterodactylus.net">David ‘Bombe’ Roden</a>
  */
-public class SoneImpl implements Sone {
+public class SoneImpl implements LocalSone {
 
        /** The logger. */
        private static final Logger logger = getLogger("Sone.Data");
 
+       /** The database. */
+       private final Database database;
+
        /** The ID of this Sone. */
        private final String id;
 
@@ -73,7 +80,7 @@ public class SoneImpl implements Sone {
        private volatile long latestEdition;
 
        /** The time of the last inserted update. */
-       private volatile long time;
+       private final long time;
 
        /** The status of this Sone. */
        private volatile SoneStatus status = SoneStatus.unknown;
@@ -82,19 +89,16 @@ public class SoneImpl implements Sone {
        private volatile Profile profile = new Profile(this);
 
        /** The client used by the Sone. */
-       private volatile Client client;
+       private final Client client;
 
        /** Whether this Sone is known. */
        private volatile boolean known;
 
-       /** All friend Sones. */
-       private final Set<String> friendSones = new CopyOnWriteArraySet<String>();
-
        /** All posts. */
-       private final Set<Post> posts = new CopyOnWriteArraySet<Post>();
+       private final ImmutableSet<Post> posts;
 
        /** All replies. */
-       private final Set<PostReply> replies = new CopyOnWriteArraySet<PostReply>();
+       private final ImmutableSet<PostReply> replies;
 
        /** The IDs of all liked posts. */
        private final Set<String> likedPostIds = new CopyOnWriteArraySet<String>();
@@ -111,15 +115,21 @@ public class SoneImpl implements Sone {
        /**
         * Creates a new Sone.
         *
+        * @param database The database
         * @param identity
         *              The identity of the Sone
         * @param local
         *              {@code true} if the Sone is a local Sone, {@code false} otherwise
         */
-       public SoneImpl(Identity identity, boolean local) {
+       public SoneImpl(Database database, Identity identity, boolean local, long time, Client client, Collection<Post> posts, Collection<PostReply> postReplies) {
+               this.database = database;
                this.id = identity.getId();
                this.identity = identity;
                this.local = local;
+               this.time = time;
+               this.client = client;
+               this.posts = ImmutableSet.copyOf(posts);
+               this.replies = ImmutableSet.copyOf(postReplies);
        }
 
        //
@@ -235,18 +245,6 @@ public class SoneImpl implements Sone {
        }
 
        /**
-        * Sets the time of the last inserted update of this Sone.
-        *
-        * @param time
-        *              The time of the update (in milliseconds since Jan 1, 1970 UTC)
-        * @return This Sone (for method chaining)
-        */
-       public Sone setTime(long time) {
-               this.time = time;
-               return this;
-       }
-
-       /**
         * Returns the status of this Sone.
         *
         * @return The status of this Sone
@@ -309,7 +307,6 @@ public class SoneImpl implements Sone {
         * @return This Sone (for method chaining)
         */
        public Sone setClient(Client client) {
-               this.client = client;
                return this;
        }
 
@@ -339,8 +336,8 @@ public class SoneImpl implements Sone {
         *
         * @return The friend Sones of this Sone
         */
-       public List<String> getFriends() {
-               return new ArrayList<String>(friendSones);
+       public Collection<String> getFriends() {
+               return database.getFriends(this);
        }
 
        /**
@@ -352,33 +349,7 @@ public class SoneImpl implements Sone {
         *         false} otherwise
         */
        public boolean hasFriend(String friendSoneId) {
-               return friendSones.contains(friendSoneId);
-       }
-
-       /**
-        * Adds the given Sone as a friend Sone.
-        *
-        * @param friendSone
-        *              The friend Sone to add
-        * @return This Sone (for method chaining)
-        */
-       public Sone addFriend(String friendSone) {
-               if (!friendSone.equals(id)) {
-                       friendSones.add(friendSone);
-               }
-               return this;
-       }
-
-       /**
-        * Removes the given Sone as a friend Sone.
-        *
-        * @param friendSoneId
-        *              The ID of the friend Sone to remove
-        * @return This Sone (for method chaining)
-        */
-       public Sone removeFriend(String friendSoneId) {
-               friendSones.remove(friendSoneId);
-               return this;
+               return database.isFriend(this, friendSoneId);
        }
 
        /**
@@ -387,52 +358,7 @@ public class SoneImpl implements Sone {
         * @return All posts of this Sone
         */
        public List<Post> getPosts() {
-               List<Post> sortedPosts;
-               synchronized (this) {
-                       sortedPosts = new ArrayList<Post>(posts);
-               }
-               Collections.sort(sortedPosts, Post.TIME_COMPARATOR);
-               return sortedPosts;
-       }
-
-       /**
-        * Sets all posts of this Sone at once.
-        *
-        * @param posts
-        *              The new (and only) posts of this Sone
-        * @return This Sone (for method chaining)
-        */
-       public Sone setPosts(Collection<Post> posts) {
-               synchronized (this) {
-                       this.posts.clear();
-                       this.posts.addAll(posts);
-               }
-               return this;
-       }
-
-       /**
-        * Adds the given post to this Sone. The post will not be added if its {@link
-        * Post#getSone() Sone} is not this Sone.
-        *
-        * @param post
-        *              The post to add
-        */
-       public void addPost(Post post) {
-               if (post.getSone().equals(this) && posts.add(post)) {
-                       logger.log(Level.FINEST, String.format("Adding %s to “%s”.", post, getName()));
-               }
-       }
-
-       /**
-        * Removes the given post from this Sone.
-        *
-        * @param post
-        *              The post to remove
-        */
-       public void removePost(Post post) {
-               if (post.getSone().equals(this)) {
-                       posts.remove(post);
-               }
+               return FluentIterable.from(posts).toSortedList(Post.TIME_COMPARATOR);
        }
 
        /**
@@ -711,7 +637,7 @@ public class SoneImpl implements Sone {
        /** {@inheritDoc} */
        @Override
        public String toString() {
-               return getClass().getName() + "[identity=" + identity + ",friends(" + friendSones.size() + "),posts(" + posts.size() + "),replies(" + replies.size() + "),albums(" + getRootAlbum().getAlbums().size() + ")]";
+               return getClass().getName() + "[identity=" + identity + ",posts(" + posts.size() + "),replies(" + replies.size() + "),albums(" + getRootAlbum().getAlbums().size() + ")]";
        }
 
 }