bbc825f4a618dfad0cec2b5346292267945e5c40
[jFCPlib.git] / src / net / pterodactylus / fcp / plugin / WebOfTrustPlugin.java
1 /*
2  * jFCPlib - WebOfTrustPlugin.java -
3  * Copyright © 2009 David Roden
4  *
5  * This program is free software; you can redistribute it and/or modify
6  * it under the terms of the GNU General Public License as published by
7  * the Free Software Foundation; either version 2 of the License, or
8  * (at your option) any later version.
9  *
10  * This program is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13  * GNU General Public License for more details.
14  *
15  * You should have received a copy of the GNU General Public License
16  * along with this program; if not, write to the Free Software
17  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
18  */
19
20 package net.pterodactylus.fcp.plugin;
21
22 import java.io.IOException;
23 import java.util.HashMap;
24 import java.util.HashSet;
25 import java.util.Map;
26 import java.util.Set;
27
28 import net.pterodactylus.fcp.highlevel.FcpClient;
29 import net.pterodactylus.fcp.highlevel.FcpException;
30
31 /**
32  * Simplifies handling of the web-of-trust plugin.
33  *
34  * @author David ‘Bombe’ Roden <bombe@freenetproject.org>
35  */
36 public class WebOfTrustPlugin {
37
38         /** The FCP client to use. */
39         private final FcpClient fcpClient;
40
41         /**
42          * Creates a new web-of-trust plugin wrapper around the given FCP client.
43          *
44          * @param fcpClient
45          *            The FCP client to use for communication with the web-of-trust
46          *            plugin
47          */
48         public WebOfTrustPlugin(FcpClient fcpClient) {
49                 this.fcpClient = fcpClient;
50         }
51
52         /**
53          * Creates a new identity.
54          *
55          * @param nickname
56          *            The nickname of the new identity
57          * @param context
58          *            The context for the new identity
59          * @param publishTrustList
60          *            {@code true} if the new identity should publish its trust list
61          * @return The new identity
62          * @throws IOException
63          *             if an I/O error occurs
64          * @throws FcpException
65          *             if an FCP error occurs
66          */
67         public OwnIdentity createIdentity(String nickname, String context, boolean publishTrustList) throws IOException, FcpException {
68                 return createIdentity(nickname, context, publishTrustList, null, null);
69         }
70
71         /**
72          * Creates a new identity from the given request and insert URI.
73          *
74          * @param nickname
75          *            The nickname of the new identity
76          * @param context
77          *            The context for the new identity
78          * @param publishTrustList
79          *            {@code true} if the new identity should publish its trust list
80          * @param requestUri
81          *            The request URI of the identity
82          * @param insertUri
83          *            The insert URI of the identity
84          * @return The new identity
85          * @throws IOException
86          *             if an I/O error occurs
87          * @throws FcpException
88          *             if an FCP error occurs
89          */
90         public OwnIdentity createIdentity(String nickname, String context, boolean publishTrustList, String requestUri, String insertUri) throws IOException, FcpException {
91                 Map<String, String> parameters = new HashMap<String, String>();
92                 parameters.put("Message", "CreateIdentity");
93                 parameters.put("Nickname", nickname);
94                 parameters.put("Context", context);
95                 parameters.put("PublishTrustList", String.valueOf(publishTrustList));
96                 if ((requestUri != null) && (insertUri != null)) {
97                         parameters.put("RequestURI", requestUri);
98                         parameters.put("InsertURI", insertUri);
99                 }
100                 Map<String, String> replies = fcpClient.sendPluginMessage("plugins.WoT.WoT", parameters);
101                 if (!replies.get("Message").equals("IdentityCreated")) {
102                         throw new FcpException("WebOfTrust Plugin did not reply with “IdentityCreated” message!");
103                 }
104                 String identifier = replies.get("ID");
105                 String newRequestUri = replies.get("RequestURI");
106                 String newInsertUri = replies.get("InsertURI");
107                 return new OwnIdentity(identifier, nickname, newRequestUri, newInsertUri);
108         }
109
110         /**
111          * Returns all own identities of the web-of-trust plugins. Almost all other
112          * commands require an {@link OwnIdentity} to return meaningful values.
113          *
114          * @return All own identities of the web-of-trust plugin
115          * @throws IOException
116          *             if an I/O error occurs
117          * @throws FcpException
118          *             if an FCP error occurs
119          */
120         public Set<OwnIdentity> getOwnIdentites() throws IOException, FcpException {
121                 Map<String, String> replies = fcpClient.sendPluginMessage("plugins.WoT.WoT", createParameters("Message", "GetOwnIdentities"));
122                 if (!replies.get("Message").equals("OwnIdentities")) {
123                         throw new FcpException("WebOfTrust Plugin did not reply with “OwnIdentities” message!");
124                 }
125                 Set<OwnIdentity> ownIdentities = new HashSet<OwnIdentity>();
126                 for (int identityIndex = 1; replies.containsKey("Identity" + identityIndex); identityIndex++) {
127                         String identity = replies.get("Identity" + identityIndex);
128                         String nickname = replies.get("Nickname" + identityIndex);
129                         String requestUri = replies.get("RequestURI" + identityIndex);
130                         String insertUri = replies.get("InsertURI" + identityIndex);
131                         ownIdentities.add(new OwnIdentity(identity, nickname, requestUri, insertUri));
132                 }
133                 return ownIdentities;
134         }
135
136         /**
137          * Returns the trust given to the identity with the given identifier by the
138          * given own identity.
139          *
140          * @param ownIdentity
141          *            The own identity that is used to calculate trust values
142          * @param identifier
143          *            The identifier of the identity whose trust to get
144          * @return The request identity trust
145          * @throws IOException
146          *             if an I/O error occurs
147          * @throws FcpException
148          *             if an FCP error occurs
149          */
150         public CalculatedTrust getIdentityTrust(OwnIdentity ownIdentity, String identifier) throws IOException, FcpException {
151                 Map<String, String> replies = fcpClient.sendPluginMessage("plugins.WoT.WoT", createParameters("Message", "GetIdentity", "TreeOwner", ownIdentity.getIdentifier(), "Identity", identifier));
152                 if (!replies.get("Message").equals("Identity")) {
153                         throw new FcpException("WebOfTrust Plugin did not reply with “Identity” message!");
154                 }
155                 Byte trust = null;
156                 try {
157                         trust = Byte.valueOf(replies.get("Trust"));
158                 } catch (NumberFormatException nfe1) {
159                         /* ignore. */
160                 }
161                 Integer score = null;
162                 try {
163                         score = Integer.valueOf(replies.get("Score"));
164                 } catch (NumberFormatException nfe1) {
165                         /* ignore. */
166                 }
167                 Integer rank = null;
168                 try {
169                         rank = Integer.valueOf(replies.get("Rank"));
170                 } catch (NumberFormatException nfe1) {
171                         /* ignore. */
172                 }
173                 return new CalculatedTrust(trust, score, rank);
174         }
175
176         /**
177          * Adds a new identity by its request URI.
178          *
179          * @param requestUri
180          *            The request URI of the identity to add
181          * @return The added identity
182          * @throws IOException
183          *             if an I/O error occurs
184          * @throws FcpException
185          *             if an FCP error occurs
186          */
187         public Identity addIdentity(String requestUri) throws IOException, FcpException {
188                 Map<String, String> replies = fcpClient.sendPluginMessage("plugins.WoT.WoT", createParameters("Message", "AddIdentity", "RequestURI", requestUri));
189                 if (!replies.get("Message").equals("IdentityAdded")) {
190                         throw new FcpException("WebOfTrust Plugin did not reply with “IdentityAdded” message!");
191                 }
192                 String identifier = replies.get("ID");
193                 String nickname = replies.get("Nickname");
194                 return new Identity(identifier, nickname, requestUri);
195         }
196
197         /**
198          * Returns identities by the given score.
199          *
200          * @param ownIdentity
201          *            The own identity
202          * @param context
203          *            The context to get the identities for
204          * @param positive
205          *            {@code null} to return neutrally trusted identities, {@code
206          *            true} to return positively trusted identities, {@code false}
207          *            for negatively trusted identities
208          * @return The trusted identites
209          * @throws IOException
210          *             if an I/O error occurs
211          * @throws FcpException
212          *             if an FCP error occurs
213          */
214         public Set<Identity> getIdentitesByScore(OwnIdentity ownIdentity, String context, Boolean positive) throws IOException, FcpException {
215                 Map<String, String> replies = fcpClient.sendPluginMessage("plugins.WoT.WoT", createParameters("Message", "GetIdentitiesByScore", "TreeOwner", ownIdentity.getIdentifier(), "Context", context, "Selection", ((positive == null) ? "0" : (positive ? "+" : "-"))));
216                 if (!replies.get("Message").equals("Identities")) {
217                         throw new FcpException("WebOfTrust Plugin did not reply with “Identities” message!");
218                 }
219                 Set<Identity> identities = new HashSet<Identity>();
220                 for (int identityIndex = 1; replies.containsKey("Identity" + identityIndex); identityIndex++) {
221                         String identifier = replies.get("Identity" + identityIndex);
222                         String nickname = replies.get("Nickname" + identityIndex);
223                         String requestUri = replies.get("RequestURI" + identityIndex);
224                         identities.add(new Identity(identifier, nickname, requestUri));
225                 }
226                 return identities;
227         }
228
229         /**
230          * Returns the identities that trust the given identity.
231          *
232          * @param identity
233          *            The identity to get the trusters for
234          * @param context
235          *            The context to get the trusters for
236          * @return The identities and their trust values
237          * @throws IOException
238          *             if an I/O error occurs
239          * @throws FcpException
240          *             if an FCP error occurs
241          */
242         public Map<Identity, IdentityTrust> getTrusters(Identity identity, String context) throws IOException, FcpException {
243                 Map<String, String> replies = fcpClient.sendPluginMessage("plugins.WoT.WoT", createParameters("Message", "GetTrusters", "Identity", identity.getIdentifier(), "Context", context));
244                 if (!replies.get("Message").equals("Identities")) {
245                         throw new FcpException("WebOfTrust Plugin did not reply with “Identities” message!");
246                 }
247                 Map<Identity, IdentityTrust> identityTrusts = new HashMap<Identity, IdentityTrust>();
248                 for (int identityIndex = 1; replies.containsKey("Identity" + identityIndex); identityIndex++) {
249                         String identifier = replies.get("Identity" + identityIndex);
250                         String nickname = replies.get("Nickname" + identityIndex);
251                         String requestUri = replies.get("RequestURI" + identityIndex);
252                         byte trust = Byte.parseByte(replies.get("Value" + identityIndex));
253                         String comment = replies.get("Comment" + identityIndex);
254                         identityTrusts.put(new Identity(identifier, nickname, requestUri), new IdentityTrust(trust, comment));
255                 }
256                 return identityTrusts;
257         }
258
259         /**
260          * Returns the identities that given identity trusts.
261          *
262          * @param identity
263          *            The identity to get the trustees for
264          * @param context
265          *            The context to get the trustees for
266          * @return The identities and their trust values
267          * @throws IOException
268          *             if an I/O error occurs
269          * @throws FcpException
270          *             if an FCP error occurs
271          */
272         public Map<Identity, IdentityTrust> getTrustees(Identity identity, String context) throws IOException, FcpException {
273                 Map<String, String> replies = fcpClient.sendPluginMessage("plugins.WoT.WoT", createParameters("Message", "GetTrustees", "Identity", identity.getIdentifier(), "Context", context));
274                 if (!replies.get("Message").equals("Identities")) {
275                         throw new FcpException("WebOfTrust Plugin did not reply with “Identities” message!");
276                 }
277                 Map<Identity, IdentityTrust> identityTrusts = new HashMap<Identity, IdentityTrust>();
278                 for (int identityIndex = 1; replies.containsKey("Identity" + identityIndex); identityIndex++) {
279                         String identifier = replies.get("Identity" + identityIndex);
280                         String nickname = replies.get("Nickname" + identityIndex);
281                         String requestUri = replies.get("RequestURI" + identityIndex);
282                         byte trust = Byte.parseByte(replies.get("Value" + identityIndex));
283                         String comment = replies.get("Comment" + identityIndex);
284                         identityTrusts.put(new Identity(identifier, nickname, requestUri), new IdentityTrust(trust, comment));
285                 }
286                 return identityTrusts;
287         }
288
289         /**
290          * Sets the trust given to the given identify by the given own identity.
291          *
292          * @param ownIdentity
293          *            The identity that gives the trust
294          * @param identity
295          *            The identity that receives the trust
296          * @param trust
297          *            The trust value (ranging from {@code -100} to {@code 100}
298          * @param comment
299          *            The comment for setting the trust
300          * @throws IOException
301          *             if an I/O error occurs
302          * @throws FcpException
303          *             if an FCP error occurs
304          */
305         public void setTrust(OwnIdentity ownIdentity, Identity identity, byte trust, String comment) throws IOException, FcpException {
306                 Map<String, String> replies = fcpClient.sendPluginMessage("plugins.WoT.WoT", createParameters("Message", "SetTrust", "Truster", ownIdentity.getIdentifier(), "Trustee", identity.getIdentifier(), "Value", String.valueOf(trust), "Comment", comment));
307                 if (!replies.get("Message").equals("TrustSet")) {
308                         throw new FcpException("WebOfTrust Plugin did not reply with “TrustSet” message!");
309                 }
310         }
311
312         /**
313          * Adds the given context to the given identity.
314          *
315          * @param ownIdentity
316          *            The identity to add the context to
317          * @param context
318          *            The context to add
319          * @throws IOException
320          *             if an I/O error occurs
321          * @throws FcpException
322          *             if an FCP error occurs
323          */
324         public void addContext(OwnIdentity ownIdentity, String context) throws IOException, FcpException {
325                 Map<String, String> replies = fcpClient.sendPluginMessage("plugins.WoT.WoT", createParameters("Message", "AddContext", "Identity", ownIdentity.getIdentifier(), "Context", context));
326                 if (!replies.get("Message").equals("ContextAdded")) {
327                         throw new FcpException("WebOfTrust Plugin did not reply with “ContextAdded” message!");
328                 }
329         }
330
331         /**
332          * Removes the given context from the given identity.
333          *
334          * @param ownIdentity
335          *            The identity to remove the context from
336          * @param context
337          *            The context to remove
338          * @throws IOException
339          *             if an I/O error occurs
340          * @throws FcpException
341          *             if an FCP error occurs
342          */
343         public void removeContext(OwnIdentity ownIdentity, String context) throws IOException, FcpException {
344                 Map<String, String> replies = fcpClient.sendPluginMessage("plugins.WoT.WoT", createParameters("Message", "RemoveContext", "Identity", ownIdentity.getIdentifier(), "Context", context));
345                 if (!replies.get("Message").equals("ContextRemoved")) {
346                         throw new FcpException("WebOfTrust Plugin did not reply with “ContextRemoved” message!");
347                 }
348         }
349
350         /**
351          * Sets the given property for the given identity.
352          *
353          * @param ownIdentity
354          *            The identity to set a property for
355          * @param property
356          *            The name of the property to set
357          * @param value
358          *            The value of the property to set
359          * @throws IOException
360          *             if an I/O error occurs
361          * @throws FcpException
362          *             if an FCP error occurs
363          */
364         public void setProperty(OwnIdentity ownIdentity, String property, String value) throws IOException, FcpException {
365                 Map<String, String> replies = fcpClient.sendPluginMessage("plugins.WoT.WoT", createParameters("Message", "SetProperty", "Identity", ownIdentity.getIdentifier(), "Property", property, "Value", value));
366                 if (!replies.get("Message").equals("PropertyAdded")) {
367                         throw new FcpException("WebOfTrust Plugin did not reply with “PropertyAdded” message!");
368                 }
369         }
370
371         /**
372          * Returns the value of the given property for the given identity.
373          *
374          * @param ownIdentity
375          *            The identity to get a property for
376          * @param property
377          *            The name of the property to get
378          * @return The value of the property
379          * @throws IOException
380          *             if an I/O error occurs
381          * @throws FcpException
382          *             if an FCP error occurs
383          */
384         public String getProperty(OwnIdentity ownIdentity, String property) throws IOException, FcpException {
385                 Map<String, String> replies = fcpClient.sendPluginMessage("plugins.WoT.WoT", createParameters("Message", "GetProperty", "Identity", ownIdentity.getIdentifier(), "Property", property));
386                 if (!replies.get("Message").equals("PropertyValue")) {
387                         throw new FcpException("WebOfTrust Plugin did not reply with “PropertyValue” message!");
388                 }
389                 return replies.get("Property");
390         }
391
392         /**
393          * Removes the given property from the given identity.
394          *
395          * @param ownIdentity
396          *            The identity to remove a property from
397          * @param property
398          *            The name of the property to remove
399          * @throws IOException
400          *             if an I/O error occurs
401          * @throws FcpException
402          *             if an FCP error occurs
403          */
404         public void removeProperty(OwnIdentity ownIdentity, String property) throws IOException, FcpException {
405                 Map<String, String> replies = fcpClient.sendPluginMessage("plugins.WoT.WoT", createParameters("Message", "RemoveProperty", "Identity", ownIdentity.getIdentifier(), "Property", property));
406                 if (!replies.get("Message").equals("PropertyRemoved")) {
407                         throw new FcpException("WebOfTrust Plugin did not reply with “PropertyRemoved” message!");
408                 }
409         }
410
411         //
412         // PRIVATE METHODS
413         //
414
415         /**
416          * Creates a map from each pair of parameters in the given array.
417          *
418          * @param parameters
419          *            The array of parameters
420          * @return The map created from the array
421          * @throws ArrayIndexOutOfBoundsException
422          *             if the given parameter array does not contains an even number
423          *             of elements
424          */
425         private Map<String, String> createParameters(String... parameters) throws ArrayIndexOutOfBoundsException {
426                 Map<String, String> parameterMap = new HashMap<String, String>();
427                 for (int index = 0; index < parameters.length; index += 2) {
428                         parameterMap.put(parameters[index], parameters[index + 1]);
429                 }
430                 return parameterMap;
431         }
432
433         /**
434          * Wrapper around a web-of-trust identity.
435          *
436          * @author David ‘Bombe’ Roden &lt;bombe@freenetproject.org&gt;
437          */
438         public static class Identity {
439
440                 /** The identity’s identifier. */
441                 private final String identifier;
442
443                 /** The identity’s nickname. */
444                 private final String nickname;
445
446                 /** The identity’s request URI. */
447                 private final String requestUri;
448
449                 /**
450                  * Creates a new identity.
451                  *
452                  * @param identifier
453                  *            The identifies of the identity
454                  * @param nickname
455                  *            The nickname of the identity
456                  * @param requestUri
457                  *            The request URI of the identity
458                  */
459                 public Identity(String identifier, String nickname, String requestUri) {
460                         this.identifier = identifier;
461                         this.nickname = nickname;
462                         this.requestUri = requestUri;
463                 }
464
465                 /**
466                  * Returns the identifier of this identity.
467                  *
468                  * @return This identity’s identifier
469                  */
470                 public String getIdentifier() {
471                         return identifier;
472                 }
473
474                 /**
475                  * Returns the nickname of this identity.
476                  *
477                  * @return This identity’s nickname
478                  */
479                 public String getNickname() {
480                         return nickname;
481                 }
482
483                 /**
484                  * Returns the request URI of this identity.
485                  *
486                  * @return This identity’s request URI
487                  */
488                 public String getRequestUri() {
489                         return requestUri;
490                 }
491
492                 /**
493                  * {@inheritDoc}
494                  */
495                 @Override
496                 public boolean equals(Object obj) {
497                         if ((obj == null) || (obj.getClass() != this.getClass())) {
498                                 return false;
499                         }
500                         Identity identity = (Identity) obj;
501                         return identifier.equals(identity.identifier);
502                 }
503
504                 /**
505                  * {@inheritDoc}
506                  */
507                 @Override
508                 public int hashCode() {
509                         return identifier.hashCode();
510                 }
511
512         }
513
514         /**
515          * Container for the trust given from one identity to another.
516          *
517          * @author David ‘Bombe’ Roden &lt;bombe@freenetproject.org&gt;
518          */
519         public static class IdentityTrust {
520
521                 /** The trust given to the identity. */
522                 private final byte trust;
523
524                 /** The command for the trust value. */
525                 private final String comment;
526
527                 /**
528                  * Creates a new identity trust container.
529                  *
530                  * @param trust
531                  *            The trust given to the identity
532                  * @param comment
533                  *            The comment for the trust value
534                  */
535                 public IdentityTrust(byte trust, String comment) {
536                         this.trust = trust;
537                         this.comment = comment;
538                 }
539
540                 /**
541                  * Returns the trust value given to the identity.
542                  *
543                  * @return The trust value
544                  */
545                 public byte getTrust() {
546                         return trust;
547                 }
548
549                 /**
550                  * Returns the comment for the trust value.
551                  *
552                  * @return The comment for the trust value
553                  */
554                 public String getComment() {
555                         return comment;
556                 }
557
558         }
559
560         /**
561          * Container that stores the trust that is calculated by taking all trustees
562          * and their trust lists into account.
563          *
564          * @author David ‘Bombe’ Roden &lt;bombe@freenetproject.org&gt;
565          */
566         public static class CalculatedTrust {
567
568                 /** The calculated trust value. */
569                 private final Byte trust;
570
571                 /** The calculated score value. */
572                 private final Integer score;
573
574                 /** The calculated rank. */
575                 private final Integer rank;
576
577                 /**
578                  * Creates a new calculated trust container.
579                  *
580                  * @param trust
581                  *            The calculated trust value
582                  * @param score
583                  *            The calculated score value
584                  * @param rank
585                  *            The calculated rank of the
586                  */
587                 public CalculatedTrust(Byte trust, Integer score, Integer rank) {
588                         this.trust = trust;
589                         this.score = score;
590                         this.rank = rank;
591                 }
592
593                 /**
594                  * Returns the calculated trust value.
595                  *
596                  * @return The calculated trust value, or {@code null} if the trust
597                  *         value is not known
598                  */
599                 public Byte getTrust() {
600                         return trust;
601                 }
602
603                 /**
604                  * Returns the calculated score value.
605                  *
606                  * @return The calculated score value, or {@code null} if the score
607                  *         value is not known
608                  */
609                 public Integer getScore() {
610                         return score;
611                 }
612
613                 /**
614                  * Returns the calculated rank.
615                  *
616                  * @return The calculated rank, or {@code null} if the rank is not known
617                  */
618                 public Integer getRank() {
619                         return rank;
620                 }
621
622         }
623
624         /**
625          * Wrapper around a web-of-trust own identity.
626          *
627          * @author David ‘Bombe’ Roden &lt;bombe@freenetproject.org&gt;
628          */
629         public static class OwnIdentity extends Identity {
630
631                 /** The identity’s insert URI. */
632                 private final String insertUri;
633
634                 /**
635                  * Creates a new web-of-trust own identity.
636                  *
637                  * @param identifier
638                  *            The identifier of the identity
639                  * @param nickname
640                  *            The nickname of the identity
641                  * @param requestUri
642                  *            The request URI of the identity
643                  * @param insertUri
644                  *            The insert URI of the identity
645                  */
646                 public OwnIdentity(String identifier, String nickname, String requestUri, String insertUri) {
647                         super(identifier, nickname, requestUri);
648                         this.insertUri = insertUri;
649                 }
650
651                 /**
652                  * Returns the insert URI of this identity.
653                  *
654                  * @return This identity’s insert URI
655                  */
656                 public String getInsertUri() {
657                         return insertUri;
658                 }
659
660         }
661
662 }