add ListPeer and ListPeers commands and replies
[jSite2.git] / src / net / pterodactylus / util / fcp / message / Peer.java
1 /**
2  * © 2008 INA Service GmbH
3  */
4 package net.pterodactylus.util.fcp.message;
5
6 import java.security.interfaces.DSAParams;
7 import java.util.StringTokenizer;
8
9 import net.pterodactylus.util.fcp.FcpMessage;
10 import net.pterodactylus.util.fcp.FcpUtils;
11
12 /**
13  * The “Peer” reply by the node contains information about a peer.
14  * 
15  * @author <a href="mailto:dr@ina-germany.de">David Roden</a>
16  * @version $Id$
17  */
18 public class Peer extends BaseMessage {
19
20         /**
21          * Creates a new “Peer” reply from the received message.
22          * 
23          * @param receivedMessage
24          *            The received message
25          */
26         public Peer(FcpMessage receivedMessage) {
27                 super(receivedMessage);
28         }
29
30         /**
31          * Returns the “physical.udp” line from the message. It contains all IP
32          * addresses and port numbers of the peer.
33          * 
34          * @return The IP addresses and port numbers of the peer
35          */
36         public String getPhysicalUDP() {
37                 return getField("physical.udp");
38         }
39
40         /**
41          * Returns whether the listed peer is an opennet peer.
42          * 
43          * @return <code>true</code> if the peer is an opennet peer,
44          *         <code>false</code> if the peer is a darknet peer
45          */
46         public boolean isOpennet() {
47                 return Boolean.valueOf(getField("opennet"));
48         }
49
50         /**
51          * Returns the “y” part of the peer’s public DSA key.
52          * 
53          * @return The public DSA key
54          */
55         public String getDSAPublicKey() {
56                 return getField("dsaPubKey.y");
57         }
58
59         /**
60          * Returns the DSA group of the peer.
61          * 
62          * @return The DSA group of the peer
63          */
64         public DSAGroup getDSAGroup() {
65                 return new DSAGroup(getField("dsaGroup.g"), getField("dsaGroup.p"), getField("dsaGroup.q"));
66         }
67
68         /**
69          * Returns the last good version of the peer, i.e. the oldest version the
70          * peer will connect to.
71          * 
72          * @return The last good version of the peer
73          */
74         public Version getLastGoodVersion() {
75                 return new Version(getField("lastGoodVersion"));
76         }
77
78         /**
79          * Returns the ARK of the peer.
80          * 
81          * @return The ARK of the peer
82          */
83         public ARK getARK() {
84                 return new ARK(getField("ark.pubURI"), getField("ark.number"));
85         }
86
87         /**
88          * Returns the identity of the peer.
89          * 
90          * @return The identity of the peer
91          */
92         public String getIdentity() {
93                 return getField("identity");
94         }
95
96         /**
97          * Returns the name of the peer. If the peer is not a darknet peer it will
98          * have no name.
99          * 
100          * @return The name of the peer, or <code>null</code> if the peer is an
101          *         opennet peer
102          */
103         public String getMyName() {
104                 return getField("myName");
105         }
106
107         /**
108          * Returns the location of the peer.
109          * 
110          * @return The location of the peer
111          * @throws NumberFormatException
112          *             if the field can not be parsed
113          */
114         public double getLocation() throws NumberFormatException {
115                 return Double.valueOf(getField("location"));
116         }
117
118         /**
119          * Returns whether the peer is a testnet node.
120          * 
121          * @return <code>true</code> if the peer is a testnet node,
122          *         <code>false</code> otherwise
123          */
124         public boolean isTestnet() {
125                 return Boolean.valueOf("testnet");
126         }
127
128         /**
129          * Returns the version of the peer.
130          * 
131          * @return The version of the peer
132          */
133         public Version getVersion() {
134                 return new Version(getField("version"));
135         }
136
137         /**
138          * Returns the negotiation types the peer supports.
139          * 
140          * @return The supported negotiation types
141          */
142         public int[] getNegotiationTypes() {
143                 return FcpUtils.parseMultiIntegerField(getField("auth.negTypes"));
144         }
145
146         /**
147          * Container for the “lastGoodVersion” field.
148          * 
149          * @author <a href="mailto:dr@ina-germany.de">David Roden</a>
150          * @version $Id$
151          */
152         public static class Version {
153
154                 /** The name of the node implementation. */
155                 private final String nodeName;
156
157                 /** The tree version of the node. */
158                 private final String treeVersion;
159
160                 /** The protocol version of the node. */
161                 private final String protocolVersion;
162
163                 /** The build number of the node. */
164                 private final int buildNumber;
165
166                 /**
167                  * Creates a new Version from the given string. The string consists of
168                  * the four required fields node name, tree version, protocol version,
169                  * and build number, separated by a comma.
170                  * 
171                  * @param version
172                  *            The version string
173                  * @throws NullPointerException
174                  *             if <code>version</code> is <code>null</code>
175                  * @throws IllegalArgumentException
176                  *             if <code>version</code> is not in the right format
177                  */
178                 public Version(String version) {
179                         if (version == null) {
180                                 throw new NullPointerException("version must not be null");
181                         }
182                         StringTokenizer versionTokens = new StringTokenizer(version, ",");
183                         if (versionTokens.countTokens() != 4) {
184                                 throw new IllegalArgumentException("version must consist of four fields");
185                         }
186                         this.nodeName = versionTokens.nextToken();
187                         this.treeVersion = versionTokens.nextToken();
188                         this.protocolVersion = versionTokens.nextToken();
189                         try {
190                                 this.buildNumber = Integer.valueOf(versionTokens.nextToken());
191                         } catch (NumberFormatException nfe1) {
192                                 throw new IllegalArgumentException("last part of version must be numeric", nfe1);
193                         }
194                 }
195
196                 /**
197                  * Creates a new Version from the given parts.
198                  * 
199                  * @param nodeName
200                  *            The name of the node implementation
201                  * @param treeVersion
202                  *            The tree version
203                  * @param protocolVersion
204                  *            The protocol version
205                  * @param buildNumber
206                  *            The build number of the node
207                  */
208                 public Version(String nodeName, String treeVersion, String protocolVersion, int buildNumber) {
209                         this.nodeName = nodeName;
210                         this.treeVersion = treeVersion;
211                         this.protocolVersion = protocolVersion;
212                         this.buildNumber = buildNumber;
213                 }
214
215                 /**
216                  * Returns the name of the node implementation.
217                  * 
218                  * @return The node name
219                  */
220                 public String getNodeName() {
221                         return nodeName;
222                 }
223
224                 /**
225                  * The tree version of the node.
226                  * 
227                  * @return The tree version of the node
228                  */
229                 public String getTreeVersion() {
230                         return treeVersion;
231                 }
232
233                 /**
234                  * The protocol version of the node
235                  * 
236                  * @return The protocol version of the node
237                  */
238                 public String getProtocolVersion() {
239                         return protocolVersion;
240                 }
241
242                 /**
243                  * The build number of the node.
244                  * 
245                  * @return The build number of the node
246                  */
247                 public int getBuildNumber() {
248                         return buildNumber;
249                 }
250
251         }
252
253         /**
254          * Container for ARKs (address resolution keys).
255          * 
256          * @author <a href="mailto:dr@ina-germany.de">David Roden</a>
257          * @version $Id$
258          */
259         public static class ARK {
260
261                 /** The public URI of the ARK. */
262                 private final String publicURI;
263
264                 /** The number of the ARK. */
265                 private final int number;
266
267                 /**
268                  * Creates a new ARK with the given URI and number.
269                  * 
270                  * @param publicURI
271                  *            The public URI of the ARK
272                  * @param number
273                  *            The number of the ARK
274                  */
275                 public ARK(String publicURI, String number) {
276                         if ((publicURI == null) || (number == null)) {
277                                 throw new NullPointerException(((publicURI == null) ? "publicURI" : "number") + " must not be null");
278                         }
279                         this.publicURI = publicURI;
280                         try {
281                                 this.number = Integer.valueOf(number);
282                         } catch (NumberFormatException nfe1) {
283                                 throw new IllegalArgumentException("number must be numeric", nfe1);
284                         }
285                 }
286
287                 /**
288                  * Returns the public URI of the ARK.
289                  * 
290                  * @return The public URI of the ARK
291                  */
292                 public String getPublicURI() {
293                         return publicURI;
294                 }
295
296                 /**
297                  * Returns the number of the ARK.
298                  * 
299                  * @return The number of the ARK
300                  */
301                 public int getNumber() {
302                         return number;
303                 }
304
305         }
306
307         /**
308          * Container for the DSA group of a peer. A DSA group consists of a base
309          * (called “g”), a prime (called “p”) and a subprime (called “q”).
310          * 
311          * @see DSAParams
312          * @author <a href="mailto:dr@ina-germany.de">David Roden</a>
313          * @version $Id$
314          */
315         public static class DSAGroup {
316
317                 /** The base of the DSA group. */
318                 private final String base;
319
320                 /** The prime of the DSA group. */
321                 private final String prime;
322
323                 /** The subprime of the DSA group. */
324                 private final String subprime;
325
326                 /**
327                  * Creates a new DSA group with the given base (“g”), prime (“p”), and
328                  * subprime (“q”).
329                  * 
330                  * @param base
331                  *            The base of the DSA group
332                  * @param prime
333                  *            The prime of the DSA group
334                  * @param subprime
335                  *            The subprime of the DSA group
336                  */
337                 public DSAGroup(String base, String prime, String subprime) {
338                         this.base = base;
339                         this.prime = prime;
340                         this.subprime = subprime;
341                 }
342
343                 /**
344                  * Returns the base (“g”) of the DSA group.
345                  * 
346                  * @return The base of the DSA group
347                  */
348                 public String getBase() {
349                         return base;
350                 }
351
352                 /**
353                  * Returns the prime (“p”) of the DSA group.
354                  * 
355                  * @return The prime of the DSA group
356                  */
357                 public String getPrime() {
358                         return prime;
359                 }
360
361                 /**
362                  * Returns the subprime (“q”) of the DSA group.
363                  * 
364                  * @return The subprime of the DSA group
365                  */
366                 public String getSubprime() {
367                         return subprime;
368                 }
369
370         }
371
372 }