a86b353f6e955a3a5d5120c7337fa38d45fc182f
[Sone.git] / src / main / java / net / pterodactylus / sone / core / TrustUpdater.java
1 /*
2  * Sone - TrustUpdater.java - Copyright © 2012 David Roden
3  *
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.
8  *
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.
13  *
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/>.
16  */
17
18 package net.pterodactylus.sone.core;
19
20 import java.util.concurrent.BlockingQueue;
21 import java.util.concurrent.LinkedBlockingQueue;
22 import java.util.logging.Level;
23 import java.util.logging.Logger;
24
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;
34
35 /**
36  * Updates identity’s trust in a background thread because getting updates from
37  * the WebOfTrust plugin can potentially last quite long.
38  *
39  * @author <a href="mailto:bombe@pterodactylus.net">David ‘Bombe’ Roden</a>
40  */
41 public class TrustUpdater extends AbstractService {
42
43         /** The logger. */
44         private static final Logger logger = Logging.getLogger(TrustUpdater.class);
45
46         /** Stop job. */
47         private static final TrustUpdateJob stopJob = new TrustUpdateJob(null, null);
48
49         /** The web of trust connector. */
50         private final WebOfTrustConnector webOfTrustConnector;
51
52         /** The queue for jobs. */
53         private final BlockingQueue<TrustUpdateJob> updateJobs = new LinkedBlockingQueue<TrustUpdateJob>();
54
55         /**
56          * Creates a new trust updater.
57          *
58          * @param webOfTrustConnector
59          *            The web of trust connector
60          */
61         public TrustUpdater(WebOfTrustConnector webOfTrustConnector) {
62                 super("Trust Updater");
63                 this.webOfTrustConnector = webOfTrustConnector;
64         }
65
66         //
67         // ACTIONS
68         //
69
70         /**
71          * Retrieves the trust relation between the truster and the trustee. This
72          * method will return immediately and perform a trust update in the
73          * background.
74          *
75          * @param truster
76          *            The identity giving the trust
77          * @param trustee
78          *            The identity receiving the trust
79          */
80         public void getTrust(OwnIdentity truster, Identity trustee) {
81                 updateJobs.add(new GetTrustJob(truster, trustee));
82         }
83
84         /**
85          * Updates the trust relation between the truster and the trustee. This
86          * method will return immediately and perform a trust update in the
87          * background.
88          *
89          * @param truster
90          *            The identity giving the trust
91          * @param trustee
92          *            The identity receiving the trust
93          * @param score
94          *            The new level of trust (from -100 to 100, may be {@code null}
95          *            to remove the trust completely)
96          * @param comment
97          *            The comment of the trust relation
98          */
99         public void setTrust(OwnIdentity truster, Identity trustee, Integer score, String comment) {
100                 updateJobs.add(new SetTrustJob(truster, trustee, score, comment));
101         }
102
103         //
104         // SERVICE METHODS
105         //
106
107         /**
108          * {@inheritDoc}
109          */
110         @Override
111         protected void serviceRun() {
112                 while (!shouldStop()) {
113                         try {
114                                 TrustUpdateJob updateJob = updateJobs.take();
115                                 if (shouldStop() || (updateJob == stopJob)) {
116                                         break;
117                                 }
118                                 updateJob.run();
119                         } catch (InterruptedException ie1) {
120                                 /* happens, ignore, loop. */
121                         }
122                 }
123         }
124
125         /**
126          * {@inheritDoc}
127          */
128         @Override
129         protected void serviceStop() {
130                 try {
131                         updateJobs.put(stopJob);
132                 } catch (InterruptedException ie1) {
133                         /* the queue is unbounded so it should never block. */
134                 }
135         }
136
137         /**
138          * Base class for trust update jobs.
139          *
140          * @author <a href="mailto:bombe@pterodactylus.net">David ‘Bombe’ Roden</a>
141          */
142         private static class TrustUpdateJob {
143
144                 /** The identity giving the trust. */
145                 protected final OwnIdentity truster;
146
147                 /** The identity receiving the trust. */
148                 protected final Identity trustee;
149
150                 /**
151                  * Creates a new trust update job.
152                  *
153                  * @param truster
154                  *            The identity giving the trust
155                  * @param trustee
156                  *            The identity receiving the trust
157                  */
158                 public TrustUpdateJob(OwnIdentity truster, Identity trustee) {
159                         this.truster = truster;
160                         this.trustee = trustee;
161                 }
162
163                 //
164                 // ACCESSORS
165                 //
166
167                 /**
168                  * Performs the actual update operation.
169                  * <p>
170                  * The implementation of this class does nothing.
171                  */
172                 public void run() {
173                         /* does nothing. */
174                 }
175
176         }
177
178         /**
179          * Update job that sets the trust relation between two identities.
180          *
181          * @author <a href="mailto:bombe@pterodactylus.net">David ‘Bombe’ Roden</a>
182          */
183         private class SetTrustJob extends TrustUpdateJob {
184
185                 /** The score of the relation. */
186                 private final Integer score;
187
188                 /** The comment of the relation. */
189                 private final String comment;
190
191                 /**
192                  * Creates a new set trust job.
193                  *
194                  * @param truster
195                  *            The identity giving the trust
196                  * @param trustee
197                  *            The identity receiving the trust
198                  * @param score
199                  *            The score of the trust (from -100 to 100, may be
200                  *            {@code null} to remote the trust relation completely)
201                  * @param comment
202                  *            The comment of the trust relation
203                  */
204                 public SetTrustJob(OwnIdentity truster, Identity trustee, Integer score, String comment) {
205                         super(truster, trustee);
206                         this.score = score;
207                         this.comment = comment;
208                 }
209
210                 /**
211                  * {@inheritDoc}
212                  */
213                 @Override
214                 @SuppressWarnings("synthetic-access")
215                 public void run() {
216                         try {
217                                 if (score != null) {
218                                         if (trustee instanceof DefaultIdentity) {
219                                                 ((DefaultIdentity) trustee).setTrust(truster, new Trust(score, null, 0));
220                                         }
221                                         webOfTrustConnector.setTrust(truster, trustee, score, comment);
222                                 } else {
223                                         if (trustee instanceof DefaultIdentity) {
224                                                 ((DefaultIdentity) trustee).setTrust(truster, null);
225                                         }
226                                         webOfTrustConnector.removeTrust(truster, trustee);
227                                 }
228                         } catch (WebOfTrustException wote1) {
229                                 logger.log(Level.WARNING, "Could not set Trust value for " + truster + " -> " + trustee + " to " + score + " (" + comment + ")!", wote1);
230                         }
231                 }
232
233         }
234
235         /**
236          * Update job that retrieves the trust relation between two identities.
237          *
238          * @author <a href="mailto:bombe@pterodactylus.net">David ‘Bombe’ Roden</a>
239          */
240         private class GetTrustJob extends TrustUpdateJob {
241
242                 /**
243                  * Creates a new trust update job.
244                  *
245                  * @param truster
246                  *            The identity giving the trust
247                  * @param trustee
248                  *            The identity receiving the trust
249                  */
250                 public GetTrustJob(OwnIdentity truster, Identity trustee) {
251                         super(truster, trustee);
252                 }
253
254                 /**
255                  * {@inheritDoc}
256                  */
257                 @Override
258                 @SuppressWarnings("synthetic-access")
259                 public void run() {
260                         try {
261                                 Trust trust = webOfTrustConnector.getTrust(truster, trustee);
262                                 if (trustee instanceof DefaultIdentity) {
263                                         ((DefaultIdentity) trustee).setTrust(truster, trust);
264                                 }
265                         } catch (PluginException pe1) {
266                                 logger.log(Level.WARNING, "Could not get Trust value for " + truster + " -> " + trustee + "!", pe1);
267                         }
268                 }
269         }
270
271 }