Add method to get all images of an album to ImageProvider.
[Sone.git] / src / main / java / net / pterodactylus / sone / database / memory / MemoryDatabase.java
index babe6fe..538d97f 100644 (file)
@@ -19,6 +19,10 @@ package net.pterodactylus.sone.database.memory;
 
 import static com.google.common.base.Optional.fromNullable;
 import static com.google.common.base.Preconditions.checkNotNull;
+import static com.google.common.base.Predicates.not;
+import static com.google.common.collect.FluentIterable.from;
+import static java.util.Collections.emptyList;
+import static net.pterodactylus.sone.data.Sone.LOCAL_SONE_FILTER;
 
 import java.util.ArrayList;
 import java.util.Collection;
@@ -40,18 +44,19 @@ import net.pterodactylus.sone.data.Post;
 import net.pterodactylus.sone.data.PostReply;
 import net.pterodactylus.sone.data.Reply;
 import net.pterodactylus.sone.data.Sone;
-import net.pterodactylus.sone.data.impl.DefaultAlbumBuilder;
-import net.pterodactylus.sone.database.AlbumBuilder;
 import net.pterodactylus.sone.database.Database;
 import net.pterodactylus.sone.database.DatabaseException;
 import net.pterodactylus.sone.database.PostBuilder;
 import net.pterodactylus.sone.database.PostDatabase;
 import net.pterodactylus.sone.database.PostReplyBuilder;
-import net.pterodactylus.sone.database.SoneProvider;
+import net.pterodactylus.sone.database.SoneBuilder;
 import net.pterodactylus.util.config.Configuration;
 import net.pterodactylus.util.config.ConfigurationException;
 
+import com.google.common.base.Function;
 import com.google.common.base.Optional;
+import com.google.common.collect.ArrayListMultimap;
+import com.google.common.collect.ListMultimap;
 import com.google.common.collect.SortedSetMultimap;
 import com.google.common.collect.TreeMultimap;
 import com.google.common.util.concurrent.AbstractService;
