2 * Sone - TrustUpdater.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 identity’s trust in a background thread because getting updates from
37 * the WebOfTrust plugin can potentially last quite long.
39 * @author <a href="mailto:bombe@pterodactylus.net">David ‘Bombe’ Roden</a>
41 public class TrustUpdater extends AbstractService {
44 private static final Logger logger = Logging.getLogger(TrustUpdater.class);
47 private static final TrustUpdateJob stopJob = new TrustUpdateJob(null, null);
49 /** The web of trust connector. */
50 private final WebOfTrustConnector webOfTrustConnector;
52 /** The queue for jobs. */
53 private final BlockingQueue<TrustUpdateJob> updateJobs = new LinkedBlockingQueue<TrustUpdateJob>();
56 * Creates a new trust updater.
58 * @param webOfTrustConnector
59 * The web of trust connector
61 public TrustUpdater(WebOfTrustConnector webOfTrustConnector) {
62 super("Trust Updater");
63 this.webOfTrustConnector = webOfTrustConnector;
71 * Retrieves the trust relation between the truster and the trustee. This
72 * method will return immediately and perform a trust update in the
76 * The identity giving the trust
78 * The identity receiving the trust
80 public void getTrust(OwnIdentity truster, Identity trustee) {
81 GetTrustJob getTrustJob = new GetTrustJob(truster, trustee);
82 if (!updateJobs.contains(getTrustJob)) {
83 logger.log(Level.FINER, "Adding Trust Update Job: " + getTrustJob);
85 updateJobs.put(getTrustJob);
86 } catch (InterruptedException ie1) {
87 /* the queue is unbounded so it should never block. */
93 * Updates the trust relation between the truster and the trustee. This
94 * method will return immediately and perform a trust update in the
98 * The identity giving the trust
100 * The identity receiving the trust
102 * The new level of trust (from -100 to 100, may be {@code null}
103 * to remove the trust completely)
105 * The comment of the trust relation
107 public void setTrust(OwnIdentity truster, Identity trustee, Integer score, String comment) {
108 SetTrustJob setTrustJob = new SetTrustJob(truster, trustee, score, comment);
109 if (updateJobs.contains(setTrustJob)) {
110 updateJobs.remove(setTrustJob);
112 logger.log(Level.FINER, "Adding Trust Update Job: " + setTrustJob);
114 updateJobs.put(setTrustJob);
115 } catch (InterruptedException e) {
116 /* the queue is unbounded so it should never block. */
128 protected void serviceRun() {
129 while (!shouldStop()) {
131 TrustUpdateJob updateJob = updateJobs.take();
132 if (shouldStop() || (updateJob == stopJob)) {
135 logger.log(Level.FINE, "Running Trust Update Job: " + updateJob);
136 long startTime = System.currentTimeMillis();
138 long endTime = System.currentTimeMillis();
139 logger.log(Level.FINE, "Trust Update Job finished, took " + (endTime - startTime) + " ms.");
140 } catch (InterruptedException ie1) {
141 /* happens, ignore, loop. */
150 protected void serviceStop() {
152 updateJobs.put(stopJob);
153 } catch (InterruptedException ie1) {
154 /* the queue is unbounded so it should never block. */
159 * Base class for trust update jobs.
161 * @author <a href="mailto:bombe@pterodactylus.net">David ‘Bombe’ Roden</a>
163 private static class TrustUpdateJob {
165 /** The identity giving the trust. */
166 protected final OwnIdentity truster;
168 /** The identity receiving the trust. */
169 protected final Identity trustee;
172 * Creates a new trust update job.
175 * The identity giving the trust
177 * The identity receiving the trust
179 public TrustUpdateJob(OwnIdentity truster, Identity trustee) {
180 this.truster = truster;
181 this.trustee = trustee;
189 * Performs the actual update operation.
191 * The implementation of this class does nothing.
205 public boolean equals(Object object) {
206 if ((object == null) || !object.getClass().equals(getClass())) {
209 TrustUpdateJob updateJob = (TrustUpdateJob) object;
210 return ((truster == null) ? (updateJob.truster == null) : updateJob.truster.equals(truster)) && ((trustee == null) ? (updateJob.trustee == null) : updateJob.trustee.equals(trustee));
217 public int hashCode() {
218 return getClass().hashCode() ^ ((truster == null) ? 0 : truster.hashCode()) ^ ((trustee == null) ? 0 : trustee.hashCode());
225 public String toString() {
226 return String.format("%s[truster=%s,trustee=%s]", getClass().getSimpleName(), (truster == null) ? null : truster.getId(), (trustee == null) ? null : trustee.getId());
232 * Update job that sets the trust relation between two identities.
234 * @author <a href="mailto:bombe@pterodactylus.net">David ‘Bombe’ Roden</a>
236 private class SetTrustJob extends TrustUpdateJob {
238 /** The score of the relation. */
239 private final Integer score;
241 /** The comment of the relation. */
242 private final String comment;
245 * Creates a new set trust job.
248 * The identity giving the trust
250 * The identity receiving the trust
252 * The score of the trust (from -100 to 100, may be
253 * {@code null} to remote the trust relation completely)
255 * The comment of the trust relation
257 public SetTrustJob(OwnIdentity truster, Identity trustee, Integer score, String comment) {
258 super(truster, trustee);
260 this.comment = comment;
267 @SuppressWarnings("synthetic-access")
271 if (trustee instanceof DefaultIdentity) {
272 ((DefaultIdentity) trustee).setTrust(truster, new Trust(score, null, 0));
274 webOfTrustConnector.setTrust(truster, trustee, score, comment);
276 if (trustee instanceof DefaultIdentity) {
277 ((DefaultIdentity) trustee).setTrust(truster, null);
279 webOfTrustConnector.removeTrust(truster, trustee);
281 } catch (WebOfTrustException wote1) {
282 logger.log(Level.WARNING, "Could not set Trust value for " + truster + " -> " + trustee + " to " + score + " (" + comment + ")!", wote1);
289 * Update job that retrieves the trust relation between two identities.
291 * @author <a href="mailto:bombe@pterodactylus.net">David ‘Bombe’ Roden</a>
293 private class GetTrustJob extends TrustUpdateJob {
296 * Creates a new trust update job.
299 * The identity giving the trust
301 * The identity receiving the trust
303 public GetTrustJob(OwnIdentity truster, Identity trustee) {
304 super(truster, trustee);
311 @SuppressWarnings("synthetic-access")
314 Trust trust = webOfTrustConnector.getTrust(truster, trustee);
315 if (trustee instanceof DefaultIdentity) {
316 ((DefaultIdentity) trustee).setTrust(truster, trust);
318 } catch (PluginException pe1) {
319 logger.log(Level.WARNING, "Could not get Trust value for " + truster + " -> " + trustee + "!", pe1);