X-Git-Url: https://git.pterodactylus.net/?a=blobdiff_plain;f=src%2Fmain%2Fjava%2Fnet%2Fpterodactylus%2Fsone%2Fcore%2FCore.java;h=ea36aad76bf88c22ff6376495271d050c5133f61;hb=bb2c8cb2d47a77bcef2d299ad4bf8e16f22a6198;hp=20852d292e5de4da98dad3d2cb07098cd89f9ce2;hpb=f69752ddd5a24ee1e56276ca45245954e36c8728;p=Sone.git
diff --git a/src/main/java/net/pterodactylus/sone/core/Core.java b/src/main/java/net/pterodactylus/sone/core/Core.java
index 20852d2..ea36aad 100644
--- a/src/main/java/net/pterodactylus/sone/core/Core.java
+++ b/src/main/java/net/pterodactylus/sone/core/Core.java
@@ -49,15 +49,16 @@ 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.collection.Pair;
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.thread.Ticker;
+import net.pterodactylus.util.validation.EqualityValidator;
import net.pterodactylus.util.validation.IntegerRangeValidator;
+import net.pterodactylus.util.validation.OrValidator;
import net.pterodactylus.util.validation.Validation;
import net.pterodactylus.util.version.Version;
-import freenet.client.FetchResult;
import freenet.keys.FreenetURI;
/**
@@ -65,7 +66,7 @@ import freenet.keys.FreenetURI;
*
* @author David âBombeâ Roden
*/
-public class Core implements IdentityListener, UpdateListener {
+public class Core implements IdentityListener, UpdateListener, SoneProvider, PostProvider {
/**
* Enumeration for the possible states of a {@link Sone}.
@@ -124,6 +125,7 @@ public class Core implements IdentityListener, UpdateListener {
private volatile FcpInterface fcpInterface;
/** Whether the core has been stopped. */
+ @SuppressWarnings("unused")
private volatile boolean stopped;
/** The Sonesâ statuses. */
@@ -138,6 +140,10 @@ public class Core implements IdentityListener, UpdateListener {
/* synchronize access on this on localSones. */
private final Map soneInserters = new HashMap();
+ /** Sone rescuers. */
+ /* synchronize access on this on localSones. */
+ private final Map soneRescuers = new HashMap();
+
/** All local Sones. */
/* synchronize access on this on itself. */
private Map localSones = new HashMap();
@@ -179,6 +185,9 @@ public class Core implements IdentityListener, UpdateListener {
/** Trusted identities, sorted by own identities. */
private Map> trustedIdentities = Collections.synchronizedMap(new HashMap>());
+ /** Ticker for threads that mark own elements as known. */
+ private Ticker localElementTicker = new Ticker();
+
/**
* Creates a new core.
*
@@ -302,6 +311,26 @@ public class Core implements IdentityListener, UpdateListener {
}
/**
+ * Returns the Sone rescuer for the given local Sone.
+ *
+ * @param sone
+ * The local Sone to get the rescuer for
+ * @return The Sone rescuer for the given Sone
+ */
+ public SoneRescuer getSoneRescuer(Sone sone) {
+ Validation.begin().isNotNull("Sone", sone).check().is("Local Sone", isLocalSone(sone)).check();
+ synchronized (localSones) {
+ SoneRescuer soneRescuer = soneRescuers.get(sone);
+ if (soneRescuer == null) {
+ soneRescuer = new SoneRescuer(this, soneDownloader, sone);
+ soneRescuers.put(sone, soneRescuer);
+ soneRescuer.start();
+ }
+ return soneRescuer;
+ }
+ }
+
+ /**
* Returns whether the given Sone is currently locked.
*
* @param sone
@@ -352,6 +381,7 @@ public class Core implements IdentityListener, UpdateListener {
* @return The Sone with the given ID, or {@code null} if there is no such
* Sone
*/
+ @Override
public Sone getSone(String id, boolean create) {
if (isLocalSone(id)) {
return getLocalSone(id);
@@ -574,6 +604,7 @@ public class Core implements IdentityListener, UpdateListener {
* exists, {@code false} to return {@code null}
* @return The post, or {@code null} if there is no such post
*/
+ @Override
public Post getPost(String postId, boolean create) {
synchronized (posts) {
Post post = posts.get(postId);
@@ -854,41 +885,7 @@ public class Core implements IdentityListener, UpdateListener {
soneInserters.put(sone, soneInserter);
setSoneStatus(sone, SoneStatus.idle);
loadSone(sone);
- if (!preferences.isSoneRescueMode()) {
- soneInserter.start();
- }
- new Thread(new Runnable() {
-
- @Override
- @SuppressWarnings("synthetic-access")
- public void run() {
- if (!preferences.isSoneRescueMode()) {
- return;
- }
- logger.log(Level.INFO, "Trying to restore Sone from Freenetâ¦");
- coreListenerManager.fireRescuingSone(sone);
- lockSone(sone);
- long edition = sone.getLatestEdition();
- /* find the latest edition the node knows about. */
- Pair currentUri = freenetInterface.fetchUri(sone.getRequestUri());
- if (currentUri != null) {
- long currentEdition = currentUri.getLeft().getEdition();
- if (currentEdition > edition) {
- edition = currentEdition;
- }
- }
- while (!stopped && (edition >= 0) && preferences.isSoneRescueMode()) {
- logger.log(Level.FINE, "Downloading edition " + edition + "â¦");
- soneDownloader.fetchSone(sone, sone.getRequestUri().setKeyType("SSK").setDocName("Sone-" + edition));
- --edition;
- }
- logger.log(Level.INFO, "Finished restoring Sone from Freenet, starting Inserterâ¦");
- saveSone(sone);
- coreListenerManager.fireRescuedSone(sone);
- soneInserter.start();
- }
-
- }, "Sone Downloader").start();
+ soneInserter.start();
return sone;
}
}
@@ -1056,14 +1053,28 @@ public class Core implements IdentityListener, UpdateListener {
}
/**
- * Updates the stores Sone with the given Sone.
+ * Updates the stored Sone with the given Sone.
*
* @param sone
* The updated Sone
*/
public void updateSone(Sone sone) {
+ updateSone(sone, false);
+ }
+
+ /**
+ * Updates the stored Sone with the given Sone. If {@code soneRescueMode} is
+ * {@code true}, an older Sone than the current Sone can be given to restore
+ * an old state.
+ *
+ * @param sone
+ * The Sone to update
+ * @param soneRescueMode
+ * {@code true} if the stored Sone should be updated regardless
+ * of the age of the given Sone
+ */
+ public void updateSone(Sone sone, boolean soneRescueMode) {
if (hasSone(sone.getId())) {
- boolean soneRescueMode = isLocalSone(sone) && preferences.isSoneRescueMode();
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 });
@@ -1500,7 +1511,7 @@ public class Core implements IdentityListener, UpdateListener {
logger.log(Level.FINE, "Tried to create post for non-local Sone: %s", sone);
return null;
}
- Post post = new Post(sone, time, text);
+ final Post post = new Post(sone, time, text);
if (recipient != null) {
post.setRecipient(recipient);
}
@@ -1513,6 +1524,16 @@ public class Core implements IdentityListener, UpdateListener {
}
sone.addPost(post);
saveSone(sone);
+ localElementTicker.registerEvent(System.currentTimeMillis() + 10 * 1000, new Runnable() {
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public void run() {
+ markPostKnown(post);
+ }
+ }, "Mark " + post + " read.");
return post;
}
@@ -1633,7 +1654,7 @@ public class Core implements IdentityListener, UpdateListener {
logger.log(Level.FINE, "Tried to create reply for non-local Sone: %s", sone);
return null;
}
- Reply reply = new Reply(sone, post, System.currentTimeMillis(), text);
+ final Reply reply = new Reply(sone, post, System.currentTimeMillis(), text);
synchronized (replies) {
replies.put(reply.getId(), reply);
}
@@ -1643,6 +1664,16 @@ public class Core implements IdentityListener, UpdateListener {
}
sone.addReply(reply);
saveSone(sone);
+ localElementTicker.registerEvent(System.currentTimeMillis() + 10 * 1000, new Runnable() {
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public void run() {
+ markReplyKnown(reply);
+ }
+ }, "Mark " + reply + " read.");
return reply;
}
@@ -1731,6 +1762,7 @@ public class Core implements IdentityListener, UpdateListener {
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/CharactersPerPost").setValue(options.getIntegerOption("CharactersPerPost").getReal());
configuration.getBooleanValue("Option/RequireFullAccess").setValue(options.getBooleanOption("RequireFullAccess").getReal());
configuration.getIntValue("Option/PositiveTrust").setValue(options.getIntegerOption("PositiveTrust").getReal());
configuration.getIntValue("Option/NegativeTrust").setValue(options.getIntegerOption("NegativeTrust").getReal());
@@ -1808,6 +1840,7 @@ public class Core implements IdentityListener, UpdateListener {
}));
options.addIntegerOption("PostsPerPage", new DefaultOption(10, new IntegerRangeValidator(1, Integer.MAX_VALUE)));
+ options.addIntegerOption("CharactersPerPost", new DefaultOption(200, new OrValidator(new IntegerRangeValidator(50, Integer.MAX_VALUE), new EqualityValidator(-1))));
options.addBooleanOption("RequireFullAccess", new DefaultOption(false));
options.addIntegerOption("PositiveTrust", new DefaultOption(75, new IntegerRangeValidator(0, 100)));
options.addIntegerOption("NegativeTrust", new DefaultOption(-25, new IntegerRangeValidator(-100, 100)));
@@ -1846,6 +1879,7 @@ public class Core implements IdentityListener, UpdateListener {
loadConfigurationValue("InsertionDelay");
loadConfigurationValue("PostsPerPage");
+ loadConfigurationValue("CharactersPerPost");
options.getBooleanOption("RequireFullAccess").set(configuration.getBooleanValue("Option/RequireFullAccess").getValue(null));
loadConfigurationValue("PositiveTrust");
loadConfigurationValue("NegativeTrust");
@@ -2037,6 +2071,7 @@ public class Core implements IdentityListener, UpdateListener {
}
synchronized (newSones) {
newSones.remove(identity.getId());
+ coreListenerManager.fireSoneRemoved(sone);
}
}
@@ -2141,6 +2176,41 @@ public class Core implements IdentityListener, UpdateListener {
}
/**
+ * Returns the number of characters per post, or -1
if the
+ * posts should not be cut off.
+ *
+ * @return The numbers of characters per post
+ */
+ public int getCharactersPerPost() {
+ return options.getIntegerOption("CharactersPerPost").get();
+ }
+
+ /**
+ * Validates the number of characters per post.
+ *
+ * @param charactersPerPost
+ * The number of characters per post
+ * @return {@code true} if the number of characters per post was valid,
+ * {@code false} otherwise
+ */
+ public boolean validateCharactersPerPost(Integer charactersPerPost) {
+ return options.getIntegerOption("CharactersPerPost").validate(charactersPerPost);
+ }
+
+ /**
+ * Sets the number of characters per post.
+ *
+ * @param charactersPerPost
+ * The number of characters per post, or -1
to
+ * not cut off the posts
+ * @return This preferences objects
+ */
+ public Preferences setCharactersPerPost(Integer charactersPerPost) {
+ options.getIntegerOption("CharactersPerPost").set(charactersPerPost);
+ return this;
+ }
+
+ /**
* Returns whether Sone requires full access to be even visible.
*
* @return {@code true} if Sone requires full access, {@code false}
@@ -2304,29 +2374,6 @@ public class Core implements IdentityListener, UpdateListener {
}
/**
- * Returns whether the rescue mode is active.
- *
- * @return {@code true} if the rescue mode is active, {@code false}
- * otherwise
- */
- public boolean isSoneRescueMode() {
- return options.getBooleanOption("SoneRescueMode").get();
- }
-
- /**
- * Sets whether the rescue mode is active.
- *
- * @param soneRescueMode
- * {@code true} if the rescue mode is active, {@code false}
- * otherwise
- * @return This preferences
- */
- public Preferences setSoneRescueMode(Boolean soneRescueMode) {
- options.getBooleanOption("SoneRescueMode").set(soneRescueMode);
- 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!