Return replies to old post ID in compatibility mode
[Sone.git] / src / main / java / net / pterodactylus / sone / core / Core.java
index fe0907f..e56eede 100644 (file)
@@ -27,6 +27,7 @@ import static java.util.logging.Logger.getLogger;
 
 import java.util.ArrayList;
 import java.util.Collection;
+import java.util.EnumSet;
 import java.util.HashMap;
 import java.util.HashSet;
 import java.util.List;
@@ -72,6 +73,7 @@ import net.pterodactylus.sone.data.Sone.ShowCustomAvatars;
 import net.pterodactylus.sone.data.Sone.SoneStatus;
 import net.pterodactylus.sone.data.TemporaryImage;
 import net.pterodactylus.sone.database.AlbumBuilder;
+import net.pterodactylus.sone.database.AlbumProvider;
 import net.pterodactylus.sone.database.Database;
 import net.pterodactylus.sone.database.DatabaseException;
 import net.pterodactylus.sone.database.ImageBuilder;
@@ -98,10 +100,14 @@ import net.pterodactylus.util.thread.NamedThreadFactory;
 import com.google.common.annotations.VisibleForTesting;
 import com.google.common.base.Function;
 import com.google.common.base.Optional;
+import com.google.common.base.Predicate;
 import com.google.common.collect.FluentIterable;
 import com.google.common.collect.HashMultimap;
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.ImmutableList.Builder;
 import com.google.common.collect.Multimap;
 import com.google.common.collect.Multimaps;
+import com.google.common.collect.Ordering;
 import com.google.common.eventbus.EventBus;
 import com.google.common.eventbus.Subscribe;
 import com.google.inject.Inject;
@@ -113,7 +119,7 @@ import com.google.inject.Singleton;
  * @author <a href="mailto:bombe@pterodactylus.net">David ‘Bombe’ Roden</a>
  */
 @Singleton
