Allow Sone, Post, and Reply creation only through the Core and its caches.
authorDavid ‘Bombe’ Roden <bombe@pterodactylus.net>
Fri, 15 Oct 2010 19:40:47 +0000 (21:40 +0200)
committerDavid ‘Bombe’ Roden <bombe@pterodactylus.net>
Fri, 15 Oct 2010 19:40:47 +0000 (21:40 +0200)
src/main/java/net/pterodactylus/sone/core/Core.java
src/main/java/net/pterodactylus/sone/core/SoneDownloader.java
src/main/java/net/pterodactylus/sone/data/Sone.java
src/main/java/net/pterodactylus/sone/web/CreatePostPage.java

index 48976b1..459431c 100644 (file)
@@ -106,7 +106,7 @@ public class Core extends AbstractService {
         */
        public Core freenetInterface(FreenetInterface freenetInterface) {
                this.freenetInterface = freenetInterface;
-               soneDownloader = new SoneDownloader(freenetInterface);
+               soneDownloader = new SoneDownloader(this, freenetInterface);
                soneDownloader.start();
                return this;
        }
@@ -136,6 +136,34 @@ public class Core extends AbstractService {
                return soneCache.get(soneId);
        }
 
+       /**
+        * Creates a new post.
+        *
+        * @param sone
+        *            The sone that creates the post
+        * @param text
+        *            The text of the post
+        * @return The created post
+        */
+       public Post createPost(Sone sone, String text) {
+               return createPost(sone, System.currentTimeMillis(), text);
+       }
+
+       /**
+        * Creates a new post.
+        *
+        * @param sone
+        *            The Sone that creates the post
+        * @param time
+        *            The time of the post
+        * @param text
+        *            The text of the post
+        * @return The created post
+        */
+       public Post createPost(Sone sone, long time, String text) {
+               return getPost(UUID.randomUUID().toString()).setSone(sone).setTime(time).setText(text);
+       }
+
        //
        // ACTIONS
        //
@@ -239,6 +267,36 @@ public class Core extends AbstractService {
                localSones.remove(sone);
        }
 
+       /**
+        * Returns the post with the given ID. If no post exists yet with the given
+        * ID, a new post is returned.
+        *
+        * @param postId
+        *            The ID of the post
+        * @return The post
+        */
+       public Post getPost(String postId) {
+               if (!postCache.containsKey(postId)) {
+                       postCache.put(postId, new Post(postId));
+               }
+               return postCache.get(postId);
+       }
+
+       /**
+        * Returns the reply with the given ID. If no reply exists yet with the
+        * given ID, a new reply is returned.
+        *
+        * @param replyId
+        *            The ID of the reply
+        * @return The reply
+        */
+       public Reply getReply(String replyId) {
+               if (!replyCache.containsKey(replyId)) {
+                       replyCache.put(replyId, new Reply(replyId));
+               }
+               return replyCache.get(replyId);
+       }
+
        //
        // SERVICE METHODS
        //
@@ -307,8 +365,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(id, sone, time, text);
-                                       postCache.put(id, post);
+                                       Post post = getPost(id).setSone(sone).setTime(time).setText(text);
                                        sone.addPost(post);
                                } while (true);
                                int replyCounter = 0;
@@ -325,7 +382,7 @@ public class Core extends AbstractService {
                                        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 Reply(replyId, replySone, replyPost, replyTime, replyText);
+                                       Reply reply = getReply(replyId).setSone(replySone).setPost(replyPost).setTime(replyTime).setText(replyText);
                                        replyCache.put(replyId, reply);
                                } while (true);
 
