Return nullable Post instead of Optional
authorDavid ‘Bombe’ Roden <bombe@pterodactylus.net>
Mon, 16 Oct 2017 19:27:57 +0000 (21:27 +0200)
committerDavid ‘Bombe’ Roden <bombe@pterodactylus.net>
Mon, 16 Oct 2017 19:27:57 +0000 (21:27 +0200)
26 files changed:
src/main/java/net/pterodactylus/sone/core/Core.java
src/main/java/net/pterodactylus/sone/data/impl/PostReplyImpl.java
src/main/java/net/pterodactylus/sone/database/memory/MemoryBookmarkDatabase.java
src/main/java/net/pterodactylus/sone/database/memory/MemoryDatabase.java
src/main/java/net/pterodactylus/sone/database/memory/MemoryPostReply.java
src/main/java/net/pterodactylus/sone/fcp/AbstractSoneCommand.java
src/main/kotlin/net/pterodactylus/sone/database/PostProvider.kt
src/main/kotlin/net/pterodactylus/sone/web/ajax/BookmarkAjaxPage.kt
src/main/kotlin/net/pterodactylus/sone/web/ajax/GetTimesAjaxPage.kt
src/main/kotlin/net/pterodactylus/sone/web/ajax/MarkAsKnownAjaxPage.kt
src/main/kotlin/net/pterodactylus/sone/web/pages/BookmarkPage.kt
src/main/kotlin/net/pterodactylus/sone/web/pages/CreateReplyPage.kt
src/main/kotlin/net/pterodactylus/sone/web/pages/DeletePostPage.kt
src/main/kotlin/net/pterodactylus/sone/web/pages/MarkAsKnownPage.kt
src/main/kotlin/net/pterodactylus/sone/web/pages/SearchPage.kt
src/main/kotlin/net/pterodactylus/sone/web/pages/ViewPostPage.kt
src/test/java/net/pterodactylus/sone/database/memory/MemoryBookmarkDatabaseTest.java
src/test/java/net/pterodactylus/sone/database/memory/MemoryDatabaseTest.java
src/test/java/net/pterodactylus/sone/text/SoneTextParserTest.java
src/test/kotlin/net/pterodactylus/sone/fcp/CreateReplyCommandTest.kt
src/test/kotlin/net/pterodactylus/sone/fcp/DeletePostCommandTest.kt
src/test/kotlin/net/pterodactylus/sone/fcp/GetPostCommandTest.kt
src/test/kotlin/net/pterodactylus/sone/fcp/LikePostCommandTest.kt
src/test/kotlin/net/pterodactylus/sone/fcp/SoneCommandTest.kt
src/test/kotlin/net/pterodactylus/sone/web/ajax/TestObjects.kt
src/test/kotlin/net/pterodactylus/sone/web/pages/WebPageTest.kt

index af69f98..2746d7b 100644 (file)
@@ -422,11 +422,9 @@ public class Core extends AbstractService implements SoneProvider, PostProvider,
                return database.newPostBuilder();
        }
 
-       /**
-        * {@inheritDoc}
-        */
+       @Nullable
        @Override
