Move album parsing to new configuration parser.
[Sone.git] / src / main / java / net / pterodactylus / sone / core / Core.java
index 1229448..e08acd1 100644 (file)
@@ -20,6 +20,7 @@ package net.pterodactylus.sone.core;
 import static com.google.common.base.Preconditions.checkArgument;
 import static com.google.common.base.Preconditions.checkNotNull;
 import static com.google.common.base.Predicates.not;
+import static java.lang.String.format;
 import static net.pterodactylus.sone.data.Sone.LOCAL_SONE_FILTER;
 
 import java.net.MalformedURLException;
@@ -38,6 +39,10 @@ import java.util.concurrent.TimeUnit;
 import java.util.logging.Level;
 import java.util.logging.Logger;
 
+import net.pterodactylus.sone.core.ConfigurationSoneParser.InvalidAlbumFound;
+import net.pterodactylus.sone.core.ConfigurationSoneParser.InvalidParentAlbumFound;
+import net.pterodactylus.sone.core.ConfigurationSoneParser.InvalidPostFound;
+import net.pterodactylus.sone.core.ConfigurationSoneParser.InvalidPostReplyFound;
 import net.pterodactylus.sone.core.Options.DefaultOption;
 import net.pterodactylus.sone.core.SoneInserter.SetInsertionDelay;
 import net.pterodactylus.sone.core.event.ImageInsertFinishedEvent;
@@ -65,6 +70,7 @@ import net.pterodactylus.sone.data.Sone.ShowCustomAvatars;
 import net.pterodactylus.sone.data.Sone.SoneStatus;
 import net.pterodactylus.sone.data.SoneImpl;
 import net.pterodactylus.sone.data.TemporaryImage;
+import net.pterodactylus.sone.database.AlbumBuilder;
 import net.pterodactylus.sone.database.Database;
 import net.pterodactylus.sone.database.DatabaseException;
 import net.pterodactylus.sone.database.PostBuilder;
@@ -229,6 +235,20 @@ public class Core extends AbstractService implements SoneProvider, PostProvider,
                this.database = database;
        }
 
+       @VisibleForTesting
+       protected Core(Configuration configuration, FreenetInterface freenetInterface, IdentityManager identityManager, SoneDownloader soneDownloader, ImageInserter imageInserter, UpdateChecker updateChecker, WebOfTrustUpdater webOfTrustUpdater, EventBus eventBus, Database database) {
+               super("Sone Core");
+               this.configuration = configuration;
+               this.freenetInterface = freenetInterface;
+               this.identityManager = identityManager;
+               this.soneDownloader = soneDownloader;
+               this.imageInserter = imageInserter;
+               this.updateChecker = updateChecker;
+               this.webOfTrustUpdater = webOfTrustUpdater;
+               this.eventBus = eventBus;
+               this.database = database;
+       }
+
        //
        // ACCESSORS
        //
