Remove the shell stuff, make objects mutable.
authorDavid ‘Bombe’ Roden <bombe@pterodactylus.net>
Fri, 15 Oct 2010 14:10:44 +0000 (16:10 +0200)
committerDavid ‘Bombe’ Roden <bombe@pterodactylus.net>
Fri, 15 Oct 2010 14:10:44 +0000 (16:10 +0200)
src/main/java/net/pterodactylus/sone/core/Core.java
src/main/java/net/pterodactylus/sone/data/Post.java
src/main/java/net/pterodactylus/sone/data/PostShell.java [deleted file]
src/main/java/net/pterodactylus/sone/data/Reply.java
src/main/java/net/pterodactylus/sone/data/ReplyShell.java [deleted file]
src/main/java/net/pterodactylus/sone/data/Shell.java [deleted file]
src/main/java/net/pterodactylus/sone/data/ShellCache.java [deleted file]
src/main/java/net/pterodactylus/sone/data/ShellCreator.java [deleted file]
src/main/java/net/pterodactylus/sone/data/Sone.java
src/main/java/net/pterodactylus/sone/data/SoneShell.java [deleted file]
src/main/java/net/pterodactylus/sone/web/FollowSonePage.java

index 72c36d8..3164484 100644 (file)
@@ -29,14 +29,9 @@ import java.util.logging.Logger;
 
 import net.pterodactylus.sone.core.SoneException.Type;
 import net.pterodactylus.sone.data.Post;
-import net.pterodactylus.sone.data.PostShell;
 import net.pterodactylus.sone.data.Profile;
 import net.pterodactylus.sone.data.Reply;
-import net.pterodactylus.sone.data.ReplyShell;
-import net.pterodactylus.sone.data.Shell;
-import net.pterodactylus.sone.data.ShellCache;
 import net.pterodactylus.sone.data.Sone;
-import net.pterodactylus.sone.data.SoneShell;
 import net.pterodactylus.util.config.Configuration;
 import net.pterodactylus.util.config.ConfigurationException;
 import net.pterodactylus.util.logging.Logging;
