Make Sone returned by a Sone provider optional.
authorDavid ‘Bombe’ Roden <bombe@pterodactylus.net>
Sun, 27 Jan 2013 21:14:26 +0000 (22:14 +0100)
committerDavid ‘Bombe’ Roden <bombe@pterodactylus.net>
Sun, 27 Jan 2013 21:14:26 +0000 (22:14 +0100)
31 files changed:
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/impl/AbstractPostBuilder.java
src/main/java/net/pterodactylus/sone/data/impl/PostImpl.java
src/main/java/net/pterodactylus/sone/data/impl/ReplyImpl.java
src/main/java/net/pterodactylus/sone/database/SoneProvider.java
src/main/java/net/pterodactylus/sone/fcp/AbstractSoneCommand.java
src/main/java/net/pterodactylus/sone/fcp/CreatePostCommand.java
src/main/java/net/pterodactylus/sone/fcp/GetPostFeedCommand.java
src/main/java/net/pterodactylus/sone/fcp/GetSoneCommand.java
src/main/java/net/pterodactylus/sone/notify/ListNotificationFilters.java
src/main/java/net/pterodactylus/sone/text/SoneTextParser.java
src/main/java/net/pterodactylus/sone/web/CreatePostPage.java
src/main/java/net/pterodactylus/sone/web/DistrustPage.java
src/main/java/net/pterodactylus/sone/web/FollowSonePage.java
src/main/java/net/pterodactylus/sone/web/ImageBrowserPage.java
src/main/java/net/pterodactylus/sone/web/IndexPage.java
src/main/java/net/pterodactylus/sone/web/MarkAsKnownPage.java
src/main/java/net/pterodactylus/sone/web/SearchPage.java
src/main/java/net/pterodactylus/sone/web/TrustPage.java
src/main/java/net/pterodactylus/sone/web/UntrustPage.java
src/main/java/net/pterodactylus/sone/web/ViewSonePage.java
src/main/java/net/pterodactylus/sone/web/ajax/CreatePostAjaxPage.java
src/main/java/net/pterodactylus/sone/web/ajax/DistrustAjaxPage.java
src/main/java/net/pterodactylus/sone/web/ajax/FollowSoneAjaxPage.java
src/main/java/net/pterodactylus/sone/web/ajax/GetPostAjaxPage.java
src/main/java/net/pterodactylus/sone/web/ajax/GetStatusAjaxPage.java
src/main/java/net/pterodactylus/sone/web/ajax/MarkAsKnownAjaxPage.java
src/main/java/net/pterodactylus/sone/web/ajax/TrustAjaxPage.java
src/main/java/net/pterodactylus/sone/web/ajax/UntrustAjaxPage.java
src/test/java/net/pterodactylus/sone/text/SoneTextParserTest.java

index fc362a6..4a71e53 100644 (file)
@@ -365,9 +365,9 @@ public class Core extends AbstractService implements SoneProvider, PostProvider,
         *         Sone
         */
        @Override
-       public Sone getSone(String id) {
+       public Optional<Sone> getSone(String id) {
                synchronized (sones) {
-                       return sones.get(id);
+                       return Optional.fromNullable(sones.get(id));
                }
        }
 
@@ -537,7 +537,7 @@ public class Core extends AbstractService implements SoneProvider, PostProvider,
 
                                @Override
                                public boolean apply(Post post) {
-                                       return (post.getRecipient() != null) && (post.getRecipient().getId().equals(recipientId));
+                                       return recipientId.equals(post.getRecipientId().orNull());
                                }
                        });
                }