@@ -432,22 +452,6 @@ public class Core extends AbstractService implements SoneProvider, PostProvider,
        }
 
        /**
-        * Returns whether the target Sone is trusted by the origin Sone.
-        *
-        * @param origin
-        *            The origin Sone
-        * @param target
-        *            The target Sone
-        * @return {@code true} if the target Sone is trusted by the origin Sone
-        */
-       public boolean isSoneTrusted(Sone origin, Sone target) {
-               checkNotNull(origin, "origin must not be null");
-               checkNotNull(target, "target must not be null");
-               checkArgument(origin.getIdentity() instanceof OwnIdentity, "origin’s identity must be an OwnIdentity");
-               return trustedIdentities.containsEntry(origin.getIdentity(), target.getIdentity());
-       }
-
-       /**
         * Returns a post builder.
         *
         * @return A new post builder
@@ -584,16 +588,8 @@ public class Core extends AbstractService implements SoneProvider, PostProvider,
                return posts;
        }
 
-       /**
-        * Returns the album with the given ID, creating a new album if no album
-        * with the given ID can be found.
-        *
-        * @param albumId
-        *            The ID of the album
-        * @return The album with the given ID
-        */
-       public Album getAlbum(String albumId) {
-               return getAlbum(albumId, true);
+       public AlbumBuilder albumBuilder() {
+               return database.newAlbumBuilder();
        }
 
        /**
@@ -602,23 +598,11 @@ public class Core extends AbstractService implements SoneProvider, PostProvider,
         *
         * @param albumId
         *            The ID of the album
-        * @param create
-        *            {@code true} to create a new album if none exists for the
-        *            given ID
         * @return The album with the given ID, or {@code null} if no album with the
-        *         given ID exists and {@code create} is {@code false}
+        *         given ID exists
         */
-       public Album getAlbum(String albumId, boolean create) {
-               Optional<Album> album = database.getAlbum(albumId);
-               if (album.isPresent()) {
-                       return album.get();
-               }
-               if (!create) {
-                       return null;
-               }
-               Album newAlbum = database.newAlbumBuilder().withId(albumId).build();
-               database.storeAlbum(newAlbum);
-               return newAlbum;
+       public Album getAlbum(String albumId) {
+               return database.getAlbum(albumId).orNull();
        }
 
        /**
@@ -1110,126 +1094,50 @@ public class Core extends AbstractService implements SoneProvider, PostProvider,
                String lastInsertFingerprint = configuration.getStringValue(sonePrefix + "/LastInsertFingerprint").getValue("");
 
                /* load profile. */
-               Profile profile = new Profile(sone);
-               profile.setFirstName(configuration.getStringValue(sonePrefix + "/Profile/FirstName").getValue(null));
-               profile.setMiddleName(configuration.getStringValue(sonePrefix + "/Profile/MiddleName").getValue(null));
-               profile.setLastName(configuration.getStringValue(sonePrefix + "/Profile/LastName").getValue(null));
-               profile.setBirthDay(configuration.getIntValue(sonePrefix + "/Profile/BirthDay").getValue(null));
-               profile.setBirthMonth(configuration.getIntValue(sonePrefix + "/Profile/BirthMonth").getValue(null));
-               profile.setBirthYear(configuration.getIntValue(sonePrefix + "/Profile/BirthYear").getValue(null));
-
-               /* load profile fields. */
-               while (true) {
-                       String fieldPrefix = sonePrefix + "/Profile/Fields/" + profile.getFields().size();
-                       String fieldName = configuration.getStringValue(fieldPrefix + "/Name").getValue(null);
-                       if (fieldName == null) {
-                               break;
-                       }
-                       String fieldValue = configuration.getStringValue(fieldPrefix + "/Value").getValue("");
-                       profile.addField(fieldName).setValue(fieldValue);
-               }
+               ConfigurationSoneParser configurationSoneParser = new ConfigurationSoneParser(configuration, sone);
+               Profile profile = configurationSoneParser.parseProfile();
 
                /* load posts. */
-               Set<Post> posts = new HashSet<Post>();
-               while (true) {
-                       String postPrefix = sonePrefix + "/Posts/" + posts.size();
-                       String postId = configuration.getStringValue(postPrefix + "/ID").getValue(null);
-                       if (postId == null) {
-                               break;
-                       }
-                       String postRecipientId = configuration.getStringValue(postPrefix + "/Recipient").getValue(null);
-                       long postTime = configuration.getLongValue(postPrefix + "/Time").getValue((long) 0);
-                       String postText = configuration.getStringValue(postPrefix + "/Text").getValue(null);
-                       if ((postTime == 0) || (postText == null)) {
-                               logger.log(Level.WARNING, "Invalid post found, aborting load!");
-                               return;
-                       }
-                       PostBuilder postBuilder = postBuilder().withId(postId).from(sone.getId()).withTime(postTime).withText(postText);
-                       if ((postRecipientId != null) && (postRecipientId.length() == 43)) {
-                               postBuilder.to(postRecipientId);
-                       }
-                       posts.add(postBuilder.build());
+               Collection<Post> posts;
+               try {
+                       posts = configurationSoneParser.parsePosts(database);
+               } catch (InvalidPostFound ipf) {
+                       logger.log(Level.WARNING, "Invalid post found, aborting load!");
+                       return;
                }
 
                /* load replies. */
-               Set<PostReply> replies = new HashSet<PostReply>();
-               while (true) {
-                       String replyPrefix = sonePrefix + "/Replies/" + replies.size();
-                       String replyId = configuration.getStringValue(replyPrefix + "/ID").getValue(null);
-                       if (replyId == null) {
-                               break;
-                       }
-                       String postId = configuration.getStringValue(replyPrefix + "/Post/ID").getValue(null);
-                       long replyTime = configuration.getLongValue(replyPrefix + "/Time").getValue((long) 0);
-                       String replyText = configuration.getStringValue(replyPrefix + "/Text").getValue(null);
-                       if ((postId == null) || (replyTime == 0) || (replyText == null)) {
-                               logger.log(Level.WARNING, "Invalid reply found, aborting load!");
-                               return;
-                       }
-                       PostReplyBuilder postReplyBuilder = postReplyBuilder().withId(replyId).from(sone.getId()).to(postId).withTime(replyTime).withText(replyText);
-                       replies.add(postReplyBuilder.build());
+               Collection<PostReply> replies;
+               try {
+                       replies = configurationSoneParser.parsePostReplies(database);
+               } catch (InvalidPostReplyFound iprf) {
+                       logger.log(Level.WARNING, "Invalid reply found, aborting load!");
+                       return;
                }
 
                /* load post likes. */
-               Set<String> likedPostIds = new HashSet<String>();
-               while (true) {
-                       String likedPostId = configuration.getStringValue(sonePrefix + "/Likes/Post/" + likedPostIds.size() + "/ID").getValue(null);
-                       if (likedPostId == null) {
-                               break;
-                       }
-                       likedPostIds.add(likedPostId);
-               }
+               Set<String> likedPostIds =
+                               configurationSoneParser.parseLikedPostIds();
 
                /* load reply likes. */
-               Set<String> likedReplyIds = new HashSet<String>();
-               while (true) {
-                       String likedReplyId = configuration.getStringValue(sonePrefix + "/Likes/Reply/" + likedReplyIds.size() + "/ID").getValue(null);
-                       if (likedReplyId == null) {
-                               break;
-                       }
-                       likedReplyIds.add(likedReplyId);
-               }
+               Set<String> likedReplyIds =
+                               configurationSoneParser.parseLikedPostReplyIds();
 
                /* load friends. */
-               Set<String> friends = new HashSet<String>();
-               while (true) {
-                       String friendId = configuration.getStringValue(sonePrefix + "/Friends/" + friends.size() + "/ID").getValue(null);
-                       if (friendId == null) {
-                               break;
-                       }
-                       friends.add(friendId);
-               }
+               Set<String> friends = configurationSoneParser.parseFriends();
 
                /* load albums. */
-               List<Album> topLevelAlbums = new ArrayList<Album>();
-               int albumCounter = 0;
-               while (true) {
-                       String albumPrefix = sonePrefix + "/Albums/" + albumCounter++;
-                       String albumId = configuration.getStringValue(albumPrefix + "/ID").getValue(null);
-                       if (albumId == null) {
-                               break;
-                       }
-                       String albumTitle = configuration.getStringValue(albumPrefix + "/Title").getValue(null);
-                       String albumDescription = configuration.getStringValue(albumPrefix + "/Description").getValue(null);
-                       String albumParentId = configuration.getStringValue(albumPrefix + "/Parent").getValue(null);
-                       String albumImageId = configuration.getStringValue(albumPrefix + "/AlbumImage").getValue(null);
-                       if ((albumTitle == null) || (albumDescription == null)) {
-                               logger.log(Level.WARNING, "Invalid album found, aborting load!");
-                               return;
-                       }
-                       Album album = getAlbum(albumId).setSone(sone).modify().setTitle(albumTitle).setDescription(albumDescription).setAlbumImage(albumImageId).update();
-                       if (albumParentId != null) {
-                               Album parentAlbum = getAlbum(albumParentId, false);
-                               if (parentAlbum == null) {
-                                       logger.log(Level.WARNING, String.format("Invalid parent album ID: %s", albumParentId));
-                                       return;
-                               }
-                               parentAlbum.addAlbum(album);
-                       } else {
-                               if (!topLevelAlbums.contains(album)) {
-                                       topLevelAlbums.add(album);
-                               }
-                       }
+               List<Album> topLevelAlbums;
+               try {
+                       topLevelAlbums =
+                                       configurationSoneParser.parseTopLevelAlbums(database);
+               } catch (InvalidAlbumFound iaf) {
+                       logger.log(Level.WARNING, "Invalid album found, aborting load!");
+                       return;
+               } catch (InvalidParentAlbumFound ipaf) {
+                       logger.log(Level.WARNING, format("Invalid parent album ID: %s",
+                                       ipaf.getAlbumParentId()));
+                       return;
                }
 
                /* load images. */
@@ -1251,7 +1159,7 @@ public class Core extends AbstractService implements SoneProvider, PostProvider,
                                logger.log(Level.WARNING, "Invalid image found, aborting load!");
                                return;
                        }
-                       Album album = getAlbum(albumId, false);
+                       Album album = getAlbum(albumId);
                        if (album == null) {
                                logger.log(Level.WARNING, "Invalid album image encountered, aborting load!");
                                return;
@@ -1315,34 +1223,6 @@ public class Core extends AbstractService implements SoneProvider, PostProvider,
         *
         * @param sone
         *            The Sone that creates the post
-        * @param text
-        *            The text of the post
-        * @return The created post
-        */
-       public Post createPost(Sone sone, String text) {
-               return createPost(sone, System.currentTimeMillis(), text);
-       }
-
-       /**
-        * Creates a new post.
-        *
-        * @param sone
-        *            The Sone that creates the post
-        * @param time
-        *            The time of the post
-        * @param text
-        *            The text of the post
-        * @return The created post
-        */
-       public Post createPost(Sone sone, long time, String text) {
-               return createPost(sone, null, time, text);
-       }
-
-       /**
-        * Creates a new post.
-        *
-        * @param sone
-        *            The Sone that creates the post
         * @param recipient
         *            The recipient Sone, or {@code null} if this post does not have
         *            a recipient
@@ -1423,16 +1303,6 @@ public class Core extends AbstractService implements SoneProvider, PostProvider,
        }
 
        /**
-        * Bookmarks the given post.
-        *
-        * @param post
-        *            The post to bookmark
-        */
-       public void bookmark(Post post) {
-               bookmarkPost(post.getId());
-       }
-
-       /**
         * Bookmarks the post with the given ID.
         *
         * @param id
@@ -1530,17 +1400,6 @@ public class Core extends AbstractService implements SoneProvider, PostProvider,
        }
 
        /**
-        * Creates a new top-level album for the given Sone.
-        *
-        * @param sone
-        *            The Sone to create the album for
-        * @return The new album
-        */
-       public Album createAlbum(Sone sone) {
-               return createAlbum(sone, sone.getRootAlbum());
-       }
-
-       /**
         * Creates a new album for the given Sone.
         *
         * @param sone
@@ -1551,9 +1410,8 @@ public class Core extends AbstractService implements SoneProvider, PostProvider,
         * @return The new album
         */
        public Album createAlbum(Sone sone, Album parent) {
-               Album album = database.newAlbumBuilder().randomId().build();
+               Album album = database.newAlbumBuilder().randomId().by(sone).build();
                database.storeAlbum(album);
-               album.setSone(sone);
                parent.addAlbum(album);
                return album;
        }
@@ -1604,7 +1462,7 @@ public class Core extends AbstractService implements SoneProvider, PostProvider,
         * Deletes the given image. This method will also delete a matching
         * temporary image.
         *
-        * @see #deleteTemporaryImage(TemporaryImage)
+        * @see #deleteTemporaryImage(String)
         * @param image
         *            The image to delete
         */
@@ -1636,17 +1494,6 @@ public class Core extends AbstractService implements SoneProvider, PostProvider,
        }
 
        /**
-        * Deletes the given temporary image.
-        *
-        * @param temporaryImage
-        *            The temporary image to delete
-        */
-       public void deleteTemporaryImage(TemporaryImage temporaryImage) {
-               checkNotNull(temporaryImage, "temporaryImage must not be null");
-               deleteTemporaryImage(temporaryImage.getId());
-       }
-
-       /**
         * Deletes the temporary image with the given ID.
         *
         * @param imageId