@@ -67,12 +72,11 @@ public class MemoryDatabase extends AbstractService implements Database {
        /** The lock. */
        private final ReadWriteLock lock = new ReentrantReadWriteLock();
 
-       /** The Sone provider. */
-       private final SoneProvider soneProvider;
-
        /** The configuration. */
        private final Configuration configuration;
 
+       private final Map<String, Sone> sones = new HashMap<String, Sone>();
+
        /** All posts by their ID. */
        private final Map<String, Post> allPosts = new HashMap<String, Post>();
 
@@ -104,20 +108,19 @@ public class MemoryDatabase extends AbstractService implements Database {
        private final Set<String> knownPostReplies = new HashSet<String>();
 
        private final Map<String, Album> allAlbums = new HashMap<String, Album>();
+       private final ListMultimap<String, String> albumChildren = ArrayListMultimap.create();
+       private final ListMultimap<String, String> albumImages = ArrayListMultimap.create();
 
        private final Map<String, Image> allImages = new HashMap<String, Image>();
 
        /**
         * Creates a new memory database.
         *
-        * @param soneProvider
-        *              The Sone provider
         * @param configuration
         *              The configuration for loading and saving elements
         */
        @Inject
-       public MemoryDatabase(SoneProvider soneProvider, Configuration configuration) {
-               this.soneProvider = soneProvider;
+       public MemoryDatabase(Configuration configuration) {
                this.configuration = configuration;
        }
 
@@ -160,6 +163,51 @@ public class MemoryDatabase extends AbstractService implements Database {
                }
        }
 
+       @Override
+       public Optional<Sone> getSone(String soneId) {
+               lock.readLock().lock();
+               try {
+                       return fromNullable(sones.get(soneId));
+               } finally {
+                       lock.readLock().unlock();
+               }
+       }
+
+       @Override
+       public Collection<Sone> getSones() {
+               lock.readLock().lock();
+               try {
+                       return Collections.unmodifiableCollection(sones.values());
+               } finally {
+                       lock.readLock().unlock();
+               }
+       }
+
+       @Override
+       public Collection<Sone> getLocalSones() {
+               lock.readLock().lock();
+               try {
+                       return from(getSones()).filter(LOCAL_SONE_FILTER).toSet();
+               } finally {
+                       lock.readLock().unlock();
+               }
+       }
+
+       @Override
+       public Collection<Sone> getRemoteSones() {
+               lock.readLock().lock();
+               try {
+                       return from(getSones()).filter(not(LOCAL_SONE_FILTER)).toSet();
+               } finally {
+                       lock.readLock().unlock();
+               }
+       }
+
+       @Override
+       public SoneBuilder newSoneBuilder() {
+               return null;
+       }
+
        //
        // POSTPROVIDER METHODS
        //
@@ -200,7 +248,7 @@ public class MemoryDatabase extends AbstractService implements Database {
        /** {@inheritDocs} */
        @Override
        public PostBuilder newPostBuilder() {
-               return new MemoryPostBuilder(this, soneProvider);
+               return new MemoryPostBuilder(this);
        }
 
        //
@@ -315,7 +363,7 @@ public class MemoryDatabase extends AbstractService implements Database {
                lock.readLock().lock();
                try {
                        if (!postReplies.containsKey(postId)) {
-                               return Collections.emptyList();
+                               return emptyList();
                        }
                        return new ArrayList<PostReply>(postReplies.get(postId));
                } finally {
@@ -330,7 +378,7 @@ public class MemoryDatabase extends AbstractService implements Database {
        /** {@inheritDocs} */
        @Override
        public PostReplyBuilder newPostReplyBuilder() {
-               return new MemoryPostReplyBuilder(this, soneProvider);
+               return new MemoryPostReplyBuilder(this, this);
        }
 
        //
@@ -434,13 +482,14 @@ public class MemoryDatabase extends AbstractService implements Database {
                }
        }
 
-       //
-       // ALBUMBUILDERFACTORY METHODS
-       //
-
        @Override
-       public AlbumBuilder newAlbumBuilder() {
-               return new DefaultAlbumBuilder();
+       public List<Album> getAlbums(Album parent) {
+               lock.readLock().lock();
+               try {
+                       return from(albumChildren.get(parent.getId())).transformAndConcat(getAlbum()).toList();
+               } finally {
+                       lock.readLock().unlock();
+               }
        }
 
        //
@@ -452,6 +501,7 @@ public class MemoryDatabase extends AbstractService implements Database {
                lock.writeLock().lock();
                try {
                        allAlbums.put(album.getId(), album);
+                       albumChildren.put(album.getParent().getId(), album.getId());
                } finally {
                        lock.writeLock().unlock();
                }
@@ -462,6 +512,7 @@ public class MemoryDatabase extends AbstractService implements Database {
                lock.writeLock().lock();
                try {
                        allAlbums.remove(album.getId());
+                       albumChildren.remove(album.getParent().getId(), album.getId());
                } finally {
                        lock.writeLock().unlock();
                }
@@ -481,6 +532,16 @@ public class MemoryDatabase extends AbstractService implements Database {
                }
        }
 
+       @Override
+       public List<Image> getImages(Album parent) {
+               lock.readLock().lock();
+               try {
+                       return from(albumImages.get(parent.getId())).transformAndConcat(getImage()).toList();
+               } finally {
+                       lock.readLock().unlock();
+               }
+       }
+
        //
        // IMAGESTORE METHODS
        //
@@ -490,6 +551,7 @@ public class MemoryDatabase extends AbstractService implements Database {
                lock.writeLock().lock();
                try {
                        allImages.put(image.getId(), image);
+                       albumImages.put(image.getAlbum().getId(), image.getId());
                } finally {
                        lock.writeLock().unlock();
                }
@@ -500,6 +562,7 @@ public class MemoryDatabase extends AbstractService implements Database {
                lock.writeLock().lock();
                try {
                        allImages.remove(image.getId());
+                       albumImages.remove(image.getAlbum().getId(), image.getId());
                } finally {
                        lock.writeLock().unlock();
                }
@@ -584,6 +647,66 @@ public class MemoryDatabase extends AbstractService implements Database {
                }
        }
 
+       void moveUp(Album album) {
+               lock.writeLock().lock();
+               try {
+                       List<String> albums = albumChildren.get(album.getParent().getId());
+                       int currentIndex = albums.indexOf(album.getId());
+                       if (currentIndex == 0) {
+                               return;
+                       }
+                       albums.remove(album.getId());
+                       albums.add(currentIndex - 1, album.getId());
+               } finally {
+                       lock.writeLock().unlock();
+               }
+       }
+
+       void moveDown(Album album) {
+               lock.writeLock().lock();
+               try {
+                       List<String> albums = albumChildren.get(album.getParent().getId());
+                       int currentIndex = albums.indexOf(album.getId());
+                       if (currentIndex == (albums.size() - 1)) {
+                               return;
+                       }
+                       albums.remove(album.getId());
+                       albums.add(currentIndex + 1, album.getId());
+               } finally {
+                       lock.writeLock().unlock();
+               }
+       }
+
+       void moveUp(Image image) {
+               lock.writeLock().lock();
+               try {
+                       List<String> images = albumImages.get(image.getAlbum().getId());
+                       int currentIndex = images.indexOf(image.getId());
+                       if (currentIndex == 0) {
+                               return;
+                       }
+                       images.remove(image.getId());
+                       images.add(currentIndex - 1, image.getId());
+               } finally {
+                       lock.writeLock().unlock();
+               }
+       }
+
+       void moveDown(Image image) {
+               lock.writeLock().lock();
+               try {
+                       List<String> images = albumChildren.get(image.getAlbum().getId());
+                       int currentIndex = images.indexOf(image.getId());
+                       if (currentIndex == (images.size() - 1)) {
+                               return;
+                       }
+                       images.remove(image.getId());
+                       images.add(currentIndex + 1, image.getId());
+               } finally {
+                       lock.writeLock().unlock();
+               }
+       }
+
        //
        // PRIVATE METHODS
        //
@@ -745,4 +868,22 @@ public class MemoryDatabase extends AbstractService implements Database {
                }
        }
 
+       private Function<String, Iterable<Album>> getAlbum() {
+               return new Function<String, Iterable<Album>>() {
+                       @Override
+                       public Iterable<Album> apply(String input) {
+                               return (input == null) ? Collections.<Album>emptyList() : getAlbum(input).asSet();
+                       }
+               };
+       }
+
+       private Function<String, Iterable<Image>> getImage() {
+               return new Function<String, Iterable<Image>>() {
+                       @Override
+                       public Iterable<Image> apply(String input) {
+                               return (input == null) ? Collections.<Image>emptyList() : getImage(input).asSet();
+                       }
+               };
+       }
+
 }