@@ -898,16 +898,16 @@ public class Core extends AbstractService implements SoneProvider, PostProvider,
                        if (!soneFollowingTimes.containsKey(soneId)) {
                                long now = System.currentTimeMillis();
                                soneFollowingTimes.put(soneId, now);
-                               Sone followedSone = getSone(soneId);
-                               if (followedSone == null) {
+                               Optional<Sone> followedSone = getSone(soneId);
+                               if (!followedSone.isPresent()) {
                                        return;
                                }
-                               for (Post post : followedSone.getPosts()) {
+                               for (Post post : followedSone.get().getPosts()) {
                                        if (post.getTime() < now) {
                                                markPostKnown(post);
                                        }
                                }
-                               for (PostReply reply : followedSone.getReplies()) {
+                               for (PostReply reply : followedSone.get().getReplies()) {
                                        if (reply.getTime() < now) {
                                                markReplyKnown(reply);
                                        }
@@ -1032,22 +1032,22 @@ public class Core extends AbstractService implements SoneProvider, PostProvider,
         *            of the age of the given Sone
         */
        public void updateSone(Sone sone, boolean soneRescueMode) {
-               if (hasSone(sone.getId())) {
-                       Sone storedSone = getSone(sone.getId());
-                       if (!soneRescueMode && !(sone.getTime() > storedSone.getTime())) {
+               Optional<Sone> storedSone = getSone(sone.getId());
+               if (storedSone.isPresent()) {
+                       if (!soneRescueMode && !(sone.getTime() > storedSone.get().getTime())) {
                                logger.log(Level.FINE, String.format("Downloaded Sone %s is not newer than stored Sone %s.", sone, storedSone));
                                return;
                        }
                        synchronized (posts) {
                                if (!soneRescueMode) {
-                                       for (Post post : storedSone.getPosts()) {
+                                       for (Post post : storedSone.get().getPosts()) {
                                                posts.remove(post.getId());
                                                if (!sone.getPosts().contains(post)) {
                                                        eventBus.post(new PostRemovedEvent(post));
                                                }
                                        }
                                }
-                               List<Post> storedPosts = storedSone.getPosts();
+                               List<Post> storedPosts = storedSone.get().getPosts();
                                synchronized (knownPosts) {
                                        for (Post post : sone.getPosts()) {
                                                post.setKnown(knownPosts.contains(post.getId()));
@@ -1065,14 +1065,14 @@ public class Core extends AbstractService implements SoneProvider, PostProvider,
                        }
                        synchronized (replies) {
                                if (!soneRescueMode) {
-                                       for (PostReply reply : storedSone.getReplies()) {
+                                       for (PostReply reply : storedSone.get().getReplies()) {
                                                replies.remove(reply.getId());
                                                if (!sone.getReplies().contains(reply)) {
                                                        eventBus.post(new PostReplyRemovedEvent(reply));
                                                }
                                        }
                                }
-                               Set<PostReply> storedReplies = storedSone.getReplies();
+                               Set<PostReply> storedReplies = storedSone.get().getReplies();
                                synchronized (knownReplies) {
                                        for (PostReply reply : sone.getReplies()) {
                                                reply.setKnown(knownReplies.contains(reply.getId()));
@@ -1090,7 +1090,7 @@ public class Core extends AbstractService implements SoneProvider, PostProvider,
                        }
                        synchronized (albums) {
                                synchronized (images) {
-                                       for (Album album : storedSone.getAlbums()) {
+                                       for (Album album : storedSone.get().getAlbums()) {
                                                albums.remove(album.getId());
                                                for (Image image : album.getImages()) {
                                                        images.remove(image.getId());
@@ -1437,7 +1437,7 @@ public class Core extends AbstractService implements SoneProvider, PostProvider,
         *            The text of the post
         * @return The created post
         */
-       public Post createPost(Sone sone, Sone recipient, String text) {
+       public Post createPost(Sone sone, Optional<Sone> recipient, String text) {
                return createPost(sone, recipient, System.currentTimeMillis(), text);
        }
 
@@ -1455,7 +1455,7 @@ public class Core extends AbstractService implements SoneProvider, PostProvider,
         *            The text of the post
         * @return The created post
         */
-       public Post createPost(Sone sone, Sone recipient, long time, String text) {
+       public Post createPost(Sone sone, Optional<Sone> recipient, long time, String text) {
                checkNotNull(text, "text must not be null");
                checkArgument(text.trim().length() > 0, "text must not be empty");
                if (!sone.isLocal()) {
@@ -1464,8 +1464,8 @@ public class Core extends AbstractService implements SoneProvider, PostProvider,
                }
                PostBuilder postBuilder = postBuilderFactory.newPostBuilder();
                postBuilder.from(sone.getId()).randomId().withTime(time).withText(text.trim());
-               if (recipient != null) {
-                       postBuilder.to(recipient.getId());
+               if (recipient.isPresent()) {
+                       postBuilder.to(recipient.get().getId());
                }
                final Post post = postBuilder.build();
                synchronized (posts) {
@@ -1919,7 +1919,7 @@ public class Core extends AbstractService implements SoneProvider, PostProvider,
                        for (Post post : sone.getPosts()) {
                                String postPrefix = sonePrefix + "/Posts/" + postCounter++;
                                configuration.getStringValue(postPrefix + "/ID").setValue(post.getId());
-                               configuration.getStringValue(postPrefix + "/Recipient").setValue((post.getRecipient() != null) ? post.getRecipient().getId() : null);
+                               configuration.getStringValue(postPrefix + "/Recipient").setValue(post.getRecipientId().orNull());
                                configuration.getLongValue(postPrefix + "/Time").setValue(post.getTime());
                                configuration.getStringValue(postPrefix + "/Text").setValue(post.getText());
                        }
@@ -2166,13 +2166,8 @@ public class Core extends AbstractService implements SoneProvider, PostProvider,
                                break;
                        }
                        long time = configuration.getLongValue("SoneFollowingTimes/" + soneCounter + "/Time").getValue(Long.MAX_VALUE);
-                       Sone followedSone = getSone(soneId);
-                       if (followedSone == null) {
-                               logger.log(Level.WARNING, String.format("Ignoring Sone with invalid ID: %s", soneId));
-                       } else {
-                               synchronized (soneFollowingTimes) {
-                                       soneFollowingTimes.put(soneId, time);
-                               }
+                       synchronized (soneFollowingTimes) {
+                               soneFollowingTimes.put(soneId, time);
                        }
                        ++soneCounter;
                }
@@ -2320,14 +2315,14 @@ public class Core extends AbstractService implements SoneProvider, PostProvider,
                        /* some local identity still trusts this identity, don’t remove. */
                        return;
                }
-               Sone sone = getSone(identity.getId());
-               if (sone == null) {
+               Optional<Sone> sone = getSone(identity.getId());
+               if (!sone.isPresent()) {
                        /* TODO - we don’t have the Sone anymore. should this happen? */
                        return;
                }
                synchronized (posts) {
                        synchronized (knownPosts) {
-                               for (Post post : sone.getPosts()) {
+                               for (Post post : sone.get().getPosts()) {
                                        posts.remove(post.getId());
                                        eventBus.post(new PostRemovedEvent(post));
                                }
@@ -2335,7 +2330,7 @@ public class Core extends AbstractService implements SoneProvider, PostProvider,
                }
                synchronized (replies) {
                        synchronized (knownReplies) {
-                               for (PostReply reply : sone.getReplies()) {
+                               for (PostReply reply : sone.get().getReplies()) {
                                        replies.remove(reply.getId());
                                        eventBus.post(new PostReplyRemovedEvent(reply));
                                }
@@ -2344,7 +2339,7 @@ public class Core extends AbstractService implements SoneProvider, PostProvider,
                synchronized (sones) {
                        sones.remove(identity.getId());
                }
-               eventBus.post(new SoneRemovedEvent(sone));
+               eventBus.post(new SoneRemovedEvent(sone.get()));
        }
 
        /**
index 160bb32..5269fe4 100644 (file)
@@ -19,6 +19,7 @@ package net.pterodactylus.sone.data;
 
 import java.util.Comparator;
 
+import com.google.common.base.Optional;
 import com.google.common.base.Predicate;
 
 /**
@@ -68,11 +69,31 @@ public interface Post {
        public Sone getSone();
 
        /**
-        * Returns the recipient of this post, if any.
+        * Returns whether this post has a recipient.
         *
-        * @return The recipient of this post, or {@code null}
+        * @return {@code true} if this post has a recipient, {@code false}
+        *         otherwise
         */
-       public Sone getRecipient();
+       public boolean hasRecipient();
+
+       /**
+        * Returns the ID of the recipient {@link Sone}, or
+        * {@link Optional#absent()} if this post does not have a recipient.
+        *
+        * @return The ID of the recipient, or {@link Optional#absent()}
+        */
+       public Optional<String> getRecipientId();
+
+       /**
+        * Returns the recipient of this post, if any. As this method can return
+        * {@link Optional#absent()} if the post has a recipient which has not yet
+        * been loaded, it is recommended to use {@link #hasRecipient()} to check
+        * for the presence of a recipient.
+        *
+        * @return The recipient of this post, or {@link Optional#absent()} if there
+        *         is no recipient
+        */
+       public Optional<Sone> getRecipient();
 
        /**
         * Returns the time of the post.
index 342ea5c..3a56dc9 100644 (file)
@@ -82,7 +82,7 @@ public abstract class AbstractPostBuilder implements PostBuilder {
                this.currentTime = false;
                this.time = post.getTime();
                this.text = post.getText();
-               this.recipientId = (post.getRecipient() != null) ? post.getRecipient().getId() : null;
+               this.recipientId = post.getRecipientId().orNull();
                return this;
        }
 
index d008463..5d0d72a 100644 (file)
@@ -23,6 +23,8 @@ import net.pterodactylus.sone.data.Post;
 import net.pterodactylus.sone.data.Sone;
 import net.pterodactylus.sone.database.SoneProvider;
 
+import com.google.common.base.Optional;
+
 /**
  * A post is a short message that a user writes in his Sone to let other users
  * know what is going on.
@@ -94,14 +96,30 @@ public class PostImpl implements Post {
         */
        @Override
        public Sone getSone() {
-               return soneProvider.getSone(soneId);
+               return soneProvider.getSone(soneId).get();
+       }
+
+       /**
+        * {@inheritDocs}
+        */
+       @Override
+       public boolean hasRecipient() {
+               return recipientId != null;
+       }
+
+       /**
+        * {@inheritDocs}
+        */
+       @Override
+       public Optional<String> getRecipientId() {
+               return Optional.fromNullable(recipientId);
        }
 
        /**
         * {@inheritDoc}
         */
        @Override
-       public Sone getRecipient() {
+       public Optional<Sone> getRecipient() {
                return soneProvider.getSone(recipientId);
        }
 
index 5f7dac0..a67081f 100644 (file)
@@ -83,7 +83,7 @@ public abstract class ReplyImpl<T extends Reply<T>> implements Reply<T> {
         */
        @Override
        public Sone getSone() {
-               return soneProvider.getSone(soneId);
+               return soneProvider.getSone(soneId).get();
        }
 
        /**
index b1b1eb4..bbe0abf 100644 (file)
@@ -19,6 +19,8 @@ package net.pterodactylus.sone.database;
 
 import net.pterodactylus.sone.data.Sone;
 
+import com.google.common.base.Optional;
+
 /**
  * Interface for objects that can provide {@link Sone}s by their ID.
  *
@@ -27,12 +29,13 @@ import net.pterodactylus.sone.data.Sone;
 public interface SoneProvider {
 
        /**
-        * Returns the Sone with the given ID, if it exists.
+        * Returns the Sone with the given ID, or {@link Optional#absent()} if it
+        * does not exist.
         *
         * @param soneId
         *            The ID of the Sone to return
-        * @return The Sone with the given ID, or {@code null}
+        * @return The Sone with the given ID, or {@link Optional#absent()}
         */
-       public Sone getSone(String soneId);
+       public Optional<Sone> getSone(String soneId);
 
 }
index 8afe7c4..108a80f 100644 (file)
@@ -134,7 +134,7 @@ public abstract class AbstractSoneCommand extends AbstractCommand {
         *             or if the Sone ID is invalid
         */
        protected Sone getSone(SimpleFieldSet simpleFieldSet, String parameterName, boolean localOnly) throws FcpException {
-               return getSone(simpleFieldSet, parameterName, localOnly, true);
+               return getSone(simpleFieldSet, parameterName, localOnly, true).get();
        }
 
        /**
@@ -158,13 +158,13 @@ public abstract class AbstractSoneCommand extends AbstractCommand {
         *             or if {@code mandatory} is {@code true} and the Sone ID is
         *             invalid
         */
-       protected Sone getSone(SimpleFieldSet simpleFieldSet, String parameterName, boolean localOnly, boolean mandatory) throws FcpException {
+       protected Optional<Sone> getSone(SimpleFieldSet simpleFieldSet, String parameterName, boolean localOnly, boolean mandatory) throws FcpException {
                String soneId = simpleFieldSet.get(parameterName);
                if (mandatory && (soneId == null)) {
                        throw new FcpException("Could not load Sone ID from “" + parameterName + "”.");
                }
-               Sone sone = localOnly ? core.getLocalSone(soneId, false) : core.getSone(soneId);
-               if (mandatory && (sone == null)) {
+               Optional<Sone> sone = core.getSone(soneId);
+               if ((mandatory && !sone.isPresent()) || (mandatory && sone.isPresent() && (localOnly && !sone.get().isLocal()))) {
                        throw new FcpException("Could not load Sone from “" + soneId + "”.");
                }
                return sone;
@@ -236,14 +236,14 @@ public abstract class AbstractSoneCommand extends AbstractCommand {
         *            such as if the Sone is followed by the local Sone
         * @return The simple field set containing the given Sone
         */
-       protected static SimpleFieldSet encodeSone(Sone sone, String prefix, Sone localSone) {
+       protected static SimpleFieldSet encodeSone(Sone sone, String prefix, Optional<Sone> localSone) {
                SimpleFieldSetBuilder soneBuilder = new SimpleFieldSetBuilder();
 
                soneBuilder.put(prefix + "Name", sone.getName());
                soneBuilder.put(prefix + "NiceName", SoneAccessor.getNiceName(sone));
                soneBuilder.put(prefix + "LastUpdated", sone.getTime());
-               if (localSone != null) {
-                       soneBuilder.put(prefix + "Followed", String.valueOf(localSone.hasFriend(sone.getId())));
+               if (localSone.isPresent()) {
+                       soneBuilder.put(prefix + "Followed", String.valueOf(localSone.get().hasFriend(sone.getId())));
                }
                Profile profile = sone.getProfile();
                soneBuilder.put(prefix + "Field.Count", profile.getFields().size());
@@ -301,8 +301,8 @@ public abstract class AbstractSoneCommand extends AbstractCommand {
 
                postBuilder.put(prefix + "ID", post.getId());
                postBuilder.put(prefix + "Sone", post.getSone().getId());
-               if (post.getRecipient() != null) {
-                       postBuilder.put(prefix + "Recipient", post.getRecipient().getId());
+               if (post.hasRecipient()) {
+                       postBuilder.put(prefix + "Recipient", post.getRecipientId().get());
                }
                postBuilder.put(prefix + "Time", post.getTime());
                postBuilder.put(prefix + "Text", encodeString(post.getText()));
index 59d69af..f6c5dd9 100644 (file)
@@ -17,6 +17,8 @@
 
 package net.pterodactylus.sone.fcp;
 
+import com.google.common.base.Optional;
+
 import net.pterodactylus.sone.core.Core;
 import net.pterodactylus.sone.data.Post;
 import net.pterodactylus.sone.data.Sone;
@@ -57,7 +59,7 @@ public class CreatePostCommand extends AbstractSoneCommand {
                if (sone.equals(recipient)) {
                        return new ErrorResponse("Sone and Recipient must not be the same.");
                }
-               Post post = getCore().createPost(sone, recipient, text);
+               Post post = getCore().createPost(sone, Optional.fromNullable(recipient), text);
                return new Response("PostCreated", new SimpleFieldSetBuilder().put("Post", post.getId()).get());
        }
 
index 0fc7eda..b22d356 100644 (file)
@@ -28,6 +28,7 @@ import net.pterodactylus.sone.data.Post;
 import net.pterodactylus.sone.data.Sone;
 import net.pterodactylus.sone.freenet.fcp.FcpException;
 
+import com.google.common.base.Optional;
 import com.google.common.collect.Collections2;
 
 import freenet.support.SimpleFieldSet;
@@ -63,10 +64,11 @@ public class GetPostFeedCommand extends AbstractSoneCommand {
                Collection<Post> allPosts = new HashSet<Post>();
                allPosts.addAll(sone.getPosts());
                for (String friendSoneId : sone.getFriends()) {
-                       if (!getCore().hasSone(friendSoneId)) {
+                       Optional<Sone> friendSone = getCore().getSone(friendSoneId);
+                       if (!friendSone.isPresent()) {
                                continue;
                        }
-                       allPosts.addAll(getCore().getSone(friendSoneId).getPosts());
+                       allPosts.addAll(friendSone.get().getPosts());
                }
                allPosts.addAll(getCore().getDirectedPosts(sone.getId()));
                allPosts = Collections2.filter(allPosts, Post.FUTURE_POSTS_FILTER);
index d32bda6..e3ec1b1 100644 (file)
@@ -21,6 +21,9 @@ import net.pterodactylus.sone.core.Core;
 import net.pterodactylus.sone.data.Profile;
 import net.pterodactylus.sone.data.Sone;
 import net.pterodactylus.sone.freenet.fcp.FcpException;
+
+import com.google.common.base.Optional;
+
 import freenet.support.SimpleFieldSet;
 import freenet.support.api.Bucket;
 
@@ -48,7 +51,7 @@ public class GetSoneCommand extends AbstractSoneCommand {
        @Override
        public Response execute(SimpleFieldSet parameters, Bucket data, AccessType accessType) throws FcpException {
                Sone sone = getSone(parameters, "Sone", false);
-               Sone localSone = getSone(parameters, "LocalSone", false, false);
+               Optional<Sone> localSone = getSone(parameters, "LocalSone", false, false);
                return new Response("Sone", encodeSone(sone, "", localSone));
        }
 
index dbf09a3..6b4773d 100644 (file)
@@ -245,7 +245,7 @@ public class ListNotificationFilters {
                                 */
                                return true;
                        }
-                       if ((!postSone.equals(sone)) && !sone.hasFriend(postSone.getId()) && !sone.equals(post.getRecipient())) {
+                       if ((!postSone.equals(sone)) && !sone.hasFriend(postSone.getId()) && !sone.getId().equals(post.getRecipientId().orNull())) {
                                return false;
                        }
                }
index f2ca0c5..6d81c0d 100644 (file)
@@ -242,15 +242,15 @@ public class SoneTextParser implements Parser<SoneTextParserContext> {
                                        if (linkType == LinkType.SONE) {
                                                if (line.length() >= (7 + 43)) {
                                                        String soneId = line.substring(7, 50);
-                                                       Sone sone = soneProvider.getSone(soneId);
-                                                       if (sone == null) {
+                                                       Optional<Sone> sone = soneProvider.getSone(soneId);
+                                                       if (!sone.isPresent()) {
                                                                /*
                                                                 * don’t use create=true above, we don’t want
                                                                 * the empty shell.
                                                                 */
-                                                               sone = new Sone(soneId, false);
+                                                               sone = Optional.fromNullable(new Sone(soneId, false));
                                                        }
-                                                       parts.add(new SonePart(sone));
+                                                       parts.add(new SonePart(sone.get()));
                                                        line = line.substring(50);
                                                } else {
                                                        parts.add(new PlainTextPart(line));
index e77e55a..83913b4 100644 (file)
@@ -17,6 +17,8 @@
 
 package net.pterodactylus.sone.web;
 
+import com.google.common.base.Optional;
+
 import net.pterodactylus.sone.data.Post;
 import net.pterodactylus.sone.data.Sone;
 import net.pterodactylus.sone.text.TextFilter;
@@ -65,7 +67,7 @@ public class CreatePostPage extends SoneTemplatePage {
                                if (sender == null) {
                                        sender = currentSone;
                                }
-                               Sone recipient = webInterface.getCore().getSone(recipientId);
+                               Optional<Sone> recipient = webInterface.getCore().getSone(recipientId);
                                text = TextFilter.filter(request.getHttpRequest().getHeader("host"), text);
                                webInterface.getCore().createPost(sender, recipient, System.currentTimeMillis(), text);
                                throw new RedirectException(returnPage);
index 262d602..c8879a0 100644 (file)
@@ -17,6 +17,8 @@
 
 package net.pterodactylus.sone.web;
 
+import com.google.common.base.Optional;
+
 import net.pterodactylus.sone.core.Core;
 import net.pterodactylus.sone.data.Sone;
 import net.pterodactylus.sone.web.page.FreenetRequest;
@@ -59,9 +61,9 @@ public class DistrustPage extends SoneTemplatePage {
                        String returnPage = request.getHttpRequest().getPartAsStringFailsafe("returnPage", 256);
                        String identity = request.getHttpRequest().getPartAsStringFailsafe("sone", 44);
                        Sone currentSone = getCurrentSone(request.getToadletContext());
-                       Sone sone = webInterface.getCore().getSone(identity);
-                       if (sone != null) {
-                               webInterface.getCore().distrustSone(currentSone, sone);
+                       Optional<Sone> sone = webInterface.getCore().getSone(identity);
+                       if (sone.isPresent()) {
+                               webInterface.getCore().distrustSone(currentSone, sone.get());
                        }
                        throw new RedirectException(returnPage);
                }
index b7598d2..11a680c 100644 (file)
@@ -17,6 +17,8 @@
 
 package net.pterodactylus.sone.web;
 
+import com.google.common.base.Optional;
+
 import net.pterodactylus.sone.data.Sone;
 import net.pterodactylus.sone.web.page.FreenetRequest;
 import net.pterodactylus.util.template.Template;
@@ -55,9 +57,10 @@ public class FollowSonePage extends SoneTemplatePage {
                        Sone currentSone = getCurrentSone(request.getToadletContext());
                        String soneIds = request.getHttpRequest().getPartAsStringFailsafe("sone", 1200);
                        for (String soneId : soneIds.split("[ ,]+")) {
-                               if (webInterface.getCore().hasSone(soneId)) {
+                               Optional<Sone> sone = webInterface.getCore().getSone(soneId);
+                               if (sone.isPresent()) {
                                        webInterface.getCore().followSone(currentSone, soneId);
-                                       webInterface.getCore().markSoneKnown(webInterface.getCore().getSone(soneId));
+                                       webInterface.getCore().markSoneKnown(sone.get());
                                }
                        }
                        throw new RedirectException(returnPage);
index d0a446f..53c22f2 100644 (file)
@@ -22,6 +22,8 @@ import java.util.ArrayList;
 import java.util.Collections;
 import java.util.List;
 
+import com.google.common.base.Optional;
+
 import net.pterodactylus.sone.data.Album;
 import net.pterodactylus.sone.data.Image;
 import net.pterodactylus.sone.data.Sone;
@@ -77,9 +79,9 @@ public class ImageBrowserPage extends SoneTemplatePage {
                }
                String soneId = request.getHttpRequest().getParam("sone", null);
                if (soneId != null) {
-                       Sone sone = webInterface.getCore().getSone(soneId);
+                       Optional<Sone> sone = webInterface.getCore().getSone(soneId);
                        templateContext.set("soneRequested", true);
-                       templateContext.set("sone", sone);
+                       templateContext.set("sone", sone.orNull());
                        return;
                }
                String mode = request.getHttpRequest().getParam("mode", null);
index b4307e3..e1a52b9 100644 (file)
@@ -31,6 +31,7 @@ import net.pterodactylus.util.number.Numbers;
 import net.pterodactylus.util.template.Template;
 import net.pterodactylus.util.template.TemplateContext;
 
+import com.google.common.base.Optional;
 import com.google.common.base.Predicate;
 import com.google.common.collect.Collections2;
 
@@ -66,14 +67,15 @@ public class IndexPage extends SoneTemplatePage {
                Collection<Post> allPosts = new ArrayList<Post>();
                allPosts.addAll(currentSone.getPosts());
                for (String friendSoneId : currentSone.getFriends()) {
-                       if (!webInterface.getCore().hasSone(friendSoneId)) {
+                       Optional<Sone> friendSone = webInterface.getCore().getSone(friendSoneId);
+                       if (!friendSone.isPresent()) {
                                continue;
                        }
-                       allPosts.addAll(webInterface.getCore().getSone(friendSoneId).getPosts());
+                       allPosts.addAll(friendSone.get().getPosts());
                }
                for (Sone sone : webInterface.getCore().getSones()) {
                        for (Post post : sone.getPosts()) {
-                               if (currentSone.equals(post.getRecipient()) && !allPosts.contains(post)) {
+                               if (currentSone.equals(post.getRecipient().orNull()) && !allPosts.contains(post)) {
                                        allPosts.add(post);
                                }
                        }
index 88f1026..66ac635 100644 (file)
@@ -79,11 +79,11 @@ public class MarkAsKnownPage extends SoneTemplatePage {
                                }
                                webInterface.getCore().markReplyKnown(reply.get());
                        } else if (type.equals("sone")) {
-                               Sone sone = webInterface.getCore().getSone(id);
-                               if (sone == null) {
+                               Optional<Sone> sone = webInterface.getCore().getSone(id);
+                               if (!sone.isPresent()) {
                                        continue;
                                }
-                               webInterface.getCore().markSoneKnown(sone);
+                               webInterface.getCore().markSoneKnown(sone.get());
                        }
                }
                String returnPage = request.getHttpRequest().getPartAsStringFailsafe("returnPage", 256);
index 6cbb11f..320e7cd 100644 (file)
@@ -464,8 +464,8 @@ public class SearchPage extends SoneTemplatePage {
                public String generateString(Post post) {
                        StringBuilder postString = new StringBuilder();
                        postString.append(post.getText());
-                       if (post.getRecipient() != null) {
-                               postString.append(' ').append(SoneStringGenerator.NAME_GENERATOR.generateString(post.getRecipient()));
+                       if (post.getRecipient().isPresent()) {
+                               postString.append(' ').append(SoneStringGenerator.NAME_GENERATOR.generateString(post.getRecipient().get()));
                        }
                        for (PostReply reply : Collections2.filter(webInterface.getCore().getReplies(post), Reply.FUTURE_REPLY_FILTER)) {
                                postString.append(' ').append(SoneStringGenerator.NAME_GENERATOR.generateString(reply.getSone()));
index 5d62399..39fd1de 100644 (file)
@@ -17,6 +17,8 @@
 
 package net.pterodactylus.sone.web;
 
+import com.google.common.base.Optional;
+
 import net.pterodactylus.sone.core.Core;
 import net.pterodactylus.sone.data.Sone;
 import net.pterodactylus.sone.web.page.FreenetRequest;
@@ -59,9 +61,9 @@ public class TrustPage extends SoneTemplatePage {
                        String returnPage = request.getHttpRequest().getPartAsStringFailsafe("returnPage", 256);
                        String identity = request.getHttpRequest().getPartAsStringFailsafe("sone", 44);
                        Sone currentSone = getCurrentSone(request.getToadletContext());
-                       Sone sone = webInterface.getCore().getSone(identity);
-                       if (sone != null) {
-                               webInterface.getCore().trustSone(currentSone, sone);
+                       Optional<Sone> sone = webInterface.getCore().getSone(identity);
+                       if (sone.isPresent()) {
+                               webInterface.getCore().trustSone(currentSone, sone.get());
                        }
                        throw new RedirectException(returnPage);
                }
index 1ee4f8e..d68d5ca 100644 (file)
@@ -17,6 +17,8 @@
 
 package net.pterodactylus.sone.web;
 
+import com.google.common.base.Optional;
+
 import net.pterodactylus.sone.core.Core;
 import net.pterodactylus.sone.data.Sone;
 import net.pterodactylus.sone.web.page.FreenetRequest;
@@ -59,9 +61,9 @@ public class UntrustPage extends SoneTemplatePage {
                        String returnPage = request.getHttpRequest().getPartAsStringFailsafe("returnPage", 256);
                        String identity = request.getHttpRequest().getPartAsStringFailsafe("sone", 44);
                        Sone currentSone = getCurrentSone(request.getToadletContext());
-                       Sone sone = webInterface.getCore().getSone(identity);
-                       if (sone != null) {
-                               webInterface.getCore().untrustSone(currentSone, sone);
+                       Optional<Sone> sone = webInterface.getCore().getSone(identity);
+                       if (sone.isPresent()) {
+                               webInterface.getCore().untrustSone(currentSone, sone.get());
                        }
                        throw new RedirectException(returnPage);
                }
index 592404f..e120e92 100644 (file)
@@ -67,9 +67,9 @@ public class ViewSonePage extends SoneTemplatePage {
        @Override
        protected String getPageTitle(FreenetRequest request) {
                String soneId = request.getHttpRequest().getParam("sone");
-               Sone sone = webInterface.getCore().getSone(soneId);
-               if ((sone != null) && (sone.getTime() > 0)) {
-                       String soneName = SoneAccessor.getNiceName(sone);
+               Optional<Sone> sone = webInterface.getCore().getSone(soneId);
+               if (sone.isPresent()) {
+                       String soneName = SoneAccessor.getNiceName(sone.get());
                        return soneName + " - " + webInterface.getL10n().getString("Page.ViewSone.Title");
                }
                return webInterface.getL10n().getString("Page.ViewSone.Page.TitleWithoutSone");
@@ -82,23 +82,23 @@ public class ViewSonePage extends SoneTemplatePage {
        protected void processTemplate(FreenetRequest request, TemplateContext templateContext) throws RedirectException {
                super.processTemplate(request, templateContext);
                String soneId = request.getHttpRequest().getParam("sone");
-               Sone sone = webInterface.getCore().getSone(soneId);
-               templateContext.set("sone", sone);
+               Optional<Sone> sone = webInterface.getCore().getSone(soneId);
+               templateContext.set("sone", sone.orNull());
                templateContext.set("soneId", soneId);
-               if (sone == null) {
+               if (!sone.isPresent()) {
                        return;
                }
-               List<Post> sonePosts = sone.getPosts();
-               sonePosts.addAll(webInterface.getCore().getDirectedPosts(sone.getId()));
+               List<Post> sonePosts = sone.get().getPosts();
+               sonePosts.addAll(webInterface.getCore().getDirectedPosts(sone.get().getId()));
                Collections.sort(sonePosts, Post.TIME_COMPARATOR);
                Pagination<Post> postPagination = new Pagination<Post>(sonePosts, webInterface.getCore().getPreferences().getPostsPerPage()).setPage(Numbers.safeParseInteger(request.getHttpRequest().getParam("postPage"), 0));
                templateContext.set("postPagination", postPagination);
                templateContext.set("posts", postPagination.getItems());
-               Set<PostReply> replies = sone.getReplies();
+               Set<PostReply> replies = sone.get().getReplies();
                final Map<Post, List<PostReply>> repliedPosts = new HashMap<Post, List<PostReply>>();
                for (PostReply reply : replies) {
                        Optional<Post> post = reply.getPost();
-                       if (!post.isPresent() || repliedPosts.containsKey(post.get()) || sone.equals(post.get().getSone()) || (sone.equals(post.get().getRecipient()))) {
+                       if (!post.isPresent() || repliedPosts.containsKey(post.get()) || sone.get().equals(post.get().getSone()) || (sone.get().getId().equals(post.get().getRecipientId().orNull()))) {
                                continue;
                        }
                        repliedPosts.put(post.get(), webInterface.getCore().getReplies(post.get()));
index 32ebfc9..4c278c6 100644 (file)
@@ -24,6 +24,8 @@ import net.pterodactylus.sone.web.WebInterface;
 import net.pterodactylus.sone.web.page.FreenetRequest;
 import net.pterodactylus.util.json.JsonObject;
 
+import com.google.common.base.Optional;
+
 /**
  * AJAX handler that creates a new post.
  *
@@ -51,7 +53,7 @@ public class CreatePostAjaxPage extends JsonPage {
                        return createErrorJsonObject("auth-required");
                }
                String recipientId = request.getHttpRequest().getParam("recipient");
-               Sone recipient = webInterface.getCore().getSone(recipientId);
+               Optional<Sone> recipient = webInterface.getCore().getSone(recipientId);
                String senderId = request.getHttpRequest().getParam("sender");
                Sone sender = webInterface.getCore().getLocalSone(senderId, false);
                if (sender == null) {
@@ -63,7 +65,7 @@ public class CreatePostAjaxPage extends JsonPage {
                }
                text = TextFilter.filter(request.getHttpRequest().getHeader("host"), text);
                Post newPost = webInterface.getCore().createPost(sender, recipient, text);
-               return createSuccessJsonObject().put("postId", newPost.getId()).put("sone", sender.getId()).put("recipient", (newPost.getRecipient() != null) ? newPost.getRecipient().getId() : null);
+               return createSuccessJsonObject().put("postId", newPost.getId()).put("sone", sender.getId()).put("recipient", newPost.getRecipientId().orNull());
        }
 
 }
index b86055d..843b088 100644 (file)
@@ -17,6 +17,8 @@
 
 package net.pterodactylus.sone.web.ajax;
 
+import com.google.common.base.Optional;
+
 import net.pterodactylus.sone.core.Core;
 import net.pterodactylus.sone.data.Sone;
 import net.pterodactylus.sone.web.WebInterface;
@@ -51,11 +53,11 @@ public class DistrustAjaxPage extends JsonPage {
                        return createErrorJsonObject("auth-required");
                }
                String soneId = request.getHttpRequest().getParam("sone");
-               Sone sone = webInterface.getCore().getSone(soneId);
-               if (sone == null) {
+               Optional<Sone> sone = webInterface.getCore().getSone(soneId);
+               if (!sone.isPresent()) {
                        return createErrorJsonObject("invalid-sone-id");
                }
-               webInterface.getCore().distrustSone(currentSone, sone);
+               webInterface.getCore().distrustSone(currentSone, sone.get());
                return createSuccessJsonObject().put("trustValue", webInterface.getCore().getPreferences().getNegativeTrust());
        }
 
index c58f82d..071f8e9 100644 (file)
@@ -17,6 +17,8 @@
 
 package net.pterodactylus.sone.web.ajax;
 
+import com.google.common.base.Optional;
+
 import net.pterodactylus.sone.data.Sone;
 import net.pterodactylus.sone.web.WebInterface;
 import net.pterodactylus.sone.web.page.FreenetRequest;
@@ -45,7 +47,8 @@ public class FollowSoneAjaxPage extends JsonPage {
        @Override
        protected JsonObject createJsonObject(FreenetRequest request) {
                String soneId = request.getHttpRequest().getParam("sone");
-               if (!webInterface.getCore().hasSone(soneId)) {
+               Optional<Sone> sone = webInterface.getCore().getSone(soneId);
+               if (!sone.isPresent()) {
                        return createErrorJsonObject("invalid-sone-id");
                }
                Sone currentSone = getCurrentSone(request.getToadletContext());
@@ -53,7 +56,7 @@ public class FollowSoneAjaxPage extends JsonPage {
                        return createErrorJsonObject("auth-required");
                }
                webInterface.getCore().followSone(currentSone, soneId);
-               webInterface.getCore().markSoneKnown(webInterface.getCore().getSone(soneId));
+               webInterface.getCore().markSoneKnown(sone.get());
                return createSuccessJsonObject();
        }
 
index e32573d..8eeedc9 100644 (file)
@@ -96,7 +96,7 @@ public class GetPostAjaxPage extends JsonPage {
                JsonObject jsonPost = new JsonObject();
                jsonPost.put("id", post.getId());
                jsonPost.put("sone", post.getSone().getId());
-               jsonPost.put("recipient", (post.getRecipient() == null) ? null : post.getRecipient().getId());
+               jsonPost.put("recipient", post.getRecipientId().orNull());
                jsonPost.put("time", post.getTime());
                StringWriter stringWriter = new StringWriter();
                TemplateContext templateContext = webInterface.getTemplateContextFactory().createTemplateContext();
index f107b71..48b25d6 100644 (file)
@@ -74,7 +74,7 @@ public class GetStatusAjaxPage extends JsonPage {
                        String[] soneIds = loadSoneIds.split(",");
                        for (String soneId : soneIds) {
                                /* just add it, we skip null further down. */
-                               sones.add(webInterface.getCore().getSone(soneId));
+                               sones.add(webInterface.getCore().getSone(soneId).orNull());
                        }
                }
                JsonArray jsonSones = new JsonArray();
@@ -105,7 +105,7 @@ public class GetStatusAjaxPage extends JsonPage {
                        JsonObject jsonPost = new JsonObject();
                        jsonPost.put("id", post.getId());
                        jsonPost.put("sone", post.getSone().getId());
-                       jsonPost.put("recipient", (post.getRecipient() != null) ? post.getRecipient().getId() : null);
+                       jsonPost.put("recipient", post.getRecipientId().orNull());
                        jsonPost.put("time", post.getTime());
                        jsonPosts.add(jsonPost);
                }
index 4701118..6610971 100644 (file)
@@ -71,11 +71,11 @@ public class MarkAsKnownAjaxPage extends JsonPage {
                                }
                                core.markReplyKnown(reply.get());
                        } else if (type.equals("sone")) {
-                               Sone sone = core.getSone(id);
-                               if (sone == null) {
+                               Optional<Sone> sone = core.getSone(id);
+                               if (!sone.isPresent()) {
                                        continue;
                                }
-                               core.markSoneKnown(sone);
+                               core.markSoneKnown(sone.get());
                        }
                }
                return createSuccessJsonObject();
index 9329c1b..d03e030 100644 (file)
@@ -17,6 +17,8 @@
 
 package net.pterodactylus.sone.web.ajax;
 
+import com.google.common.base.Optional;
+
 import net.pterodactylus.sone.core.Core;
 import net.pterodactylus.sone.data.Sone;
 import net.pterodactylus.sone.web.WebInterface;
@@ -51,11 +53,11 @@ public class TrustAjaxPage extends JsonPage {
                        return createErrorJsonObject("auth-required");
                }
                String soneId = request.getHttpRequest().getParam("sone");
-               Sone sone = webInterface.getCore().getSone(soneId);
-               if (sone == null) {
+               Optional<Sone> sone = webInterface.getCore().getSone(soneId);
+               if (!sone.isPresent()) {
                        return createErrorJsonObject("invalid-sone-id");
                }
-               webInterface.getCore().trustSone(currentSone, sone);
+               webInterface.getCore().trustSone(currentSone, sone.get());
                return createSuccessJsonObject().put("trustValue", webInterface.getCore().getPreferences().getPositiveTrust());
        }
 
index 70e1448..65d45c9 100644 (file)
@@ -17,6 +17,8 @@
 
 package net.pterodactylus.sone.web.ajax;
 
+import com.google.common.base.Optional;
+
 import net.pterodactylus.sone.core.Core;
 import net.pterodactylus.sone.data.Sone;
 import net.pterodactylus.sone.web.WebInterface;
@@ -51,11 +53,11 @@ public class UntrustAjaxPage extends JsonPage {
                        return createErrorJsonObject("auth-required");
                }
                String soneId = request.getHttpRequest().getParam("sone");
-               Sone sone = webInterface.getCore().getSone(soneId);
-               if (sone == null) {
+               Optional<Sone> sone = webInterface.getCore().getSone(soneId);
+               if (!sone.isPresent()) {
                        return createErrorJsonObject("invalid-sone-id");
                }
-               webInterface.getCore().untrustSone(currentSone, sone);
+               webInterface.getCore().untrustSone(currentSone, sone.get());
                return createSuccessJsonObject().put("trustValue", (String) null);
        }
 
index 76f3755..444f45f 100644 (file)
@@ -21,6 +21,8 @@ import java.io.IOException;
 import java.io.StringReader;
 import java.util.Arrays;
 
+import com.google.common.base.Optional;
+
 import junit.framework.TestCase;
 import net.pterodactylus.sone.data.Sone;
 import net.pterodactylus.sone.database.SoneProvider;
@@ -181,8 +183,8 @@ public class SoneTextParserTest extends TestCase {
                 * {@inheritDoc}
                 */
                @Override
-               public Sone getSone(final String soneId) {
-                       return new Sone(soneId, false) {
+               public Optional<Sone> getSone(final String soneId) {
+                       return Optional.<Sone> fromNullable(new Sone(soneId, false) {
 
                                /**
                                 * {@inheritDoc}
@@ -191,7 +193,7 @@ public class SoneTextParserTest extends TestCase {
                                public String getName() {
                                        return soneId;
                                }
-                       };
+                       });
                }
 
        }