X-Git-Url: https://git.pterodactylus.net/?p=Sone.git;a=blobdiff_plain;f=src%2Fmain%2Fjava%2Fnet%2Fpterodactylus%2Fsone%2Fcore%2FWebOfTrustUpdater.java;h=59abc8e20c86435cc6a930b6ffe3e1dd76d6adc8;hp=5143053f0ffe62bc303d525f671bb67081cd626d;hb=b9887a5b57681169625761cd5a18237f3b8eaf58;hpb=8d5f29fad2c8f6934a41ae5b3a266bcb802c174f diff --git a/src/main/java/net/pterodactylus/sone/core/WebOfTrustUpdater.java b/src/main/java/net/pterodactylus/sone/core/WebOfTrustUpdater.java index 5143053..59abc8e 100644 --- a/src/main/java/net/pterodactylus/sone/core/WebOfTrustUpdater.java +++ b/src/main/java/net/pterodactylus/sone/core/WebOfTrustUpdater.java @@ -31,6 +31,7 @@ import net.pterodactylus.sone.freenet.wot.WebOfTrustConnector; import net.pterodactylus.sone.freenet.wot.WebOfTrustException; import net.pterodactylus.util.logging.Logging; import net.pterodactylus.util.service.AbstractService; +import net.pterodactylus.util.validation.Validation; /** * Updates WebOfTrust identity data in a background thread because communicating @@ -45,7 +46,7 @@ public class WebOfTrustUpdater extends AbstractService { /** Stop job. */ @SuppressWarnings("synthetic-access") - private static final WebOfTrustUpdateJob stopJob = new WebOfTrustUpdateJob(); + private final WebOfTrustUpdateJob stopJob = new WebOfTrustUpdateJob(); /** The web of trust connector. */ private final WebOfTrustConnector webOfTrustConnector; @@ -118,6 +119,70 @@ public class WebOfTrustUpdater extends AbstractService { } } + /** + * Adds the given context to the given own identity. + * + * @param ownIdentity + * The own identity to add the context to + * @param context + * The context to add + */ + public void addContext(OwnIdentity ownIdentity, String context) { + addContextWait(ownIdentity, context, false); + } + + /** + * Adds the given context to the given own identity, waiting for completion + * of the operation. + * + * @param ownIdentity + * The own identity to add the context to + * @param context + * The context to add + * @return {@code true} if the context was added successfully, {@code false} + * otherwise + */ + public boolean addContextWait(OwnIdentity ownIdentity, String context) { + return addContextWait(ownIdentity, context, true); + } + + /** + * Adds the given context to the given own identity, waiting for completion + * of the operation. + * + * @param ownIdentity + * The own identity to add the context to + * @param context + * The context to add + * @param wait + * {@code true} to wait for the end of the operation, + * {@code false} to return immediately + * @return {@code true} if the context was added successfully, {@code false} + * if the context was not added successfully, or if the job should + * not wait for completion + */ + private boolean addContextWait(OwnIdentity ownIdentity, String context, boolean wait) { + AddContextJob addContextJob = new AddContextJob(ownIdentity, context); + if (!updateJobs.contains(addContextJob)) { + logger.log(Level.FINER, "Adding Context Job: " + addContextJob); + try { + updateJobs.put(addContextJob); + } catch (InterruptedException ie1) { + /* the queue is unbounded so it should never block. */ + } + if (wait) { + return addContextJob.waitForCompletion(); + } + } else if (wait) { + for (WebOfTrustUpdateJob updateJob : updateJobs) { + if (updateJob.equals(addContextJob)) { + return updateJob.waitForCompletion(); + } + } + } + return false; + } + // // SERVICE METHODS // @@ -161,7 +226,17 @@ public class WebOfTrustUpdater extends AbstractService { * * @author David ‘Bombe’ Roden */ - private static class WebOfTrustUpdateJob { + private class WebOfTrustUpdateJob { + + /** Object for synchronization. */ + @SuppressWarnings("hiding") + private final Object syncObject = new Object(); + + /** Whether the job has finished. */ + private boolean finished; + + /** Whether the job was successful. */ + private boolean success; // // ACTIONS @@ -176,6 +251,48 @@ public class WebOfTrustUpdater extends AbstractService { /* does nothing. */ } + /** + * Waits for completion of this job or stopping of the WebOfTrust + * updater. + * + * @return {@code true} if this job finished successfully, {@code false} + * otherwise + * + * @see WebOfTrustUpdater#stop() + */ + @SuppressWarnings("synthetic-access") + public boolean waitForCompletion() { + synchronized (syncObject) { + while (!finished && !shouldStop()) { + try { + syncObject.wait(); + } catch (InterruptedException ie1) { + /* we’re looping, ignore. */ + } + } + return success; + } + } + + // + // PROTECTED METHODS + // + + /** + * Signals that this job has finished. + * + * @param success + * {@code true} if this job finished successfully, + * {@code false} otherwise + */ + protected void finish(boolean success) { + synchronized (syncObject) { + finished = true; + this.success = success; + syncObject.notifyAll(); + } + } + } /** @@ -183,7 +300,7 @@ public class WebOfTrustUpdater extends AbstractService { * * @author David ‘Bombe’ Roden */ - private static class WebOfTrustTrustUpdateJob extends WebOfTrustUpdateJob { + private class WebOfTrustTrustUpdateJob extends WebOfTrustUpdateJob { /** The identity giving the trust. */ protected final OwnIdentity truster; @@ -201,7 +318,6 @@ public class WebOfTrustUpdater extends AbstractService { */ @SuppressWarnings("synthetic-access") public WebOfTrustTrustUpdateJob(OwnIdentity truster, Identity trustee) { - super(); this.truster = truster; this.trustee = trustee; } @@ -290,8 +406,10 @@ public class WebOfTrustUpdater extends AbstractService { } webOfTrustConnector.removeTrust(truster, trustee); } + finish(true); } catch (WebOfTrustException wote1) { logger.log(Level.WARNING, "Could not set Trust value for " + truster + " -> " + trustee + " to " + score + " (" + comment + ")!", wote1); + finish(false); } } @@ -327,10 +445,112 @@ public class WebOfTrustUpdater extends AbstractService { if (trustee instanceof DefaultIdentity) { ((DefaultIdentity) trustee).setTrust(truster, trust); } + finish(true); } catch (PluginException pe1) { logger.log(Level.WARNING, "Could not get Trust value for " + truster + " -> " + trustee + "!", pe1); + finish(false); + } + } + + } + + /** + * Base class for context updates of an {@link OwnIdentity}. + * + * @author David ‘Bombe’ Roden + */ + private class WebOfTrustContextUpdateJob extends WebOfTrustUpdateJob { + + /** The own identity whose contexts to manage. */ + protected final OwnIdentity ownIdentity; + + /** The context to update. */ + protected final String context; + + /** + * Creates a new context update job. + * + * @param ownIdentity + * The own identity to update + * @param context + * The context to update + */ + @SuppressWarnings("synthetic-access") + public WebOfTrustContextUpdateJob(OwnIdentity ownIdentity, String context) { + Validation.begin().isNotNull("OwnIdentity", ownIdentity).isNotNull("Context", context).check(); + this.ownIdentity = ownIdentity; + this.context = context; + } + + // + // OBJECT METHODS + // + + /** + * {@inheritDoc} + */ + @Override + public boolean equals(Object object) { + if ((object == null) || !object.getClass().equals(getClass())) { + return false; + } + WebOfTrustContextUpdateJob updateJob = (WebOfTrustContextUpdateJob) object; + return updateJob.ownIdentity.equals(ownIdentity) && updateJob.context.equals(context); + } + + /** + * {@inheritDoc} + */ + @Override + public int hashCode() { + return getClass().hashCode() ^ ownIdentity.hashCode() ^ context.hashCode(); + } + + /** + * {@inheritDoc} + */ + @Override + public String toString() { + return String.format("%s[ownIdentity=%s,context=%s]", getClass().getSimpleName(), ownIdentity, context); + } + + } + + /** + * Job that adds a context to an {@link OwnIdentity}. + * + * @author David ‘Bombe’ Roden + */ + private class AddContextJob extends WebOfTrustContextUpdateJob { + + /** + * Creates a new add-context job. + * + * @param ownIdentity + * The own identity whose contexts to manage + * @param context + * The context to add + */ + public AddContextJob(OwnIdentity ownIdentity, String context) { + super(ownIdentity, context); + } + + /** + * {@inheritDoc} + */ + @Override + @SuppressWarnings("synthetic-access") + public void run() { + try { + webOfTrustConnector.addContext(ownIdentity, context); + ownIdentity.addContext(context); + finish(true); + } catch (PluginException pe1) { + logger.log(Level.WARNING, String.format("Could not add Context “%2$s” to Own Identity %1$s!", ownIdentity, context), pe1); + finish(false); } } + } }