2 * Sone - WebOfTrustUpdater.java - Copyright © 2012 David Roden
4 * This program is free software: you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation, either version 3 of the License, or
7 * (at your option) any later version.
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
14 * You should have received a copy of the GNU General Public License
15 * along with this program. If not, see <http://www.gnu.org/licenses/>.
18 package net.pterodactylus.sone.core;
20 import java.util.concurrent.BlockingQueue;
21 import java.util.concurrent.LinkedBlockingQueue;
22 import java.util.logging.Level;
23 import java.util.logging.Logger;
25 import net.pterodactylus.sone.freenet.plugin.PluginException;
26 import net.pterodactylus.sone.freenet.wot.DefaultIdentity;
27 import net.pterodactylus.sone.freenet.wot.Identity;
28 import net.pterodactylus.sone.freenet.wot.OwnIdentity;
29 import net.pterodactylus.sone.freenet.wot.Trust;
30 import net.pterodactylus.sone.freenet.wot.WebOfTrustConnector;
31 import net.pterodactylus.sone.freenet.wot.WebOfTrustException;
32 import net.pterodactylus.util.logging.Logging;
33 import net.pterodactylus.util.service.AbstractService;
36 * Updates WebOfTrust identity data in a background thread because communicating
37 * with the WebOfTrust plugin can potentially last quite long.
39 * @author <a href="mailto:bombe@pterodactylus.net">David ‘Bombe’ Roden</a>
41 public class WebOfTrustUpdater extends AbstractService {
44 private static final Logger logger = Logging.getLogger(WebOfTrustUpdater.class);
47 @SuppressWarnings("synthetic-access")
48 private final WebOfTrustUpdateJob stopJob = new WebOfTrustUpdateJob();
50 /** The web of trust connector. */
51 private final WebOfTrustConnector webOfTrustConnector;
53 /** The queue for jobs. */
54 private final BlockingQueue<WebOfTrustUpdateJob> updateJobs = new LinkedBlockingQueue<WebOfTrustUpdateJob>();
57 * Creates a new trust updater.
59 * @param webOfTrustConnector
60 * The web of trust connector
62 public WebOfTrustUpdater(WebOfTrustConnector webOfTrustConnector) {
63 super("Trust Updater");
64 this.webOfTrustConnector = webOfTrustConnector;
72 * Retrieves the trust relation between the truster and the trustee. This
73 * method will return immediately and perform a trust update in the
77 * The identity giving the trust
79 * The identity receiving the trust
81 public void getTrust(OwnIdentity truster, Identity trustee) {
82 GetTrustJob getTrustJob = new GetTrustJob(truster, trustee);
83 if (!updateJobs.contains(getTrustJob)) {
84 logger.log(Level.FINER, "Adding Trust Update Job: " + getTrustJob);
86 updateJobs.put(getTrustJob);
87 } catch (InterruptedException ie1) {
88 /* the queue is unbounded so it should never block. */
94 * Updates the trust relation between the truster and the trustee. This
95 * method will return immediately and perform a trust update in the
99 * The identity giving the trust
101 * The identity receiving the trust
103 * The new level of trust (from -100 to 100, may be {@code null}
104 * to remove the trust completely)
106 * The comment of the trust relation
108 public void setTrust(OwnIdentity truster, Identity trustee, Integer score, String comment) {
109 SetTrustJob setTrustJob = new SetTrustJob(truster, trustee, score, comment);
110 if (updateJobs.contains(setTrustJob)) {
111 updateJobs.remove(setTrustJob);
113 logger.log(Level.FINER, "Adding Trust Update Job: " + setTrustJob);
115 updateJobs.put(setTrustJob);
116 } catch (InterruptedException e) {
117 /* the queue is unbounded so it should never block. */
129 protected void serviceRun() {
130 while (!shouldStop()) {
132 WebOfTrustUpdateJob updateJob = updateJobs.take();
133 if (shouldStop() || (updateJob == stopJob)) {
136 logger.log(Level.FINE, "Running Trust Update Job: " + updateJob);
137 long startTime = System.currentTimeMillis();
139 long endTime = System.currentTimeMillis();
140 logger.log(Level.FINE, "Trust Update Job finished, took " + (endTime - startTime) + " ms.");
141 } catch (InterruptedException ie1) {
142 /* happens, ignore, loop. */
151 protected void serviceStop() {
153 updateJobs.put(stopJob);
154 } catch (InterruptedException ie1) {
155 /* the queue is unbounded so it should never block. */
160 * Base class for WebOfTrust update jobs.
162 * @author <a href="mailto:bombe@pterodactylus.net">David ‘Bombe’ Roden</a>
164 private class WebOfTrustUpdateJob {
166 /** Object for synchronization. */
167 @SuppressWarnings("hiding")
168 private final Object syncObject = new Object();
170 /** Whether the job has finished. */
171 private boolean finished;
178 * Performs the actual update operation.
180 * The implementation of this class does nothing.
187 * Waits for completion of this job or stopping of the WebOfTrust
190 * @see WebOfTrustUpdater#stop()
192 @SuppressWarnings("synthetic-access")
193 public void waitForCompletion() {
194 synchronized (syncObject) {
195 while (!finished && !shouldStop()) {
198 } catch (InterruptedException ie1) {
199 /* we’re looping, ignore. */
210 * Signals that this job has finished.
212 protected void finish() {
213 synchronized (syncObject) {
215 syncObject.notifyAll();
222 * Base class for WebOfTrust trust update jobs.
224 * @author <a href="mailto:bombe@pterodactylus.net">David ‘Bombe’ Roden</a>
226 private class WebOfTrustTrustUpdateJob extends WebOfTrustUpdateJob {
228 /** The identity giving the trust. */
229 protected final OwnIdentity truster;
231 /** The identity receiving the trust. */
232 protected final Identity trustee;
235 * Creates a new trust update job.
238 * The identity giving the trust
240 * The identity receiving the trust
242 @SuppressWarnings("synthetic-access")
243 public WebOfTrustTrustUpdateJob(OwnIdentity truster, Identity trustee) {
244 this.truster = truster;
245 this.trustee = trustee;
256 public boolean equals(Object object) {
257 if ((object == null) || !object.getClass().equals(getClass())) {
260 WebOfTrustTrustUpdateJob updateJob = (WebOfTrustTrustUpdateJob) object;
261 return ((truster == null) ? (updateJob.truster == null) : updateJob.truster.equals(truster)) && ((trustee == null) ? (updateJob.trustee == null) : updateJob.trustee.equals(trustee));
268 public int hashCode() {
269 return getClass().hashCode() ^ ((truster == null) ? 0 : truster.hashCode()) ^ ((trustee == null) ? 0 : trustee.hashCode());
276 public String toString() {
277 return String.format("%s[truster=%s,trustee=%s]", getClass().getSimpleName(), (truster == null) ? null : truster.getId(), (trustee == null) ? null : trustee.getId());
283 * Update job that sets the trust relation between two identities.
285 * @author <a href="mailto:bombe@pterodactylus.net">David ‘Bombe’ Roden</a>
287 private class SetTrustJob extends WebOfTrustTrustUpdateJob {
289 /** The score of the relation. */
290 private final Integer score;
292 /** The comment of the relation. */
293 private final String comment;
296 * Creates a new set trust job.
299 * The identity giving the trust
301 * The identity receiving the trust
303 * The score of the trust (from -100 to 100, may be
304 * {@code null} to remote the trust relation completely)
306 * The comment of the trust relation
308 public SetTrustJob(OwnIdentity truster, Identity trustee, Integer score, String comment) {
309 super(truster, trustee);
311 this.comment = comment;
318 @SuppressWarnings("synthetic-access")
322 if (trustee instanceof DefaultIdentity) {
323 ((DefaultIdentity) trustee).setTrust(truster, new Trust(score, null, 0));
325 webOfTrustConnector.setTrust(truster, trustee, score, comment);
327 if (trustee instanceof DefaultIdentity) {
328 ((DefaultIdentity) trustee).setTrust(truster, null);
330 webOfTrustConnector.removeTrust(truster, trustee);
332 } catch (WebOfTrustException wote1) {
333 logger.log(Level.WARNING, "Could not set Trust value for " + truster + " -> " + trustee + " to " + score + " (" + comment + ")!", wote1);
341 * Update job that retrieves the trust relation between two identities.
343 * @author <a href="mailto:bombe@pterodactylus.net">David ‘Bombe’ Roden</a>
345 private class GetTrustJob extends WebOfTrustTrustUpdateJob {
348 * Creates a new trust update job.
351 * The identity giving the trust
353 * The identity receiving the trust
355 public GetTrustJob(OwnIdentity truster, Identity trustee) {
356 super(truster, trustee);
363 @SuppressWarnings("synthetic-access")
366 Trust trust = webOfTrustConnector.getTrust(truster, trustee);
367 if (trustee instanceof DefaultIdentity) {
368 ((DefaultIdentity) trustee).setTrust(truster, trust);
370 } catch (PluginException pe1) {
371 logger.log(Level.WARNING, "Could not get Trust value for " + truster + " -> " + trustee + "!", pe1);