Add dedicated listener manager.
[jFCPlib.git] / src / net / pterodactylus / fcp / FcpConnection.java
index 0dc1e7f..05d8815 100644 (file)
@@ -19,6 +19,7 @@
 
 package net.pterodactylus.fcp;
 
+import java.io.Closeable;
 import java.io.FilterInputStream;
 import java.io.IOException;
 import java.io.InputStream;
@@ -31,14 +32,17 @@ import java.util.Collections;
 import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
+import java.util.logging.Logger;
 
 /**
  * An FCP connection to a Freenet node.
  * 
  * @author David ‘Bombe’ Roden <bombe@freenetproject.org>
- * @version $Id$
  */
-public class FcpConnection {
+public class FcpConnection implements Closeable {
+
+       /** Logger. */
+       private static final Logger logger = Logger.getLogger(FcpConnection.class.getName());
 
        /** The default port for FCP v2. */
        public static final int DEFAULT_PORT = 9481;
@@ -163,7 +167,7 @@ public class FcpConnection {
         *            The “NodeHello” message
         */
        private void fireReceivedNodeHello(NodeHello nodeHello) {
-               for (FcpListener fcpListener: fcpListeners) {
+               for (FcpListener fcpListener : fcpListeners) {
                        fcpListener.receivedNodeHello(this, nodeHello);
                }
        }
@@ -178,7 +182,7 @@ public class FcpConnection {
         *            The “CloseConnectionDuplicateClientName” message
         */
        private void fireReceivedCloseConnectionDuplicateClientName(CloseConnectionDuplicateClientName closeConnectionDuplicateClientName) {
-               for (FcpListener fcpListener: fcpListeners) {
+               for (FcpListener fcpListener : fcpListeners) {
                        fcpListener.receivedCloseConnectionDuplicateClientName(this, closeConnectionDuplicateClientName);
                }
        }
@@ -191,7 +195,7 @@ public class FcpConnection {
         *            The “SSKKeypair” message
         */
        private void fireReceivedSSKKeypair(SSKKeypair sskKeypair) {
-               for (FcpListener fcpListener: fcpListeners) {
+               for (FcpListener fcpListener : fcpListeners) {
                        fcpListener.receivedSSKKeypair(this, sskKeypair);
                }
        }
@@ -204,7 +208,7 @@ public class FcpConnection {
         *            The “Peer” message
         */
        private void fireReceivedPeer(Peer peer) {
-               for (FcpListener fcpListener: fcpListeners) {
+               for (FcpListener fcpListener : fcpListeners) {
                        fcpListener.receivedPeer(this, peer);
                }
        }
@@ -217,7 +221,7 @@ public class FcpConnection {
         *            The “EndListPeers” message
         */
        private void fireReceivedEndListPeers(EndListPeers endListPeers) {
-               for (FcpListener fcpListener: fcpListeners) {
+               for (FcpListener fcpListener : fcpListeners) {
                        fcpListener.receivedEndListPeers(this, endListPeers);
                }
        }
@@ -229,7 +233,7 @@ public class FcpConnection {
         * @param peerNote
         */
        private void fireReceivedPeerNote(PeerNote peerNote) {
-               for (FcpListener fcpListener: fcpListeners) {
+               for (FcpListener fcpListener : fcpListeners) {
                        fcpListener.receivedPeerNote(this, peerNote);
                }
        }
@@ -243,7 +247,7 @@ public class FcpConnection {
         *            The “EndListPeerNotes” message
         */
        private void fireReceivedEndListPeerNotes(EndListPeerNotes endListPeerNotes) {
-               for (FcpListener fcpListener: fcpListeners) {
+               for (FcpListener fcpListener : fcpListeners) {
                        fcpListener.receivedEndListPeerNotes(this, endListPeerNotes);
                }
        }
@@ -256,7 +260,7 @@ public class FcpConnection {
         *            The “PeerRemoved” message
         */
        private void fireReceivedPeerRemoved(PeerRemoved peerRemoved) {
-               for (FcpListener fcpListener: fcpListeners) {
+               for (FcpListener fcpListener : fcpListeners) {
                        fcpListener.receivedPeerRemoved(this, peerRemoved);
                }
        }
@@ -269,7 +273,7 @@ public class FcpConnection {
         *            The “NodeData” message
         */
        private void fireReceivedNodeData(NodeData nodeData) {
-               for (FcpListener fcpListener: fcpListeners) {
+               for (FcpListener fcpListener : fcpListeners) {
                        fcpListener.receivedNodeData(this, nodeData);
                }
        }
@@ -282,7 +286,7 @@ public class FcpConnection {
         *            The “TestDDAReply” message
         */
        private void fireReceivedTestDDAReply(TestDDAReply testDDAReply) {
-               for (FcpListener fcpListener: fcpListeners) {
+               for (FcpListener fcpListener : fcpListeners) {
                        fcpListener.receivedTestDDAReply(this, testDDAReply);
                }
        }
@@ -295,7 +299,7 @@ public class FcpConnection {
         *            The “TestDDAComplete” message
         */
        private void fireReceivedTestDDAComplete(TestDDAComplete testDDAComplete) {
-               for (FcpListener fcpListener: fcpListeners) {
+               for (FcpListener fcpListener : fcpListeners) {
                        fcpListener.receivedTestDDAComplete(this, testDDAComplete);
                }
        }
@@ -308,7 +312,7 @@ public class FcpConnection {
         *            The “PersistentGet” message
         */
        private void fireReceivedPersistentGet(PersistentGet persistentGet) {
-               for (FcpListener fcpListener: fcpListeners) {
+               for (FcpListener fcpListener : fcpListeners) {
                        fcpListener.receivedPersistentGet(this, persistentGet);
                }
        }
@@ -321,7 +325,7 @@ public class FcpConnection {
         *            The “PersistentPut” message
         */
        private void fireReceivedPersistentPut(PersistentPut persistentPut) {
-               for (FcpListener fcpListener: fcpListeners) {
+               for (FcpListener fcpListener : fcpListeners) {
                        fcpListener.receivedPersistentPut(this, persistentPut);
                }
        }
@@ -336,7 +340,7 @@ public class FcpConnection {
         *            The “EndListPersistentRequests” message
         */
        private void fireReceivedEndListPersistentRequests(EndListPersistentRequests endListPersistentRequests) {
-               for (FcpListener fcpListener: fcpListeners) {
+               for (FcpListener fcpListener : fcpListeners) {
                        fcpListener.receivedEndListPersistentRequests(this, endListPersistentRequests);
                }
        }
@@ -349,7 +353,7 @@ public class FcpConnection {
         *            The “URIGenerated” message
         */
        private void fireReceivedURIGenerated(URIGenerated uriGenerated) {
-               for (FcpListener fcpListener: fcpListeners) {
+               for (FcpListener fcpListener : fcpListeners) {
                        fcpListener.receivedURIGenerated(this, uriGenerated);
                }
        }
@@ -362,7 +366,7 @@ public class FcpConnection {
         *            The “DataFound” message
         */
        private void fireReceivedDataFound(DataFound dataFound) {
-               for (FcpListener fcpListener: fcpListeners) {
+               for (FcpListener fcpListener : fcpListeners) {
                        fcpListener.receivedDataFound(this, dataFound);
                }
        }
@@ -375,7 +379,7 @@ public class FcpConnection {
         *            The “AllData” message
         */
        private void fireReceivedAllData(AllData allData) {
-               for (FcpListener fcpListener: fcpListeners) {
+               for (FcpListener fcpListener : fcpListeners) {
                        fcpListener.receivedAllData(this, allData);
                }
        }
@@ -388,7 +392,7 @@ public class FcpConnection {
         *            The “SimpleProgress” message
         */
        private void fireReceivedSimpleProgress(SimpleProgress simpleProgress) {
-               for (FcpListener fcpListener: fcpListeners) {
+               for (FcpListener fcpListener : fcpListeners) {
                        fcpListener.receivedSimpleProgress(this, simpleProgress);
                }
        }
@@ -402,7 +406,7 @@ public class FcpConnection {
         *            The “StartedCompression” message
         */
        private void fireReceivedStartedCompression(StartedCompression startedCompression) {
-               for (FcpListener fcpListener: fcpListeners) {
+               for (FcpListener fcpListener : fcpListeners) {
                        fcpListener.receivedStartedCompression(this, startedCompression);
                }
        }
@@ -416,7 +420,7 @@ public class FcpConnection {
         *            The “FinishedCompression” message
         */
        private void fireReceivedFinishedCompression(FinishedCompression finishedCompression) {
-               for (FcpListener fcpListener: fcpListeners) {
+               for (FcpListener fcpListener : fcpListeners) {
                        fcpListener.receviedFinishedCompression(this, finishedCompression);
                }
        }
@@ -431,7 +435,7 @@ public class FcpConnection {
         *            The “UnknownPeerNoteType” message
         */
        private void fireReceivedUnknownPeerNoteType(UnknownPeerNoteType unknownPeerNoteType) {
-               for (FcpListener fcpListener: fcpListeners) {
+               for (FcpListener fcpListener : fcpListeners) {
                        fcpListener.receivedUnknownPeerNoteType(this, unknownPeerNoteType);
                }
        }
@@ -446,7 +450,7 @@ public class FcpConnection {
         *            The “UnknownNodeIdentifier” message
         */
        private void fireReceivedUnknownNodeIdentifier(UnknownNodeIdentifier unknownNodeIdentifier) {
-               for (FcpListener fcpListener: fcpListeners) {
+               for (FcpListener fcpListener : fcpListeners) {
                        fcpListener.receivedUnknownNodeIdentifier(this, unknownNodeIdentifier);
                }
        }
@@ -459,7 +463,7 @@ public class FcpConnection {
         *            The “ConfigData” message
         */
        private void fireReceivedConfigData(ConfigData configData) {
-               for (FcpListener fcpListener: fcpListeners) {
+               for (FcpListener fcpListener : fcpListeners) {
                        fcpListener.receivedConfigData(this, configData);
                }
        }
@@ -472,7 +476,7 @@ public class FcpConnection {
         *            The “GetFailed” message
         */
        private void fireReceivedGetFailed(GetFailed getFailed) {
-               for (FcpListener fcpListener: fcpListeners) {
+               for (FcpListener fcpListener : fcpListeners) {
                        fcpListener.receivedGetFailed(this, getFailed);
                }
        }
@@ -485,7 +489,7 @@ public class FcpConnection {
         *            The “PutFailed” message
         */
        private void fireReceivedPutFailed(PutFailed putFailed) {
-               for (FcpListener fcpListener: fcpListeners) {
+               for (FcpListener fcpListener : fcpListeners) {
                        fcpListener.receivedPutFailed(this, putFailed);
                }
        }
@@ -500,7 +504,7 @@ public class FcpConnection {
         *            The “IdentifierCollision” message
         */
        private void fireReceivedIdentifierCollision(IdentifierCollision identifierCollision) {
-               for (FcpListener fcpListener: fcpListeners) {
+               for (FcpListener fcpListener : fcpListeners) {
                        fcpListener.receivedIdentifierCollision(this, identifierCollision);
                }
        }
@@ -514,7 +518,7 @@ public class FcpConnection {
         *            The “PersistentPutDir” message
         */
        private void fireReceivedPersistentPutDir(PersistentPutDir persistentPutDir) {
-               for (FcpListener fcpListener: fcpListeners) {
+               for (FcpListener fcpListener : fcpListeners) {
                        fcpListener.receivedPersistentPutDir(this, persistentPutDir);
                }
        }
@@ -529,7 +533,7 @@ public class FcpConnection {
         *            The “PersistentRequestRemoved” message
         */
        private void fireReceivedPersistentRequestRemoved(PersistentRequestRemoved persistentRequestRemoved) {
-               for (FcpListener fcpListener: fcpListeners) {
+               for (FcpListener fcpListener : fcpListeners) {
                        fcpListener.receivedPersistentRequestRemoved(this, persistentRequestRemoved);
                }
        }
@@ -543,7 +547,7 @@ public class FcpConnection {
         *            The “SubscribedUSKUpdate” message
         */
        private void fireReceivedSubscribedUSKUpdate(SubscribedUSKUpdate subscribedUSKUpdate) {
-               for (FcpListener fcpListener: fcpListeners) {
+               for (FcpListener fcpListener : fcpListeners) {
                        fcpListener.receivedSubscribedUSKUpdate(this, subscribedUSKUpdate);
                }
        }
@@ -556,7 +560,7 @@ public class FcpConnection {
         *            The “PluginInfo” message
         */
        private void fireReceivedPluginInfo(PluginInfo pluginInfo) {
-               for (FcpListener fcpListener: fcpListeners) {
+               for (FcpListener fcpListener : fcpListeners) {
                        fcpListener.receivedPluginInfo(this, pluginInfo);
                }
        }
@@ -569,7 +573,7 @@ public class FcpConnection {
         *            The “FCPPluginReply” message
         */
        private void fireReceivedFCPPluginReply(FCPPluginReply fcpPluginReply) {
-               for (FcpListener fcpListener: fcpListeners) {
+               for (FcpListener fcpListener : fcpListeners) {
                        fcpListener.receivedFCPPluginReply(this, fcpPluginReply);
                }
        }
@@ -584,7 +588,7 @@ public class FcpConnection {
         *            The “PersistentRequestModified” message
         */
        private void fireReceivedPersistentRequestModified(PersistentRequestModified persistentRequestModified) {
-               for (FcpListener fcpListener: fcpListeners) {
+               for (FcpListener fcpListener : fcpListeners) {
                        fcpListener.receivedPersistentRequestModified(this, persistentRequestModified);
                }
        }
@@ -597,7 +601,7 @@ public class FcpConnection {
         *            The “PutSuccessful” message
         */
        private void fireReceivedPutSuccessful(PutSuccessful putSuccessful) {
-               for (FcpListener fcpListener: fcpListeners) {
+               for (FcpListener fcpListener : fcpListeners) {
                        fcpListener.receivedPutSuccessful(this, putSuccessful);
                }
        }
@@ -610,7 +614,7 @@ public class FcpConnection {
         *            The “PutFetchable” message
         */
        private void fireReceivedPutFetchable(PutFetchable putFetchable) {
-               for (FcpListener fcpListener: fcpListeners) {
+               for (FcpListener fcpListener : fcpListeners) {
                        fcpListener.receivedPutFetchable(this, putFetchable);
                }
        }
@@ -623,7 +627,7 @@ public class FcpConnection {
         *            The “ProtocolError” message
         */
        private void fireReceivedProtocolError(ProtocolError protocolError) {
-               for (FcpListener fcpListener: fcpListeners) {
+               for (FcpListener fcpListener : fcpListeners) {
                        fcpListener.receivedProtocolError(this, protocolError);
                }
        }
@@ -636,7 +640,7 @@ public class FcpConnection {
         *            The message that was received
         */
        private void fireMessageReceived(FcpMessage fcpMessage) {
-               for (FcpListener fcpListener: fcpListeners) {
+               for (FcpListener fcpListener : fcpListeners) {
                        fcpListener.receivedMessage(this, fcpMessage);
                }
        }
@@ -644,11 +648,14 @@ public class FcpConnection {
        /**
         * Notifies all listeners that the connection to the node was closed.
         * 
-        * @see FcpListener#connectionClosed(FcpConnection)
+        * @param throwable
+        *            The exception that caused the disconnect, or <code>null</code>
+        *            if there was no exception
+        * @see FcpListener#connectionClosed(FcpConnection, Throwable)
         */
-       private void fireConnectionClosed() {
-               for (FcpListener fcpListener: fcpListeners) {
-                       fcpListener.connectionClosed(this);
+       private void fireConnectionClosed(Throwable throwable) {
+               for (FcpListener fcpListener : fcpListeners) {
+                       fcpListener.connectionClosed(this, throwable);
                }
        }
 
@@ -668,6 +675,7 @@ public class FcpConnection {
                if (connectionHandler != null) {
                        throw new IllegalStateException("already connected, disconnect first");
                }
+               logger.info("connecting to " + address + ":" + port + "…");
                remoteSocket = new Socket(address, port);
                remoteInputStream = remoteSocket.getInputStream();
                remoteOutputStream = remoteSocket.getOutputStream();
@@ -677,15 +685,20 @@ public class FcpConnection {
        /**
         * Disconnects from the node. If there is no connection to the node, this
         * method does nothing.
+        * 
+        * @deprecated Use {@link #close()} instead
         */
+       @Deprecated
        public synchronized void disconnect() {
-               if (connectionHandler == null) {
-                       return;
-               }
-               FcpUtils.close(remoteSocket);
-               connectionHandler.stop();
-               connectionHandler = null;
-               fireConnectionClosed();
+               close();
+       }
+
+       /**
+        * Closes the connection. If there is no connection to the node, this method
+        * does nothing.
+        */
+       public void close() {
+               handleDisconnect(null);
        }
 
        /**
@@ -697,7 +710,7 @@ public class FcpConnection {
         *             if an I/O error occurs
         */
        public synchronized void sendMessage(FcpMessage fcpMessage) throws IOException {
-               System.out.println("sending message: " + fcpMessage.getName());
+               logger.fine("sending message: " + fcpMessage.getName());
                fcpMessage.write(remoteOutputStream);
        }
 
@@ -713,6 +726,7 @@ public class FcpConnection {
         *            The received message
         */
        void handleMessage(FcpMessage fcpMessage) {
+               logger.fine("received message: " + fcpMessage.getName());
                String messageName = fcpMessage.getName();
                countMessage(messageName);
                if ("SimpleProgress".equals(messageName)) {
@@ -804,13 +818,20 @@ public class FcpConnection {
 
        /**
         * Handles a disconnect from the node.
+        * 
+        * @param throwable
+        *            The exception that caused the disconnect, or <code>null</code>
+        *            if there was no exception
         */
-       synchronized void handleDisconnect() {
+       synchronized void handleDisconnect(Throwable throwable) {
                FcpUtils.close(remoteInputStream);
                FcpUtils.close(remoteOutputStream);
                FcpUtils.close(remoteSocket);
-               connectionHandler = null;
-               fireConnectionClosed();
+               if (connectionHandler != null) {
+                       connectionHandler.stop();
+                       connectionHandler = null;
+                       fireConnectionClosed(throwable);
+               }
        }
 
        //
@@ -830,6 +851,7 @@ public class FcpConnection {
                        oldValue = incomingMessageStatistics.get(name);
                }
                incomingMessageStatistics.put(name, oldValue + 1);
+               logger.finest("count for " + name + ": " + (oldValue + 1));
        }
 
        /**
@@ -850,8 +872,7 @@ public class FcpConnection {
         * A wrapper around an {@link InputStream} that only supplies a limit number
         * of bytes from the underlying input stream.
         * 
-        * @author <a href="mailto:dr@ina-germany.de">David Roden</a>
-        * @version $Id$
+        * @author David ‘Bombe’ Roden &lt;bombe@freenetproject.org&gt;
         */
        private static class LimitedInputStream extends FilterInputStream {