-       public Optional<Post> getPost(String postId) {
+       public Post getPost(@Nonnull String postId) {
                return database.getPost(postId);
        }
 
index 5084c1c..3571172 100644 (file)
@@ -17,6 +17,8 @@
 
 package net.pterodactylus.sone.data.impl;
 
+import static com.google.common.base.Optional.fromNullable;
+
 import net.pterodactylus.sone.data.Post;
 import net.pterodactylus.sone.data.PostReply;
 import net.pterodactylus.sone.database.PostProvider;
@@ -78,7 +80,7 @@ public class PostReplyImpl extends ReplyImpl<PostReply> implements PostReply {
         */
        @Override
        public Optional<Post> getPost() {
-               return postProvider.getPost(postId);
+               return fromNullable(postProvider.getPost(postId));
        }
 
 }
index 594cf2b..4c4bc3f 100644 (file)
@@ -1,5 +1,6 @@
 package net.pterodactylus.sone.database.memory;
 
+import static com.google.common.base.Optional.fromNullable;
 import static com.google.common.collect.FluentIterable.from;
 
 import java.util.HashSet;
@@ -99,7 +100,7 @@ public class MemoryBookmarkDatabase implements BookmarkDatabase {
                                        new Function<String, Post>() {
                                                @Override
                                                public Post apply(String postId) {
-                                                       return memoryDatabase.getPost(postId)
+                                                       return fromNullable(memoryDatabase.getPost(postId))
                                                                        .or(new EmptyPost(postId));
                                                }
                                        }).toSet();
index 0223c82..5e5021c 100644 (file)
@@ -59,7 +59,6 @@ import net.pterodactylus.sone.database.SoneProvider;
 import net.pterodactylus.util.config.Configuration;
 import net.pterodactylus.util.config.ConfigurationException;
 
-import com.google.common.base.Optional;
 import com.google.common.base.Predicate;
 import com.google.common.collect.HashMultimap;
 import com.google.common.collect.Multimap;
@@ -332,12 +331,12 @@ public class MemoryDatabase extends AbstractService implements Database {
        // POSTPROVIDER METHODS
        //
 
-       /** {@inheritDocs} */
+       @Nullable
        @Override
-       public Optional<Post> getPost(String postId) {
+       public Post getPost(@Nonnull String postId) {
                lock.readLock().lock();
                try {
-                       return fromNullable(allPosts.get(postId));
+                       return allPosts.get(postId);
                } finally {
                        lock.readLock().unlock();
                }
index 2fc8a88..687c28a 100644 (file)
@@ -17,6 +17,8 @@
 
 package net.pterodactylus.sone.database.memory;
 
+import static com.google.common.base.Optional.fromNullable;
+
 import net.pterodactylus.sone.data.Post;
 import net.pterodactylus.sone.data.PostReply;
 import net.pterodactylus.sone.data.Sone;
@@ -150,7 +152,7 @@ class MemoryPostReply implements PostReply {
         */
        @Override
        public Optional<Post> getPost() {
-               return database.getPost(postId);
+               return fromNullable(database.getPost(postId));
        }
 
        //
index a47bde3..9942af7 100644 (file)
@@ -184,11 +184,11 @@ public abstract class AbstractSoneCommand extends AbstractCommand {
        protected Post getPost(SimpleFieldSet simpleFieldSet, String parameterName) throws FcpException {
                try {
                        String postId = simpleFieldSet.getString(parameterName);
-                       Optional<Post> post = core.getPost(postId);
-                       if (!post.isPresent()) {
+                       Post post = core.getPost(postId);
+                       if (post == null) {
                                throw new FcpException("Could not load post from “" + postId + "”.");
                        }
-                       return post.get();
+                       return post;
                } catch (FSParseException fspe1) {
                        throw new FcpException("Could not post ID from “" + parameterName + "”.", fspe1);
                }
index fba9daf..37cb2a1 100644 (file)
@@ -29,7 +29,7 @@ import com.google.inject.ImplementedBy
 @ImplementedBy(MemoryDatabase::class)
 interface PostProvider {
 
-       fun getPost(postId: String): Optional<Post>
+       fun getPost(postId: String): Post?
        fun getPosts(soneId: String): Collection<Post>
        fun getDirectedPosts(recipientId: String): Collection<Post>
 
index b185d2b..35ac0e2 100644 (file)
@@ -1,6 +1,5 @@
 package net.pterodactylus.sone.web.ajax
 
-import net.pterodactylus.sone.utils.also
 import net.pterodactylus.sone.utils.emptyToNull
 import net.pterodactylus.sone.utils.parameters
 import net.pterodactylus.sone.web.WebInterface
@@ -15,9 +14,10 @@ class BookmarkAjaxPage(webInterface: WebInterface) : JsonPage("bookmark.ajax", w
 
        override fun createJsonObject(request: FreenetRequest) =
                        request.parameters["post"].emptyToNull
-                                       ?.let(core::getPost)
-                                       ?.also(core::bookmarkPost)
-                                       ?.let { createSuccessJsonObject() }
+                                       ?.let { postId ->
+                                               core.getPost(postId)?.also(core::bookmarkPost)
+                                               createSuccessJsonObject()
+                                       }
                                        ?: createErrorJsonObject("invalid-post-id")
 
 }
index 96fb7e4..cb3b86d 100644 (file)
@@ -3,7 +3,6 @@ package net.pterodactylus.sone.web.ajax
 import net.pterodactylus.sone.freenet.L10nFilter
 import net.pterodactylus.sone.text.TimeTextConverter
 import net.pterodactylus.sone.utils.jsonObject
-import net.pterodactylus.sone.utils.let
 import net.pterodactylus.sone.utils.parameters
 import net.pterodactylus.sone.web.WebInterface
 import net.pterodactylus.sone.web.page.FreenetRequest
@@ -27,7 +26,7 @@ class GetTimesAjaxPage(webInterface: WebInterface,
 
        override fun createJsonObject(request: FreenetRequest) =
                        createSuccessJsonObject().apply {
-                               put("postTimes", request.parameters["posts"]!!.idsToJson { core.getPost(it).let { it.id to it.time } })
+                               put("postTimes", request.parameters["posts"]!!.idsToJson { core.getPost(it)?.let { it.id to it.time } })
                                put("replyTimes", request.parameters["replies"]!!.idsToJson { core.getPostReply(it)?.let { it.id to it.time } })
                        }
 
index 224007d..0451eaa 100644 (file)
@@ -1,8 +1,5 @@
 package net.pterodactylus.sone.web.ajax
 
-import com.google.common.base.Optional
-import net.pterodactylus.sone.utils.asOptional
-import net.pterodactylus.sone.utils.mapPresent
 import net.pterodactylus.sone.utils.parameters
 import net.pterodactylus.sone.web.WebInterface
 import net.pterodactylus.sone.web.page.FreenetRequest
@@ -16,16 +13,16 @@ class MarkAsKnownAjaxPage(webInterface: WebInterface) : JsonPage("markAsKnown.aj
        override val requiresLogin = false
 
        override fun createJsonObject(request: FreenetRequest) = when (request.parameters["type"]) {
-               "sone" -> processIds(request, { core.getSone(it).asOptional() }, core::markSoneKnown)
+               "sone" -> processIds(request, core::getSone, core::markSoneKnown)
                "post" -> processIds(request, core::getPost, core::markPostKnown)
-               "reply" -> processIds(request, { core.getPostReply(it).asOptional() }, core::markReplyKnown)
+               "reply" -> processIds(request, core::getPostReply, core::markReplyKnown)
                else -> createErrorJsonObject("invalid-type")
        }
 
-       private fun <T> processIds(request: FreenetRequest, getter: (String) -> Optional<T>, marker: (T) -> Unit) =
+       private fun <T : Any> processIds(request: FreenetRequest, getter: (String) -> T?, marker: (T) -> Unit) =
                        request.parameters["id"]
                                        ?.split(Regex(" +"))
-                                       ?.mapPresent(getter)
+                                       ?.mapNotNull(getter)
                                        ?.onEach(marker)
                                        .let { createSuccessJsonObject() }
 
index 519d49e..7fb2320 100644 (file)
@@ -16,7 +16,7 @@ class BookmarkPage(template: Template, webInterface: WebInterface)
                if (freenetRequest.isPOST) {
                        val returnPage = freenetRequest.httpRequest.getPartAsStringFailsafe("returnPage", 256)
                        val postId = freenetRequest.httpRequest.getPartAsStringFailsafe("post", 36)
-                       webInterface.core.getPost(postId).orNull()?.let {
+                       webInterface.core.getPost(postId)?.let {
                                webInterface.core.bookmarkPost(it)
                        }
                        throw RedirectException(returnPage)
index a6c58e4..a3fc1f3 100644 (file)
@@ -22,7 +22,7 @@ class CreateReplyPage(template: Template, webInterface: WebInterface):
                                templateContext["errorTextEmpty"] = true
                                return
                        }
-                       val post = webInterface.core.getPost(postId).orNull() ?: throw RedirectException("noPermission.html")
+                       val post = webInterface.core.getPost(postId) ?: throw RedirectException("noPermission.html")
                        val sender = webInterface.core.getLocalSone(freenetRequest.httpRequest.getPartAsStringFailsafe("sender", 43)) ?: getCurrentSone(freenetRequest.toadletContext)
                        webInterface.core.createReply(sender, post, TextFilter.filter(freenetRequest.httpRequest.getHeader("Host"), text))
                        throw RedirectException(returnPage)
index 21465d7..181144e 100644 (file)
@@ -14,7 +14,7 @@ class DeletePostPage(template: Template, webInterface: WebInterface):
 
        override fun handleRequest(freenetRequest: FreenetRequest, templateContext: TemplateContext) {
                if (freenetRequest.isPOST) {
-                       val post = webInterface.core.getPost(freenetRequest.httpRequest.getPartAsStringFailsafe("post", 36)).orNull() ?: throw RedirectException("noPermission.html")
+                       val post = webInterface.core.getPost(freenetRequest.httpRequest.getPartAsStringFailsafe("post", 36)) ?: throw RedirectException("noPermission.html")
                        val returnPage = freenetRequest.httpRequest.getPartAsStringFailsafe("returnPage", 256)
                        if (!post.sone.isLocal) {
                                throw RedirectException("noPermission.html")
@@ -29,7 +29,7 @@ class DeletePostPage(template: Template, webInterface: WebInterface):
                        templateContext["returnPage"] = returnPage
                        return
                }
-               templateContext["post"] = webInterface.core.getPost(freenetRequest.httpRequest.getParam("post")).orNull() ?: throw RedirectException("noPermission.html")
+               templateContext["post"] = webInterface.core.getPost(freenetRequest.httpRequest.getParam("post")) ?: throw RedirectException("noPermission.html")
                templateContext["returnPage"] = freenetRequest.httpRequest.getParam("returnPage")
        }
 
index 31e70fc..49c1075 100644 (file)
@@ -19,7 +19,7 @@ class MarkAsKnownPage(template: Template, webInterface: WebInterface):
                val ids = freenetRequest.parameters["id", 65536]!!.split(" ")
                when (freenetRequest.parameters["type", 5]) {
                        "sone" -> ids.mapNotNull(webInterface.core::getSone).forEach(webInterface.core::markSoneKnown)
-                       "post" -> ids.mapPresent(webInterface.core::getPost).forEach(webInterface.core::markPostKnown)
+                       "post" -> ids.mapNotNull(webInterface.core::getPost).forEach(webInterface.core::markPostKnown)
                        "reply" -> ids.mapNotNull(webInterface.core::getPostReply).forEach(webInterface.core::markReplyKnown)
                        else -> throw RedirectException("invalid.html")
                }
index d021dfb..02d63c5 100644 (file)
@@ -43,7 +43,7 @@ class SearchPage @JvmOverloads constructor(template: Template, webInterface: Web
                        1 -> phrases.first().phrase.also { word ->
                                when {
                                        word.removePrefix("sone://").let(webInterface.core::getSone) != null -> redirect("viewSone.html?sone=${word.removePrefix("sone://")}")
-                                       word.removePrefix("post://").let(webInterface.core::getPost).isPresent -> redirect("viewPost.html?post=${word.removePrefix("post://")}")
+                                       word.removePrefix("post://").let(webInterface.core::getPost) != null -> redirect("viewPost.html?post=${word.removePrefix("post://")}")
                                        word.removePrefix("reply://").let(webInterface.core::getPostReply) != null -> redirect("viewPost.html?post=${word.removePrefix("reply://").let(webInterface.core::getPostReply)?.postId}")
                                        word.removePrefix("album://").let(webInterface.core::getAlbum) != null -> redirect("imageBrowser.html?album=${word.removePrefix("album://")}")
                                        word.removePrefix("image://").let { webInterface.core.getImage(it, false) } != null -> redirect("imageBrowser.html?image=${word.removePrefix("image://")}")
index d331417..910c939 100644 (file)
@@ -16,7 +16,7 @@ class ViewPostPage(template: Template, webInterface: WebInterface):
                SoneTemplatePage("viewPost.html", template, "Page.ViewPost.Title", webInterface, false) {
 
        override fun handleRequest(freenetRequest: FreenetRequest, templateContext: TemplateContext) {
-               templateContext["post"] = freenetRequest.parameters["post"]?.let(webInterface.core::getPost)?.orNull()
+               templateContext["post"] = freenetRequest.parameters["post"]?.let(webInterface.core::getPost)
                templateContext["raw"] = freenetRequest.parameters["raw"] == "true"
        }
 
index e6bfffe..7edea06 100644 (file)
@@ -1,6 +1,5 @@
 package net.pterodactylus.sone.database.memory;
 
-import static com.google.common.base.Optional.fromNullable;
 import static net.pterodactylus.sone.test.Matchers.isPostWithId;
 import static org.hamcrest.MatcherAssert.assertThat;
 import static org.hamcrest.Matchers.contains;
@@ -19,7 +18,6 @@ import java.util.Set;
 
 import net.pterodactylus.sone.data.Post;
 
-import com.google.common.base.Optional;
 import org.junit.Before;
 import org.junit.Test;
 import org.mockito.invocation.InvocationOnMock;
@@ -42,12 +40,11 @@ public class MemoryBookmarkDatabaseTest {
        @Before
        public void setupMemoryDatabase() {
                when(memoryDatabase.getPost(anyString())).thenAnswer(
-                               new Answer<Optional<Post>>() {
+                               new Answer<Post>() {
                                        @Override
-                                       public Optional<Post> answer(
+                                       public Post answer(
                                                        InvocationOnMock invocation) {
-                                               return fromNullable(
-                                                               posts.get(invocation.getArguments()[0]));
+                                               return posts.get(invocation.getArguments()[0]);
                                        }
                                });
        }
index d4c0954..bb62eaf 100644 (file)
@@ -178,12 +178,12 @@ public class MemoryDatabaseTest {
                firstAlbum.addImage(thirdImage);
                secondAlbum.addImage(secondImage);
                memoryDatabase.storeSone(sone);
-               assertThat(memoryDatabase.getPost("post1").get(),
+               assertThat(memoryDatabase.getPost("post1"),
                                isPost(firstPost.getId(), 1000L, "post1",
                                                Optional.<String>absent()));
-               assertThat(memoryDatabase.getPost("post2").get(),
+               assertThat(memoryDatabase.getPost("post2"),
                                isPost(secondPost.getId(), 2000L, "post2", of(RECIPIENT_ID)));
-               assertThat(memoryDatabase.getPost("post3").isPresent(), is(false));
+               assertThat(memoryDatabase.getPost("post3"), nullValue());
                assertThat(memoryDatabase.getPostReply("reply1"),
                                isPostReply("reply1", "post1", 3000L, "reply1"));
                assertThat(memoryDatabase.getPostReply("reply2"),
index b763cd1..79f1974 100644 (file)
@@ -467,9 +467,10 @@ public class SoneTextParserTest {
 
        private static class TestPostProvider implements PostProvider {
 
+               @Nullable
                @Override
-               public Optional<Post> getPost(final String postId) {
-                       return Optional.<Post>of(new Post() {
+               public Post getPost(@Nonnull final String postId) {
+                       return new Post() {
                                @Override
                                public String getId() {
                                        return postId;
@@ -514,7 +515,7 @@ public class SoneTextParserTest {
                                public Post setKnown(boolean known) {
                                        return null;
                                }
-                       });
+                       };
                }
 
                @Override
@@ -531,9 +532,10 @@ public class SoneTextParserTest {
 
        private static class AbsentPostProvider extends TestPostProvider {
 
+               @Nullable
                @Override
-               public Optional<Post> getPost(String postId) {
-                       return Optional.absent();
+               public Post getPost(@Nonnull String postId) {
+                       return null;
                }
 
        }
index 5b4809c..a6e69cd 100644 (file)
@@ -64,7 +64,7 @@ class CreateReplyCommandTest : SoneCommandTest() {
 
        private fun addValidPostParameter() {
                parameters += "Post" to "ValidPostId"
-               whenever(core.getPost("ValidPostId")).thenReturn(of(post))
+               whenever(core.getPost("ValidPostId")).thenReturn(post)
        }
 
        @Test
index 751ad24..30fc4cb 100644 (file)
@@ -38,7 +38,7 @@ class DeletePostCommandTest : SoneCommandTest() {
        @Test
        fun `request with post from remote sone returns error response`() {
                parameters += "Post" to "RemotePostId"
-               whenever(core.getPost("RemotePostId")).thenReturn(of(postFromRemoteSone))
+               whenever(core.getPost("RemotePostId")).thenReturn(postFromRemoteSone)
                val response = command.execute(parameters)
                assertThat(response.replyParameters["Message"], equalTo("Error"))
                assertThat(response.replyParameters["ErrorCode"], equalTo("401"))
@@ -47,7 +47,7 @@ class DeletePostCommandTest : SoneCommandTest() {
        @Test
        fun `request with post from local sone deletes posts`() {
                parameters += "Post" to "LocalPostId"
-               whenever(core.getPost("LocalPostId")).thenReturn(of(postFromLocalSone))
+               whenever(core.getPost("LocalPostId")).thenReturn(postFromLocalSone)
                val response = command.execute(parameters)
                assertThat(response.replyParameters["Message"], equalTo("PostDeleted"))
                verify(core).deletePost(postFromLocalSone)
index b7f911c..5c76c5b 100644 (file)
@@ -31,7 +31,7 @@ class GetPostCommandTest : SoneCommandTest() {
 
        @Before
        fun setupPostWithLikesAndReplies() {
-               whenever(core.getPost("ValidPostId")).thenReturn(post.asOptional())
+               whenever(core.getPost("ValidPostId")).thenReturn(post)
                whenever(core.getLikes(post)).thenReturn(setOf(sone1, sone2))
                val replies = listOf(postReply1, postReply2)
                whenever(core.getReplies("ValidPostId")).thenReturn(replies)
index b344f51..6c7d40c 100644 (file)
@@ -23,7 +23,7 @@ class LikePostCommandTest : SoneCommandTest() {
 
        @Before
        fun setupPostAndSones() {
-               whenever(core.getPost("PostId")).thenReturn(post.asOptional())
+               whenever(core.getPost("PostId")).thenReturn(post)
                whenever(core.getSone("RemoteSoneId")).thenReturn(remoteSone)
                whenever(core.getSone("LocalSoneId")).thenReturn(localSone)
        }
index 5397683..de92612 100644 (file)
@@ -39,7 +39,7 @@ abstract class SoneCommandTest {
        @Before
        fun setupCore() {
                whenever(core.getSone(anyString())).thenReturn(null)
-               whenever(core.getPost(anyString())).thenReturn(absent())
+               whenever(core.getPost(anyString())).thenReturn(null)
                whenever(core.getPostReply(anyString())).thenReturn(null)
        }
 
index 0dbbeaf..a42e5ba 100644 (file)
@@ -93,7 +93,7 @@ open class TestObjects {
                whenever(core.updateChecker).thenReturn(updateChecker)
                whenever(core.getSone(ArgumentMatchers.anyString())).thenAnswer { (localSones + remoteSones)[it.getArgument(0)] }
                whenever(core.getLocalSone(ArgumentMatchers.anyString())).thenAnswer { localSones[it[0]] }
-               whenever(core.getPost(ArgumentMatchers.anyString())).thenAnswer { (posts + newPosts)[it[0]].asOptional() }
+               whenever(core.getPost(ArgumentMatchers.anyString())).thenAnswer { (posts + newPosts)[it[0]] }
                whenever(core.getLikes(ArgumentMatchers.any<Post>())).then { postLikes[it[0]] ?: emptySet<Sone>() }
                whenever(core.getLikes(ArgumentMatchers.any<PostReply>())).then { replyLikes[it[0]] ?: emptySet<Sone>() }
                whenever(core.getPostReply(ArgumentMatchers.anyString())).then { replies[it[0]] }
index 2687963..ce16c85 100644 (file)
@@ -92,7 +92,7 @@ open class WebPageTest(pageSupplier: (Template, WebInterface) -> SoneTemplatePag
                whenever(core.getSone(anyString())).then { allSones[it[0]] }
                whenever(core.localSones).then { localSones.values }
                whenever(core.getLocalSone(anyString())).then { localSones[it[0]] }
-               whenever(core.getPost(anyString())).then { allPosts[it[0]].asOptional() }
+               whenever(core.getPost(anyString())).then { allPosts[it[0]] }
                whenever(core.getPostReply(anyString())).then { allPostReplies[it[0]] }
                whenever(core.getReplies(anyString())).then { perPostReplies[it[0]].asList() }
                whenever(core.getAlbum(anyString())).then { allAlbums[it[0]] }