add cancelling of requests in case of protocol errors or connection aborts
[jFCPlib.git] / src / net / pterodactylus / fcp / highlevel / HighLevelClient.java
1 /*
2  * fcplib - HighLevelClient.java -
3  * Copyright © 2008 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.highlevel;
21
22 import java.io.IOException;
23 import java.net.InetAddress;
24 import java.net.UnknownHostException;
25 import java.util.Collections;
26 import java.util.HashMap;
27 import java.util.Map;
28 import java.util.Map.Entry;
29
30 import net.pterodactylus.fcp.AllData;
31 import net.pterodactylus.fcp.ClientHello;
32 import net.pterodactylus.fcp.CloseConnectionDuplicateClientName;
33 import net.pterodactylus.fcp.ConfigData;
34 import net.pterodactylus.fcp.DataFound;
35 import net.pterodactylus.fcp.EndListPeerNotes;
36 import net.pterodactylus.fcp.EndListPeers;
37 import net.pterodactylus.fcp.EndListPersistentRequests;
38 import net.pterodactylus.fcp.FCPPluginReply;
39 import net.pterodactylus.fcp.FcpConnection;
40 import net.pterodactylus.fcp.FcpListener;
41 import net.pterodactylus.fcp.FcpMessage;
42 import net.pterodactylus.fcp.FinishedCompression;
43 import net.pterodactylus.fcp.GenerateSSK;
44 import net.pterodactylus.fcp.GetFailed;
45 import net.pterodactylus.fcp.IdentifierCollision;
46 import net.pterodactylus.fcp.ListPeers;
47 import net.pterodactylus.fcp.NodeData;
48 import net.pterodactylus.fcp.NodeHello;
49 import net.pterodactylus.fcp.Peer;
50 import net.pterodactylus.fcp.PeerNote;
51 import net.pterodactylus.fcp.PeerRemoved;
52 import net.pterodactylus.fcp.PersistentGet;
53 import net.pterodactylus.fcp.PersistentPut;
54 import net.pterodactylus.fcp.PersistentPutDir;
55 import net.pterodactylus.fcp.PersistentRequestModified;
56 import net.pterodactylus.fcp.PersistentRequestRemoved;
57 import net.pterodactylus.fcp.PluginInfo;
58 import net.pterodactylus.fcp.ProtocolError;
59 import net.pterodactylus.fcp.PutFailed;
60 import net.pterodactylus.fcp.PutFetchable;
61 import net.pterodactylus.fcp.PutSuccessful;
62 import net.pterodactylus.fcp.SSKKeypair;
63 import net.pterodactylus.fcp.SimpleProgress;
64 import net.pterodactylus.fcp.StartedCompression;
65 import net.pterodactylus.fcp.SubscribedUSKUpdate;
66 import net.pterodactylus.fcp.TestDDAComplete;
67 import net.pterodactylus.fcp.TestDDAReply;
68 import net.pterodactylus.fcp.URIGenerated;
69 import net.pterodactylus.fcp.UnknownNodeIdentifier;
70 import net.pterodactylus.fcp.UnknownPeerNoteType;
71
72 /**
73  * A high-level client that allows simple yet full-featured access to a Freenet
74  * node.
75  * 
76  * @author David ‘Bombe’ Roden <bombe@freenetproject.org>
77  * @version $Id$
78  */
79 public class HighLevelClient {
80
81         /** Object for internal synchronization. */
82         private final Object syncObject = new Object();
83
84         /** The name of the client. */
85         private final String clientName;
86
87         /** The address of the node. */
88         private InetAddress address;
89
90         /** The port number of the node. */
91         private int port;
92
93         /** The FCP connection to the node. */
94         private FcpConnection fcpConnection;
95
96         /** The listener for the connection. */
97         private HighLevelClientFcpListener highLevelClientFcpListener = new HighLevelClientFcpListener();
98
99         /** The callback for {@link #connect()}. */
100         private HighLevelCallback<ConnectResult> connectCallback;
101
102         /** Mapping from request identifiers to callbacks. */
103         private Map<String, HighLevelCallback<KeyGenerationResult>> keyGenerationCallbacks = Collections.synchronizedMap(new HashMap<String, HighLevelCallback<KeyGenerationResult>>());
104
105         /** Mapping from request identifier to peer list callbacks. */
106         private Map<String, HighLevelCallback<PeerListResult>> peerListCallbacks = Collections.synchronizedMap(new HashMap<String, HighLevelCallback<PeerListResult>>());
107
108         /**
109          * Creates a new high-level client that connects to a node on
110          * <code>localhost</code>.
111          * 
112          * @param clientName
113          *            The name of the client
114          * @throws UnknownHostException
115          *             if the hostname of the node can not be resolved.
116          */
117         public HighLevelClient(String clientName) throws UnknownHostException {
118                 this(clientName, "localhost");
119         }
120
121         /**
122          * Creates a new high-level client that connects to a node on the given
123          * host.
124          * 
125          * @param clientName
126          *            The name of the client
127          * @param host
128          *            The hostname of the node
129          * @throws UnknownHostException
130          *             if the hostname of the node can not be resolved.
131          */
132         public HighLevelClient(String clientName, String host) throws UnknownHostException {
133                 this(clientName, host, FcpConnection.DEFAULT_PORT);
134         }
135
136         /**
137          * Creates a new high-level client that connects to a node on the given
138          * host.
139          * 
140          * @param clientName
141          *            The name of the client
142          * @param host
143          *            The hostname of the node
144          * @param port
145          *            The port number of the node
146          * @throws UnknownHostException
147          *             if the hostname of the node can not be resolved.
148          */
149         public HighLevelClient(String clientName, String host, int port) throws UnknownHostException {
150                 this(clientName, InetAddress.getByName(host), port);
151         }
152
153         /**
154          * Creates a new high-level client that connects to a node at the given
155          * address.
156          * 
157          * @param clientName
158          *            The name of the client
159          * @param address
160          *            The address of the node
161          * @param port
162          *            The port number of the node
163          */
164         public HighLevelClient(String clientName, InetAddress address, int port) {
165                 this.clientName = clientName;
166                 this.address = address;
167                 this.port = port;
168         }
169
170         //
171         // ACCESSORS
172         //
173
174         //
175         // ACTIONS
176         //
177
178         /**
179          * Connects the client.
180          * 
181          * @return A callback with a connection result
182          * @throws IOException
183          *             if an I/O error occurs communicating with the node
184          */
185         public HighLevelCallback<ConnectResult> connect() throws IOException {
186                 fcpConnection = new FcpConnection(address, port);
187                 fcpConnection.addFcpListener(highLevelClientFcpListener);
188                 ClientHello clientHello = new ClientHello(clientName);
189                 connectCallback = new HighLevelCallback<ConnectResult>(new ConnectResult());
190                 fcpConnection.sendMessage(clientHello);
191                 return connectCallback;
192         }
193
194         /**
195          * Disconnects the client from the node.
196          */
197         public void disconnect() {
198         }
199
200         /**
201          * Generates a new SSK keypair.
202          * 
203          * @return A callback with the keypair
204          * @throws IOException
205          *             if an I/O error occurs communicating with the node
206          */
207         public HighLevelCallback<KeyGenerationResult> generateKey() throws IOException {
208                 String identifier = generateIdentifier("generateSSK");
209                 GenerateSSK generateSSK = new GenerateSSK(identifier);
210                 HighLevelCallback<KeyGenerationResult> keyGenerationCallback = new HighLevelCallback<KeyGenerationResult>(new KeyGenerationResult());
211                 keyGenerationCallbacks.put(identifier, keyGenerationCallback);
212                 fcpConnection.sendMessage(generateSSK);
213                 return keyGenerationCallback;
214         }
215
216         /**
217          * Gets a list of all peers from the node.
218          * 
219          * @return A callback with the peer list
220          * @throws IOException
221          *             if an I/O error occurs with the node
222          */
223         public HighLevelCallback<PeerListResult> getPeers() throws IOException {
224                 String identifier = generateIdentifier("listPeers");
225                 ListPeers listPeers = new ListPeers(identifier, true, true);
226                 HighLevelCallback<PeerListResult> peerListCallback = new HighLevelCallback<PeerListResult>(new PeerListResult());
227                 peerListCallbacks.put(identifier, peerListCallback);
228                 fcpConnection.sendMessage(listPeers);
229                 return peerListCallback;
230         }
231
232         /**
233          * Generates an identifier for the given function.
234          * 
235          * @param function
236          *            The name of the function
237          * @return An identifier
238          */
239         private String generateIdentifier(String function) {
240                 return "jFCPlib-" + function + "-" + System.currentTimeMillis();
241         }
242
243         /**
244          * FCP listener for {@link HighLevelClient}.
245          * 
246          * @author David ‘Bombe’ Roden &lt;bombe@freenetproject.org&gt;
247          * @version $Id$
248          */
249         private class HighLevelClientFcpListener implements FcpListener {
250
251                 /**
252                  * Creates a new FCP listener for {@link HighLevelClient}.
253                  */
254                 HighLevelClientFcpListener() {
255                 }
256
257                 //
258                 // PRIVATE METHODS
259                 //
260
261                 /**
262                  * Searches all callback collections for a callback with the given
263                  * identifier and cancels it.
264                  * 
265                  * @param identifier
266                  *            The identifier to search for, or <code>null</code> to
267                  *            cancel all pending requests
268                  */
269                 @SuppressWarnings("synthetic-access")
270                 private void cancelIdentifier(String identifier) {
271                         synchronized (syncObject) {
272                                 if (connectCallback != null) {
273                                         connectCallback.getIntermediaryResult().setFailed(true);
274                                         connectCallback.setDone();
275                                         connectCallback = null;
276                                 }
277                         }
278                         if (identifier == null) {
279                                 /* key generation callbacks */
280                                 for (Entry<String, HighLevelCallback<KeyGenerationResult>> keyGenerationEntry: keyGenerationCallbacks.entrySet()) {
281                                         keyGenerationEntry.getValue().getIntermediaryResult().setFailed(true);
282                                         keyGenerationEntry.getValue().setDone();
283                                 }
284                                 keyGenerationCallbacks.clear();
285                                 /* peer list callbacks. */
286                                 for (Entry<String, HighLevelCallback<PeerListResult>> peerListEntry: peerListCallbacks.entrySet()) {
287                                         peerListEntry.getValue().getIntermediaryResult().setFailed(true);
288                                         peerListEntry.getValue().setDone();
289                                 }
290                                 peerListCallbacks.clear();
291                         } else {
292                                 HighLevelCallback<KeyGenerationResult> keyGenerationCallback = keyGenerationCallbacks.remove(identifier);
293                                 if (keyGenerationCallback != null) {
294                                         keyGenerationCallback.getIntermediaryResult().setFailed(true);
295                                         keyGenerationCallback.setDone();
296                                         return;
297                                 }
298                                 HighLevelCallback<PeerListResult> peerListCallback = peerListCallbacks.remove(identifier);
299                                 if (peerListCallback != null) {
300                                         peerListCallback.getIntermediaryResult().setFailed(true);
301                                         peerListCallback.setDone();
302                                         return;
303                                 }
304                         }
305                 }
306
307                 //
308                 // INTERFACE FcpListener
309                 //
310
311                 /**
312                  * @see net.pterodactylus.fcp.FcpListener#connectionClosed(net.pterodactylus.fcp.FcpConnection)
313                  */
314                 @SuppressWarnings("synthetic-access")
315                 public void connectionClosed(FcpConnection fcpConnection) {
316                         if (fcpConnection != HighLevelClient.this.fcpConnection) {
317                                 return;
318                         }
319                         cancelIdentifier(null);
320                 }
321
322                 /**
323                  * @see net.pterodactylus.fcp.FcpListener#receivedAllData(net.pterodactylus.fcp.FcpConnection,
324                  *      net.pterodactylus.fcp.AllData)
325                  */
326                 public void receivedAllData(FcpConnection fcpConnection, AllData allData) {
327                 }
328
329                 /**
330                  * @see net.pterodactylus.fcp.FcpListener#receivedCloseConnectionDuplicateClientName(net.pterodactylus.fcp.FcpConnection,
331                  *      net.pterodactylus.fcp.CloseConnectionDuplicateClientName)
332                  */
333                 public void receivedCloseConnectionDuplicateClientName(FcpConnection fcpConnection, CloseConnectionDuplicateClientName closeConnectionDuplicateClientName) {
334                 }
335
336                 /**
337                  * @see net.pterodactylus.fcp.FcpListener#receivedConfigData(net.pterodactylus.fcp.FcpConnection,
338                  *      net.pterodactylus.fcp.ConfigData)
339                  */
340                 public void receivedConfigData(FcpConnection fcpConnection, ConfigData configData) {
341                 }
342
343                 /**
344                  * @see net.pterodactylus.fcp.FcpListener#receivedDataFound(net.pterodactylus.fcp.FcpConnection,
345                  *      net.pterodactylus.fcp.DataFound)
346                  */
347                 public void receivedDataFound(FcpConnection fcpConnection, DataFound dataFound) {
348                 }
349
350                 /**
351                  * @see net.pterodactylus.fcp.FcpListener#receivedEndListPeerNotes(net.pterodactylus.fcp.FcpConnection,
352                  *      net.pterodactylus.fcp.EndListPeerNotes)
353                  */
354                 public void receivedEndListPeerNotes(FcpConnection fcpConnection, EndListPeerNotes endListPeerNotes) {
355                 }
356
357                 /**
358                  * @see net.pterodactylus.fcp.FcpListener#receivedEndListPeers(net.pterodactylus.fcp.FcpConnection,
359                  *      net.pterodactylus.fcp.EndListPeers)
360                  */
361                 @SuppressWarnings("synthetic-access")
362                 public void receivedEndListPeers(FcpConnection fcpConnection, EndListPeers endListPeers) {
363                         if (fcpConnection != HighLevelClient.this.fcpConnection) {
364                                 return;
365                         }
366                         String identifier = endListPeers.getIdentifier();
367                         HighLevelCallback<PeerListResult> peerListCallback = peerListCallbacks.remove(identifier);
368                         if (peerListCallback == null) {
369                                 return;
370                         }
371                         peerListCallback.setDone();
372                 }
373
374                 /**
375                  * @see net.pterodactylus.fcp.FcpListener#receivedEndListPersistentRequests(net.pterodactylus.fcp.FcpConnection,
376                  *      net.pterodactylus.fcp.EndListPersistentRequests)
377                  */
378                 public void receivedEndListPersistentRequests(FcpConnection fcpConnection, EndListPersistentRequests endListPersistentRequests) {
379                 }
380
381                 /**
382                  * @see net.pterodactylus.fcp.FcpListener#receivedFCPPluginReply(net.pterodactylus.fcp.FcpConnection,
383                  *      net.pterodactylus.fcp.FCPPluginReply)
384                  */
385                 public void receivedFCPPluginReply(FcpConnection fcpConnection, FCPPluginReply fcpPluginReply) {
386                 }
387
388                 /**
389                  * @see net.pterodactylus.fcp.FcpListener#receivedGetFailed(net.pterodactylus.fcp.FcpConnection,
390                  *      net.pterodactylus.fcp.GetFailed)
391                  */
392                 public void receivedGetFailed(FcpConnection fcpConnection, GetFailed getFailed) {
393                 }
394
395                 /**
396                  * @see net.pterodactylus.fcp.FcpListener#receivedIdentifierCollision(net.pterodactylus.fcp.FcpConnection,
397                  *      net.pterodactylus.fcp.IdentifierCollision)
398                  */
399                 public void receivedIdentifierCollision(FcpConnection fcpConnection, IdentifierCollision identifierCollision) {
400                 }
401
402                 /**
403                  * @see net.pterodactylus.fcp.FcpListener#receivedMessage(net.pterodactylus.fcp.FcpConnection,
404                  *      net.pterodactylus.fcp.FcpMessage)
405                  */
406                 public void receivedMessage(FcpConnection fcpConnection, FcpMessage fcpMessage) {
407                 }
408
409                 /**
410                  * @see net.pterodactylus.fcp.FcpListener#receivedNodeData(net.pterodactylus.fcp.FcpConnection,
411                  *      net.pterodactylus.fcp.NodeData)
412                  */
413                 public void receivedNodeData(FcpConnection fcpConnection, NodeData nodeData) {
414                 }
415
416                 /**
417                  * @see net.pterodactylus.fcp.FcpListener#receivedNodeHello(net.pterodactylus.fcp.FcpConnection,
418                  *      net.pterodactylus.fcp.NodeHello)
419                  */
420                 @SuppressWarnings("synthetic-access")
421                 public void receivedNodeHello(FcpConnection fcpConnection, NodeHello nodeHello) {
422                         if (fcpConnection != HighLevelClient.this.fcpConnection) {
423                                 return;
424                         }
425                         synchronized (syncObject) {
426                                 connectCallback.getIntermediaryResult().setFailed(false);
427                                 connectCallback.setDone();
428                                 connectCallback = null;
429                         }
430                 }
431
432                 /**
433                  * @see net.pterodactylus.fcp.FcpListener#receivedPeer(net.pterodactylus.fcp.FcpConnection,
434                  *      net.pterodactylus.fcp.Peer)
435                  */
436                 @SuppressWarnings("synthetic-access")
437                 public void receivedPeer(FcpConnection fcpConnection, Peer peer) {
438                         if (fcpConnection != HighLevelClient.this.fcpConnection) {
439                                 return;
440                         }
441                         String identifier = peer.getIdentifier();
442                         HighLevelCallback<PeerListResult> peerListCallback = peerListCallbacks.get(identifier);
443                         if (peerListCallback == null) {
444                                 return;
445                         }
446                         peerListCallback.getIntermediaryResult().addPeer(peer);
447                 }
448
449                 /**
450                  * @see net.pterodactylus.fcp.FcpListener#receivedPeerNote(net.pterodactylus.fcp.FcpConnection,
451                  *      net.pterodactylus.fcp.PeerNote)
452                  */
453                 public void receivedPeerNote(FcpConnection fcpConnection, PeerNote peerNote) {
454                 }
455
456                 /**
457                  * @see net.pterodactylus.fcp.FcpListener#receivedPeerRemoved(net.pterodactylus.fcp.FcpConnection,
458                  *      net.pterodactylus.fcp.PeerRemoved)
459                  */
460                 public void receivedPeerRemoved(FcpConnection fcpConnection, PeerRemoved peerRemoved) {
461                 }
462
463                 /**
464                  * @see net.pterodactylus.fcp.FcpListener#receivedPersistentGet(net.pterodactylus.fcp.FcpConnection,
465                  *      net.pterodactylus.fcp.PersistentGet)
466                  */
467                 public void receivedPersistentGet(FcpConnection fcpConnection, PersistentGet persistentGet) {
468                 }
469
470                 /**
471                  * @see net.pterodactylus.fcp.FcpListener#receivedPersistentPut(net.pterodactylus.fcp.FcpConnection,
472                  *      net.pterodactylus.fcp.PersistentPut)
473                  */
474                 public void receivedPersistentPut(FcpConnection fcpConnection, PersistentPut persistentPut) {
475                 }
476
477                 /**
478                  * @see net.pterodactylus.fcp.FcpListener#receivedPersistentPutDir(net.pterodactylus.fcp.FcpConnection,
479                  *      net.pterodactylus.fcp.PersistentPutDir)
480                  */
481                 public void receivedPersistentPutDir(FcpConnection fcpConnection, PersistentPutDir persistentPutDir) {
482                 }
483
484                 /**
485                  * @see net.pterodactylus.fcp.FcpListener#receivedPersistentRequestModified(net.pterodactylus.fcp.FcpConnection,
486                  *      net.pterodactylus.fcp.PersistentRequestModified)
487                  */
488                 public void receivedPersistentRequestModified(FcpConnection fcpConnection, PersistentRequestModified persistentRequestModified) {
489                 }
490
491                 /**
492                  * @see net.pterodactylus.fcp.FcpListener#receivedPersistentRequestRemoved(net.pterodactylus.fcp.FcpConnection,
493                  *      net.pterodactylus.fcp.PersistentRequestRemoved)
494                  */
495                 public void receivedPersistentRequestRemoved(FcpConnection fcpConnection, PersistentRequestRemoved persistentRequestRemoved) {
496                 }
497
498                 /**
499                  * @see net.pterodactylus.fcp.FcpListener#receivedPluginInfo(net.pterodactylus.fcp.FcpConnection,
500                  *      net.pterodactylus.fcp.PluginInfo)
501                  */
502                 public void receivedPluginInfo(FcpConnection fcpConnection, PluginInfo pluginInfo) {
503                 }
504
505                 /**
506                  * @see net.pterodactylus.fcp.FcpListener#receivedProtocolError(net.pterodactylus.fcp.FcpConnection,
507                  *      net.pterodactylus.fcp.ProtocolError)
508                  */
509                 @SuppressWarnings("synthetic-access")
510                 public void receivedProtocolError(FcpConnection fcpConnection, ProtocolError protocolError) {
511                         if (fcpConnection != HighLevelClient.this.fcpConnection) {
512                                 return;
513                         }
514                         String identifier = protocolError.getIdentifier();
515                         if (identifier == null) {
516                                 return;
517                         }
518                         cancelIdentifier(identifier);
519                 }
520
521                 /**
522                  * @see net.pterodactylus.fcp.FcpListener#receivedPutFailed(net.pterodactylus.fcp.FcpConnection,
523                  *      net.pterodactylus.fcp.PutFailed)
524                  */
525                 public void receivedPutFailed(FcpConnection fcpConnection, PutFailed putFailed) {
526                 }
527
528                 /**
529                  * @see net.pterodactylus.fcp.FcpListener#receivedPutFetchable(net.pterodactylus.fcp.FcpConnection,
530                  *      net.pterodactylus.fcp.PutFetchable)
531                  */
532                 public void receivedPutFetchable(FcpConnection fcpConnection, PutFetchable putFetchable) {
533                 }
534
535                 /**
536                  * @see net.pterodactylus.fcp.FcpListener#receivedPutSuccessful(net.pterodactylus.fcp.FcpConnection,
537                  *      net.pterodactylus.fcp.PutSuccessful)
538                  */
539                 public void receivedPutSuccessful(FcpConnection fcpConnection, PutSuccessful putSuccessful) {
540                 }
541
542                 /**
543                  * @see net.pterodactylus.fcp.FcpListener#receivedSSKKeypair(net.pterodactylus.fcp.FcpConnection,
544                  *      net.pterodactylus.fcp.SSKKeypair)
545                  */
546                 @SuppressWarnings("synthetic-access")
547                 public void receivedSSKKeypair(FcpConnection fcpConnection, SSKKeypair sskKeypair) {
548                         if (fcpConnection != HighLevelClient.this.fcpConnection) {
549                                 return;
550                         }
551                         HighLevelCallback<KeyGenerationResult> keyGenerationCallback = keyGenerationCallbacks.remove(sskKeypair.getIdentifier());
552                         if (keyGenerationCallback == null) {
553                                 return;
554                         }
555                         KeyGenerationResult keyGenerationResult = keyGenerationCallback.getIntermediaryResult();
556                         keyGenerationResult.setInsertURI(sskKeypair.getInsertURI());
557                         keyGenerationResult.setRequestURI(sskKeypair.getRequestURI());
558                         keyGenerationCallback.setDone();
559                 }
560
561                 /**
562                  * @see net.pterodactylus.fcp.FcpListener#receivedSimpleProgress(net.pterodactylus.fcp.FcpConnection,
563                  *      net.pterodactylus.fcp.SimpleProgress)
564                  */
565                 public void receivedSimpleProgress(FcpConnection fcpConnection, SimpleProgress simpleProgress) {
566                 }
567
568                 /**
569                  * @see net.pterodactylus.fcp.FcpListener#receivedStartedCompression(net.pterodactylus.fcp.FcpConnection,
570                  *      net.pterodactylus.fcp.StartedCompression)
571                  */
572                 public void receivedStartedCompression(FcpConnection fcpConnection, StartedCompression startedCompression) {
573                 }
574
575                 /**
576                  * @see net.pterodactylus.fcp.FcpListener#receivedSubscribedUSKUpdate(net.pterodactylus.fcp.FcpConnection,
577                  *      net.pterodactylus.fcp.SubscribedUSKUpdate)
578                  */
579                 public void receivedSubscribedUSKUpdate(FcpConnection fcpConnection, SubscribedUSKUpdate subscribedUSKUpdate) {
580                 }
581
582                 /**
583                  * @see net.pterodactylus.fcp.FcpListener#receivedTestDDAComplete(net.pterodactylus.fcp.FcpConnection,
584                  *      net.pterodactylus.fcp.TestDDAComplete)
585                  */
586                 public void receivedTestDDAComplete(FcpConnection fcpConnection, TestDDAComplete testDDAComplete) {
587                 }
588
589                 /**
590                  * @see net.pterodactylus.fcp.FcpListener#receivedTestDDAReply(net.pterodactylus.fcp.FcpConnection,
591                  *      net.pterodactylus.fcp.TestDDAReply)
592                  */
593                 public void receivedTestDDAReply(FcpConnection fcpConnection, TestDDAReply testDDAReply) {
594                 }
595
596                 /**
597                  * @see net.pterodactylus.fcp.FcpListener#receivedURIGenerated(net.pterodactylus.fcp.FcpConnection,
598                  *      net.pterodactylus.fcp.URIGenerated)
599                  */
600                 public void receivedURIGenerated(FcpConnection fcpConnection, URIGenerated uriGenerated) {
601                 }
602
603                 /**
604                  * @see net.pterodactylus.fcp.FcpListener#receivedUnknownNodeIdentifier(net.pterodactylus.fcp.FcpConnection,
605                  *      net.pterodactylus.fcp.UnknownNodeIdentifier)
606                  */
607                 public void receivedUnknownNodeIdentifier(FcpConnection fcpConnection, UnknownNodeIdentifier unknownNodeIdentifier) {
608                 }
609
610                 /**
611                  * @see net.pterodactylus.fcp.FcpListener#receivedUnknownPeerNoteType(net.pterodactylus.fcp.FcpConnection,
612                  *      net.pterodactylus.fcp.UnknownPeerNoteType)
613                  */
614                 public void receivedUnknownPeerNoteType(FcpConnection fcpConnection, UnknownPeerNoteType unknownPeerNoteType) {
615                 }
616
617                 /**
618                  * @see net.pterodactylus.fcp.FcpListener#receviedFinishedCompression(net.pterodactylus.fcp.FcpConnection,
619                  *      net.pterodactylus.fcp.FinishedCompression)
620                  */
621                 public void receviedFinishedCompression(FcpConnection fcpConnection, FinishedCompression finishedCompression) {
622                 }
623
624         }
625
626 }