-public class Core extends AbstractService implements SoneProvider, PostProvider, PostReplyProvider {
+public class Core extends AbstractService implements SoneProvider, PostProvider, PostReplyProvider, AlbumProvider {
 
        /** The logger. */
        private static final Logger logger = getLogger(Core.class.getName());
@@ -154,6 +160,8 @@ public class Core extends AbstractService implements SoneProvider, PostProvider,
        /** The trust updater. */
        private final WebOfTrustUpdater webOfTrustUpdater;
 
+       private final Set<CompatibilityMode> compatibilityModes = EnumSet.noneOf(CompatibilityMode.class);
+
        /** The times Sones were followed. */
        private final Map<String, Long> soneFollowingTimes = new HashMap<String, Long>();
 
@@ -273,6 +281,18 @@ public class Core extends AbstractService implements SoneProvider, PostProvider,
                return updateChecker;
        }
 
+       public boolean isCompatibilityMode(CompatibilityMode compatibilityMode) {
+               return compatibilityModes.contains(compatibilityMode);
+       }
+
+       public void setCompatibilityMode(CompatibilityMode compatibilityMode) {
+               compatibilityModes.add(compatibilityMode);
+       }
+
+       public void clearCompatibilityMod(CompatibilityMode compatibilityMode) {
+               compatibilityModes.remove(compatibilityMode);
+       }
+
        /**
         * Returns the Sone rescuer for the given local Sone.
         *
@@ -420,8 +440,17 @@ public class Core extends AbstractService implements SoneProvider, PostProvider,
         * {@inheritDoc}
         */
        @Override
-       public Optional<Post> getPost(String postId) {
-               return database.getPost(postId);
+       public Optional<Post> getPost(final String postId) {
+               Optional<Post> post = database.getPost(postId);
+               if (post.isPresent() || !isCompatibilityMode(CompatibilityMode.oldElementIds)) {
+                       return post;
+               }
+               return FluentIterable.from(getSones()).transformAndConcat(Sone.toAllPosts).filter(new Predicate<Post>() {
+                       @Override
+                       public boolean apply(Post input) {
+                               return (input != null) && input.getInternalId().equals(postId);
+                       }
+               }).first();
        }
 
        /**
@@ -463,7 +492,14 @@ public class Core extends AbstractService implements SoneProvider, PostProvider,
         */
        @Override
        public List<PostReply> getReplies(final String postId) {
-               return database.getReplies(postId);
+               Builder<PostReply> postReplies = ImmutableList.<PostReply>builder().addAll(database.getReplies(postId));
+               if (isCompatibilityMode(CompatibilityMode.oldElementIds)) {
+                       Optional<Post> post = getPost(postId);
+                       if (post.isPresent()) {
+                               postReplies.addAll(database.getReplies(post.get().getInternalId()));
+                       }
+               }
+               return Ordering.from(Reply.TIME_COMPARATOR).sortedCopy(postReplies.build());
        }
 
        /**
@@ -534,8 +570,8 @@ public class Core extends AbstractService implements SoneProvider, PostProvider,
         * @return The album with the given ID, or {@code null} if no album with the
         *         given ID exists
         */
-       public Album getAlbum(String albumId) {
-               return database.getAlbum(albumId).orNull();
+       public Optional<Album> getAlbum(String albumId) {
+               return database.getAlbum(albumId);
        }
 
        public ImageBuilder imageBuilder() {
@@ -651,6 +687,7 @@ public class Core extends AbstractService implements SoneProvider, PostProvider,
                        soneInserters.put(sone, soneInserter);
                }
                loadSone(sone);
+               database.storeSone(sone);
                sone.setStatus(SoneStatus.idle);
                soneInserter.start();
                return sone;
@@ -1085,7 +1122,6 @@ public class Core extends AbstractService implements SoneProvider, PostProvider,
                        for (Album album : topLevelAlbums) {
                                sone.getRootAlbum().addAlbum(album);
                        }
-                       database.storeSone(sone);
                        synchronized (soneInserters) {
                                soneInserters.get(sone).setLastInsertFingerprint(lastInsertFingerprint);
                        }
@@ -1476,7 +1512,7 @@ public class Core extends AbstractService implements SoneProvider, PostProvider,
                        int postCounter = 0;
                        for (Post post : sone.getPosts()) {
                                String postPrefix = sonePrefix + "/Posts/" + postCounter++;
-                               configuration.getStringValue(postPrefix + "/ID").setValue(post.getId());
+                               configuration.getStringValue(postPrefix + "/ID").setValue(post.getInternalId());
                                configuration.getStringValue(postPrefix + "/Recipient").setValue(post.getRecipientId().orNull());
                                configuration.getLongValue(postPrefix + "/Time").setValue(post.getTime());
                                configuration.getStringValue(postPrefix + "/Text").setValue(post.getText());
@@ -1487,7 +1523,7 @@ public class Core extends AbstractService implements SoneProvider, PostProvider,
                        int replyCounter = 0;
                        for (PostReply reply : sone.getReplies()) {
                                String replyPrefix = sonePrefix + "/Replies/" + replyCounter++;
-                               configuration.getStringValue(replyPrefix + "/ID").setValue(reply.getId());
+                               configuration.getStringValue(replyPrefix + "/ID").setValue(reply.getInternalId());
                                configuration.getStringValue(replyPrefix + "/Post/ID").setValue(reply.getPostId());
                                configuration.getLongValue(replyPrefix + "/Time").setValue(reply.getTime());
                                configuration.getStringValue(replyPrefix + "/Text").setValue(reply.getText());
@@ -1514,7 +1550,7 @@ public class Core extends AbstractService implements SoneProvider, PostProvider,
                        int albumCounter = 0;
                        for (Album album : albums) {
                                String albumPrefix = sonePrefix + "/Albums/" + albumCounter++;
-                               configuration.getStringValue(albumPrefix + "/ID").setValue(album.getId());
+                               configuration.getStringValue(albumPrefix + "/ID").setValue(album.getInternalId());
                                configuration.getStringValue(albumPrefix + "/Title").setValue(album.getTitle());
                                configuration.getStringValue(albumPrefix + "/Description").setValue(album.getDescription());
                                configuration.getStringValue(albumPrefix + "/Parent").setValue(album.getParent().equals(sone.getRootAlbum()) ? null : album.getParent().getId());
@@ -1530,8 +1566,8 @@ public class Core extends AbstractService implements SoneProvider, PostProvider,
                                                continue;
                                        }
                                        String imagePrefix = sonePrefix + "/Images/" + imageCounter++;
-                                       configuration.getStringValue(imagePrefix + "/ID").setValue(image.getId());
-                                       configuration.getStringValue(imagePrefix + "/Album").setValue(album.getId());
+                                       configuration.getStringValue(imagePrefix + "/ID").setValue(image.getInternalId());
+                                       configuration.getStringValue(imagePrefix + "/Album").setValue(album.getInternalId());
                                        configuration.getStringValue(imagePrefix + "/Key").setValue(image.getKey());
                                        configuration.getStringValue(imagePrefix + "/Title").setValue(image.getTitle());
                                        configuration.getStringValue(imagePrefix + "/Description").setValue(image.getDescription());
@@ -1596,6 +1632,9 @@ public class Core extends AbstractService implements SoneProvider, PostProvider,
                                configuration.getStringValue("SoneFollowingTimes/" + soneCounter + "/Sone").setValue(null);
                        }
 
+                       /* save compatibility modes. */
+                       configuration.getBooleanValue("CompatibilityModes/OldElementIds").setValue(compatibilityModes.contains(CompatibilityMode.oldElementIds));
+
                        /* save known posts. */
                        database.save();
 
@@ -1644,6 +1683,11 @@ public class Core extends AbstractService implements SoneProvider, PostProvider,
                        }
                        ++soneCounter;
                }
+
+               /* load compatibility modes. */
+               if (configuration.getBooleanValue("CompatibilityModes/OldElementIds").getValue(false)) {
+                       setCompatibilityMode(CompatibilityMode.oldElementIds);
+               }
        }
 
        /**