X-Git-Url: https://git.pterodactylus.net/?p=Sone.git;a=blobdiff_plain;f=src%2Fmain%2Fjava%2Fnet%2Fpterodactylus%2Fsone%2Fcore%2FCore.java;h=47a77ee496c4d06d70de5d26d8264fb4a91ddd60;hp=a6b4c96b03161aa314900323f7d0560c79d206fb;hb=01540cbd527e955dac1e41c2e6855a89ab12605c;hpb=ec06ae64c86f0b06bb0cf9f8b289e7907e81dffa diff --git a/src/main/java/net/pterodactylus/sone/core/Core.java b/src/main/java/net/pterodactylus/sone/core/Core.java index a6b4c96..47a77ee 100644 --- a/src/main/java/net/pterodactylus/sone/core/Core.java +++ b/src/main/java/net/pterodactylus/sone/core/Core.java @@ -17,10 +17,15 @@ package net.pterodactylus.sone.core; +import static com.google.common.base.Optional.fromNullable; 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 com.google.common.primitives.Longs.tryParse; +import static java.lang.String.format; +import static java.util.logging.Level.WARNING; import static net.pterodactylus.sone.data.Sone.LOCAL_SONE_FILTER; +import static net.pterodactylus.sone.data.Sone.toAllAlbums; import java.net.MalformedURLException; import java.util.ArrayList; @@ -38,9 +43,14 @@ 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.InvalidImageFound; +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.SoneChangeDetector.PostProcessor; +import net.pterodactylus.sone.core.SoneChangeDetector.PostReplyProcessor; import net.pterodactylus.sone.core.SoneInserter.SetInsertionDelay; import net.pterodactylus.sone.core.event.ImageInsertFinishedEvent; import net.pterodactylus.sone.core.event.MarkPostKnownEvent; @@ -70,6 +80,7 @@ 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.ImageBuilder; import net.pterodactylus.sone.database.PostBuilder; import net.pterodactylus.sone.database.PostProvider; import net.pterodactylus.sone.database.PostReplyBuilder; @@ -602,6 +613,10 @@ public class Core extends AbstractService implements SoneProvider, PostProvider, return database.getAlbum(albumId).orNull(); } + public ImageBuilder imageBuilder() { + return database.newImageBuilder(); + } + /** * Returns the image with the given ID, creating it if necessary. * @@ -753,6 +768,8 @@ public class Core extends AbstractService implements SoneProvider, PostProvider, logger.log(Level.WARNING, "Given Identity is null!"); return null; } + final Long latestEdition = tryParse(fromNullable( + identity.getProperty("Sone.LatestEdition")).or("0")); synchronized (sones) { final Sone sone = getRemoteSone(identity.getId(), true); if (sone.isLocal()) { @@ -761,7 +778,7 @@ public class Core extends AbstractService implements SoneProvider, PostProvider, sone.setIdentity(identity); boolean newSone = sone.getRequestUri() == null; sone.setRequestUri(SoneUri.create(identity.getRequestUri())); - sone.setLatestEdition(Numbers.safeParseLong(identity.getProperty("Sone.LatestEdition"), (long) 0)); + sone.setLatestEdition(latestEdition); if (newSone) { synchronized (knownSones) { newSone = !knownSones.contains(sone.getId()); @@ -931,7 +948,7 @@ public class Core extends AbstractService implements SoneProvider, PostProvider, * {@code true} if the stored Sone should be updated regardless * of the age of the given Sone */ - public void updateSone(Sone sone, boolean soneRescueMode) { + public void updateSone(final Sone sone, boolean soneRescueMode) { Optional storedSone = getSone(sone.getId()); if (storedSone.isPresent()) { if (!soneRescueMode && !(sone.getTime() > storedSone.get().getTime())) { @@ -939,72 +956,41 @@ public class Core extends AbstractService implements SoneProvider, PostProvider, return; } /* find removed posts. */ - Collection removedPosts = new ArrayList(); - Collection newPosts = new ArrayList(); - Collection existingPosts = database.getPosts(sone.getId()); - for (Post oldPost : existingPosts) { - if (!sone.getPosts().contains(oldPost)) { - removedPosts.add(oldPost); - } - } - /* find new posts. */ - for (Post newPost : sone.getPosts()) { - if (existingPosts.contains(newPost)) { - continue; - } - if (newPost.getTime() < getSoneFollowingTime(sone)) { - newPost.setKnown(true); - } else if (!newPost.isKnown()) { - newPosts.add(newPost); - } - } - /* store posts. */ - database.storePosts(sone, sone.getPosts()); - Collection newPostReplies = new ArrayList(); - Collection removedPostReplies = new ArrayList(); - if (!soneRescueMode) { - for (PostReply reply : storedSone.get().getReplies()) { - if (!sone.getReplies().contains(reply)) { - removedPostReplies.add(reply); + SoneChangeDetector soneChangeDetector = new SoneChangeDetector(storedSone.get()); + soneChangeDetector.onNewPosts(new PostProcessor() { + @Override + public void processPost(Post post) { + if (post.getTime() < getSoneFollowingTime(sone)) { + post.setKnown(true); + } else if (!post.isKnown()) { + eventBus.post(new NewPostFoundEvent(post)); } } - } - Set storedReplies = storedSone.get().getReplies(); - for (PostReply reply : sone.getReplies()) { - if (storedReplies.contains(reply)) { - continue; + }); + soneChangeDetector.onRemovedPosts(new PostProcessor() { + @Override + public void processPost(Post post) { + eventBus.post(new PostRemovedEvent(post)); } - if (reply.getTime() < getSoneFollowingTime(sone)) { - reply.setKnown(true); - } else if (!reply.isKnown()) { - newPostReplies.add(reply); + }); + soneChangeDetector.onNewPostReplies(new PostReplyProcessor() { + @Override + public void processPostReply(PostReply postReply) { + if (postReply.getTime() < getSoneFollowingTime(sone)) { + postReply.setKnown(true); + } else if (!postReply.isKnown()) { + eventBus.post(new NewPostReplyFoundEvent(postReply)); + } } - } - database.storePostReplies(sone, sone.getReplies()); - for (Album album : storedSone.get().getRootAlbum().getAlbums()) { - database.removeAlbum(album); - for (Image image : album.getImages()) { - database.removeImage(image); + }); + soneChangeDetector.onRemovedPostReplies(new PostReplyProcessor() { + @Override + public void processPostReply(PostReply postReply) { + eventBus.post(new PostReplyRemovedEvent(postReply)); } - } - for (Post removedPost : removedPosts) { - eventBus.post(new PostRemovedEvent(removedPost)); - } - for (Post newPost : newPosts) { - eventBus.post(new NewPostFoundEvent(newPost)); - } - for (PostReply removedPostReply : removedPostReplies) { - eventBus.post(new PostReplyRemovedEvent(removedPostReply)); - } - for (PostReply newPostReply : newPostReplies) { - eventBus.post(new NewPostReplyFoundEvent(newPostReply)); - } - for (Album album : sone.getRootAlbum().getAlbums()) { - database.storeAlbum(album); - for (Image image : album.getImages()) { - database.storeImage(image); - } - } + }); + soneChangeDetector.detectChanges(sone); + database.storeSone(sone); synchronized (sones) { sone.setOptions(storedSone.get().getOptions()); sone.setKnown(storedSone.get().isKnown()); @@ -1124,77 +1110,38 @@ public class Core extends AbstractService implements SoneProvider, PostProvider, Set friends = configurationSoneParser.parseFriends(); /* load albums. */ - List topLevelAlbums = new ArrayList(); - 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 = database.newAlbumBuilder() - .withId(albumId) - .by(sone) - .build() - .modify() - .setTitle(albumTitle) - .setDescription(albumDescription) - .setAlbumImage(albumImageId) - .update(); - if (albumParentId != null) { - Album parentAlbum = getAlbum(albumParentId); - 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 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. */ - int imageCounter = 0; - while (true) { - String imagePrefix = sonePrefix + "/Images/" + imageCounter++; - String imageId = configuration.getStringValue(imagePrefix + "/ID").getValue(null); - if (imageId == null) { - break; - } - String albumId = configuration.getStringValue(imagePrefix + "/Album").getValue(null); - String key = configuration.getStringValue(imagePrefix + "/Key").getValue(null); - String title = configuration.getStringValue(imagePrefix + "/Title").getValue(null); - String description = configuration.getStringValue(imagePrefix + "/Description").getValue(null); - Long creationTime = configuration.getLongValue(imagePrefix + "/CreationTime").getValue(null); - Integer width = configuration.getIntValue(imagePrefix + "/Width").getValue(null); - Integer height = configuration.getIntValue(imagePrefix + "/Height").getValue(null); - if ((albumId == null) || (key == null) || (title == null) || (description == null) || (creationTime == null) || (width == null) || (height == null)) { - logger.log(Level.WARNING, "Invalid image found, aborting load!"); - return; - } - Album album = getAlbum(albumId); - if (album == null) { - logger.log(Level.WARNING, "Invalid album image encountered, aborting load!"); - return; - } - Image image = getImage(imageId).modify().setSone(sone).setCreationTime(creationTime).setKey(key).setTitle(title).setDescription(description).setWidth(width).setHeight(height).update(); - album.addImage(image); + try { + configurationSoneParser.parseImages(database); + } catch (InvalidImageFound iif) { + logger.log(WARNING, "Invalid image found, aborting load!"); + return; + } catch (InvalidParentAlbumFound ipaf) { + logger.log(Level.WARNING, + format("Invalid album image (%s) encountered, aborting load!", + ipaf.getAlbumParentId())); + return; } /* load avatar. */ String avatarId = configuration.getStringValue(sonePrefix + "/Profile/Avatar").getValue(null); if (avatarId != null) { - profile.setAvatar(getImage(avatarId, false)); + final Map images = + configurationSoneParser.getImages(); + profile.setAvatar(images.get(avatarId)); } /* load options. */ @@ -1223,6 +1170,12 @@ public class Core extends AbstractService implements SoneProvider, PostProvider, sone.getRootAlbum().addAlbum(album); } soneInserters.get(sone).setLastInsertFingerprint(lastInsertFingerprint); + for (Album album : toAllAlbums.apply(sone)) { + database.storeAlbum(album); + for (Image image : album.getImages()) { + database.storeImage(image); + } + } } synchronized (knownSones) { for (String friend : friends) { @@ -1970,19 +1923,14 @@ public class Core extends AbstractService implements SoneProvider, PostProvider, OwnIdentity ownIdentity = identityRemovedEvent.ownIdentity(); Identity identity = identityRemovedEvent.identity(); trustedIdentities.remove(ownIdentity, identity); - boolean foundIdentity = false; for (Entry> trustedIdentity : trustedIdentities.asMap().entrySet()) { if (trustedIdentity.getKey().equals(ownIdentity)) { continue; } if (trustedIdentity.getValue().contains(identity)) { - foundIdentity = true; + return; } } - if (foundIdentity) { - /* some local identity still trusts this identity, don’t remove. */ - return; - } Optional sone = getSone(identity.getId()); if (!sone.isPresent()) { /* TODO - we don’t have the Sone anymore. should this happen? */