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