X-Git-Url: https://git.pterodactylus.net/?p=Sone.git;a=blobdiff_plain;f=src%2Fmain%2Fjava%2Fnet%2Fpterodactylus%2Fsone%2Fcore%2FCore.java;h=34083837bf30bffd220958f577284e2bf1d055d0;hp=d37f90397b66abf2695612bf76966563e75138e7;hb=a90c83da842c28f0e045d8a09dd3480643cd87f1;hpb=a47643aed43d118ca68044f95451bb5374cdb332 diff --git a/src/main/java/net/pterodactylus/sone/core/Core.java b/src/main/java/net/pterodactylus/sone/core/Core.java index d37f903..3408383 100644 --- a/src/main/java/net/pterodactylus/sone/core/Core.java +++ b/src/main/java/net/pterodactylus/sone/core/Core.java @@ -46,20 +46,20 @@ 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.TemporaryImage; +import net.pterodactylus.sone.data.impl.PostImpl; import net.pterodactylus.sone.fcp.FcpInterface; import net.pterodactylus.sone.fcp.FcpInterface.FullAccessRequired; import net.pterodactylus.sone.freenet.wot.Identity; import net.pterodactylus.sone.freenet.wot.IdentityListener; import net.pterodactylus.sone.freenet.wot.IdentityManager; import net.pterodactylus.sone.freenet.wot.OwnIdentity; -import net.pterodactylus.sone.freenet.wot.Trust; -import net.pterodactylus.sone.freenet.wot.WebOfTrustException; import net.pterodactylus.sone.main.SonePlugin; import net.pterodactylus.util.config.Configuration; import net.pterodactylus.util.config.ConfigurationException; import net.pterodactylus.util.logging.Logging; import net.pterodactylus.util.number.Numbers; import net.pterodactylus.util.service.AbstractService; +import net.pterodactylus.util.thread.NamedThreadFactory; import net.pterodactylus.util.thread.Ticker; import net.pterodactylus.util.validation.EqualityValidator; import net.pterodactylus.util.validation.IntegerRangeValidator; @@ -78,6 +78,9 @@ public class Core extends AbstractService implements IdentityListener, UpdateLis /** The logger. */ private static final Logger logger = Logging.getLogger(Core.class); + /** The start time. */ + private final long startupTime = System.currentTimeMillis(); + /** The options. */ private final Options options = new Options(); @@ -106,11 +109,14 @@ public class Core extends AbstractService implements IdentityListener, UpdateLis private final ImageInserter imageInserter; /** Sone downloader thread-pool. */ - private final ExecutorService soneDownloaders = Executors.newFixedThreadPool(10); + private final ExecutorService soneDownloaders = Executors.newFixedThreadPool(10, new NamedThreadFactory("Sone Downloader %2$d")); /** The update checker. */ private final UpdateChecker updateChecker; + /** The trust updater. */ + private final WebOfTrustUpdater webOfTrustUpdater; + /** The FCP interface. */ private volatile FcpInterface fcpInterface; @@ -183,8 +189,10 @@ public class Core extends AbstractService implements IdentityListener, UpdateLis * The freenet interface * @param identityManager * The identity manager + * @param webOfTrustUpdater + * The WebOfTrust updater */ - public Core(Configuration configuration, FreenetInterface freenetInterface, IdentityManager identityManager) { + public Core(Configuration configuration, FreenetInterface freenetInterface, IdentityManager identityManager, WebOfTrustUpdater webOfTrustUpdater) { super("Sone Core"); this.configuration = configuration; this.freenetInterface = freenetInterface; @@ -192,6 +200,7 @@ public class Core extends AbstractService implements IdentityListener, UpdateLis this.soneDownloader = new SoneDownloader(this, freenetInterface); this.imageInserter = new ImageInserter(this, freenetInterface); this.updateChecker = new UpdateChecker(freenetInterface); + this.webOfTrustUpdater = webOfTrustUpdater; } // @@ -223,6 +232,15 @@ public class Core extends AbstractService implements IdentityListener, UpdateLis // /** + * Returns the time Sone was started. + * + * @return The startup time (in milliseconds since Jan 1, 1970 UTC) + */ + public long getStartupTime() { + return startupTime; + } + + /** * Sets the configuration to use. This will automatically save the current * configuration to the given configuration. * @@ -561,7 +579,7 @@ public class Core extends AbstractService implements IdentityListener, UpdateLis synchronized (posts) { Post post = posts.get(postId); if ((post == null) && create) { - post = new Post(postId); + post = new PostImpl(postId); posts.put(postId, post); } return post; @@ -858,7 +876,7 @@ public class Core extends AbstractService implements IdentityListener, UpdateLis try { sone = getLocalSone(ownIdentity.getId()).setIdentity(ownIdentity).setInsertUri(new FreenetURI(ownIdentity.getInsertUri())).setRequestUri(new FreenetURI(ownIdentity.getRequestUri())); } catch (MalformedURLException mue1) { - logger.log(Level.SEVERE, "Could not convert the Identity’s URIs to Freenet URIs: " + ownIdentity.getInsertUri() + ", " + ownIdentity.getRequestUri(), mue1); + logger.log(Level.SEVERE, String.format("Could not convert the Identity’s URIs to Freenet URIs: %s, %s", ownIdentity.getInsertUri(), ownIdentity.getRequestUri()), mue1); return null; } sone.setLatestEdition(Numbers.safeParseLong(ownIdentity.getProperty("Sone.LatestEdition"), (long) 0)); @@ -884,10 +902,8 @@ public class Core extends AbstractService implements IdentityListener, UpdateLis * @return The created Sone */ public Sone createSone(OwnIdentity ownIdentity) { - try { - ownIdentity.addContext("Sone"); - } catch (WebOfTrustException wote1) { - logger.log(Level.SEVERE, "Could not add “Sone” context to own identity: " + ownIdentity, wote1); + if (!webOfTrustUpdater.addContextWait(ownIdentity, "Sone")) { + logger.log(Level.SEVERE, String.format("Could not add “Sone” context to own identity: %s", ownIdentity)); return null; } Sone sone = addLocalSone(ownIdentity); @@ -1038,25 +1054,6 @@ public class Core extends AbstractService implements IdentityListener, UpdateLis } /** - * Retrieves the trust relationship from the origin to the target. If the - * trust relationship can not be retrieved, {@code null} is returned. - * - * @see Identity#getTrust(OwnIdentity) - * @param origin - * The origin of the trust tree - * @param target - * The target of the trust - * @return The trust relationship - */ - public Trust getTrust(Sone origin, Sone target) { - if (!isLocalSone(origin)) { - logger.log(Level.WARNING, "Tried to get trust from remote Sone: %s", origin); - return null; - } - return target.getIdentity().getTrust((OwnIdentity) origin.getIdentity()); - } - - /** * Sets the trust value of the given origin Sone for the target Sone. * * @param origin @@ -1068,11 +1065,7 @@ public class Core extends AbstractService implements IdentityListener, UpdateLis */ public void setTrust(Sone origin, Sone target, int trustValue) { Validation.begin().isNotNull("Trust Origin", origin).check().isInstanceOf("Trust Origin", origin.getIdentity(), OwnIdentity.class).isNotNull("Trust Target", target).isLessOrEqual("Trust Value", trustValue, 100).isGreaterOrEqual("Trust Value", trustValue, -100).check(); - try { - ((OwnIdentity) origin.getIdentity()).setTrust(target.getIdentity(), trustValue, preferences.getTrustComment()); - } catch (WebOfTrustException wote1) { - logger.log(Level.WARNING, "Could not set trust for Sone: " + target, wote1); - } + webOfTrustUpdater.setTrust((OwnIdentity) origin.getIdentity(), target.getIdentity(), trustValue, preferences.getTrustComment()); } /** @@ -1085,11 +1078,7 @@ public class Core extends AbstractService implements IdentityListener, UpdateLis */ public void removeTrust(Sone origin, Sone target) { Validation.begin().isNotNull("Trust Origin", origin).isNotNull("Trust Target", target).check().isInstanceOf("Trust Origin Identity", origin.getIdentity(), OwnIdentity.class).check(); - try { - ((OwnIdentity) origin.getIdentity()).removeTrust(target.getIdentity()); - } catch (WebOfTrustException wote1) { - logger.log(Level.WARNING, "Could not remove trust for Sone: " + target, wote1); - } + webOfTrustUpdater.setTrust((OwnIdentity) origin.getIdentity(), target.getIdentity(), null, null); } /** @@ -1153,7 +1142,7 @@ public class Core extends AbstractService implements IdentityListener, UpdateLis if (hasSone(sone.getId())) { Sone storedSone = getSone(sone.getId()); if (!soneRescueMode && !(sone.getTime() > storedSone.getTime())) { - logger.log(Level.FINE, "Downloaded Sone %s is not newer than stored Sone %s.", new Object[] { sone, storedSone }); + logger.log(Level.FINE, String.format("Downloaded Sone %s is not newer than stored Sone %s.", sone, storedSone)); return; } synchronized (posts) { @@ -1172,8 +1161,8 @@ public class Core extends AbstractService implements IdentityListener, UpdateLis if (!storedPosts.contains(post)) { if (post.getTime() < getSoneFollowingTime(sone)) { knownPosts.add(post.getId()); + post.setKnown(true); } else if (!knownPosts.contains(post.getId())) { - sone.setKnown(false); coreListenerManager.fireNewPostFound(post); } } @@ -1197,8 +1186,8 @@ public class Core extends AbstractService implements IdentityListener, UpdateLis if (!storedReplies.contains(reply)) { if (reply.getTime() < getSoneFollowingTime(sone)) { knownReplies.add(reply.getId()); + reply.setKnown(true); } else if (!knownReplies.contains(reply.getId())) { - reply.setKnown(false); coreListenerManager.fireNewReplyFound(reply); } } @@ -1266,12 +1255,12 @@ public class Core extends AbstractService implements IdentityListener, UpdateLis */ public void deleteSone(Sone sone) { if (!(sone.getIdentity() instanceof OwnIdentity)) { - logger.log(Level.WARNING, "Tried to delete Sone of non-own identity: %s", sone); + logger.log(Level.WARNING, String.format("Tried to delete Sone of non-own identity: %s", sone)); return; } synchronized (localSones) { if (!localSones.containsKey(sone.getId())) { - logger.log(Level.WARNING, "Tried to delete non-local Sone: %s", sone); + logger.log(Level.WARNING, String.format("Tried to delete non-local Sone: %s", sone)); return; } localSones.remove(sone.getId()); @@ -1279,12 +1268,8 @@ public class Core extends AbstractService implements IdentityListener, UpdateLis soneInserter.removeSoneInsertListener(this); soneInserter.stop(); } - try { - ((OwnIdentity) sone.getIdentity()).removeContext("Sone"); - ((OwnIdentity) sone.getIdentity()).removeProperty("Sone.LatestEdition"); - } catch (WebOfTrustException wote1) { - logger.log(Level.WARNING, "Could not remove context and properties from Sone: " + sone, wote1); - } + webOfTrustUpdater.removeContext((OwnIdentity) sone.getIdentity(), "Sone"); + webOfTrustUpdater.removeProperty((OwnIdentity) sone.getIdentity(), "Sone.LatestEdition"); try { configuration.getLongValue("Sone/" + sone.getId() + "/Time").setValue(null); } catch (ConfigurationException ce1) { @@ -1319,7 +1304,7 @@ public class Core extends AbstractService implements IdentityListener, UpdateLis */ public void loadSone(Sone sone) { if (!isLocalSone(sone)) { - logger.log(Level.FINE, "Tried to load non-local Sone: %s", sone); + logger.log(Level.FINE, String.format("Tried to load non-local Sone: %s", sone)); return; } @@ -1451,7 +1436,7 @@ public class Core extends AbstractService implements IdentityListener, UpdateLis if (albumParentId != null) { Album parentAlbum = getAlbum(albumParentId, false); if (parentAlbum == null) { - logger.log(Level.WARNING, "Invalid parent album ID: " + albumParentId); + logger.log(Level.WARNING, String.format("Invalid parent album ID: %s", albumParentId)); return; } parentAlbum.addAlbum(album); @@ -1596,10 +1581,10 @@ public class Core extends AbstractService implements IdentityListener, UpdateLis */ public Post createPost(Sone sone, Sone recipient, long time, String text) { if (!isLocalSone(sone)) { - logger.log(Level.FINE, "Tried to create post for non-local Sone: %s", sone); + logger.log(Level.FINE, String.format("Tried to create post for non-local Sone: %s", sone)); return null; } - final Post post = new Post(sone, time, text); + final Post post = new PostImpl(sone, time, text); if (recipient != null) { post.setRecipient(recipient); } @@ -1630,7 +1615,7 @@ public class Core extends AbstractService implements IdentityListener, UpdateLis */ public void deletePost(Post post) { if (!isLocalSone(post.getSone())) { - logger.log(Level.WARNING, "Tried to delete post of non-local Sone: %s", post.getSone()); + logger.log(Level.WARNING, String.format("Tried to delete post of non-local Sone: %s", post.getSone())); return; } post.getSone().removePost(post); @@ -1736,7 +1721,7 @@ public class Core extends AbstractService implements IdentityListener, UpdateLis */ public PostReply createReply(Sone sone, Post post, long time, String text) { if (!isLocalSone(sone)) { - logger.log(Level.FINE, "Tried to create reply for non-local Sone: %s", sone); + logger.log(Level.FINE, String.format("Tried to create reply for non-local Sone: %s", sone)); return null; } final PostReply reply = new PostReply(sone, post, System.currentTimeMillis(), text); @@ -1770,7 +1755,7 @@ public class Core extends AbstractService implements IdentityListener, UpdateLis public void deleteReply(PostReply reply) { Sone sone = reply.getSone(); if (!isLocalSone(sone)) { - logger.log(Level.FINE, "Tried to delete non-local reply: %s", reply); + logger.log(Level.FINE, String.format("Tried to delete non-local reply: %s", reply)); return; } synchronized (replies) { @@ -1856,7 +1841,7 @@ public class Core extends AbstractService implements IdentityListener, UpdateLis synchronized (albums) { albums.remove(album.getId()); } - saveSone(album.getSone()); + touchConfiguration(); } /** @@ -1896,7 +1881,7 @@ public class Core extends AbstractService implements IdentityListener, UpdateLis synchronized (images) { images.remove(image.getId()); } - saveSone(image.getSone()); + touchConfiguration(); } /** @@ -1966,6 +1951,7 @@ public class Core extends AbstractService implements IdentityListener, UpdateLis loadConfiguration(); updateChecker.addUpdateListener(this); updateChecker.start(); + webOfTrustUpdater.start(); } /** @@ -1993,11 +1979,14 @@ public class Core extends AbstractService implements IdentityListener, UpdateLis @Override public void serviceStop() { synchronized (localSones) { - for (SoneInserter soneInserter : soneInserters.values()) { - soneInserter.removeSoneInsertListener(this); - soneInserter.stop(); + for (Entry soneInserter : soneInserters.entrySet()) { + soneInserter.getValue().removeSoneInsertListener(this); + soneInserter.getValue().stop(); + saveSone(soneInserter.getKey()); } } + saveConfiguration(); + webOfTrustUpdater.stop(); updateChecker.stop(); updateChecker.removeUpdateListener(this); soneDownloader.stop(); @@ -2016,15 +2005,15 @@ public class Core extends AbstractService implements IdentityListener, UpdateLis */ private synchronized void saveSone(Sone sone) { if (!isLocalSone(sone)) { - logger.log(Level.FINE, "Tried to save non-local Sone: %s", sone); + logger.log(Level.FINE, String.format("Tried to save non-local Sone: %s", sone)); return; } if (!(sone.getIdentity() instanceof OwnIdentity)) { - logger.log(Level.WARNING, "Local Sone without OwnIdentity found, refusing to save: %s", sone); + logger.log(Level.WARNING, String.format("Local Sone without OwnIdentity found, refusing to save: %s", sone)); return; } - logger.log(Level.INFO, "Saving Sone: %s", sone); + logger.log(Level.INFO, String.format("Saving Sone: %s", sone)); try { /* save Sone into configuration. */ String sonePrefix = "Sone/" + sone.getId(); @@ -2137,13 +2126,11 @@ public class Core extends AbstractService implements IdentityListener, UpdateLis configuration.save(); - ((OwnIdentity) sone.getIdentity()).setProperty("Sone.LatestEdition", String.valueOf(sone.getLatestEdition())); + webOfTrustUpdater.setProperty((OwnIdentity) sone.getIdentity(), "Sone.LatestEdition", String.valueOf(sone.getLatestEdition())); - logger.log(Level.INFO, "Sone %s saved.", sone); + logger.log(Level.INFO, String.format("Sone %s saved.", sone)); } catch (ConfigurationException ce1) { - logger.log(Level.WARNING, "Could not save Sone: " + sone, ce1); - } catch (WebOfTrustException wote1) { - logger.log(Level.WARNING, "Could not set WoT property for Sone: " + sone, wote1); + logger.log(Level.WARNING, String.format("Could not save Sone: %s", sone), ce1); } } @@ -2164,6 +2151,7 @@ public class Core extends AbstractService implements IdentityListener, UpdateLis configuration.getIntValue("Option/ConfigurationVersion").setValue(0); configuration.getIntValue("Option/InsertionDelay").setValue(options.getIntegerOption("InsertionDelay").getReal()); configuration.getIntValue("Option/PostsPerPage").setValue(options.getIntegerOption("PostsPerPage").getReal()); + configuration.getIntValue("Option/ImagesPerPage").setValue(options.getIntegerOption("ImagesPerPage").getReal()); configuration.getIntValue("Option/CharactersPerPost").setValue(options.getIntegerOption("CharactersPerPost").getReal()); configuration.getIntValue("Option/PostCutOffLength").setValue(options.getIntegerOption("PostCutOffLength").getReal()); configuration.getBooleanValue("Option/RequireFullAccess").setValue(options.getBooleanOption("RequireFullAccess").getReal()); @@ -2172,9 +2160,6 @@ public class Core extends AbstractService implements IdentityListener, UpdateLis configuration.getStringValue("Option/TrustComment").setValue(options.getStringOption("TrustComment").getReal()); configuration.getBooleanValue("Option/ActivateFcpInterface").setValue(options.getBooleanOption("ActivateFcpInterface").getReal()); configuration.getIntValue("Option/FcpFullAccessRequired").setValue(options.getIntegerOption("FcpFullAccessRequired").getReal()); - configuration.getBooleanValue("Option/SoneRescueMode").setValue(options.getBooleanOption("SoneRescueMode").getReal()); - configuration.getBooleanValue("Option/ClearOnNextRestart").setValue(options.getBooleanOption("ClearOnNextRestart").getReal()); - configuration.getBooleanValue("Option/ReallyClearOnNextRestart").setValue(options.getBooleanOption("ReallyClearOnNextRestart").getReal()); /* save known Sones. */ int soneCounter = 0; @@ -2250,6 +2235,7 @@ public class Core extends AbstractService implements IdentityListener, UpdateLis })); options.addIntegerOption("PostsPerPage", new DefaultOption(10, new IntegerRangeValidator(1, Integer.MAX_VALUE))); + options.addIntegerOption("ImagesPerPage", new DefaultOption(9, new IntegerRangeValidator(1, Integer.MAX_VALUE))); options.addIntegerOption("CharactersPerPost", new DefaultOption(400, new OrValidator(new IntegerRangeValidator(50, Integer.MAX_VALUE), new EqualityValidator(-1)))); options.addIntegerOption("PostCutOffLength", new DefaultOption(200, new OrValidator(new IntegerRangeValidator(50, Integer.MAX_VALUE), new EqualityValidator(-1)))); options.addBooleanOption("RequireFullAccess", new DefaultOption(false)); @@ -2273,23 +2259,10 @@ public class Core extends AbstractService implements IdentityListener, UpdateLis } })); - options.addBooleanOption("SoneRescueMode", new DefaultOption(false)); - options.addBooleanOption("ClearOnNextRestart", new DefaultOption(false)); - options.addBooleanOption("ReallyClearOnNextRestart", new DefaultOption(false)); - - /* read options from configuration. */ - options.getBooleanOption("ClearOnNextRestart").set(configuration.getBooleanValue("Option/ClearOnNextRestart").getValue(null)); - options.getBooleanOption("ReallyClearOnNextRestart").set(configuration.getBooleanValue("Option/ReallyClearOnNextRestart").getValue(null)); - boolean clearConfiguration = options.getBooleanOption("ClearOnNextRestart").get() && options.getBooleanOption("ReallyClearOnNextRestart").get(); - options.getBooleanOption("ClearOnNextRestart").set(null); - options.getBooleanOption("ReallyClearOnNextRestart").set(null); - if (clearConfiguration) { - /* stop loading the configuration. */ - return; - } loadConfigurationValue("InsertionDelay"); loadConfigurationValue("PostsPerPage"); + loadConfigurationValue("ImagesPerPage"); loadConfigurationValue("CharactersPerPost"); loadConfigurationValue("PostCutOffLength"); options.getBooleanOption("RequireFullAccess").set(configuration.getBooleanValue("Option/RequireFullAccess").getValue(null)); @@ -2298,7 +2271,6 @@ public class Core extends AbstractService implements IdentityListener, UpdateLis options.getStringOption("TrustComment").set(configuration.getStringValue("Option/TrustComment").getValue(null)); options.getBooleanOption("ActivateFcpInterface").set(configuration.getBooleanValue("Option/ActivateFcpInterface").getValue(null)); options.getIntegerOption("FcpFullAccessRequired").set(configuration.getIntValue("Option/FcpFullAccessRequired").getValue(null)); - options.getBooleanOption("SoneRescueMode").set(configuration.getBooleanValue("Option/SoneRescueMode").getValue(null)); /* load known Sones. */ int soneCounter = 0; @@ -2380,7 +2352,7 @@ public class Core extends AbstractService implements IdentityListener, UpdateLis try { options.getIntegerOption(optionName).set(configuration.getIntValue("Option/" + optionName).getValue(null)); } catch (IllegalArgumentException iae1) { - logger.log(Level.WARNING, "Invalid value for " + optionName + " in configuration, using default."); + logger.log(Level.WARNING, String.format("Invalid value for %s in configuration, using default.", optionName)); } } @@ -2391,12 +2363,12 @@ public class Core extends AbstractService implements IdentityListener, UpdateLis * The URI to derive the Sone URI from * @return The derived URI */ - private FreenetURI getSoneUri(String uriString) { + private static FreenetURI getSoneUri(String uriString) { try { FreenetURI uri = new FreenetURI(uriString).setDocName("Sone").setMetaString(new String[0]); return uri; } catch (MalformedURLException mue1) { - logger.log(Level.WARNING, "Could not create Sone URI from URI: " + uriString, mue1); + logger.log(Level.WARNING, String.format("Could not create Sone URI from URI: %s", uriString), mue1); return null; } } @@ -2410,7 +2382,7 @@ public class Core extends AbstractService implements IdentityListener, UpdateLis */ @Override public void ownIdentityAdded(OwnIdentity ownIdentity) { - logger.log(Level.FINEST, "Adding OwnIdentity: " + ownIdentity); + logger.log(Level.FINEST, String.format("Adding OwnIdentity: %s", ownIdentity)); if (ownIdentity.hasContext("Sone")) { trustedIdentities.put(ownIdentity, Collections.synchronizedSet(new HashSet())); addLocalSone(ownIdentity); @@ -2422,7 +2394,7 @@ public class Core extends AbstractService implements IdentityListener, UpdateLis */ @Override public void ownIdentityRemoved(OwnIdentity ownIdentity) { - logger.log(Level.FINEST, "Removing OwnIdentity: " + ownIdentity); + logger.log(Level.FINEST, String.format("Removing OwnIdentity: %s", ownIdentity)); trustedIdentities.remove(ownIdentity); } @@ -2431,7 +2403,7 @@ public class Core extends AbstractService implements IdentityListener, UpdateLis */ @Override public void identityAdded(OwnIdentity ownIdentity, Identity identity) { - logger.log(Level.FINEST, "Adding Identity: " + identity); + logger.log(Level.FINEST, String.format("Adding Identity: %s", identity)); trustedIdentities.get(ownIdentity).add(identity); addRemoteSone(identity); } @@ -2441,7 +2413,7 @@ public class Core extends AbstractService implements IdentityListener, UpdateLis */ @Override public void identityUpdated(OwnIdentity ownIdentity, final Identity identity) { - new Thread(new Runnable() { + soneDownloaders.execute(new Runnable() { @Override @SuppressWarnings("synthetic-access") @@ -2452,7 +2424,7 @@ public class Core extends AbstractService implements IdentityListener, UpdateLis soneDownloader.addSone(sone); soneDownloader.fetchSone(sone); } - }).start(); + }); } /** @@ -2550,7 +2522,7 @@ public class Core extends AbstractService implements IdentityListener, UpdateLis */ @Override public void imageInsertStarted(Image image) { - logger.log(Level.WARNING, "Image insert started for " + image); + logger.log(Level.WARNING, String.format("Image insert started for %s...", image)); coreListenerManager.fireImageInsertStarted(image); } @@ -2559,7 +2531,7 @@ public class Core extends AbstractService implements IdentityListener, UpdateLis */ @Override public void imageInsertAborted(Image image) { - logger.log(Level.WARNING, "Image insert aborted for " + image); + logger.log(Level.WARNING, String.format("Image insert aborted for %s.", image)); coreListenerManager.fireImageInsertAborted(image); } @@ -2568,10 +2540,10 @@ public class Core extends AbstractService implements IdentityListener, UpdateLis */ @Override public void imageInsertFinished(Image image, FreenetURI key) { - logger.log(Level.WARNING, "Image insert finished for " + image + ": " + key); + logger.log(Level.WARNING, String.format("Image insert finished for %s: %s", image, key)); image.setKey(key.toString()); deleteTemporaryImage(image.getId()); - saveSone(image.getSone()); + touchConfiguration(); coreListenerManager.fireImageInsertFinished(image); } @@ -2580,7 +2552,7 @@ public class Core extends AbstractService implements IdentityListener, UpdateLis */ @Override public void imageInsertFailed(Image image, Throwable cause) { - logger.log(Level.WARNING, "Image insert failed for " + image, cause); + logger.log(Level.WARNING, String.format("Image insert failed for %s." + image), cause); coreListenerManager.fireImageInsertFailed(image, cause); } @@ -2673,6 +2645,39 @@ public class Core extends AbstractService implements IdentityListener, UpdateLis } /** + * Returns the number of images to show per page. + * + * @return The number of images to show per page + */ + public int getImagesPerPage() { + return options.getIntegerOption("ImagesPerPage").get(); + } + + /** + * Validates the number of images per page. + * + * @param imagesPerPage + * The number of images per page + * @return {@code true} if the number of images per page was valid, + * {@code false} otherwise + */ + public boolean validateImagesPerPage(Integer imagesPerPage) { + return options.getIntegerOption("ImagesPerPage").validate(imagesPerPage); + } + + /** + * Sets the number of images per page. + * + * @param imagesPerPage + * The number of images per page + * @return This preferences object + */ + public Preferences setImagesPerPage(Integer imagesPerPage) { + options.getIntegerOption("ImagesPerPage").set(imagesPerPage); + return this; + } + + /** * Returns the number of characters per post, or -1 if the * posts should not be cut off. * @@ -2903,58 +2908,6 @@ public class Core extends AbstractService implements IdentityListener, UpdateLis return this; } - /** - * Returns whether Sone should clear its settings on the next restart. - * In order to be effective, {@link #isReallyClearOnNextRestart()} needs - * to return {@code true} as well! - * - * @return {@code true} if Sone should clear its settings on the next - * restart, {@code false} otherwise - */ - public boolean isClearOnNextRestart() { - return options.getBooleanOption("ClearOnNextRestart").get(); - } - - /** - * Sets whether Sone will clear its settings on the next restart. - * - * @param clearOnNextRestart - * {@code true} if Sone should clear its settings on the next - * restart, {@code false} otherwise - * @return This preferences - */ - public Preferences setClearOnNextRestart(Boolean clearOnNextRestart) { - options.getBooleanOption("ClearOnNextRestart").set(clearOnNextRestart); - return this; - } - - /** - * Returns whether Sone should really clear its settings on next - * restart. This is a confirmation option that needs to be set in - * addition to {@link #isClearOnNextRestart()} in order to clear Sone’s - * settings on the next restart. - * - * @return {@code true} if Sone should really clear its settings on the - * next restart, {@code false} otherwise - */ - public boolean isReallyClearOnNextRestart() { - return options.getBooleanOption("ReallyClearOnNextRestart").get(); - } - - /** - * Sets whether Sone should really clear its settings on the next - * restart. - * - * @param reallyClearOnNextRestart - * {@code true} if Sone should really clear its settings on - * the next restart, {@code false} otherwise - * @return This preferences - */ - public Preferences setReallyClearOnNextRestart(Boolean reallyClearOnNextRestart) { - options.getBooleanOption("ReallyClearOnNextRestart").set(reallyClearOnNextRestart); - return this; - } - } }