From aba6bd1d58ef244050703e1b99d7389e024809c6 Mon Sep 17 00:00:00 2001 From: =?utf8?q?David=20=E2=80=98Bombe=E2=80=99=20Roden?= Date: Fri, 3 Oct 2014 23:08:33 +0200 Subject: [PATCH] Add bookmark database. --- .../sone/database/BookmarkDatabase.java | 20 +++++ .../database/memory/MemoryBookmarkDatabase.java | 86 +++++++++++++++++++ .../memory/MemoryBookmarkDatabaseTest.java | 97 ++++++++++++++++++++++ 3 files changed, 203 insertions(+) create mode 100644 src/main/java/net/pterodactylus/sone/database/BookmarkDatabase.java create mode 100644 src/main/java/net/pterodactylus/sone/database/memory/MemoryBookmarkDatabase.java create mode 100644 src/test/java/net/pterodactylus/sone/database/memory/MemoryBookmarkDatabaseTest.java diff --git a/src/main/java/net/pterodactylus/sone/database/BookmarkDatabase.java b/src/main/java/net/pterodactylus/sone/database/BookmarkDatabase.java new file mode 100644 index 0000000..dbcdb84 --- /dev/null +++ b/src/main/java/net/pterodactylus/sone/database/BookmarkDatabase.java @@ -0,0 +1,20 @@ +package net.pterodactylus.sone.database; + +import java.util.Set; + +import net.pterodactylus.sone.data.Post; + +/** + * Database interface for bookmark-related functionality. + * + * @author David ‘Bombe’ Roden + */ +public interface BookmarkDatabase { + + void bookmarkPost(String postId); // FIXME – remove me + void bookmarkPost(Post post); + void unbookmarkPost(Post post); + boolean isPostBookmarked(Post post); + Set getBookmarkedPosts(); + +} diff --git a/src/main/java/net/pterodactylus/sone/database/memory/MemoryBookmarkDatabase.java b/src/main/java/net/pterodactylus/sone/database/memory/MemoryBookmarkDatabase.java new file mode 100644 index 0000000..1aec573 --- /dev/null +++ b/src/main/java/net/pterodactylus/sone/database/memory/MemoryBookmarkDatabase.java @@ -0,0 +1,86 @@ +package net.pterodactylus.sone.database.memory; + +import static com.google.common.collect.FluentIterable.from; + +import java.util.HashSet; +import java.util.Set; +import java.util.concurrent.locks.ReadWriteLock; +import java.util.concurrent.locks.ReentrantReadWriteLock; + +import net.pterodactylus.sone.data.Post; +import net.pterodactylus.sone.database.BookmarkDatabase; + +import com.google.common.base.Function; + +/** + * Memory-based {@link BookmarkDatabase} implementation. + * + * @author David ‘Bombe’ Roden + */ +public class MemoryBookmarkDatabase implements BookmarkDatabase { + + private final ReadWriteLock lock = new ReentrantReadWriteLock(); + private final MemoryDatabase memoryDatabase; + private final Set bookmarkedPosts = new HashSet(); + + public MemoryBookmarkDatabase(MemoryDatabase memoryDatabase) { + this.memoryDatabase = memoryDatabase; + } + + @Override + public void bookmarkPost(String postId) { + lock.writeLock().lock(); + try { + bookmarkedPosts.add(postId); + } finally { + lock.writeLock().unlock(); + } + } + + @Override + public void bookmarkPost(Post post) { + lock.writeLock().lock(); + try { + bookmarkedPosts.add(post.getId()); + } finally { + lock.writeLock().unlock(); + } + } + + @Override + public void unbookmarkPost(Post post) { + lock.writeLock().lock(); + try { + bookmarkedPosts.remove(post.getId()); + } finally { + lock.writeLock().unlock(); + } + } + + @Override + public boolean isPostBookmarked(Post post) { + lock.readLock().lock(); + try { + return bookmarkedPosts.contains(post.getId()); + } finally { + lock.readLock().unlock(); + } + } + + @Override + public Set getBookmarkedPosts() { + lock.readLock().lock(); + try { + return from(bookmarkedPosts).transformAndConcat( + new Function>() { + @Override + public Iterable apply(String postId) { + return memoryDatabase.getPost(postId).asSet(); + } + }).toSet(); + } finally { + lock.readLock().unlock(); + } + } + +} diff --git a/src/test/java/net/pterodactylus/sone/database/memory/MemoryBookmarkDatabaseTest.java b/src/test/java/net/pterodactylus/sone/database/memory/MemoryBookmarkDatabaseTest.java new file mode 100644 index 0000000..93efe11 --- /dev/null +++ b/src/test/java/net/pterodactylus/sone/database/memory/MemoryBookmarkDatabaseTest.java @@ -0,0 +1,97 @@ +package net.pterodactylus.sone.database.memory; + +import static com.google.common.base.Optional.fromNullable; +import static org.hamcrest.MatcherAssert.assertThat; +import static org.hamcrest.Matchers.contains; +import static org.hamcrest.Matchers.is; +import static org.mockito.Matchers.anyString; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; + +import java.util.HashMap; +import java.util.HashSet; +import java.util.Map; +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; +import org.mockito.stubbing.Answer; + +/** + * Unit test for {@link MemoryBookmarkDatabase}. + * + * @author David ‘Bombe’ Roden + */ +public class MemoryBookmarkDatabaseTest { + + private final MemoryDatabase memoryDatabase = mock(MemoryDatabase.class); + private final MemoryBookmarkDatabase bookmarkDatabase = + new MemoryBookmarkDatabase(memoryDatabase); + private final Map posts = new HashMap(); + + @Before + public void setupMemoryDatabase() { + when(memoryDatabase.getPost(anyString())).thenAnswer( + new Answer>() { + @Override + public Optional answer( + InvocationOnMock invocation) { + return fromNullable( + posts.get(invocation.getArguments()[0])); + } + }); + } + + @Before + public void setupPosts() { + createPost("PostId1"); + createPost("PostId2"); + } + + private void createPost(String postId) { + Post post = mock(Post.class); + when(post.getId()).thenReturn(postId); + posts.put(postId, post); + } + + @Test + public void bookmarkDatabaseRetainsBookmarkedPosts() { + Set allPosts = new HashSet(posts.values()); + for (Post post : allPosts) { + bookmarkDatabase.bookmarkPost(post); + } + assertThat(bookmarkDatabase.getBookmarkedPosts(), is(allPosts)); + for (Post post : allPosts) { + assertThat(bookmarkDatabase.isPostBookmarked(post), is(true)); + } + } + + @Test + public void removingABookmarkRemovesTheCorrectBookmark() { + Set allPosts = new HashSet(posts.values()); + for (Post post : allPosts) { + bookmarkDatabase.bookmarkPost(post); + } + Post randomPost = posts.values().iterator().next(); + bookmarkDatabase.unbookmarkPost(randomPost); + allPosts.remove(randomPost); + assertThat(bookmarkDatabase.getBookmarkedPosts(), is(allPosts)); + for (Post post : posts.values()) { + assertThat(bookmarkDatabase.isPostBookmarked(post), + is(!post.equals(randomPost))); + } + } + + @Test + public void addingABookmarkByIdBookmarksTheCorrectPost() { + Post randomPost = posts.values().iterator().next(); + bookmarkDatabase.bookmarkPost(randomPost.getId()); + assertThat(bookmarkDatabase.getBookmarkedPosts(), + contains(randomPost)); + } + +} -- 2.7.4