X-Git-Url: https://git.pterodactylus.net/?p=Sone.git;a=blobdiff_plain;f=src%2Fmain%2Fjava%2Fnet%2Fpterodactylus%2Fsone%2Fcore%2FCore.java;h=26d21edae4ad35fb4fea259cde68502d1aaa05c7;hp=b612c740a5a07588546436bf42009e5eba79b980;hb=c9e306ac8e3ada846e87a0cc256a20fc148f381c;hpb=c21a3eda7b784f1c5b39ed12a5ce983d2bf62166 diff --git a/src/main/java/net/pterodactylus/sone/core/Core.java b/src/main/java/net/pterodactylus/sone/core/Core.java index b612c74..26d21ed 100644 --- a/src/main/java/net/pterodactylus/sone/core/Core.java +++ b/src/main/java/net/pterodactylus/sone/core/Core.java @@ -24,8 +24,8 @@ import java.util.HashMap; import java.util.HashSet; import java.util.List; import java.util.Map; -import java.util.Set; import java.util.Map.Entry; +import java.util.Set; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import java.util.logging.Level; @@ -40,10 +40,12 @@ import net.pterodactylus.sone.data.Image; import net.pterodactylus.sone.data.Post; import net.pterodactylus.sone.data.PostReply; 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.TemporaryImage; -import net.pterodactylus.sone.data.Profile.Field; import net.pterodactylus.sone.fcp.FcpInterface; import net.pterodactylus.sone.fcp.FcpInterface.FullAccessRequired; import net.pterodactylus.sone.freenet.wot.Identity; @@ -73,26 +75,6 @@ import freenet.keys.FreenetURI; */ public class Core extends AbstractService implements IdentityListener, UpdateListener, SoneProvider, PostProvider, SoneInsertListener, ImageInsertListener { - /** - * Enumeration for the possible states of a {@link Sone}. - * - * @author David ‘Bombe’ Roden - */ - public enum SoneStatus { - - /** The Sone is unknown, i.e. not yet downloaded. */ - unknown, - - /** The Sone is idle, i.e. not being downloaded or inserted. */ - idle, - - /** The Sone is currently being inserted. */ - inserting, - - /** The Sone is currently being downloaded. */ - downloading, - } - /** The logger. */ private static final Logger logger = Logging.getLogger(Core.class); @@ -132,10 +114,6 @@ public class Core extends AbstractService implements IdentityListener, UpdateLis /** The FCP interface. */ private volatile FcpInterface fcpInterface; - /** The Sones’ statuses. */ - /* synchronize access on itself. */ - private final Map soneStatuses = new HashMap(); - /** The times Sones were followed. */ private final Map soneFollowingTimes = new HashMap(); @@ -159,29 +137,18 @@ public class Core extends AbstractService implements IdentityListener, UpdateLis /* synchronize access on this on itself. */ private Map remoteSones = new HashMap(); - /** All new Sones. */ - private Set newSones = new HashSet(); - /** All known Sones. */ - /* synchronize access on {@link #newSones}. */ private Set knownSones = new HashSet(); /** All posts. */ private Map posts = new HashMap(); - /** All new posts. */ - private Set newPosts = new HashSet(); - /** All known posts. */ - /* synchronize access on {@link #newPosts}. */ private Set knownPosts = new HashSet(); /** All replies. */ private Map replies = new HashMap(); - /** All new replies. */ - private Set newReplies = new HashSet(); - /** All known replies. */ private Set knownReplies = new HashSet(); @@ -305,33 +272,6 @@ public class Core extends AbstractService implements IdentityListener, UpdateLis } /** - * Returns the status of the given Sone. - * - * @param sone - * The Sone to get the status for - * @return The status of the Sone - */ - public SoneStatus getSoneStatus(Sone sone) { - synchronized (soneStatuses) { - return soneStatuses.get(sone); - } - } - - /** - * Sets the status of the given Sone. - * - * @param sone - * The Sone to set the status of - * @param soneStatus - * The status to set - */ - public void setSoneStatus(Sone sone, SoneStatus soneStatus) { - synchronized (soneStatuses) { - soneStatuses.put(sone, soneStatus); - } - } - - /** * Returns the Sone rescuer for the given local Sone. * * @param sone @@ -487,7 +427,6 @@ public class Core extends AbstractService implements IdentityListener, UpdateLis if ((sone == null) && create) { sone = new Sone(id); localSones.put(id, sone); - setSoneStatus(sone, SoneStatus.unknown); } return sone; } @@ -520,7 +459,6 @@ public class Core extends AbstractService implements IdentityListener, UpdateLis if ((sone == null) && create && (id != null) && (id.length() == 43)) { sone = new Sone(id); remoteSones.put(id, sone); - setSoneStatus(sone, SoneStatus.unknown); } return sone; } @@ -555,19 +493,6 @@ public class Core extends AbstractService implements IdentityListener, UpdateLis } /** - * Returns whether the Sone with the given ID is a new Sone. - * - * @param soneId - * The ID of the sone to check for - * @return {@code true} if the given Sone is new, false otherwise - */ - public boolean isNewSone(String soneId) { - synchronized (newSones) { - return !knownSones.contains(soneId) && newSones.contains(soneId); - } - } - - /** * Returns whether the given Sone has been modified. * * @param sone @@ -644,20 +569,6 @@ public class Core extends AbstractService implements IdentityListener, UpdateLis } /** - * Returns whether the given post ID is new. - * - * @param postId - * The post ID - * @return {@code true} if the post is considered to be new, {@code false} - * otherwise - */ - public boolean isNewPost(String postId) { - synchronized (newPosts) { - return !knownPosts.contains(postId) && newPosts.contains(postId); - } - } - - /** * Returns all posts that have the given Sone as recipient. * * @see Post#getRecipient() @@ -735,20 +646,6 @@ public class Core extends AbstractService implements IdentityListener, UpdateLis } /** - * Returns whether the reply with the given ID is new. - * - * @param replyId - * The ID of the reply to check - * @return {@code true} if the reply is considered to be new, {@code false} - * otherwise - */ - public boolean isNewReply(String replyId) { - synchronized (newReplies) { - return !knownReplies.contains(replyId) && newReplies.contains(replyId); - } - } - - /** * Returns all Sones that have liked the given post. * * @param post @@ -961,17 +858,18 @@ 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)); sone.setClient(new Client("Sone", SonePlugin.VERSION.toString())); + sone.setKnown(true); /* TODO - load posts ’n stuff */ localSones.put(ownIdentity.getId(), sone); final SoneInserter soneInserter = new SoneInserter(this, freenetInterface, sone); soneInserter.addSoneInsertListener(this); soneInserters.put(sone, soneInserter); - setSoneStatus(sone, SoneStatus.idle); + sone.setStatus(SoneStatus.idle); loadSone(sone); soneInserter.start(); return sone; @@ -989,7 +887,7 @@ public class Core extends AbstractService implements IdentityListener, UpdateLis try { ownIdentity.addContext("Sone"); } catch (WebOfTrustException wote1) { - logger.log(Level.SEVERE, "Could not add “Sone” context to own identity: " + ownIdentity, wote1); + logger.log(Level.SEVERE, String.format("Could not add “Sone” context to own identity: %s", ownIdentity), wote1); return null; } Sone sone = addLocalSone(ownIdentity); @@ -998,6 +896,8 @@ public class Core extends AbstractService implements IdentityListener, UpdateLis sone.getOptions().addBooleanOption("ShowNotification/NewSones", new DefaultOption(true)); sone.getOptions().addBooleanOption("ShowNotification/NewPosts", new DefaultOption(true)); sone.getOptions().addBooleanOption("ShowNotification/NewReplies", new DefaultOption(true)); + sone.getOptions().addEnumOption("ShowCustomAvatars", new DefaultOption(ShowCustomAvatars.NEVER)); + followSone(sone, getSone("nwa8lHa271k2QvJ8aa0Ov7IHAV-DFOCFgmDt3X6BpCI")); touchConfiguration(); return sone; @@ -1021,12 +921,10 @@ public class Core extends AbstractService implements IdentityListener, UpdateLis sone.setRequestUri(getSoneUri(identity.getRequestUri())); sone.setLatestEdition(Numbers.safeParseLong(identity.getProperty("Sone.LatestEdition"), (long) 0)); if (newSone) { - synchronized (newSones) { + synchronized (knownSones) { newSone = !knownSones.contains(sone.getId()); - if (newSone) { - newSones.add(sone.getId()); - } } + sone.setKnown(!newSone); if (newSone) { coreListenerManager.fireNewSoneFound(sone); for (Sone localSone : getLocalSones()) { @@ -1037,7 +935,6 @@ public class Core extends AbstractService implements IdentityListener, UpdateLis } } soneDownloader.addSone(sone); - setSoneStatus(sone, SoneStatus.unknown); soneDownloaders.execute(new Runnable() { @Override @@ -1061,6 +958,11 @@ public class Core extends AbstractService implements IdentityListener, UpdateLis */ public void followSone(Sone sone, String soneId) { Validation.begin().isNotNull("Sone", sone).isNotNull("Sone ID", soneId).check(); + Sone followedSone = getSone(soneId, true); + if (followedSone == null) { + logger.log(Level.INFO, String.format("Ignored Sone with invalid ID: %s", soneId)); + return; + } followSone(sone, getSone(soneId)); } @@ -1148,7 +1050,7 @@ public class Core extends AbstractService implements IdentityListener, UpdateLis */ public Trust getTrust(Sone origin, Sone target) { if (!isLocalSone(origin)) { - logger.log(Level.WARNING, "Tried to get trust from remote Sone: %s", origin); + logger.log(Level.WARNING, String.format("Tried to get trust from remote Sone: %s", origin)); return null; } return target.getIdentity().getTrust((OwnIdentity) origin.getIdentity()); @@ -1169,7 +1071,7 @@ public class Core extends AbstractService implements IdentityListener, UpdateLis 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); + logger.log(Level.WARNING, String.format("Could not set trust for Sone: %s", target), wote1); } } @@ -1186,7 +1088,7 @@ public class Core extends AbstractService implements IdentityListener, UpdateLis try { ((OwnIdentity) origin.getIdentity()).removeTrust(target.getIdentity()); } catch (WebOfTrustException wote1) { - logger.log(Level.WARNING, "Could not remove trust for Sone: " + target, wote1); + logger.log(Level.WARNING, String.format("Could not remove trust for Sone: %s", target), wote1); } } @@ -1251,7 +1153,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) { @@ -1264,14 +1166,14 @@ public class Core extends AbstractService implements IdentityListener, UpdateLis } } List storedPosts = storedSone.getPosts(); - synchronized (newPosts) { + synchronized (knownPosts) { for (Post post : sone.getPosts()) { - post.setSone(storedSone); + post.setSone(storedSone).setKnown(knownPosts.contains(post.getId())); if (!storedPosts.contains(post)) { if (post.getTime() < getSoneFollowingTime(sone)) { knownPosts.add(post.getId()); } else if (!knownPosts.contains(post.getId())) { - newPosts.add(post.getId()); + sone.setKnown(false); coreListenerManager.fireNewPostFound(post); } } @@ -1289,14 +1191,14 @@ public class Core extends AbstractService implements IdentityListener, UpdateLis } } Set storedReplies = storedSone.getReplies(); - synchronized (newReplies) { + synchronized (knownReplies) { for (PostReply reply : sone.getReplies()) { - reply.setSone(storedSone); + reply.setSone(storedSone).setKnown(knownReplies.contains(reply.getId())); if (!storedReplies.contains(reply)) { if (reply.getTime() < getSoneFollowingTime(sone)) { knownReplies.add(reply.getId()); } else if (!knownReplies.contains(reply.getId())) { - newReplies.add(reply.getId()); + reply.setKnown(false); coreListenerManager.fireNewReplyFound(reply); } } @@ -1364,12 +1266,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()); @@ -1381,7 +1283,7 @@ public class Core extends AbstractService implements IdentityListener, UpdateLis ((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); + logger.log(Level.WARNING, String.format("Could not remove context and properties from Sone: %s", sone), wote1); } try { configuration.getLongValue("Sone/" + sone.getId() + "/Time").setValue(null); @@ -1391,19 +1293,20 @@ public class Core extends AbstractService implements IdentityListener, UpdateLis } /** - * Marks the given Sone as known. If the Sone was {@link #isNewPost(String) - * new} before, a {@link CoreListener#markSoneKnown(Sone)} event is fired. + * Marks the given Sone as known. If the Sone was not {@link Post#isKnown() + * known} before, a {@link CoreListener#markSoneKnown(Sone)} event is fired. * * @param sone * The Sone to mark as known */ public void markSoneKnown(Sone sone) { - synchronized (newSones) { - if (newSones.remove(sone.getId())) { + if (!sone.isKnown()) { + sone.setKnown(true); + synchronized (knownSones) { knownSones.add(sone.getId()); - coreListenerManager.fireMarkSoneKnown(sone); - touchConfiguration(); } + coreListenerManager.fireMarkSoneKnown(sone); + touchConfiguration(); } } @@ -1416,7 +1319,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; } @@ -1426,6 +1329,7 @@ public class Core extends AbstractService implements IdentityListener, UpdateLis sone.getOptions().addBooleanOption("ShowNotification/NewSones", new DefaultOption(true)); sone.getOptions().addBooleanOption("ShowNotification/NewPosts", new DefaultOption(true)); sone.getOptions().addBooleanOption("ShowNotification/NewReplies", new DefaultOption(true)); + sone.getOptions().addEnumOption("ShowCustomAvatars", new DefaultOption(ShowCustomAvatars.NEVER)); /* load Sone. */ String sonePrefix = "Sone/" + sone.getId(); @@ -1437,7 +1341,7 @@ public class Core extends AbstractService implements IdentityListener, UpdateLis String lastInsertFingerprint = configuration.getStringValue(sonePrefix + "/LastInsertFingerprint").getValue(""); /* load profile. */ - Profile profile = new 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)); @@ -1547,7 +1451,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); @@ -1585,12 +1489,19 @@ public class Core extends AbstractService implements IdentityListener, UpdateLis album.addImage(image); } + /* load avatar. */ + String avatarId = configuration.getStringValue(sonePrefix + "/Profile/Avatar").getValue(null); + if (avatarId != null) { + profile.setAvatar(getImage(avatarId, false)); + } + /* load options. */ sone.getOptions().getBooleanOption("AutoFollow").set(configuration.getBooleanValue(sonePrefix + "/Options/AutoFollow").getValue(null)); sone.getOptions().getBooleanOption("EnableSoneInsertNotifications").set(configuration.getBooleanValue(sonePrefix + "/Options/EnableSoneInsertNotifications").getValue(null)); sone.getOptions().getBooleanOption("ShowNotification/NewSones").set(configuration.getBooleanValue(sonePrefix + "/Options/ShowNotification/NewSones").getValue(null)); sone.getOptions().getBooleanOption("ShowNotification/NewPosts").set(configuration.getBooleanValue(sonePrefix + "/Options/ShowNotification/NewPosts").getValue(null)); sone.getOptions().getBooleanOption("ShowNotification/NewReplies").set(configuration.getBooleanValue(sonePrefix + "/Options/ShowNotification/NewReplies").getValue(null)); + sone.getOptions(). getEnumOption("ShowCustomAvatars").set(ShowCustomAvatars.valueOf(configuration.getStringValue(sonePrefix + "/Options/ShowCustomAvatars").getValue(ShowCustomAvatars.NEVER.name()))); /* if we’re still here, Sone was loaded successfully. */ synchronized (sone) { @@ -1606,17 +1517,17 @@ public class Core extends AbstractService implements IdentityListener, UpdateLis sone.setAlbums(topLevelAlbums); soneInserters.get(sone).setLastInsertFingerprint(lastInsertFingerprint); } - synchronized (newSones) { + synchronized (knownSones) { for (String friend : friends) { knownSones.add(friend); } } - synchronized (newPosts) { + synchronized (knownPosts) { for (Post post : posts) { knownPosts.add(post.getId()); } } - synchronized (newReplies) { + synchronized (knownReplies) { for (PostReply reply : replies) { knownReplies.add(reply.getId()); } @@ -1683,7 +1594,7 @@ 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); @@ -1693,10 +1604,7 @@ public class Core extends AbstractService implements IdentityListener, UpdateLis synchronized (posts) { posts.put(post.getId(), post); } - synchronized (newPosts) { - newPosts.add(post.getId()); - coreListenerManager.fireNewPostFound(post); - } + coreListenerManager.fireNewPostFound(post); sone.addPost(post); touchConfiguration(); localElementTicker.registerEvent(System.currentTimeMillis() + 10 * 1000, new Runnable() { @@ -1720,7 +1628,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); @@ -1728,28 +1636,28 @@ public class Core extends AbstractService implements IdentityListener, UpdateLis posts.remove(post.getId()); } coreListenerManager.firePostRemoved(post); - synchronized (newPosts) { - markPostKnown(post); - knownPosts.remove(post.getId()); - } + markPostKnown(post); touchConfiguration(); } /** - * Marks the given post as known, if it is currently a new post (according - * to {@link #isNewPost(String)}). + * Marks the given post as known, if it is currently not a known post + * (according to {@link Post#isKnown()}). * * @param post * The post to mark as known */ public void markPostKnown(Post post) { - synchronized (newPosts) { - if (newPosts.remove(post.getId())) { - knownPosts.add(post.getId()); - coreListenerManager.fireMarkPostKnown(post); + post.setKnown(true); + synchronized (knownPosts) { + coreListenerManager.fireMarkPostKnown(post); + if (knownPosts.add(post.getId())) { touchConfiguration(); } } + for (PostReply reply : getReplies(post)) { + markReplyKnown(reply); + } } /** @@ -1826,15 +1734,14 @@ 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); synchronized (replies) { replies.put(reply.getId(), reply); } - synchronized (newReplies) { - newReplies.add(reply.getId()); + synchronized (knownReplies) { coreListenerManager.fireNewReplyFound(reply); } sone.addReply(reply); @@ -1861,13 +1768,13 @@ 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) { replies.remove(reply.getId()); } - synchronized (newReplies) { + synchronized (knownReplies) { markReplyKnown(reply); knownReplies.remove(reply.getId()); } @@ -1876,17 +1783,17 @@ public class Core extends AbstractService implements IdentityListener, UpdateLis } /** - * Marks the given reply as known, if it is currently a new reply (according - * to {@link #isNewReply(String)}). + * Marks the given reply as known, if it is currently not a known reply + * (according to {@link Reply#isKnown()}). * * @param reply * The reply to mark as known */ public void markReplyKnown(PostReply reply) { - synchronized (newReplies) { - if (newReplies.remove(reply.getId())) { - knownReplies.add(reply.getId()); - coreListenerManager.fireMarkReplyKnown(reply); + reply.setKnown(true); + synchronized (knownReplies) { + coreListenerManager.fireMarkReplyKnown(reply); + if (knownReplies.add(reply.getId())) { touchConfiguration(); } } @@ -2107,15 +2014,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(); @@ -2130,6 +2037,7 @@ public class Core extends AbstractService implements IdentityListener, UpdateLis configuration.getIntValue(sonePrefix + "/Profile/BirthDay").setValue(profile.getBirthDay()); configuration.getIntValue(sonePrefix + "/Profile/BirthMonth").setValue(profile.getBirthMonth()); configuration.getIntValue(sonePrefix + "/Profile/BirthYear").setValue(profile.getBirthYear()); + configuration.getStringValue(sonePrefix + "/Profile/Avatar").setValue(profile.getAvatar()); /* save profile fields. */ int fieldCounter = 0; @@ -2223,16 +2131,17 @@ public class Core extends AbstractService implements IdentityListener, UpdateLis configuration.getBooleanValue(sonePrefix + "/Options/ShowNotification/NewPosts").setValue(sone.getOptions().getBooleanOption("ShowNotification/NewPosts").getReal()); configuration.getBooleanValue(sonePrefix + "/Options/ShowNotification/NewReplies").setValue(sone.getOptions().getBooleanOption("ShowNotification/NewReplies").getReal()); configuration.getBooleanValue(sonePrefix + "/Options/EnableSoneInsertNotifications").setValue(sone.getOptions().getBooleanOption("EnableSoneInsertNotifications").getReal()); + configuration.getStringValue(sonePrefix + "/Options/ShowCustomAvatars").setValue(sone.getOptions(). getEnumOption("ShowCustomAvatars").get().name()); configuration.save(); ((OwnIdentity) sone.getIdentity()).setProperty("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); + logger.log(Level.WARNING, String.format("Could not save Sone: %s", 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 set WoT property for Sone: %s", sone), wote1); } } @@ -2267,7 +2176,7 @@ public class Core extends AbstractService implements IdentityListener, UpdateLis /* save known Sones. */ int soneCounter = 0; - synchronized (newSones) { + synchronized (knownSones) { for (String knownSoneId : knownSones) { configuration.getStringValue("KnownSone/" + soneCounter++ + "/ID").setValue(knownSoneId); } @@ -2287,7 +2196,7 @@ public class Core extends AbstractService implements IdentityListener, UpdateLis /* save known posts. */ int postCounter = 0; - synchronized (newPosts) { + synchronized (knownPosts) { for (String knownPostId : knownPosts) { configuration.getStringValue("KnownPosts/" + postCounter++ + "/ID").setValue(knownPostId); } @@ -2296,7 +2205,7 @@ public class Core extends AbstractService implements IdentityListener, UpdateLis /* save known replies. */ int replyCounter = 0; - synchronized (newReplies) { + synchronized (knownReplies) { for (String knownReplyId : knownReplies) { configuration.getStringValue("KnownReplies/" + replyCounter++ + "/ID").setValue(knownReplyId); } @@ -2396,7 +2305,7 @@ public class Core extends AbstractService implements IdentityListener, UpdateLis if (knownSoneId == null) { break; } - synchronized (newSones) { + synchronized (knownSones) { knownSones.add(knownSoneId); } } @@ -2409,8 +2318,13 @@ public class Core extends AbstractService implements IdentityListener, UpdateLis break; } long time = configuration.getLongValue("SoneFollowingTimes/" + soneCounter + "/Time").getValue(Long.MAX_VALUE); - synchronized (soneFollowingTimes) { - soneFollowingTimes.put(getSone(soneId), time); + Sone followedSone = getSone(soneId); + if (followedSone == null) { + logger.log(Level.WARNING, String.format("Ignoring Sone with invalid ID: %s", soneId)); + } else { + synchronized (soneFollowingTimes) { + soneFollowingTimes.put(getSone(soneId), time); + } } ++soneCounter; } @@ -2422,7 +2336,7 @@ public class Core extends AbstractService implements IdentityListener, UpdateLis if (knownPostId == null) { break; } - synchronized (newPosts) { + synchronized (knownPosts) { knownPosts.add(knownPostId); } } @@ -2434,7 +2348,7 @@ public class Core extends AbstractService implements IdentityListener, UpdateLis if (knownReplyId == null) { break; } - synchronized (newReplies) { + synchronized (knownReplies) { knownReplies.add(knownReplyId); } } @@ -2464,7 +2378,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)); } } @@ -2480,7 +2394,7 @@ public class Core extends AbstractService implements IdentityListener, UpdateLis 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; } } @@ -2494,7 +2408,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); @@ -2506,7 +2420,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); } @@ -2515,7 +2429,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); } @@ -2564,19 +2478,17 @@ public class Core extends AbstractService implements IdentityListener, UpdateLis return; } synchronized (posts) { - synchronized (newPosts) { + synchronized (knownPosts) { for (Post post : sone.getPosts()) { posts.remove(post.getId()); - newPosts.remove(post.getId()); coreListenerManager.firePostRemoved(post); } } } synchronized (replies) { - synchronized (newReplies) { + synchronized (knownReplies) { for (PostReply reply : sone.getReplies()) { replies.remove(reply.getId()); - newReplies.remove(reply.getId()); coreListenerManager.fireReplyRemoved(reply); } } @@ -2584,10 +2496,7 @@ public class Core extends AbstractService implements IdentityListener, UpdateLis synchronized (remoteSones) { remoteSones.remove(identity.getId()); } - synchronized (newSones) { - newSones.remove(identity.getId()); - coreListenerManager.fireSoneRemoved(sone); - } + coreListenerManager.fireSoneRemoved(sone); } // @@ -2639,7 +2548,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); } @@ -2648,7 +2557,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); } @@ -2657,7 +2566,7 @@ 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()); @@ -2669,7 +2578,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); } @@ -2708,8 +2617,8 @@ public class Core extends AbstractService implements IdentityListener, UpdateLis * * @param insertionDelay * The insertion delay to validate - * @return {@code true} if the given insertion delay was valid, {@code - * false} otherwise + * @return {@code true} if the given insertion delay was valid, + * {@code false} otherwise */ public boolean validateInsertionDelay(Integer insertionDelay) { return options.getIntegerOption("InsertionDelay").validate(insertionDelay);