🔥 Remove FLATTENER from Album interface
authorDavid ‘Bombe’ Roden <bombe@pterodactylus.net>
Tue, 18 Feb 2020 15:31:45 +0000 (16:31 +0100)
committerDavid ‘Bombe’ Roden <bombe@pterodactylus.net>
Tue, 18 Feb 2020 15:43:45 +0000 (16:43 +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/Album.java
src/main/java/net/pterodactylus/sone/template/SoneAccessor.java
src/main/kotlin/net/pterodactylus/sone/data/Sone.kt
src/main/kotlin/net/pterodactylus/sone/database/memory/MemoryDatabase.kt
src/main/kotlin/net/pterodactylus/sone/web/pages/ImageBrowserPage.kt
src/test/kotlin/net/pterodactylus/sone/data/SoneTest.kt
src/test/kotlin/net/pterodactylus/sone/web/pages/ImageBrowserPageTest.kt

index 7a8f5df..e186e6f 100644 (file)
@@ -53,7 +53,6 @@ import net.pterodactylus.sone.core.ConfigurationSoneParser.InvalidPostFound;
 import net.pterodactylus.sone.core.ConfigurationSoneParser.InvalidPostReplyFound;
 import net.pterodactylus.sone.core.event.*;
 import net.pterodactylus.sone.data.Album;
-import net.pterodactylus.sone.data.AlbumsKt;
 import net.pterodactylus.sone.data.Client;
 import net.pterodactylus.sone.data.Image;
 import net.pterodactylus.sone.data.Post;
@@ -63,6 +62,7 @@ import net.pterodactylus.sone.data.Profile.Field;
 import net.pterodactylus.sone.data.Reply;
 import net.pterodactylus.sone.data.Sone;
 import net.pterodactylus.sone.data.Sone.SoneStatus;
+import net.pterodactylus.sone.data.SoneKt;
 import net.pterodactylus.sone.data.SoneOptions.LoadExternalContent;
 import net.pterodactylus.sone.data.TemporaryImage;
 import net.pterodactylus.sone.database.AlbumBuilder;
@@ -1392,7 +1392,7 @@ public class Core extends AbstractService implements SoneProvider, PostProvider,
                        configuration.getStringValue(sonePrefix + "/Likes/Reply/" + replyLikeCounter + "/ID").setValue(null);
 
                        /* save albums. first, collect in a flat structure, top-level first. */
-                       List<Album> albums = AlbumsKt.getAllAlbums(sone.getRootAlbum());
+                       List<Album> albums = SoneKt.getAllAlbums(sone);
 
                        int albumCounter = 0;
                        for (Album album : albums) {
index a67c15d..e74c98d 100644 (file)
@@ -21,6 +21,7 @@ import static java.lang.String.format;
 import static java.lang.System.currentTimeMillis;
 import static java.util.concurrent.TimeUnit.*;
 import static java.util.logging.Logger.getLogger;
+import static java.util.stream.Collectors.toList;
 
 import java.io.*;
 import java.nio.charset.Charset;
@@ -39,12 +40,12 @@ import net.pterodactylus.sone.core.event.InsertionDelayChangedEvent;
 import net.pterodactylus.sone.core.event.SoneInsertAbortedEvent;
 import net.pterodactylus.sone.core.event.SoneInsertedEvent;
 import net.pterodactylus.sone.core.event.SoneInsertingEvent;
-import net.pterodactylus.sone.data.Album;
 import net.pterodactylus.sone.data.AlbumsKt;
 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.SoneKt;
 import net.pterodactylus.sone.main.SonePlugin;
 import net.pterodactylus.util.service.AbstractService;
 import net.pterodactylus.util.template.HtmlFilter;
@@ -57,7 +58,6 @@ import net.pterodactylus.util.template.TemplateParser;
 import net.pterodactylus.util.template.XmlFilter;
 
 import com.google.common.annotations.VisibleForTesting;
-import com.google.common.collect.FluentIterable;
 import com.google.common.collect.Ordering;
 import com.google.common.eventbus.EventBus;
 import com.google.common.eventbus.Subscribe;
@@ -312,7 +312,7 @@ public class SoneInserter extends AbstractService {
                        soneProperties.put("replies", Ordering.from(Reply.TIME_COMPARATOR).reverse().sortedCopy(sone.getReplies()));
                        soneProperties.put("likedPostIds", new HashSet<>(sone.getLikedPostIds()));
                        soneProperties.put("likedReplyIds", new HashSet<>(sone.getLikedReplyIds()));
-                       soneProperties.put("albums", FluentIterable.from(sone.getRootAlbum().getAlbums()).transformAndConcat(Album.FLATTENER).filter(AlbumsKt.notEmpty()::invoke).toList());
+                       soneProperties.put("albums", SoneKt.getAllAlbums(sone).stream().filter(AlbumsKt.notEmpty()::invoke).collect(toList()));
                        manifestCreator = new ManifestCreator(core, soneProperties);
                }
 
index efaa470..3eefc3e 100644 (file)
 
 package net.pterodactylus.sone.data;
 
-import static java.util.Arrays.asList;
-import static java.util.Collections.emptyList;
-
-import java.util.ArrayList;
 import java.util.Collections;
 import java.util.List;
 import javax.annotation.Nonnull;
 
 import com.google.common.base.Function;
-import com.google.common.base.Predicate;
-import com.google.common.collect.FluentIterable;
-import com.google.common.collect.ImmutableList;
 
 /**
  * Container for images that can also contain nested {@link Album}s.
  */
 public interface Album extends Identified, Fingerprintable {
 
-       /** Function that flattens the given album and all albums beneath it. */
-       Function<Album, List<Album>> FLATTENER = new Function<Album, List<Album>>() {
-
-               @Override
-               @Nonnull
-               public List<Album> apply(Album album) {
-                       if (album == null) {
-                               return emptyList();
-                       }
-                       List<Album> albums = new ArrayList<>();
-                       albums.add(album);
-                       for (Album subAlbum : album.getAlbums()) {
-                               albums.addAll(FluentIterable.from(ImmutableList.of(subAlbum)).transformAndConcat(FLATTENER).toList());
-                       }
-                       return albums;
-               }
-       };
-
        /** Function that transforms an album into the images it contains. */
        Function<Album, List<Image>> IMAGES = new Function<Album, List<Image>>() {
 
index 4bc6a5f..06922fc 100644 (file)
 
 package net.pterodactylus.sone.template;
 
-import static com.google.common.collect.FluentIterable.from;
-import static java.util.Arrays.asList;
 import static java.util.logging.Logger.getLogger;
-import static net.pterodactylus.sone.data.Album.FLATTENER;
+import static java.util.stream.Collectors.toList;
 import static net.pterodactylus.sone.data.Album.IMAGES;
 
 import java.util.logging.Level;
@@ -30,6 +28,7 @@ import net.pterodactylus.sone.core.Core;
 import net.pterodactylus.sone.data.Profile;
 import net.pterodactylus.sone.data.Sone;
 import net.pterodactylus.sone.data.Sone.SoneStatus;
+import net.pterodactylus.sone.data.SoneKt;
 import net.pterodactylus.sone.freenet.wot.OwnIdentity;
 import net.pterodactylus.sone.freenet.wot.Trust;
 import net.pterodactylus.sone.text.TimeTextConverter;
@@ -116,7 +115,7 @@ public class SoneAccessor extends ReflectionAccessor {
                        }
                        return trust;
                } else if (member.equals("allImages")) {
-                       return from(asList(sone.getRootAlbum())).transformAndConcat(FLATTENER).transformAndConcat(IMAGES);
+                       return SoneKt.getAllAlbums(sone).stream().flatMap(a -> IMAGES.apply(a).stream()).collect(toList());
                } else if (member.equals("albums")) {
                        return sone.getRootAlbum().getAlbums();
                }
index 3f70ad7..46ff336 100644 (file)
@@ -51,3 +51,7 @@ val postCountComparator: Comparator<Sone> =
 
 val imageCountComparator: Comparator<Sone> =
                comparing<Sone, Int> { it.rootAlbum.allImages.size }.reversed()
+
+val Sone.allAlbums: List<Album>
+       get() =
+               rootAlbum.albums.flatMap(Album::allAlbums)
index df65a5a..5c32486 100644 (file)
@@ -123,7 +123,7 @@ class MemoryDatabase @Inject constructor(private val configuration: Configuratio
                        for (postReply in sone.replies) {
                                allPostReplies[postReply.id] = postReply
                        }
-                       sone.rootAlbum.allAlbums.let { albums ->
+                       sone.allAlbums.let { albums ->
                                soneAlbums.putAll(sone.id, albums)
                                albums.forEach { album -> allAlbums[album.id] = album }
                        }
index 20219d7..a0ca0d7 100644 (file)
@@ -29,9 +29,7 @@ class ImageBrowserPage @Inject constructor(webInterface: WebInterface, loaders:
                } else if (soneRequest.parameters["mode"] == "gallery") {
                        templateContext["galleryRequested"] = true
                        soneRequest.core.sones
-                                       .map(Sone::getRootAlbum)
-                                       .flatMap(Album::getAlbums)
-                                       .flatMap { Album.FLATTENER.apply(it)!! }
+                                       .flatMap(Sone::allAlbums)
                                        .filterNot(Album::isEmpty)
                                        .sortedBy(Album::getTitle)
                                        .also { albums ->
index 1429e54..42980ee 100644 (file)
@@ -142,4 +142,16 @@ class SoneTest {
                assertThat(imageCountComparator.compare(sone1, sone2), equalTo(0))
        }
 
+       @Test
+       fun `allAlbums returns all albums of a Sone but the root album`() {
+               val sone = object : IdOnlySone("1") {
+                       private val rootAlbum = AlbumImpl(this)
+                       override fun getRootAlbum() = rootAlbum
+               }
+               val album1 = AlbumImpl(sone).also(sone.rootAlbum::addAlbum)
+               val album11 = AlbumImpl(sone).also(album1::addAlbum)
+               val album2 = AlbumImpl(sone).also(sone.rootAlbum::addAlbum)
+               assertThat(sone.allAlbums, contains<Album>(album1, album11, album2))
+       }
+
 }
index 1533f4b..38ecce4 100644 (file)
@@ -1,6 +1,8 @@
 package net.pterodactylus.sone.web.pages
 
 import net.pterodactylus.sone.data.*
+import net.pterodactylus.sone.data.impl.AlbumImpl
+import net.pterodactylus.sone.data.impl.ImageImpl
 import net.pterodactylus.sone.test.*
 import net.pterodactylus.sone.web.*
 import net.pterodactylus.sone.web.page.*
@@ -105,16 +107,13 @@ class ImageBrowserPageTest : WebPageTest(::ImageBrowserPage) {
 
        private fun createSone(firstAlbumTitle: String, secondAlbumTitle: String): Sone {
                return mock<Sone>().apply {
-                       val rootAlbum = mock<Album>()
-                       val firstAlbum = mock<Album>()
-                       val firstImage = mock<Image>().run { whenever(isInserted).thenReturn(true); this }
-                       whenever(firstAlbum.images).thenReturn(listOf(firstImage))
-                       val secondAlbum = mock<Album>()
-                       val secondImage = mock<Image>().run { whenever(isInserted).thenReturn(true); this }
-                       whenever(secondAlbum.images).thenReturn(listOf(secondImage))
-                       whenever(firstAlbum.title).thenReturn(firstAlbumTitle)
-                       whenever(secondAlbum.title).thenReturn(secondAlbumTitle)
-                       whenever(rootAlbum.albums).thenReturn(listOf(firstAlbum, secondAlbum))
+                       val rootAlbum = AlbumImpl(this)
+                       val firstAlbum = AlbumImpl(this).modify().setTitle(firstAlbumTitle).update()
+                       firstAlbum.addImage(ImageImpl("1").modify().setSone(this).setKey("key").update())
+                       val secondAlbum = AlbumImpl(this).modify().setTitle(secondAlbumTitle).update()
+                       secondAlbum.addImage(ImageImpl("2").modify().setSone(this).setKey("key").update())
+                       rootAlbum.addAlbum(firstAlbum)
+                       rootAlbum.addAlbum(secondAlbum)
                        whenever(this.rootAlbum).thenReturn(rootAlbum)
                }
        }