Remove updated time setter from Sone, store update time in database.
authorDavid ‘Bombe’ Roden <bombe@pterodactylus.net>
Sun, 7 Dec 2014 00:32:02 +0000 (01:32 +0100)
committerDavid ‘Bombe’ Roden <bombe@pterodactylus.net>
Sun, 7 Dec 2014 00:32:02 +0000 (01:32 +0100)
src/main/java/net/pterodactylus/sone/core/Core.java
src/main/java/net/pterodactylus/sone/core/SoneInserter.java
src/main/java/net/pterodactylus/sone/data/Sone.java
src/main/java/net/pterodactylus/sone/data/impl/IdOnlySone.java
src/main/java/net/pterodactylus/sone/data/impl/SoneImpl.java
src/main/java/net/pterodactylus/sone/database/SoneDatabase.java
src/main/java/net/pterodactylus/sone/database/memory/MemoryDatabase.java
src/main/java/net/pterodactylus/sone/database/memory/MemorySoneDatabase.java
src/test/java/net/pterodactylus/sone/core/SoneInserterTest.java
src/test/java/net/pterodactylus/sone/database/memory/MemoryDatabaseTest.java

index 291cb95..c3ac305 100644 (file)
@@ -607,7 +607,7 @@ public class Core extends AbstractService implements SoneProvider, PostProvider,
                }
                logger.info(String.format("Adding Sone from OwnIdentity: %s", ownIdentity));
                LocalSone sone = database.registerLocalSone(ownIdentity);
                }
                logger.info(String.format("Adding Sone from OwnIdentity: %s", ownIdentity));
                LocalSone sone = database.registerLocalSone(ownIdentity);