index 47bd940..4dd634c 100644 (file)
@@ -49,6 +49,9 @@ public class SoneDownloader extends AbstractService {
        /** The logger. */
        private static final Logger logger = Logging.getLogger(SoneDownloader.class);
 
+       /** The core. */
+       private final Core core;
+
        /** The Freenet interface. */
        private final FreenetInterface freenetInterface;
 
@@ -58,11 +61,14 @@ public class SoneDownloader extends AbstractService {
        /**
         * Creates a new Sone downloader.
         *
+        * @param core
+        *            The core
         * @param freenetInterface
         *            The Freenet interface
         */
-       public SoneDownloader(FreenetInterface freenetInterface) {
+       public SoneDownloader(Core core, FreenetInterface freenetInterface) {
                super("Sone Downloader");
+               this.core = core;
                this.freenetInterface = freenetInterface;
        }
 
@@ -180,7 +186,7 @@ public class SoneDownloader extends AbstractService {
                                        return;
                                }
                                try {
-                                       posts.add(new Post(postId, sone, Long.parseLong(postTime), postText));
+                                       posts.add(core.getPost(postId).setSone(sone).setTime(Long.parseLong(postTime)).setText(postText));
                                } catch (NumberFormatException nfe1) {
                                        /* TODO - mark Sone as bad. */
                                        logger.log(Level.WARNING, "Downloaded post for Sone %s with invalid time: %s", new Object[] { sone, postTime });
@@ -202,7 +208,24 @@ public class SoneDownloader extends AbstractService {
                                String replyPostId = replyXml.getValue("post-id", null);
                                String replyTime = replyXml.getValue("time", null);
                                String replyText = replyXml.getValue("text", null);
-                               /* TODO - finish! */
+                               if ((replyId == null) || (replyPostId == null) || (replyTime == null) || (replyText == null)) {
+                                       /* TODO - mark Sone as bad. */
+                                       logger.log(Level.WARNING, "Downloaded reply for Sone %s with missing data! ID: %s, Post: %s, Time: %s, Text: %s", new Object[] { sone, replyId, replyPostId, replyTime, replyText });
+                                       return;
+                               }
+                               try {
+                                       replies.add(core.getReply(replyId).setSone(sone).setPost(core.getPost(replyPostId)).setTime(Long.parseLong(replyTime)).setText(replyText));
+                               } catch (NumberFormatException nfe1) {
+                                       /* TODO - mark Sone as bad. */
+                                       logger.log(Level.WARNING, "Downloaded reply for Sone %s with invalid time: %s", new Object[] { sone, replyTime });
+                                       return;
+                               }
+                       }
+
+                       /* okay, apparently everything was parsed correctly. Now import. */
+                       /* atomic setter operation on the Sone. */
+                       synchronized (sone) {
+                               sone.setProfile(profile);
                        }
                } catch (IOException ioe1) {
                        logger.log(Level.WARNING, "Could not read XML file from " + sone + "!", ioe1);
index 4d50527..9219e99 100644 (file)
@@ -18,6 +18,7 @@
 package net.pterodactylus.sone.data;
 
 import java.util.ArrayList;
+import java.util.Collection;
 import java.util.Collections;
 import java.util.Comparator;
 import java.util.HashSet;
@@ -191,6 +192,20 @@ public class Sone {
        }
 
        /**
+        * Sets all friends of this Sone at once.
+        *
+        * @param friends
+        *            The new (and only) friends of this Sone
+        * @return This Sone (for method chaining)
+        */
+       public synchronized Sone setFriends(Collection<Sone> friends) {
+               friendSones.clear();
+               friendSones.addAll(friends);
+               modificationCounter++;
+               return this;
+       }
+
+       /**
         * Returns whether this Sone has the given Sone as a friend Sone.
         *
         * @param friendSone
@@ -249,6 +264,20 @@ public class Sone {
        }
 
        /**
+        * 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 synchronized Sone setPosts(Collection<Post> posts) {
+               this.posts.clear();
+               this.posts.addAll(posts);
+               modificationCounter++;
+               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.
         *
@@ -285,6 +314,20 @@ public class Sone {
        }
 
        /**
+        * Sets all replies of this Sone at once.
+        *
+        * @param replies
+        *            The new (and only) replies of this Sone
+        * @return This Sone (for method chaining)
+        */
+       public synchronized Sone setReplies(Collection<Reply> replies) {
+               this.replies.clear();
+               this.replies.addAll(replies);
+               modificationCounter++;
+               return this;
+       }
+
+       /**
         * Adds a reply to this Sone. If the given reply was not made by this Sone,
         * nothing is added to this Sone.
         *
index d44ee4f..58fd74e 100644 (file)
@@ -53,7 +53,7 @@ public class CreatePostPage extends SoneTemplatePage {
                String text = request.getHttpRequest().getPartAsStringFailsafe("text", 65536).trim();
                if (text.length() != 0) {
                        Sone currentSone = getCurrentSone(request.getToadletContext());
-                       Post post = new Post(currentSone, System.currentTimeMillis(), text);
+                       Post post = webInterface.core().createPost(currentSone, System.currentTimeMillis(), text);
                        currentSone.addPost(post);
                        throw new RedirectException("index.html");
                }