X-Git-Url: https://git.pterodactylus.net/?p=Sone.git;a=blobdiff_plain;f=src%2Fmain%2Fjava%2Fnet%2Fpterodactylus%2Fsone%2Fcore%2FCore.java;h=a2a400b8ef97f0670abcfafcb13c328f6e59ef03;hp=dc5e207125ea0f2e6d88359c2bf3da43714ebb5b;hb=8e313509a42a8c638fcac018dd73dd975bf9cb68;hpb=161c216be80f6f0438bacd2642b1aa0091ba1b1f diff --git a/src/main/java/net/pterodactylus/sone/core/Core.java b/src/main/java/net/pterodactylus/sone/core/Core.java index dc5e207..a2a400b 100644 --- a/src/main/java/net/pterodactylus/sone/core/Core.java +++ b/src/main/java/net/pterodactylus/sone/core/Core.java @@ -1,5 +1,5 @@ /* - * Sone - Core.java - Copyright © 2010–2013 David Roden + * Sone - Core.java - Copyright © 2010–2016 David Roden * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -40,6 +40,9 @@ import java.util.concurrent.TimeUnit; import java.util.logging.Level; import java.util.logging.Logger; +import javax.annotation.Nonnull; +import javax.annotation.Nullable; + import net.pterodactylus.sone.core.ConfigurationSoneParser.InvalidAlbumFound; import net.pterodactylus.sone.core.ConfigurationSoneParser.InvalidImageFound; import net.pterodactylus.sone.core.ConfigurationSoneParser.InvalidParentAlbumFound; @@ -68,8 +71,8 @@ import net.pterodactylus.sone.data.Profile; 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.ShowCustomAvatars; import net.pterodactylus.sone.data.Sone.SoneStatus; +import net.pterodactylus.sone.data.SoneOptions.LoadExternalContent; import net.pterodactylus.sone.data.TemporaryImage; import net.pterodactylus.sone.database.AlbumBuilder; import net.pterodactylus.sone.database.Database; @@ -105,6 +108,7 @@ import com.google.common.eventbus.EventBus; import com.google.common.eventbus.Subscribe; import com.google.inject.Inject; import com.google.inject.Singleton; +import kotlin.jvm.functions.Function1; /** * The Sone core. @@ -115,7 +119,7 @@ import com.google.inject.Singleton; public class Core extends AbstractService implements SoneProvider, PostProvider, PostReplyProvider { /** The logger. */ - private static final Logger logger = getLogger("Sone.Core"); + private static final Logger logger = getLogger(Core.class.getName()); /** The start time. */ private final long startupTime = System.currentTimeMillis(); @@ -203,14 +207,14 @@ public class Core extends AbstractService implements SoneProvider, PostProvider, * The database */ @Inject - public Core(Configuration configuration, FreenetInterface freenetInterface, IdentityManager identityManager, WebOfTrustUpdater webOfTrustUpdater, EventBus eventBus, Database database) { + public Core(Configuration configuration, FreenetInterface freenetInterface, IdentityManager identityManager, UpdateChecker updateChecker, WebOfTrustUpdater webOfTrustUpdater, EventBus eventBus, Database database) { super("Sone Core"); this.configuration = configuration; this.freenetInterface = freenetInterface; this.identityManager = identityManager; this.soneDownloader = new SoneDownloaderImpl(this, freenetInterface); this.imageInserter = new ImageInserter(freenetInterface, freenetInterface.new InsertTokenSupplier()); - this.updateChecker = new UpdateChecker(eventBus, freenetInterface); + this.updateChecker = updateChecker; this.webOfTrustUpdater = webOfTrustUpdater; this.eventBus = eventBus; this.database = database; @@ -313,11 +317,18 @@ public class Core extends AbstractService implements SoneProvider, PostProvider, /** * {@inheritDocs} */ + @Nonnull @Override public Collection getSones() { return database.getSones(); } + @Nonnull + @Override + public Function1 getSoneLoader() { + return database.getSoneLoader(); + } + /** * Returns the Sone with the given ID, regardless whether it’s local or * remote. @@ -328,7 +339,8 @@ public class Core extends AbstractService implements SoneProvider, PostProvider, * Sone */ @Override - public Optional getSone(String id) { + @Nullable + public Sone getSone(@Nonnull String id) { return database.getSone(id); } @@ -348,9 +360,9 @@ public class Core extends AbstractService implements SoneProvider, PostProvider, * @return The Sone with the given ID, or {@code null} */ public Sone getLocalSone(String id) { - Optional sone = database.getSone(id); - if (sone.isPresent() && sone.get().isLocal()) { - return sone.get(); + Sone sone = database.getSone(id); + if ((sone != null) && sone.isLocal()) { + return sone; } return null; } @@ -372,7 +384,7 @@ public class Core extends AbstractService implements SoneProvider, PostProvider, * @return The Sone with the given ID */ public Sone getRemoteSone(String id) { - return database.getSone(id).orNull(); + return database.getSone(id); } /** @@ -528,7 +540,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) { + @Nullable + public Album getAlbum(@Nonnull String albumId) { return database.getAlbum(albumId).orNull(); } @@ -543,6 +556,7 @@ public class Core extends AbstractService implements SoneProvider, PostProvider, * The ID of the image * @return The image with the given ID */ + @Nullable public Image getImage(String imageId) { return getImage(imageId, true); } @@ -559,6 +573,7 @@ public class Core extends AbstractService implements SoneProvider, PostProvider, * @return The image with the given ID, or {@code null} if none exists and * none was created */ + @Nullable public Image getImage(String imageId, boolean create) { Optional image = database.getImage(imageId); if (image.isPresent()) { @@ -635,8 +650,9 @@ public class Core extends AbstractService implements SoneProvider, PostProvider, } logger.info(String.format("Adding Sone from OwnIdentity: %s", ownIdentity)); Sone sone = database.newSoneBuilder().local().from(ownIdentity).build(); - sone.setLatestEdition(fromNullable(tryParse(ownIdentity.getProperty("Sone.LatestEdition"))).or(0L)); - sone.setClient(new Client("Sone", SonePlugin.VERSION.toString())); + String property = fromNullable(ownIdentity.getProperty("Sone.LatestEdition")).or("0"); + sone.setLatestEdition(fromNullable(tryParse(property)).or(0L)); + sone.setClient(new Client("Sone", SonePlugin.getPluginVersion())); sone.setKnown(true); SoneInserter soneInserter = new SoneInserter(this, eventBus, freenetInterface, ownIdentity.getId()); eventBus.register(soneInserter); @@ -644,6 +660,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; @@ -680,14 +697,14 @@ 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")); - Optional existingSone = getSone(identity.getId()); - if (existingSone.isPresent() && existingSone.get().isLocal()) { - return existingSone.get(); + String property = fromNullable(identity.getProperty("Sone.LatestEdition")).or("0"); + long latestEdition = fromNullable(tryParse(property)).or(0L); + Sone existingSone = getSone(identity.getId()); + if ((existingSone != null )&& existingSone.isLocal()) { + return existingSone; } - boolean newSone = !existingSone.isPresent(); - Sone sone = !newSone ? existingSone.get() : database.newSoneBuilder().from(identity).build(); + boolean newSone = existingSone == null; + Sone sone = !newSone ? existingSone : database.newSoneBuilder().from(identity).build(); sone.setLatestEdition(latestEdition); if (newSone) { synchronized (knownSones) { @@ -720,21 +737,21 @@ public class Core extends AbstractService implements SoneProvider, PostProvider, public void followSone(Sone sone, String soneId) { checkNotNull(sone, "sone must not be null"); checkNotNull(soneId, "soneId must not be null"); - sone.addFriend(soneId); + database.addFriend(sone, soneId); synchronized (soneFollowingTimes) { if (!soneFollowingTimes.containsKey(soneId)) { long now = System.currentTimeMillis(); soneFollowingTimes.put(soneId, now); - Optional followedSone = getSone(soneId); - if (!followedSone.isPresent()) { + Sone followedSone = getSone(soneId); + if (followedSone == null) { return; } - for (Post post : followedSone.get().getPosts()) { + for (Post post : followedSone.getPosts()) { if (post.getTime() < now) { markPostKnown(post); } } - for (PostReply reply : followedSone.get().getReplies()) { + for (PostReply reply : followedSone.getReplies()) { if (reply.getTime() < now) { markReplyKnown(reply); } @@ -755,7 +772,7 @@ public class Core extends AbstractService implements SoneProvider, PostProvider, public void unfollowSone(Sone sone, String soneId) { checkNotNull(sone, "sone must not be null"); checkNotNull(soneId, "soneId must not be null"); - sone.removeFriend(soneId); + database.removeFriend(sone, soneId); boolean unfollowedSoneStillFollowed = false; for (Sone localSone : getLocalSones()) { unfollowedSoneStillFollowed |= localSone.hasFriend(soneId); @@ -859,20 +876,20 @@ public class Core extends AbstractService implements SoneProvider, PostProvider, * of the age of the given Sone */ public void updateSone(final Sone sone, boolean soneRescueMode) { - Optional storedSone = getSone(sone.getId()); - if (storedSone.isPresent()) { - if (!soneRescueMode && !(sone.getTime() > storedSone.get().getTime())) { + Sone storedSone = getSone(sone.getId()); + if (storedSone != null) { + if (!soneRescueMode && !(sone.getTime() > storedSone.getTime())) { logger.log(Level.FINE, String.format("Downloaded Sone %s is not newer than stored Sone %s.", sone, storedSone)); return; } List events = - collectEventsForChangesInSone(storedSone.get(), sone); + collectEventsForChangesInSone(storedSone, sone); database.storeSone(sone); for (Object event : events) { eventBus.post(event); } - sone.setOptions(storedSone.get().getOptions()); - sone.setKnown(storedSone.get().isKnown()); + sone.setOptions(storedSone.getOptions()); + sone.setKnown(storedSone.isKnown()); sone.setStatus((sone.getTime() == 0) ? SoneStatus.unknown : SoneStatus.idle); if (sone.isLocal()) { touchConfiguration(); @@ -1021,9 +1038,6 @@ public class Core extends AbstractService implements SoneProvider, PostProvider, Set likedReplyIds = configurationSoneParser.parseLikedPostReplyIds(); - /* load friends. */ - Set friends = configurationSoneParser.parseFriends(); - /* load albums. */ List topLevelAlbums; try { @@ -1060,12 +1074,13 @@ public class Core extends AbstractService implements SoneProvider, PostProvider, } /* load options. */ - sone.getOptions().setAutoFollow(configuration.getBooleanValue(sonePrefix + "/Options/AutoFollow").getValue(null)); - sone.getOptions().setSoneInsertNotificationEnabled(configuration.getBooleanValue(sonePrefix + "/Options/EnableSoneInsertNotifications").getValue(null)); - sone.getOptions().setShowNewSoneNotifications(configuration.getBooleanValue(sonePrefix + "/Options/ShowNotification/NewSones").getValue(null)); - sone.getOptions().setShowNewPostNotifications(configuration.getBooleanValue(sonePrefix + "/Options/ShowNotification/NewPosts").getValue(null)); - sone.getOptions().setShowNewReplyNotifications(configuration.getBooleanValue(sonePrefix + "/Options/ShowNotification/NewReplies").getValue(null)); - sone.getOptions().setShowCustomAvatars(ShowCustomAvatars.valueOf(configuration.getStringValue(sonePrefix + "/Options/ShowCustomAvatars").getValue(ShowCustomAvatars.NEVER.name()))); + sone.getOptions().setAutoFollow(configuration.getBooleanValue(sonePrefix + "/Options/AutoFollow").getValue(false)); + sone.getOptions().setSoneInsertNotificationEnabled(configuration.getBooleanValue(sonePrefix + "/Options/EnableSoneInsertNotifications").getValue(false)); + sone.getOptions().setShowNewSoneNotifications(configuration.getBooleanValue(sonePrefix + "/Options/ShowNotification/NewSones").getValue(true)); + sone.getOptions().setShowNewPostNotifications(configuration.getBooleanValue(sonePrefix + "/Options/ShowNotification/NewPosts").getValue(true)); + sone.getOptions().setShowNewReplyNotifications(configuration.getBooleanValue(sonePrefix + "/Options/ShowNotification/NewReplies").getValue(true)); + sone.getOptions().setShowCustomAvatars(LoadExternalContent.valueOf(configuration.getStringValue(sonePrefix + "/Options/ShowCustomAvatars").getValue(LoadExternalContent.NEVER.name()))); + sone.getOptions().setLoadLinkedImages(LoadExternalContent.valueOf(configuration.getStringValue(sonePrefix + "/Options/LoadLinkedImages").getValue(LoadExternalContent.NEVER.name()))); /* if we’re still here, Sone was loaded successfully. */ synchronized (sone) { @@ -1075,25 +1090,16 @@ public class Core extends AbstractService implements SoneProvider, PostProvider, sone.setReplies(replies); sone.setLikePostIds(likedPostIds); sone.setLikeReplyIds(likedReplyIds); - for (String friendId : friends) { - followSone(sone, friendId); - } for (Album album : sone.getRootAlbum().getAlbums()) { sone.getRootAlbum().removeAlbum(album); } for (Album album : topLevelAlbums) { sone.getRootAlbum().addAlbum(album); } - database.storeSone(sone); synchronized (soneInserters) { soneInserters.get(sone).setLastInsertFingerprint(lastInsertFingerprint); } } - synchronized (knownSones) { - for (String friend : friends) { - knownSones.add(friend); - } - } for (Post post : posts) { post.setKnown(true); } @@ -1415,6 +1421,11 @@ public class Core extends AbstractService implements SoneProvider, PostProvider, saveSone(soneInserter.getKey()); } } + synchronized (soneRescuers) { + for (SoneRescuer soneRescuer : soneRescuers.values()) { + soneRescuer.stop(); + } + } saveConfiguration(); database.stop(); webOfTrustUpdater.stop(); @@ -1507,13 +1518,6 @@ public class Core extends AbstractService implements SoneProvider, PostProvider, } configuration.getStringValue(sonePrefix + "/Likes/Reply/" + replyLikeCounter + "/ID").setValue(null); - /* save friends. */ - int friendCounter = 0; - for (String friendId : sone.getFriends()) { - configuration.getStringValue(sonePrefix + "/Friends/" + friendCounter++ + "/ID").setValue(friendId); - } - configuration.getStringValue(sonePrefix + "/Friends/" + friendCounter + "/ID").setValue(null); - /* save albums. first, collect in a flat structure, top-level first. */ List albums = FluentIterable.from(sone.getRootAlbum().getAlbums()).transformAndConcat(Album.FLATTENER).toList(); @@ -1524,7 +1528,6 @@ public class Core extends AbstractService implements SoneProvider, PostProvider, 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()); - configuration.getStringValue(albumPrefix + "/AlbumImage").setValue(album.getAlbumImage() == null ? null : album.getAlbumImage().getId()); } configuration.getStringValue(sonePrefix + "/Albums/" + albumCounter + "/ID").setValue(null); @@ -1555,6 +1558,7 @@ public class Core extends AbstractService implements SoneProvider, PostProvider, configuration.getBooleanValue(sonePrefix + "/Options/ShowNotification/NewPosts").setValue(sone.getOptions().isShowNewPostNotifications()); configuration.getBooleanValue(sonePrefix + "/Options/ShowNotification/NewReplies").setValue(sone.getOptions().isShowNewReplyNotifications()); configuration.getStringValue(sonePrefix + "/Options/ShowCustomAvatars").setValue(sone.getOptions().getShowCustomAvatars().name()); + configuration.getStringValue(sonePrefix + "/Options/LoadLinkedImages").setValue(sone.getOptions().getLoadLinkedImages().name()); configuration.save(); @@ -1731,13 +1735,19 @@ public class Core extends AbstractService implements SoneProvider, PostProvider, return; } } - Optional sone = getSone(identity.getId()); - if (!sone.isPresent()) { + Sone sone = getSone(identity.getId()); + if (sone == null) { /* TODO - we don’t have the Sone anymore. should this happen? */ return; } - database.removeSone(sone.get()); - eventBus.post(new SoneRemovedEvent(sone.get())); + for (PostReply postReply : sone.getReplies()) { + eventBus.post(new PostReplyRemovedEvent(postReply)); + } + for (Post post : sone.getPosts()) { + eventBus.post(new PostRemovedEvent(post)); + } + eventBus.post(new SoneRemovedEvent(sone)); + database.removeSone(sone); } /**