-               SoneInserter soneInserter = new SoneInserter(this, eventBus, freenetInterface, ownIdentity.getId());
+               SoneInserter soneInserter = new SoneInserter(this, eventBus, freenetInterface, database, ownIdentity.getId());
                eventBus.register(soneInserter);
                synchronized (soneInserters) {
                        soneInserters.put(sone, soneInserter);
                eventBus.register(soneInserter);
                synchronized (soneInserters) {
                        soneInserters.put(sone, soneInserter);
index 5ae2f73..8c24fc0 100644 (file)
@@ -44,6 +44,7 @@ import net.pterodactylus.sone.data.Post;
 import net.pterodactylus.sone.data.Reply;
 import net.pterodactylus.sone.data.Sone;
 import net.pterodactylus.sone.data.Sone.SoneStatus;
 import net.pterodactylus.sone.data.Reply;
 import net.pterodactylus.sone.data.Sone;
 import net.pterodactylus.sone.data.Sone.SoneStatus;
+import net.pterodactylus.sone.database.Database;
 import net.pterodactylus.sone.freenet.StringBucket;
 import net.pterodactylus.sone.main.SonePlugin;
 import net.pterodactylus.util.io.Closer;
 import net.pterodactylus.sone.freenet.StringBucket;
 import net.pterodactylus.sone.main.SonePlugin;
 import net.pterodactylus.util.io.Closer;
@@ -100,7 +101,7 @@ public class SoneInserter extends AbstractService {
 
        /** The Freenet interface. */
        private final FreenetInterface freenetInterface;
 
        /** The Freenet interface. */
        private final FreenetInterface freenetInterface;
-
+       private final Database database;
        private final SoneModificationDetector soneModificationDetector;
        private final long delay;
        private final String soneId;
        private final SoneModificationDetector soneModificationDetector;
        private final long delay;
        private final String soneId;
@@ -117,8 +118,8 @@ public class SoneInserter extends AbstractService {
         * @param soneId
         *            The ID of the Sone to insert
         */
         * @param soneId
         *            The ID of the Sone to insert
         */
-       public SoneInserter(final Core core, EventBus eventBus, FreenetInterface freenetInterface, final String soneId) {
-               this(core, eventBus, freenetInterface, soneId, new SoneModificationDetector(new LockableFingerprintProvider() {
+       public SoneInserter(final Core core, EventBus eventBus, FreenetInterface freenetInterface, Database database, final String soneId) {
+               this(core, eventBus, freenetInterface, database, soneId, new SoneModificationDetector(new LockableFingerprintProvider() {
                        @Override
                        public boolean isLocked() {
                                final Optional<LocalSone> sone = core.getLocalSone(soneId);
                        @Override
                        public boolean isLocked() {
                                final Optional<LocalSone> sone = core.getLocalSone(soneId);
@@ -140,11 +141,12 @@ public class SoneInserter extends AbstractService {
        }
 
        @VisibleForTesting
        }
 
        @VisibleForTesting
-       SoneInserter(Core core, EventBus eventBus, FreenetInterface freenetInterface, String soneId, SoneModificationDetector soneModificationDetector, long delay) {
+       SoneInserter(Core core, EventBus eventBus, FreenetInterface freenetInterface, Database database, String soneId, SoneModificationDetector soneModificationDetector, long delay) {
                super("Sone Inserter for “" + soneId + "”", false);
                this.core = core;
                this.eventBus = eventBus;
                this.freenetInterface = freenetInterface;
                super("Sone Inserter for “" + soneId + "”", false);
                this.core = core;
                this.eventBus = eventBus;
                this.freenetInterface = freenetInterface;
+               this.database = database;
                this.soneId = soneId;
                this.soneModificationDetector = soneModificationDetector;
                this.delay = delay;
                this.soneId = soneId;
                this.soneModificationDetector = soneModificationDetector;
                this.delay = delay;
@@ -236,7 +238,7 @@ public class SoneInserter extends AbstractService {
                                                        /* if so, bail out, don’t change anything. */
                                                        break;
                                                }
                                                        /* if so, bail out, don’t change anything. */
                                                        break;
                                                }
-                                               sone.setTime(insertTime);
+                                               database.updateSoneTime(sone, insertTime);
                                                sone.setLatestEdition(finalUri.getEdition());
                                                core.touchConfiguration();
                                                success = true;
                                                sone.setLatestEdition(finalUri.getEdition());
                                                core.touchConfiguration();
                                                success = true;
index 04c5f39..45909d5 100644 (file)
@@ -259,15 +259,6 @@ public interface Sone extends Identified, Fingerprintable, Comparable<Sone> {
        long getTime();
 
        /**
        long getTime();
 
        /**
-        * Sets the time of the last inserted update of this Sone.
-        *
-        * @param time
-        *              The time of the update (in milliseconds since Jan 1, 1970 UTC)
-        * @return This Sone (for method chaining)
-        */
-       Sone setTime(long time);
-
-       /**
         * Returns the status of this Sone.
         *
         * @return The status of this Sone
         * Returns the status of this Sone.
         *
         * @return The status of this Sone
index 0ef220b..8875f9a 100644 (file)
@@ -72,11 +72,6 @@ public class IdOnlySone implements Sone {
        }
 
        @Override
        }
 
        @Override
-       public Sone setTime(long time) {
-               return null;
-       }
-
-       @Override
        public SoneStatus getStatus() {
                return null;
        }
        public SoneStatus getStatus() {
                return null;
        }
index 9b46988..eccce4b 100644 (file)
@@ -240,17 +240,6 @@ public class SoneImpl implements LocalSone {
        }
 
        /**
        }
 
        /**
-        * Sets the time of the last inserted update of this Sone.
-        *
-        * @param time
-        *              The time of the update (in milliseconds since Jan 1, 1970 UTC)
-        * @return This Sone (for method chaining)
-        */
-       public Sone setTime(long time) {
-               return this;
-       }
-
-       /**
         * Returns the status of this Sone.
         *
         * @return The status of this Sone
         * Returns the status of this Sone.
         *
         * @return The status of this Sone
index b81271f..a3df63a 100644 (file)
@@ -13,4 +13,6 @@ public interface SoneDatabase extends SoneProvider, SoneBuilderFactory, SoneStor
        boolean isSoneKnown(Sone sone);
        void setSoneKnown(Sone sone);
 
        boolean isSoneKnown(Sone sone);
        void setSoneKnown(Sone sone);
 
+       void updateSoneTime(Sone sone, long soneTime);
+
 }
 }
index 2d8d1be..d5d5396 100644 (file)
@@ -275,7 +275,7 @@ public class MemoryDatabase extends AbstractService implements Database {
                /* if we’re still here, Sone was loaded successfully. */
                lock.writeLock().lock();
                try {
                /* if we’re still here, Sone was loaded successfully. */
                lock.writeLock().lock();
                try {
-                       sone.setTime(soneTime);
+                       updateSoneTime(sone, soneTime);
                        sone.setProfile(profile);
                        sone.setLikePostIds(likedPostIds);
                        sone.setLikeReplyIds(likedReplyIds);
                        sone.setProfile(profile);
                        sone.setLikePostIds(likedPostIds);
                        sone.setLikeReplyIds(likedReplyIds);
@@ -517,6 +517,11 @@ public class MemoryDatabase extends AbstractService implements Database {
                soneDatabase.setSoneKnown(sone.getId());
        }
 
                soneDatabase.setSoneKnown(sone.getId());
        }
 
+       @Override
+       public void updateSoneTime(Sone sone, long soneTime) {
+               soneDatabase.updateSoneTime(sone.getId(), soneTime);
+       }
+
        private void storePosts(String soneId, Collection<Post> posts) {
                postDatabase.storePosts(soneId, posts);
        }
        private void storePosts(String soneId, Collection<Post> posts) {
                postDatabase.storePosts(soneId, posts);
        }
index 67f3425..8435959 100644 (file)
@@ -1,6 +1,8 @@
 package net.pterodactylus.sone.database.memory;
 
 package net.pterodactylus.sone.database.memory;
 
+import java.util.HashMap;
 import java.util.HashSet;
 import java.util.HashSet;
+import java.util.Map;
 import java.util.Set;
 import java.util.concurrent.locks.ReadWriteLock;
 import java.util.concurrent.locks.ReentrantReadWriteLock;
 import java.util.Set;
 import java.util.concurrent.locks.ReadWriteLock;
 import java.util.concurrent.locks.ReentrantReadWriteLock;
@@ -17,6 +19,7 @@ public class MemorySoneDatabase {
        private final ReadWriteLock lock = new ReentrantReadWriteLock();
        private final ConfigurationLoader configurationLoader;
        private final Set<String> knownSones = new HashSet<String>();
        private final ReadWriteLock lock = new ReentrantReadWriteLock();
        private final ConfigurationLoader configurationLoader;
        private final Set<String> knownSones = new HashSet<String>();
+       private final Map<String, Long> soneUpdateTimes = new HashMap<String, Long>();
 
        public MemorySoneDatabase(ConfigurationLoader configurationLoader) {
                this.configurationLoader = configurationLoader;
 
        public MemorySoneDatabase(ConfigurationLoader configurationLoader) {
                this.configurationLoader = configurationLoader;
@@ -68,4 +71,13 @@ public class MemorySoneDatabase {
                }
        }
 
                }
        }
 
+       void updateSoneTime(String soneId, long soneTime) {
+               lock.writeLock().lock();
+               try {
+                       soneUpdateTimes.put(soneId, soneTime);
+               } finally {
+                       lock.writeLock().unlock();
+               }
+       }
+
 }
 }
index 8a4bd52..53eda56 100644 (file)
@@ -26,7 +26,6 @@ import java.io.IOException;
 import java.util.HashMap;
 import java.util.Map;
 
 import java.util.HashMap;
 import java.util.Map;
 
-import net.pterodactylus.sone.core.SoneInserter.InsertInformation;
 import net.pterodactylus.sone.core.SoneInserter.ManifestCreator;
 import net.pterodactylus.sone.core.event.InsertionDelayChangedEvent;
 import net.pterodactylus.sone.core.event.SoneEvent;
 import net.pterodactylus.sone.core.SoneInserter.ManifestCreator;
 import net.pterodactylus.sone.core.event.InsertionDelayChangedEvent;
 import net.pterodactylus.sone.core.event.SoneEvent;
@@ -36,6 +35,7 @@ import net.pterodactylus.sone.core.event.SoneInsertingEvent;
 import net.pterodactylus.sone.data.Album;
 import net.pterodactylus.sone.data.LocalSone;
 import net.pterodactylus.sone.data.Sone;
 import net.pterodactylus.sone.data.Album;
 import net.pterodactylus.sone.data.LocalSone;
 import net.pterodactylus.sone.data.Sone;
+import net.pterodactylus.sone.database.Database;
 import net.pterodactylus.sone.main.SonePlugin;
 
 import freenet.client.async.ManifestElement;
 import net.pterodactylus.sone.main.SonePlugin;
 
 import freenet.client.async.ManifestElement;
@@ -61,6 +61,7 @@ public class SoneInserterTest {
        private final Core core = mock(Core.class);
        private final EventBus eventBus = mock(EventBus.class);
        private final FreenetInterface freenetInterface = mock(FreenetInterface.class);
        private final Core core = mock(Core.class);
        private final EventBus eventBus = mock(EventBus.class);
        private final FreenetInterface freenetInterface = mock(FreenetInterface.class);
+       private final Database database = mock(Database.class);
 
        @Before
        public void setupCore() {
 
        @Before
        public void setupCore() {
@@ -73,7 +74,7 @@ public class SoneInserterTest {
        @Test
        public void insertionDelayIsForwardedToSoneInserter() {
                EventBus eventBus = new AsyncEventBus(sameThreadExecutor());
        @Test
        public void insertionDelayIsForwardedToSoneInserter() {
                EventBus eventBus = new AsyncEventBus(sameThreadExecutor());
-               eventBus.register(new SoneInserter(core, eventBus, freenetInterface, "SoneId"));
+               eventBus.register(new SoneInserter(core, eventBus, freenetInterface, database, "SoneId"));
                eventBus.post(new InsertionDelayChangedEvent(15));
                assertThat(SoneInserter.getInsertionDelay().get(), is(15));
        }
                eventBus.post(new InsertionDelayChangedEvent(15));
                assertThat(SoneInserter.getInsertionDelay().get(), is(15));
        }
@@ -92,27 +93,27 @@ public class SoneInserterTest {
        public void isModifiedIsTrueIfModificationDetectorSaysSo() {
                SoneModificationDetector soneModificationDetector = mock(SoneModificationDetector.class);
                when(soneModificationDetector.isModified()).thenReturn(true);
        public void isModifiedIsTrueIfModificationDetectorSaysSo() {
                SoneModificationDetector soneModificationDetector = mock(SoneModificationDetector.class);
                when(soneModificationDetector.isModified()).thenReturn(true);
-               SoneInserter soneInserter = new SoneInserter(core, eventBus, freenetInterface, "SoneId", soneModificationDetector, 1);
+               SoneInserter soneInserter = new SoneInserter(core, eventBus, freenetInterface, database, "SoneId", soneModificationDetector, 1);
                assertThat(soneInserter.isModified(), is(true));
        }
 
        @Test
        public void isModifiedIsFalseIfModificationDetectorSaysSo() {
                SoneModificationDetector soneModificationDetector = mock(SoneModificationDetector.class);
                assertThat(soneInserter.isModified(), is(true));
        }
 
        @Test
        public void isModifiedIsFalseIfModificationDetectorSaysSo() {
                SoneModificationDetector soneModificationDetector = mock(SoneModificationDetector.class);
-               SoneInserter soneInserter = new SoneInserter(core, eventBus, freenetInterface, "SoneId", soneModificationDetector, 1);
+               SoneInserter soneInserter = new SoneInserter(core, eventBus, freenetInterface, database, "SoneId", soneModificationDetector, 1);
                assertThat(soneInserter.isModified(), is(false));
        }
 
        @Test
        public void lastFingerprintIsStoredCorrectly() {
                assertThat(soneInserter.isModified(), is(false));
        }
 
        @Test
        public void lastFingerprintIsStoredCorrectly() {
-               SoneInserter soneInserter = new SoneInserter(core, eventBus, freenetInterface, "SoneId");
+               SoneInserter soneInserter = new SoneInserter(core, eventBus, freenetInterface, database, "SoneId");
                soneInserter.setLastInsertFingerprint("last-fingerprint");
                assertThat(soneInserter.getLastInsertFingerprint(), is("last-fingerprint"));
        }
 
        @Test
        public void soneInserterStopsWhenItShould() {
                soneInserter.setLastInsertFingerprint("last-fingerprint");
                assertThat(soneInserter.getLastInsertFingerprint(), is("last-fingerprint"));
        }
 
        @Test
        public void soneInserterStopsWhenItShould() {
-               SoneInserter soneInserter = new SoneInserter(core, eventBus, freenetInterface, "SoneId");
+               SoneInserter soneInserter = new SoneInserter(core, eventBus, freenetInterface, database, "SoneId");
                soneInserter.stop();
                soneInserter.serviceRun();
        }
                soneInserter.stop();
                soneInserter.serviceRun();
        }
@@ -126,7 +127,7 @@ public class SoneInserterTest {
                SoneModificationDetector soneModificationDetector = mock(SoneModificationDetector.class);
                when(soneModificationDetector.isEligibleForInsert()).thenReturn(true);
                when(freenetInterface.insertDirectory(eq(insertUri), any(HashMap.class), eq("index.html"))).thenReturn(finalUri);
                SoneModificationDetector soneModificationDetector = mock(SoneModificationDetector.class);
                when(soneModificationDetector.isEligibleForInsert()).thenReturn(true);
                when(freenetInterface.insertDirectory(eq(insertUri), any(HashMap.class), eq("index.html"))).thenReturn(finalUri);
-               final SoneInserter soneInserter = new SoneInserter(core, eventBus, freenetInterface, "SoneId", soneModificationDetector, 1);
+               final SoneInserter soneInserter = new SoneInserter(core, eventBus, freenetInterface, database, "SoneId", soneModificationDetector, 1);
                doAnswer(new Answer<Void>() {
                        @Override
                        public Void answer(InvocationOnMock invocation) throws Throwable {
                doAnswer(new Answer<Void>() {
                        @Override
                        public Void answer(InvocationOnMock invocation) throws Throwable {
@@ -152,7 +153,7 @@ public class SoneInserterTest {
                Sone sone = createSone(insertUri, fingerprint);
                SoneModificationDetector soneModificationDetector = mock(SoneModificationDetector.class);
                when(soneModificationDetector.isEligibleForInsert()).thenReturn(true);
                Sone sone = createSone(insertUri, fingerprint);
                SoneModificationDetector soneModificationDetector = mock(SoneModificationDetector.class);
                when(soneModificationDetector.isEligibleForInsert()).thenReturn(true);
-               final SoneInserter soneInserter = new SoneInserter(core, eventBus, freenetInterface, "SoneId", soneModificationDetector, 1);
+               final SoneInserter soneInserter = new SoneInserter(core, eventBus, freenetInterface, database, "SoneId", soneModificationDetector, 1);
                when(freenetInterface.insertDirectory(eq(insertUri), any(HashMap.class), eq("index.html"))).thenAnswer(new Answer<FreenetURI>() {
                        @Override
                        public FreenetURI answer(InvocationOnMock invocation) throws Throwable {
                when(freenetInterface.insertDirectory(eq(insertUri), any(HashMap.class), eq("index.html"))).thenAnswer(new Answer<FreenetURI>() {
                        @Override
                        public FreenetURI answer(InvocationOnMock invocation) throws Throwable {
@@ -177,7 +178,7 @@ public class SoneInserterTest {
                String fingerprint = "fingerprint";
                Sone sone = createSone(insertUri, fingerprint);
                SoneModificationDetector soneModificationDetector = mock(SoneModificationDetector.class);
                String fingerprint = "fingerprint";
                Sone sone = createSone(insertUri, fingerprint);
                SoneModificationDetector soneModificationDetector = mock(SoneModificationDetector.class);
-               final SoneInserter soneInserter = new SoneInserter(core, eventBus, freenetInterface, "SoneId", soneModificationDetector, 1);
+               final SoneInserter soneInserter = new SoneInserter(core, eventBus, freenetInterface, database, "SoneId", soneModificationDetector, 1);
                new Thread(new Runnable() {
                        @Override
                        public void run() {
                new Thread(new Runnable() {
                        @Override
                        public void run() {
@@ -201,7 +202,7 @@ public class SoneInserterTest {
                Sone sone = createSone(insertUri, fingerprint);
                SoneModificationDetector soneModificationDetector = mock(SoneModificationDetector.class);
                when(soneModificationDetector.isEligibleForInsert()).thenReturn(true);
                Sone sone = createSone(insertUri, fingerprint);
                SoneModificationDetector soneModificationDetector = mock(SoneModificationDetector.class);
                when(soneModificationDetector.isEligibleForInsert()).thenReturn(true);
-               final SoneInserter soneInserter = new SoneInserter(core, eventBus, freenetInterface, "SoneId", soneModificationDetector, 1);
+               final SoneInserter soneInserter = new SoneInserter(core, eventBus, freenetInterface, database, "SoneId", soneModificationDetector, 1);
                final SoneException soneException = new SoneException(new Exception());
                when(freenetInterface.insertDirectory(eq(insertUri), any(HashMap.class), eq("index.html"))).thenAnswer(new Answer<FreenetURI>() {
                        @Override
                final SoneException soneException = new SoneException(new Exception());
                when(freenetInterface.insertDirectory(eq(insertUri), any(HashMap.class), eq("index.html"))).thenAnswer(new Answer<FreenetURI>() {
                        @Override
@@ -226,7 +227,7 @@ public class SoneInserterTest {
                SoneModificationDetector soneModificationDetector =
                                mock(SoneModificationDetector.class);
                SoneInserter soneInserter =
                SoneModificationDetector soneModificationDetector =
                                mock(SoneModificationDetector.class);
                SoneInserter soneInserter =
-                               new SoneInserter(core, eventBus, freenetInterface, "SoneId",
+                               new SoneInserter(core, eventBus, freenetInterface, database, "SoneId",
                                                soneModificationDetector, 1);
                when(soneModificationDetector.isEligibleForInsert()).thenReturn(true);
                when(core.getSone("SoneId")).thenReturn(Optional.<Sone>absent());
                                                soneModificationDetector, 1);
                when(soneModificationDetector.isEligibleForInsert()).thenReturn(true);
                when(core.getSone("SoneId")).thenReturn(Optional.<Sone>absent());
@@ -238,7 +239,7 @@ public class SoneInserterTest {
                SoneModificationDetector soneModificationDetector =
                                mock(SoneModificationDetector.class);
                final SoneInserter soneInserter =
                SoneModificationDetector soneModificationDetector =
                                mock(SoneModificationDetector.class);
                final SoneInserter soneInserter =
-                               new SoneInserter(core, eventBus, freenetInterface, "SoneId",
+                               new SoneInserter(core, eventBus, freenetInterface, database, "SoneId",
                                                soneModificationDetector, 1);
                Answer<Optional<Sone>> stopInserterAndThrowException =
                                new Answer<Optional<Sone>>() {
                                                soneModificationDetector, 1);
                Answer<Optional<Sone>> stopInserterAndThrowException =
                                new Answer<Optional<Sone>>() {
index 8da6498..ee576b2 100644 (file)
@@ -64,6 +64,7 @@ import net.pterodactylus.util.config.Value;
 
 import com.google.common.base.Optional;
 import org.junit.Before;
 
 import com.google.common.base.Optional;
 import org.junit.Before;
+import org.junit.Ignore;
 import org.junit.Test;
 import org.mockito.Mockito;
 import org.mockito.invocation.InvocationOnMock;
 import org.junit.Test;
 import org.mockito.Mockito;
 import org.mockito.invocation.InvocationOnMock;
@@ -475,4 +476,13 @@ public class MemoryDatabaseTest {
                assertThat(stringValues.get("SoneFollowingTimes/0/Sone").getValue(), nullValue());
        }
 
                assertThat(stringValues.get("SoneFollowingTimes/0/Sone").getValue(), nullValue());
        }
 
+       @Test
+       @Ignore("enable once Sones are built by the database")
+       public void soneUpdateTimeIsRetained() {
+               memoryDatabase.storeSone(sone);
+               memoryDatabase.updateSoneTime(sone, 1000L);
+               Sone updatedSone = memoryDatabase.getSone(SONE_ID).get();
+               assertThat(updatedSone.getTime(), is(1000L));
+       }
+
 }
 }