@@ -71,13 +66,13 @@ public class Core extends AbstractService {
        /* various caches follow here. */
 
        /** Cache for all known Sones. */
-       private final ShellCache<Sone> soneCache = new ShellCache<Sone>(SoneShell.creator);
+       private final Map<String, Sone> soneCache = new HashMap<String, Sone>();
 
        /** Cache for all known posts. */
-       private final ShellCache<Post> postCache = new ShellCache<Post>(PostShell.creator);
+       private final Map<String, Post> postCache = new HashMap<String, Post>();
 
        /** Cache for all known replies. */
-       private final ShellCache<Reply> replyCache = new ShellCache<Reply>(ReplyShell.creator);
+       private final Map<String, Reply> replyCache = new HashMap<String, Reply>();
 
        /**
         * Creates a new core.
@@ -125,18 +120,19 @@ public class Core extends AbstractService {
        }
 
        /**
-        * Returns a Sone or a {@link Shell} around one for the given ID.
+        * Returns the Sone with the given ID, or an empty Sone that has been
+        * initialized with the given ID.
         *
         * @param soneId
         *            The ID of the Sone
-        * @return The Sone, or a {@link Shell} around one
+        * @return The Sone
         */
        public Sone getSone(String soneId) {
-               Sone sone = soneCache.get(soneId);
-               if (sone instanceof SoneShell) {
-                       soneCache.put(soneId, sone = ((SoneShell) sone).getShelled());
+               if (!soneCache.containsKey(soneId)) {
+                       Sone sone = new Sone(soneId);
+                       soneCache.put(soneId, sone);
                }
-               return sone;
+               return soneCache.get(soneId);
        }
 
        //
@@ -166,8 +162,10 @@ public class Core extends AbstractService {
         *            The sone to watch
         */
        public void addRemoteSone(Sone sone) {
-               Sone updatedSone = soneCache.put(sone.getId(), sone);
-               soneDownloader.addSone(updatedSone);
+               if (!soneCache.containsKey(sone.getId())) {
+                       soneCache.put(sone.getId(), sone);
+               }
+               soneDownloader.addSone(sone);
        }
 
        /**
@@ -217,7 +215,7 @@ public class Core extends AbstractService {
                Sone sone;
                try {
                        logger.log(Level.FINEST, "Creating new Sone “%s” at %s (%s)…", new Object[] { name, finalRequestUri, finalInsertUri });
-                       sone = new Sone(UUID.randomUUID(), name, new FreenetURI(finalRequestUri).setKeyType("USK").setDocName("Sone-" + name), new FreenetURI(finalInsertUri).setKeyType("USK").setDocName("Sone-" + name));
+                       sone = new Sone(UUID.randomUUID().toString()).setName(name).setRequestUri(new FreenetURI(finalRequestUri).setKeyType("USK").setDocName("Sone-" + name)).setInsertUri(new FreenetURI(finalInsertUri).setKeyType("USK").setDocName("Sone-" + name));
                        sone.setProfile(new Profile());
                        /* set modification counter to 1 so it is inserted immediately. */
                        sone.setModificationCounter(1);
@@ -296,7 +294,7 @@ public class Core extends AbstractService {
                                profile.setFirstName(firstName);
                                profile.setMiddleName(middleName);
                                profile.setLastName(lastName);
-                               Sone sone = new Sone(UUID.fromString(id), name, new FreenetURI(requestUri), new FreenetURI(insertUri));
+                               Sone sone = new Sone(id).setName(name).setRequestUri(new FreenetURI(requestUri)).setInsertUri(new FreenetURI(insertUri));
                                soneCache.put(id, sone);
                                sone.setProfile(profile);
                                int postId = 0;
@@ -308,7 +306,7 @@ public class Core extends AbstractService {
                                        }
                                        long time = configuration.getLongValue(postPrefix + "/Time").getValue(null);
                                        String text = configuration.getStringValue(postPrefix + "/Text").getValue(null);
-                                       Post post = new Post(UUID.fromString(id), sone, time, text);
+                                       Post post = new Post(id, sone, time, text);
                                        postCache.put(id, post);
                                        sone.addPost(post);
                                } while (true);
@@ -319,16 +317,14 @@ public class Core extends AbstractService {
                                        if (replyId == null) {
                                                break;
                                        }
-                                       Sone replySone = soneCache.get(configuration.getStringValue(replyPrefix + "/Sone/ID").getValue(null));
+                                       Sone replySone = getSone(configuration.getStringValue(replyPrefix + "/Sone/ID").getValue(null));
                                        String replySoneKey = configuration.getStringValue(replyPrefix + "/Sone/Key").getValue(null);
                                        String replySoneName = configuration.getStringValue(replyPrefix + "/Sone/Name").getValue(null);
-                                       if (replySone instanceof SoneShell) {
-                                               ((SoneShell) replySone).setRequestUri(new FreenetURI(replySoneKey)).setName(replySoneName);
-                                       }
+                                       replySone.setRequestUri(new FreenetURI(replySoneKey)).setName(replySoneName);
                                        Post replyPost = postCache.get(configuration.getStringValue(replyPrefix + "/Post").getValue(null));
                                        long replyTime = configuration.getLongValue(replyPrefix + "/Time").getValue(null);
                                        String replyText = configuration.getStringValue(replyPrefix + "/Text").getValue(null);
-                                       Reply reply = new ReplyShell().setSone(replySone).setPost(replyPost).setTime(replyTime).setText(replyText).getShelled();
+                                       Reply reply = new Reply(replyId, replySone, replyPost, replyTime, replyText);
                                        replyCache.put(replyId, reply);
                                } while (true);
 
@@ -341,11 +337,9 @@ public class Core extends AbstractService {
                                                break;
                                        }
                                        Sone friendSone = soneCache.get(friendId);
-                                       if (friendSone instanceof SoneShell) {
-                                               String friendKey = configuration.getStringValue(friendPrefix + "/Key").getValue(null);
-                                               String friendName = configuration.getStringValue(friendPrefix + "/Name").getValue(null);
-                                               ((SoneShell) friendSone).setRequestUri(new FreenetURI(friendKey)).setName(friendName);
-                                       }
+                                       String friendKey = configuration.getStringValue(friendPrefix + "/Key").getValue(null);
+                                       String friendName = configuration.getStringValue(friendPrefix + "/Name").getValue(null);
+                                       friendSone.setRequestUri(new FreenetURI(friendKey)).setName(friendName);
                                        addRemoteSone(friendSone);
                                        sone.addFriend(sone);
                                }
index d468af6..5124b49 100644 (file)
@@ -37,13 +37,13 @@ public class Post {
        private final UUID id;
 
        /** The Sone this post belongs to. */
-       private final Sone sone;
+       private Sone sone;
 
        /** The time of the post (in milliseconds since Jan 1, 1970 UTC). */
-       private final long time;
+       private long time;
 
        /** The text of the post. */
-       private final String text;
+       private String text;
 
        /** The replies that have been loaded for this post. */
        private final Set<Reply> replies = new HashSet<Reply>();
@@ -71,7 +71,7 @@ public class Post {
         *            The text of the post
         */
        public Post(Sone sone, long time, String text) {
-               this(UUID.randomUUID(), sone, time, text);
+               this(UUID.randomUUID().toString(), sone, time, text);
        }
 
        /**
@@ -86,8 +86,8 @@ public class Post {
         * @param text
         *            The text of the post
         */
-       public Post(UUID id, Sone sone, long time, String text) {
-               this.id = id;
+       public Post(String id, Sone sone, long time, String text) {
+               this.id = UUID.fromString(id);
                this.sone = sone;
                this.time = time;
                this.text = text;
@@ -116,6 +116,18 @@ public class Post {
        }
 
        /**
+        * Sets the Sone of this post.
+        *
+        * @param sone
+        *            The Sone of this post
+        * @return This post (for method chaining)
+        */
+       public Post setSone(Sone sone) {
+               this.sone = sone;
+               return this;
+       }
+
+       /**
         * Returns the time of the post.
         *
         * @return The time of the post (in milliseconds since Jan 1, 1970 UTC)
@@ -125,6 +137,18 @@ public class Post {
        }
 
        /**
+        * Sets the time of this post.
+        *
+        * @param time
+        *            The time of this post (in milliseconds since Jan 1, 1970 UTC)
+        * @return This post (for method chaining)
+        */
+       public Post setTime(long time) {
+               this.time = time;
+               return this;
+       }
+
+       /**
         * Returns the text of the post.
         *
         * @return The text of the post
@@ -134,6 +158,18 @@ public class Post {
        }
 
        /**
+        * Sets the text of this post.
+        *
+        * @param text
+        *            The text of this post
+        * @return This post (for method chaining)
+        */
+       public Post setText(String text) {
+               this.text = text;
+               return this;
+       }
+
+       /**
         * Returns all replies to this post in unspecified order.
         *
         * @return All replies to this post
@@ -205,7 +241,7 @@ public class Post {
         */
        @Override
        public String toString() {
-               return getClass().getName() + "[id=" + getId() + ",sone=" + getSone() + ",time=" + getTime() + ",text=" + getText() + "]";
+               return getClass().getName() + "[id=" + id + ",sone=" + sone + ",time=" + time + ",text=" + text + ",replies(" + replies.size() + ")]";
        }
 
 }
diff --git a/src/main/java/net/pterodactylus/sone/data/PostShell.java b/src/main/java/net/pterodactylus/sone/data/PostShell.java
deleted file mode 100644 (file)
index 05b0045..0000000
+++ /dev/null
@@ -1,243 +0,0 @@
-/*
- * Sone - PostShell.java - Copyright © 2010 David Roden
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-package net.pterodactylus.sone.data;
-
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.Comparator;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Set;
-import java.util.UUID;
-import java.util.logging.Level;
-import java.util.logging.Logger;
-
-import net.pterodactylus.util.logging.Logging;
-
-/**
- * {@link Shell} around a {@link Post} that has not yet been retrieved from
- * Freenet.
- *
- * @author <a href="mailto:bombe@pterodactylus.net">David ‘Bombe’ Roden</a>
- */
-public class PostShell extends Post implements Shell<Post> {
-
-       /** The logger. */
-       private static final Logger logger = Logging.getLogger(PostShell.class);
-
-       /** The shell creator. */
-       public static final ShellCreator<Post> creator = new ShellCreator<Post>() {
-
-               @Override
-               public Shell<Post> createShell(String id) {
-                       return new PostShell().setId(id);
-               }
-       };
-
-       /** The GUID of the post. */
-       private UUID id;
-
-       /** The Sone this post belongs to. */
-       private Sone sone;
-
-       /** The time of the post (in milliseconds since Jan 1, 1970 UTC). */
-       private Long time;
-
-       /** The text of the post. */
-       private String text;
-
-       /** The replies that have been loaded for this post. */
-       private final Set<Reply> replies = new HashSet<Reply>();
-
-       /**
-        * Creates a new post shell.
-        */
-       public PostShell() {
-               super(null, null);
-       }
-
-       //
-       // ACCESSORS
-       //
-
-       /**
-        * Returns the ID of the post.
-        *
-        * @return The ID of the post
-        */
-       @Override
-       public String getId() {
-               return id.toString();
-       }
-
-       /**
-        * Sets the ID of the post.
-        *
-        * @param id
-        *            The ID of the post
-        * @return This post shell (for method chaining)
-        */
-       public PostShell setId(String id) {
-               try {
-                       this.id = UUID.fromString(id);
-               } catch (IllegalArgumentException iae1) {
-                       logger.log(Level.WARNING, "Invalid ID: “" + id + "”.", iae1);
-                       this.id = UUID.randomUUID();
-               }
-               return this;
-       }
-
-       /**
-        * Returns the Sone this post belongs to.
-        *
-        * @return The Sone of this post
-        */
-       @Override
-       public Sone getSone() {
-               return sone;
-       }
-
-       /**
-        * Sets the Sone the post belongs to.
-        *
-        * @param sone
-        *            The Sone the post belongs to
-        * @return This post shell (for method chaining)
-        */
-       public PostShell setSone(Sone sone) {
-               this.sone = sone;
-               return this;
-       }
-
-       /**
-        * Returns the time of the post.
-        *
-        * @return The time of the post (in milliseconds since Jan 1, 1970 UTC)
-        */
-       @Override
-       public long getTime() {
-               return (time != null) ? time : 0;
-       }
-
-       /**
-        * Sets the time of the post.
-        *
-        * @param time
-        *            The time of the post (in milliseconds since Jan 1, 1970 UTC)
-        * @return This post shell (for method chaining)
-        */
-       public PostShell setTime(long time) {
-               this.time = time;
-               return this;
-       }
-
-       /**
-        * Returns the text of the post.
-        *
-        * @return The text of the post
-        */
-       @Override
-       public String getText() {
-               return text;
-       }
-
-       /**
-        * Sets the text of the post.
-        *
-        * @param text
-        *            The text of the post.
-        * @return This post shell (for method chaining)
-        */
-       public PostShell setText(String text) {
-               this.text = text;
-               return this;
-       }
-
-       /**
-        * Returns all replies to this post in unspecified order.
-        *
-        * @return All replies to this post
-        */
-       @Override
-       public List<Reply> getReplies() {
-               List<Reply> sortedReplies = new ArrayList<Reply>(replies);
-               Collections.sort(sortedReplies, new Comparator<Reply>() {
-
-                       @Override
-                       public int compare(Reply leftReply, Reply rightReply) {
-                               return (int) Math.max(Integer.MIN_VALUE, Math.min(Integer.MAX_VALUE, leftReply.getTime() - rightReply.getTime()));
-                       }
-
-               });
-               return sortedReplies;
-       }
-
-       /**
-        * Adds a reply to this post. The reply will not be added if its
-        * {@link Reply#getPost() post} is not equal to this post.
-        *
-        * @param reply
-        *            The reply to add
-        */
-       @Override
-       public void addReply(Reply reply) {
-               if (reply.getPost().equals(this)) {
-                       replies.add(reply);
-               }
-       }
-
-       /**
-        * Removes a reply from this post.
-        *
-        * @param reply
-        *            The reply to remove
-        */
-       @Override
-       public void removeReply(Reply reply) {
-               if (reply.getPost().equals(this)) {
-                       replies.remove(reply);
-               }
-       }
-
-       //
-       // INTERFACE Shell
-       //
-
-       /**
-        * {@inheritDoc}
-        */
-       @Override
-       public boolean canUnshell() {
-               return (id != null) && (sone != null) && (!(sone instanceof Shell<?>)) && (time != null) && (text != null);
-       }
-
-       /**
-        * {@inheritDoc}
-        */
-       @Override
-       public Post getShelled() {
-               if (canUnshell()) {
-                       Post post = new Post(id, sone, time, text);
-                       for (Reply reply : replies) {
-                               post.addReply(reply);
-                       }
-               }
-               return this;
-       }
-
-}
index 44aaf89..c97d57b 100644 (file)
@@ -27,20 +27,20 @@ import java.util.UUID;
  */
 public class Reply {
 
-       /** The Sone that posted this reply. */
-       private final Sone sone;
-
        /** The ID of the reply. */
        private final UUID id;
 
+       /** The Sone that posted this reply. */
+       private Sone sone;
+
        /** The Post this reply refers to. */
-       private final Post post;
+       private Post post;
 
        /** The time of the reply. */
-       private final long time;
+       private long time;
 
        /** The text of the reply. */
-       private final String text;
+       private String text;
 
        /**
         * Creates a new reply.
@@ -69,7 +69,7 @@ public class Reply {
         *            The text of the reply
         */
        public Reply(Sone sone, Post post, long time, String text) {
-               this(sone, UUID.randomUUID(), post, time, text);
+               this(UUID.randomUUID().toString(), sone, post, time, text);
        }
 
        /**
@@ -86,9 +86,9 @@ public class Reply {
         * @param text
         *            The text of the reply
         */
-       public Reply(Sone sone, UUID id, Post post, long time, String text) {
+       public Reply(String id, Sone sone, Post post, long time, String text) {
+               this.id = UUID.fromString(id);
                this.sone = sone;
-               this.id = id;
                this.post = post;
                this.time = time;
                this.text = text;
@@ -99,6 +99,15 @@ public class Reply {
        //
 
        /**
+        * Returns the ID of the reply.
+        *
+        * @return The ID of the reply
+        */
+       public String getId() {
+               return id.toString();
+       }
+
+       /**
         * Returns the Sone that posted this reply.
         *
         * @return The Sone that posted this reply
@@ -108,12 +117,15 @@ public class Reply {
        }
 
        /**
-        * Returns the ID of the reply.
+        * Sets the Sone that posted this reply.
         *
-        * @return The ID of the reply
+        * @param sone
+        *            The Sone that posted this reply
+        * @return This reply (for method chaining)
         */
-       public String getId() {
-               return id.toString();
+       public Reply setSone(Sone sone) {
+               this.sone = sone;
+               return this;
        }
 
        /**
@@ -126,6 +138,18 @@ public class Reply {
        }
 
        /**
+        * Sets the post this reply refers to.
+        *
+        * @param post
+        *            The post this reply refers to
+        * @return This reply (for method chaining)
+        */
+       public Reply setPost(Post post) {
+               this.post = post;
+               return this;
+       }
+
+       /**
         * Returns the time of the reply.
         *
         * @return The time of the reply (in milliseconds since Jan 1, 1970 UTC)
@@ -135,6 +159,18 @@ public class Reply {
        }
 
        /**
+        * Sets the time of this reply.
+        *
+        * @param time
+        *            The time of this reply (in milliseconds since Jan 1, 1970 UTC)
+        * @return This reply (for method chaining)
+        */
+       public Reply setTime(long time) {
+               this.time = time;
+               return this;
+       }
+
+       /**
         * Returns the text of the reply.
         *
         * @return The text of the reply
@@ -143,6 +179,18 @@ public class Reply {
                return text;
        }
 
+       /**
+        * Sets the text of this reply.
+        *
+        * @param text
+        *            The text of this reply
+        * @return This reply (for method chaining)
+        */
+       public Reply setText(String text) {
+               this.text = text;
+               return this;
+       }
+
        //
        // OBJECT METHODS
        //
@@ -152,7 +200,7 @@ public class Reply {
         */
        @Override
        public int hashCode() {
-               return sone.hashCode() ^ id.hashCode() ^ post.hashCode() ^ (int) (time >> 32) ^ (int) (time & 0xffffffff);
+               return sone.hashCode() ^ id.hashCode() ^ post.hashCode() ^ (int) (time >> 32) ^ (int) (time & 0xffffffff) ^ text.hashCode();
        }
 
        /**
@@ -167,4 +215,12 @@ public class Reply {
                return reply.sone.equals(sone) && reply.id.equals(id) && reply.post.equals(post) && (reply.time == time) && reply.text.equals(text);
        }
 
+       /**
+        * {@inheritDoc}
+        */
+       @Override
+       public String toString() {
+               return getClass().getName() + "[id=" + id + ",sone=" + sone + ",post=" + post + ",time=" + time + ",text=" + text + "]";
+       }
+
 }
diff --git a/src/main/java/net/pterodactylus/sone/data/ReplyShell.java b/src/main/java/net/pterodactylus/sone/data/ReplyShell.java
deleted file mode 100644 (file)
index 3886e63..0000000
+++ /dev/null
@@ -1,210 +0,0 @@
-/*
- * Sone - ReplyShell.java - Copyright © 2010 David Roden
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-package net.pterodactylus.sone.data;
-
-import java.util.UUID;
-import java.util.logging.Level;
-import java.util.logging.Logger;
-
-import net.pterodactylus.util.logging.Logging;
-
-/**
- * A shell around a {@link Reply} for replies that have not yet been retrieved
- * from Freenet.
- *
- * @author <a href="mailto:bombe@pterodactylus.net">David ‘Bombe’ Roden</a>
- */
-public class ReplyShell extends Reply implements Shell<Reply> {
-
-       /** The logger. */
-       private static final Logger logger = Logging.getLogger(ReplyShell.class);
-
-       /** The shell creator. */
-       public static final ShellCreator<Reply> creator = new ShellCreator<Reply>() {
-
-               @Override
-               public Shell<Reply> createShell(String id) {
-                       return new ReplyShell().setId(id);
-               }
-       };
-
-       /** The Sone that posted this reply. */
-       private Sone sone;
-
-       /** The ID of the reply. */
-       private UUID id;
-
-       /** The Post this reply refers to. */
-       private Post post;
-
-       /** The time of the reply. */
-       private Long time;
-
-       /** The text of the reply. */
-       private String text;
-
-       /**
-        * Creates a new reply shell.
-        */
-       public ReplyShell() {
-               super(null, null, null);
-       }
-
-       //
-       // ACCESSORS
-       //
-
-       /**
-        * Returns the Sone that posted this reply.
-        *
-        * @return The Sone that posted this reply
-        */
-       @Override
-       public Sone getSone() {
-               return sone;
-       }
-
-       /**
-        * Sets the Sone that posted this reply.
-        *
-        * @param sone
-        *            The sone that pasted this reply
-        * @return This reply shell (for method chaining)
-        */
-       public ReplyShell setSone(Sone sone) {
-               this.sone = sone;
-               return this;
-       }
-
-       /**
-        * Returns the ID of the reply.
-        *
-        * @return The ID of the reply
-        */
-       @Override
-       public String getId() {
-               return id.toString();
-       }
-
-       /**
-        * Sets the ID of this reply.
-        *
-        * @param id
-        *            The ID of this reply
-        * @return This reply shell (for method chaining)
-        */
-       public ReplyShell setId(String id) {
-               try {
-                       this.id = UUID.fromString(id);
-               } catch (IllegalArgumentException iae1) {
-                       logger.log(Level.WARNING, "Invalid ID: “" + id + "”.", iae1);
-                       this.id = UUID.randomUUID();
-               }
-               return this;
-       }
-
-       /**
-        * Returns the post this reply refers to.
-        *
-        * @return The post this reply refers to
-        */
-       @Override
-       public Post getPost() {
-               return post;
-       }
-
-       /**
-        * Sets the post this reply refers to.
-        *
-        * @param post
-        *            The post this reply refers to
-        * @return This reply shell (for method chaining)
-        */
-       public ReplyShell setPost(Post post) {
-               this.post = post;
-               return this;
-       }
-
-       /**
-        * Returns the time of the reply.
-        *
-        * @return The time of the reply (in milliseconds since Jan 1, 1970 UTC)
-        */
-       @Override
-       public long getTime() {
-               return (time != null) ? time : 0;
-       }
-
-       /**
-        * Sets the time of this reply.
-        *
-        * @param time
-        *            The time of this reply (in milliseconds since Jan 1, 1970 UTC)
-        * @return This reply shell (for method chaining)
-        */
-       public ReplyShell setTime(long time) {
-               this.time = time;
-               return this;
-       }
-
-       /**
-        * Returns the text of the reply.
-        *
-        * @return The text of the reply
-        */
-       @Override
-       public String getText() {
-               return text;
-       }
-
-       /**
-        * Sets the text of the reply.
-        *
-        * @param text
-        *            The text of the reply
-        * @return This reply shell (for method chaining)
-        */
-       public ReplyShell setText(String text) {
-               this.text = text;
-               return this;
-       }
-
-       //
-       // INTERFACE Shell
-       //
-
-       /**
-        * {@inheritDoc}
-        */
-       @Override
-       public boolean canUnshell() {
-               return (sone != null) && (!(sone instanceof Shell<?>)) && (id != null) && (post != null) && (!(post instanceof Shell<?>)) && (time != null) && (text != null);
-       }
-
-       /**
-        * {@inheritDoc}
-        */
-       @Override
-       public Reply getShelled() {
-               if (canUnshell()) {
-                       return new Reply(sone, id, post, time, text);
-               }
-               return this;
-       }
-
-}
diff --git a/src/main/java/net/pterodactylus/sone/data/Shell.java b/src/main/java/net/pterodactylus/sone/data/Shell.java
deleted file mode 100644 (file)
index 8d7068e..0000000
+++ /dev/null
@@ -1,47 +0,0 @@
-/*
- * Sone - Shell.java - Copyright © 2010 David Roden
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-package net.pterodactylus.sone.data;
-
-/**
- * Marker interface for classes that are only empty shells for objects that have
- * not yet been retrieved from Freenet.
- *
- * @param <T>
- *            The type of object that is shelled
- * @author <a href="mailto:bombe@pterodactylus.net">David ‘Bombe’ Roden</a>
- */
-public interface Shell<T> {
-
-       /**
-        * Returns whether the shelled object can be unshelled now.
-        *
-        * @return {@code true} if {@link #getShelled()} can return the shelled
-        *         object, {@code false} otherwise
-        */
-       public boolean canUnshell();
-
-       /**
-        * Returns the object that is shelled. This method with return the shell
-        * itself if {@link #canUnshell()} returns {@code false} and will return the
-        * real object once {@link #canUnshell()} returns true.
-        *
-        * @return The shelled object, or the shell itself
-        */
-       public T getShelled();
-
-}
diff --git a/src/main/java/net/pterodactylus/sone/data/ShellCache.java b/src/main/java/net/pterodactylus/sone/data/ShellCache.java
deleted file mode 100644 (file)
index 7e28285..0000000
+++ /dev/null
@@ -1,110 +0,0 @@
-/*
- * Sone - ShellCache.java - Copyright © 2010 David Roden
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-package net.pterodactylus.sone.data;
-
-import java.util.Collection;
-import java.util.HashMap;
-import java.util.Map;
-
-/**
- * {@link Shell}-aware cache that will replace {@link Shell}s with the real
- * objects but not the other way around.
- *
- * @param <T>
- *            The type of the cached objects
- * @author <a href="mailto:bombe@pterodactylus.net">David ‘Bombe’ Roden</a>
- */
-public class ShellCache<T> {
-
-       /** The object cache. */
-       private final Map<String, T> objectCache = new HashMap<String, T>();
-
-       /** The shell cache. */
-       private final Map<String, Shell<T>> shellCache = new HashMap<String, Shell<T>>();
-
-       /** The shell creator. */
-       private final ShellCreator<T> shellCreator;
-
-       /**
-        * Creates a new shell cache.
-        *
-        * @param shellCreator
-        *            The creator for new shells
-        */
-       public ShellCache(ShellCreator<T> shellCreator) {
-               this.shellCreator = shellCreator;
-       }
-
-       //
-       // ACCESSORS
-       //
-
-       /**
-        * Stores the given object in this cache. If the given object is not a
-        * {@link Shell}, it is stored. If it is a {@link Shell} it is only stored
-        * if there is no object stored for the given ID.
-        *
-        * @param id
-        *            The ID of the object
-        * @param object
-        *            The object to store
-        * @return The real object, or the shell if there is no real object yet
-        */
-       @SuppressWarnings("unchecked")
-       public T put(String id, T object) {
-               if (!(object instanceof Shell<?>)) {
-                       objectCache.put(id, object);
-                       shellCache.remove(id);
-                       return object;
-               }
-               if (objectCache.containsKey(id)) {
-                       return objectCache.get(id);
-               }
-               shellCache.put(id, (Shell<T>) object);
-               return object;
-       }
-
-       /**
-        * Returns the post with the given ID.
-        *
-        * @param id
-        *            The ID of the post
-        * @return The post with the given ID, or {@code null} if there is no post
-        *         with the given ID
-        */
-       public T get(String id) {
-               if (!objectCache.containsKey(id)) {
-                       if (!shellCache.containsKey(id)) {
-                               Shell<T> shell = shellCreator.createShell(id);
-                               shellCache.put(id, shell);
-                       }
-                       return shellCache.get(id).getShelled();
-               }
-               return objectCache.get(id);
-       }
-
-       /**
-        * Returns all cached shells.
-        *
-        * @return All cached shells
-        */
-       public Collection<Shell<T>> getShells() {
-               return shellCache.values();
-       }
-
-}
diff --git a/src/main/java/net/pterodactylus/sone/data/ShellCreator.java b/src/main/java/net/pterodactylus/sone/data/ShellCreator.java
deleted file mode 100644 (file)
index 6835b00..0000000
+++ /dev/null
@@ -1,38 +0,0 @@
-/*
- * Sone - ShellCreator.java - Copyright © 2010 David Roden
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-package net.pterodactylus.sone.data;
-
-/**
- * Creator interface for {@link ShellCache}.
- *
- * @param <T>
- *            The type of the real object
- * @author <a href="mailto:bombe@pterodactylus.net">David ‘Bombe’ Roden</a>
- */
-public interface ShellCreator<T> {
-
-       /**
-        * Creates a new shell.
-        *
-        * @param id
-        *            The ID of the shell object
-        * @return The new shell
-        */
-       public Shell<T> createShell(String id);
-
-}
index 6d729c3..4d50527 100644 (file)
@@ -47,7 +47,7 @@ public class Sone {
        private final UUID id;
 
        /** The name of this Sone. */
-       private final String name;
+       private String name;
 
        /** The URI under which the Sone is stored in Freenet. */
        private FreenetURI requestUri;
@@ -76,32 +76,9 @@ public class Sone {
         *
         * @param id
         *            The ID of this Sone
-        * @param name
-        *            The name of the Sone
-        * @param requestUri
-        *            The request URI of the Sone
-        */
-       public Sone(UUID id, String name, FreenetURI requestUri) {
-               this(id, name, requestUri, null);
-       }
-
-       /**
-        * Creates a new Sone.
-        *
-        * @param id
-        *            The ID of this Sone
-        * @param name
-        *            The name of the Sone
-        * @param requestUri
-        *            The request URI of the Sone
-        * @param insertUri
-        *            The insert URI of the Sone
         */
-       public Sone(UUID id, String name, FreenetURI requestUri, FreenetURI insertUri) {
-               this.id = id;
-               this.name = name;
-               this.requestUri = requestUri;
-               this.insertUri = insertUri;
+       public Sone(String id) {
+               this.id = UUID.fromString(id);
        }
 
        //
@@ -127,6 +104,18 @@ public class Sone {
        }
 
        /**
+        * Sets the name of this Sone.
+        *
+        * @param name
+        *            The name of this Sone
+        * @return This sone (for method chaining)
+        */
+       public Sone setName(String name) {
+               this.name = name;
+               return this;
+       }
+
+       /**
         * Returns the request URI of this Sone.
         *
         * @return The request URI of this Sone
@@ -136,6 +125,18 @@ public class Sone {
        }
 
        /**
+        * Sets the request URI of this Sone.
+        *
+        * @param requestUri
+        *            The request URI of this Sone
+        * @return This Sone (for method chaining)
+        */
+       public Sone setRequestUri(FreenetURI requestUri) {
+               this.requestUri = requestUri;
+               return this;
+       }
+
+       /**
         * Returns the insert URI of this Sone.
         *
         * @return The insert URI of this Sone
@@ -145,6 +146,18 @@ public class Sone {
        }
 
        /**
+        * Sets the insert URI of this Sone.
+        *
+        * @param insertUri
+        *            The insert URI of this Sone
+        * @return This Sone (for method chaining)
+        */
+       public Sone setInsertUri(FreenetURI insertUri) {
+               this.insertUri = insertUri;
+               return this;
+       }
+
+       /**
         * Returns a copy of the profile. If you want to update values in the
         * profile of this Sone, update the values in the returned {@link Profile}
         * and use {@link #setProfile(Profile)} to change the profile in this Sone.
@@ -267,6 +280,7 @@ public class Sone {
         * @return All replies this Sone made
         */
        public Set<Reply> getReplies() {
+               logger.log(Level.FINEST, "Friends of %s: %s", new Object[] { this, friendSones });
                return Collections.unmodifiableSet(replies);
        }
 
@@ -324,7 +338,9 @@ public class Sone {
                /* TODO - check for the correct URI. */
                long latestEdition = requestUri.getSuggestedEdition();
                this.requestUri = this.requestUri.setSuggestedEdition(latestEdition);
-               this.insertUri = this.insertUri.setSuggestedEdition(latestEdition);
+               if (this.insertUri != null) {
+                       this.insertUri = this.insertUri.setSuggestedEdition(latestEdition);
+               }
        }
 
        //
@@ -336,7 +352,7 @@ public class Sone {
         */
        @Override
        public int hashCode() {
-               return getId().hashCode();
+               return id.hashCode();
        }
 
        /**
@@ -347,7 +363,7 @@ public class Sone {
                if (!(object instanceof Sone)) {
                        return false;
                }
-               return ((Sone) object).id.equals(getId());
+               return ((Sone) object).id.equals(id);
        }
 
        /**
@@ -355,7 +371,7 @@ public class Sone {
         */
        @Override
        public String toString() {
-               return getClass().getName() + "[id=" + getId() + ",name=" + getName() + ",requestUri=" + getRequestUri() + ",insertUri=" + getInsertUri() + ",friends(" + friendSones.size() + "),posts(" + posts.size() + "),replies(" + replies.size() + ")]";
+               return getClass().getName() + "[id=" + id + ",name=" + name + ",requestUri=" + requestUri + ",insertUri=" + insertUri + ",friends(" + friendSones.size() + "),posts(" + posts.size() + "),replies(" + replies.size() + ")]";
        }
 
 }
diff --git a/src/main/java/net/pterodactylus/sone/data/SoneShell.java b/src/main/java/net/pterodactylus/sone/data/SoneShell.java
deleted file mode 100644 (file)
index 9063d31..0000000
+++ /dev/null
@@ -1,333 +0,0 @@
-/*
- * Sone - SoneShell.java - Copyright © 2010 David Roden
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-package net.pterodactylus.sone.data;
-
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.Comparator;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Set;
-import java.util.UUID;
-import java.util.logging.Level;
-import java.util.logging.Logger;
-
-import net.pterodactylus.util.logging.Logging;
-import freenet.keys.FreenetURI;
-
-/**
- * {@link Shell} around a {@link Sone} that has not yet been retrieved.
- *
- * @author <a href="mailto:bombe@pterodactylus.net">David ‘Bombe’ Roden</a>
- */
-public class SoneShell extends Sone implements Shell<Sone> {
-
-       /** The logger. */
-       private static final Logger logger = Logging.getLogger(SoneShell.class);
-
-       /** The shell creator. */
-       public static final ShellCreator<Sone> creator = new ShellCreator<Sone>() {
-
-               @Override
-               public Shell<Sone> createShell(String id) {
-                       return new SoneShell().setId(id);
-               }
-       };
-
-       /** A GUID for this Sone. */
-       private UUID id;
-
-       /** The name of this Sone. */
-       private String name;
-
-       /** The URI under which the Sone is stored in Freenet. */
-       private FreenetURI requestUri;
-
-       /** The profile of this Sone. */
-       private Profile profile;
-
-       /** All friend Sones. */
-       private final Set<Sone> friendSones = new HashSet<Sone>();
-
-       /** All posts. */
-       private final List<Post> posts = new ArrayList<Post>();
-
-       /** All replies. */
-       private final Set<Reply> replies = new HashSet<Reply>();
-
-       /**
-        * Creates a new Sone shell.
-        */
-       public SoneShell() {
-               super(null, null, null);
-       }
-
-       //
-       // ACCESSORS
-       //
-
-       /**
-        * Returns the ID of this Sone.
-        *
-        * @return The ID of this Sone
-        */
-       @Override
-       public String getId() {
-               return id.toString();
-       }
-
-       /**
-        * Sets the ID of the Sone.
-        *
-        * @param id
-        *            The ID of the Sone
-        * @return This Sone shell (for method chaining)
-        */
-       public SoneShell setId(String id) {
-               try {
-                       this.id = UUID.fromString(id);
-               } catch (IllegalArgumentException iae1) {
-                       logger.log(Level.WARNING, "Invalid ID: “" + id + "”.", iae1);
-                       this.id = UUID.randomUUID();
-               }
-               return this;
-       }
-
-       /**
-        * Returns the name of this Sone.
-        *
-        * @return The name of this Sone
-        */
-       @Override
-       public String getName() {
-               return name;
-       }
-
-       /**
-        * Sets the name of the Sone.
-        *
-        * @param name
-        *            The name of the Sone
-        * @return This Sone shell (for method chaining)
-        */
-       public SoneShell setName(String name) {
-               this.name = name;
-               return this;
-       }
-
-       /**
-        * Returns the request URI of this Sone.
-        *
-        * @return The request URI of this Sone
-        */
-       @Override
-       public FreenetURI getRequestUri() {
-               return requestUri;
-       }
-
-       /**
-        * Sets the request URI of the Sone.
-        *
-        * @param requestUri
-        *            The request URI of the Sone
-        * @return This Sone shell (for method chaining)
-        */
-       public SoneShell setRequestUri(FreenetURI requestUri) {
-               this.requestUri = requestUri;
-               return this;
-       }
-
-       /**
-        * Returns a copy of the profile. If you want to update values in the
-        * profile of this Sone, update the values in the returned {@link Profile}
-        * and use {@link #setProfile(Profile)} to change the profile in this Sone.
-        *
-        * @return A copy of the profile
-        */
-       @Override
-       public Profile getProfile() {
-               return new Profile(profile);
-       }
-
-       /**
-        * {@inheritDoc}
-        */
-       @Override
-       public void setProfile(Profile profile) {
-               this.profile = profile;
-       }
-
-       /**
-        * Returns all friend Sones of this Sone.
-        *
-        * @return The friend Sones of this Sone
-        */
-       @Override
-       public Set<Sone> getFriends() {
-               return Collections.unmodifiableSet(friendSones);
-       }
-
-       /**
-        * Returns whether this Sone has the given Sone as a friend Sone.
-        *
-        * @param friendSone
-        *            The friend Sone to check for
-        * @return {@code true} if this Sone has the given Sone as a friend,
-        *         {@code false} otherwise
-        */
-       @Override
-       public boolean hasFriend(Sone friendSone) {
-               return friendSones.contains(friendSone);
-       }
-
-       /**
-        * Adds the given Sone as a friend Sone.
-        *
-        * @param friendSone
-        *            The friend Sone to add
-        * @return This Sone (for method chaining)
-        */
-       @Override
-       public Sone addFriend(Sone friendSone) {
-               friendSones.add(friendSone);
-               return this;
-       }
-
-       /**
-        * Removes the given Sone as a friend Sone.
-        *
-        * @param friendSone
-        *            The friend Sone to remove
-        * @return This Sone (for method chaining)
-        */
-       @Override
-       public Sone removeFriend(Sone friendSone) {
-               friendSones.remove(friendSone);
-               return this;
-       }
-
-       /**
-        * Returns the list of posts of this Sone, sorted by time, newest first.
-        *
-        * @return All posts of this Sone
-        */
-       @Override
-       public List<Post> getPosts() {
-               List<Post> sortedPosts = new ArrayList<Post>(posts);
-               Collections.sort(sortedPosts, new Comparator<Post>() {
-
-                       @Override
-                       public int compare(Post leftPost, Post rightPost) {
-                               return (int) Math.max(Integer.MIN_VALUE, Math.min(Integer.MAX_VALUE, rightPost.getTime() - leftPost.getTime()));
-                       }
-
-               });
-               return sortedPosts;
-       }
-
-       /**
-        * 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
-        */
-       @Override
-       public void addPost(Post post) {
-               posts.add(post);
-       }
-
-       /**
-        * Removes the given post from this Sone.
-        *
-        * @param post
-        *            The post to remove
-        */
-       @Override
-       public void removePost(Post post) {
-               posts.remove(post);
-       }
-
-       /**
-        * Returns all replies this Sone made.
-        *
-        * @return All replies this Sone made
-        */
-       @Override
-       public Set<Reply> getReplies() {
-               return Collections.unmodifiableSet(replies);
-       }
-
-       /**
-        * Adds a reply to this Sone. If the given reply was not made by this Sone,
-        * nothing is added to this Sone.
-        *
-        * @param reply
-        *            The reply to add
-        */
-       @Override
-       public void addReply(Reply reply) {
-               replies.add(reply);
-       }
-
-       /**
-        * Removes a reply from this Sone.
-        *
-        * @param reply
-        *            The reply to remove
-        */
-       @Override
-       public void removeReply(Reply reply) {
-               replies.remove(reply);
-       }
-
-       //
-       // INTERFACE Shell
-       //
-
-       /**
-        * {@inheritDoc}
-        */
-       @Override
-       public boolean canUnshell() {
-               return (id != null) && (name != null) && (requestUri != null) && (profile != null);
-       }
-
-       /**
-        * {@inheritDoc}
-        */
-       @Override
-       public Sone getShelled() {
-               if (canUnshell()) {
-                       Sone sone = new Sone(id, name, requestUri);
-                       sone.setProfile(profile);
-                       for (Sone friendSone : friendSones) {
-                               sone.addFriend(friendSone);
-                       }
-                       for (Post post : posts) {
-                               sone.addPost(post);
-                       }
-                       for (Reply reply : replies) {
-                               sone.addReply(reply);
-                       }
-                       return sone;
-               }
-               return this;
-       }
-
-}
index ba55e23..3729768 100644 (file)
@@ -18,7 +18,6 @@
 package net.pterodactylus.sone.web;
 
 import net.pterodactylus.sone.data.Sone;
-import net.pterodactylus.sone.data.SoneShell;
 import net.pterodactylus.util.template.Template;
 
 /**
@@ -51,7 +50,7 @@ public class FollowSonePage extends SoneTemplatePage {
                String soneId = request.getHttpRequest().getParam("sone");
                Sone currentSone = getCurrentSone(request.getToadletContext());
                Sone sone = webInterface.core().getSone(soneId);
-               if (!(sone instanceof SoneShell) && !sone.equals(currentSone)) {
+               if (!sone.equals(currentSone)) {
                        currentSone.addFriend(sone);
                }
                throw new RedirectException("viewSone.html?sone=" + soneId);