Move source and test files to maven’s favourite locations.
authorDavid ‘Bombe’ Roden <bombe@freenetproject.org>
Tue, 17 Nov 2009 21:03:02 +0000 (22:03 +0100)
committerDavid ‘Bombe’ Roden <bombe@freenetproject.org>
Tue, 17 Nov 2009 21:03:02 +0000 (22:03 +0100)
210 files changed:
.classpath
.project
src/main/java/net/pterodactylus/fcp/ARK.java [new file with mode: 0644]
src/main/java/net/pterodactylus/fcp/AbstractSendFeedMessage.java [new file with mode: 0644]
src/main/java/net/pterodactylus/fcp/AddPeer.java [new file with mode: 0644]
src/main/java/net/pterodactylus/fcp/AllData.java [new file with mode: 0644]
src/main/java/net/pterodactylus/fcp/BaseMessage.java [new file with mode: 0644]
src/main/java/net/pterodactylus/fcp/ClientGet.java [new file with mode: 0644]
src/main/java/net/pterodactylus/fcp/ClientHello.java [new file with mode: 0644]
src/main/java/net/pterodactylus/fcp/ClientPut.java [new file with mode: 0644]
src/main/java/net/pterodactylus/fcp/ClientPutComplexDir.java [new file with mode: 0644]
src/main/java/net/pterodactylus/fcp/ClientPutDiskDir.java [new file with mode: 0644]
src/main/java/net/pterodactylus/fcp/CloseConnectionDuplicateClientName.java [new file with mode: 0644]
src/main/java/net/pterodactylus/fcp/ConfigData.java [new file with mode: 0644]
src/main/java/net/pterodactylus/fcp/DSAGroup.java [new file with mode: 0644]
src/main/java/net/pterodactylus/fcp/DataFound.java [new file with mode: 0644]
src/main/java/net/pterodactylus/fcp/EndListPeerNotes.java [new file with mode: 0644]
src/main/java/net/pterodactylus/fcp/EndListPeers.java [new file with mode: 0644]
src/main/java/net/pterodactylus/fcp/EndListPersistentRequests.java [new file with mode: 0644]
src/main/java/net/pterodactylus/fcp/FCPPluginMessage.java [new file with mode: 0644]
src/main/java/net/pterodactylus/fcp/FCPPluginReply.java [new file with mode: 0644]
src/main/java/net/pterodactylus/fcp/FcpAdapter.java [new file with mode: 0644]
src/main/java/net/pterodactylus/fcp/FcpConnection.java [new file with mode: 0644]
src/main/java/net/pterodactylus/fcp/FcpConnectionHandler.java [new file with mode: 0644]
src/main/java/net/pterodactylus/fcp/FcpKeyPair.java [new file with mode: 0644]
src/main/java/net/pterodactylus/fcp/FcpListener.java [new file with mode: 0644]
src/main/java/net/pterodactylus/fcp/FcpListenerManager.java [new file with mode: 0644]
src/main/java/net/pterodactylus/fcp/FcpMessage.java [new file with mode: 0644]
src/main/java/net/pterodactylus/fcp/FcpTest.java [new file with mode: 0644]
src/main/java/net/pterodactylus/fcp/FcpUtils.java [new file with mode: 0644]
src/main/java/net/pterodactylus/fcp/FileEntry.java [new file with mode: 0644]
src/main/java/net/pterodactylus/fcp/FinishedCompression.java [new file with mode: 0644]
src/main/java/net/pterodactylus/fcp/GenerateSSK.java [new file with mode: 0644]
src/main/java/net/pterodactylus/fcp/GetConfig.java [new file with mode: 0644]
src/main/java/net/pterodactylus/fcp/GetFailed.java [new file with mode: 0644]
src/main/java/net/pterodactylus/fcp/GetNode.java [new file with mode: 0644]
src/main/java/net/pterodactylus/fcp/GetPluginInfo.java [new file with mode: 0644]
src/main/java/net/pterodactylus/fcp/GetRequestStatus.java [new file with mode: 0644]
src/main/java/net/pterodactylus/fcp/IdentifierCollision.java [new file with mode: 0644]
src/main/java/net/pterodactylus/fcp/ListPeer.java [new file with mode: 0644]
src/main/java/net/pterodactylus/fcp/ListPeerNotes.java [new file with mode: 0644]
src/main/java/net/pterodactylus/fcp/ListPeers.java [new file with mode: 0644]
src/main/java/net/pterodactylus/fcp/ListPersistentRequests.java [new file with mode: 0644]
src/main/java/net/pterodactylus/fcp/ModifyConfig.java [new file with mode: 0644]
src/main/java/net/pterodactylus/fcp/ModifyPeer.java [new file with mode: 0644]
src/main/java/net/pterodactylus/fcp/ModifyPeerNote.java [new file with mode: 0644]
src/main/java/net/pterodactylus/fcp/ModifyPersistentRequest.java [new file with mode: 0644]
src/main/java/net/pterodactylus/fcp/NodeData.java [new file with mode: 0644]
src/main/java/net/pterodactylus/fcp/NodeHello.java [new file with mode: 0644]
src/main/java/net/pterodactylus/fcp/NodeRef.java [new file with mode: 0644]
src/main/java/net/pterodactylus/fcp/Peer.java [new file with mode: 0644]
src/main/java/net/pterodactylus/fcp/PeerNote.java [new file with mode: 0644]
src/main/java/net/pterodactylus/fcp/PeerRemoved.java [new file with mode: 0644]
src/main/java/net/pterodactylus/fcp/Persistence.java [new file with mode: 0644]
src/main/java/net/pterodactylus/fcp/PersistentGet.java [new file with mode: 0644]
src/main/java/net/pterodactylus/fcp/PersistentPut.java [new file with mode: 0644]
src/main/java/net/pterodactylus/fcp/PersistentPutDir.java [new file with mode: 0644]
src/main/java/net/pterodactylus/fcp/PersistentRequestModified.java [new file with mode: 0644]
src/main/java/net/pterodactylus/fcp/PersistentRequestRemoved.java [new file with mode: 0644]
src/main/java/net/pterodactylus/fcp/PluginInfo.java [new file with mode: 0644]
src/main/java/net/pterodactylus/fcp/Priority.java [new file with mode: 0644]
src/main/java/net/pterodactylus/fcp/ProtocolError.java [new file with mode: 0644]
src/main/java/net/pterodactylus/fcp/PutFailed.java [new file with mode: 0644]
src/main/java/net/pterodactylus/fcp/PutFetchable.java [new file with mode: 0644]
src/main/java/net/pterodactylus/fcp/PutSuccessful.java [new file with mode: 0644]
src/main/java/net/pterodactylus/fcp/ReceivedBookmarkFeed.java [new file with mode: 0644]
src/main/java/net/pterodactylus/fcp/RemovePeer.java [new file with mode: 0644]
src/main/java/net/pterodactylus/fcp/RemovePersistentRequest.java [new file with mode: 0644]
src/main/java/net/pterodactylus/fcp/ReturnType.java [new file with mode: 0644]
src/main/java/net/pterodactylus/fcp/SSKKeypair.java [new file with mode: 0644]
src/main/java/net/pterodactylus/fcp/SendBookmarkFeed.java [new file with mode: 0644]
src/main/java/net/pterodactylus/fcp/SendDownloadFeed.java [new file with mode: 0644]
src/main/java/net/pterodactylus/fcp/SendTextFeed.java [new file with mode: 0644]
src/main/java/net/pterodactylus/fcp/SentFeed.java [new file with mode: 0644]
src/main/java/net/pterodactylus/fcp/Shutdown.java [new file with mode: 0644]
src/main/java/net/pterodactylus/fcp/SimpleProgress.java [new file with mode: 0644]
src/main/java/net/pterodactylus/fcp/StartedCompression.java [new file with mode: 0644]
src/main/java/net/pterodactylus/fcp/SubscribeFeeds.java [new file with mode: 0644]
src/main/java/net/pterodactylus/fcp/SubscribeUSK.java [new file with mode: 0644]
src/main/java/net/pterodactylus/fcp/SubscribedUSKUpdate.java [new file with mode: 0644]
src/main/java/net/pterodactylus/fcp/TestDDAComplete.java [new file with mode: 0644]
src/main/java/net/pterodactylus/fcp/TestDDAReply.java [new file with mode: 0644]
src/main/java/net/pterodactylus/fcp/TestDDARequest.java [new file with mode: 0644]
src/main/java/net/pterodactylus/fcp/TestDDAResponse.java [new file with mode: 0644]
src/main/java/net/pterodactylus/fcp/URIGenerated.java [new file with mode: 0644]
src/main/java/net/pterodactylus/fcp/UnknownNodeIdentifier.java [new file with mode: 0644]
src/main/java/net/pterodactylus/fcp/UnknownPeerNoteType.java [new file with mode: 0644]
src/main/java/net/pterodactylus/fcp/UploadFrom.java [new file with mode: 0644]
src/main/java/net/pterodactylus/fcp/Verbosity.java [new file with mode: 0644]
src/main/java/net/pterodactylus/fcp/Version.java [new file with mode: 0644]
src/main/java/net/pterodactylus/fcp/WatchGlobal.java [new file with mode: 0644]
src/main/java/net/pterodactylus/fcp/highlevel/FcpClient.java [new file with mode: 0644]
src/main/java/net/pterodactylus/fcp/highlevel/FcpClientListener.java [new file with mode: 0644]
src/main/java/net/pterodactylus/fcp/highlevel/FcpClientListenerManager.java [new file with mode: 0644]
src/main/java/net/pterodactylus/fcp/highlevel/FcpException.java [new file with mode: 0644]
src/main/java/net/pterodactylus/fcp/highlevel/GetRequest.java [new file with mode: 0644]
src/main/java/net/pterodactylus/fcp/highlevel/PutRequest.java [new file with mode: 0644]
src/main/java/net/pterodactylus/fcp/highlevel/Request.java [new file with mode: 0644]
src/main/java/net/pterodactylus/fcp/package-info.java [new file with mode: 0644]
src/main/java/net/pterodactylus/fcp/plugin/WebOfTrustPlugin.java [new file with mode: 0644]
src/main/java/net/pterodactylus/util/event/AbstractListenerManager.java [new file with mode: 0644]
src/main/java/net/pterodactylus/util/filter/Filter.java [new file with mode: 0644]
src/main/java/net/pterodactylus/util/filter/Filters.java [new file with mode: 0644]
src/main/java/net/pterodactylus/util/thread/CurrentThreadExecutor.java [new file with mode: 0644]
src/main/java/net/pterodactylus/util/thread/ObjectWrapper.java [new file with mode: 0644]
src/net/pterodactylus/fcp/ARK.java [deleted file]
src/net/pterodactylus/fcp/AbstractSendFeedMessage.java [deleted file]
src/net/pterodactylus/fcp/AddPeer.java [deleted file]
src/net/pterodactylus/fcp/AllData.java [deleted file]
src/net/pterodactylus/fcp/BaseMessage.java [deleted file]
src/net/pterodactylus/fcp/ClientGet.java [deleted file]
src/net/pterodactylus/fcp/ClientHello.java [deleted file]
src/net/pterodactylus/fcp/ClientPut.java [deleted file]
src/net/pterodactylus/fcp/ClientPutComplexDir.java [deleted file]
src/net/pterodactylus/fcp/ClientPutDiskDir.java [deleted file]
src/net/pterodactylus/fcp/CloseConnectionDuplicateClientName.java [deleted file]
src/net/pterodactylus/fcp/ConfigData.java [deleted file]
src/net/pterodactylus/fcp/DSAGroup.java [deleted file]
src/net/pterodactylus/fcp/DataFound.java [deleted file]
src/net/pterodactylus/fcp/EndListPeerNotes.java [deleted file]
src/net/pterodactylus/fcp/EndListPeers.java [deleted file]
src/net/pterodactylus/fcp/EndListPersistentRequests.java [deleted file]
src/net/pterodactylus/fcp/FCPPluginMessage.java [deleted file]
src/net/pterodactylus/fcp/FCPPluginReply.java [deleted file]
src/net/pterodactylus/fcp/FcpAdapter.java [deleted file]
src/net/pterodactylus/fcp/FcpConnection.java [deleted file]
src/net/pterodactylus/fcp/FcpConnectionHandler.java [deleted file]
src/net/pterodactylus/fcp/FcpKeyPair.java [deleted file]
src/net/pterodactylus/fcp/FcpListener.java [deleted file]
src/net/pterodactylus/fcp/FcpListenerManager.java [deleted file]
src/net/pterodactylus/fcp/FcpMessage.java [deleted file]
src/net/pterodactylus/fcp/FcpTest.java [deleted file]
src/net/pterodactylus/fcp/FcpUtils.java [deleted file]
src/net/pterodactylus/fcp/FileEntry.java [deleted file]
src/net/pterodactylus/fcp/FinishedCompression.java [deleted file]
src/net/pterodactylus/fcp/GenerateSSK.java [deleted file]
src/net/pterodactylus/fcp/GetConfig.java [deleted file]
src/net/pterodactylus/fcp/GetFailed.java [deleted file]
src/net/pterodactylus/fcp/GetNode.java [deleted file]
src/net/pterodactylus/fcp/GetPluginInfo.java [deleted file]
src/net/pterodactylus/fcp/GetRequestStatus.java [deleted file]
src/net/pterodactylus/fcp/IdentifierCollision.java [deleted file]
src/net/pterodactylus/fcp/ListPeer.java [deleted file]
src/net/pterodactylus/fcp/ListPeerNotes.java [deleted file]
src/net/pterodactylus/fcp/ListPeers.java [deleted file]
src/net/pterodactylus/fcp/ListPersistentRequests.java [deleted file]
src/net/pterodactylus/fcp/ModifyConfig.java [deleted file]
src/net/pterodactylus/fcp/ModifyPeer.java [deleted file]
src/net/pterodactylus/fcp/ModifyPeerNote.java [deleted file]
src/net/pterodactylus/fcp/ModifyPersistentRequest.java [deleted file]
src/net/pterodactylus/fcp/NodeData.java [deleted file]
src/net/pterodactylus/fcp/NodeHello.java [deleted file]
src/net/pterodactylus/fcp/NodeRef.java [deleted file]
src/net/pterodactylus/fcp/Peer.java [deleted file]
src/net/pterodactylus/fcp/PeerNote.java [deleted file]
src/net/pterodactylus/fcp/PeerRemoved.java [deleted file]
src/net/pterodactylus/fcp/Persistence.java [deleted file]
src/net/pterodactylus/fcp/PersistentGet.java [deleted file]
src/net/pterodactylus/fcp/PersistentPut.java [deleted file]
src/net/pterodactylus/fcp/PersistentPutDir.java [deleted file]
src/net/pterodactylus/fcp/PersistentRequestModified.java [deleted file]
src/net/pterodactylus/fcp/PersistentRequestRemoved.java [deleted file]
src/net/pterodactylus/fcp/PluginInfo.java [deleted file]
src/net/pterodactylus/fcp/Priority.java [deleted file]
src/net/pterodactylus/fcp/ProtocolError.java [deleted file]
src/net/pterodactylus/fcp/PutFailed.java [deleted file]
src/net/pterodactylus/fcp/PutFetchable.java [deleted file]
src/net/pterodactylus/fcp/PutSuccessful.java [deleted file]
src/net/pterodactylus/fcp/ReceivedBookmarkFeed.java [deleted file]
src/net/pterodactylus/fcp/RemovePeer.java [deleted file]
src/net/pterodactylus/fcp/RemovePersistentRequest.java [deleted file]
src/net/pterodactylus/fcp/ReturnType.java [deleted file]
src/net/pterodactylus/fcp/SSKKeypair.java [deleted file]
src/net/pterodactylus/fcp/SendBookmarkFeed.java [deleted file]
src/net/pterodactylus/fcp/SendDownloadFeed.java [deleted file]
src/net/pterodactylus/fcp/SendTextFeed.java [deleted file]
src/net/pterodactylus/fcp/SentFeed.java [deleted file]
src/net/pterodactylus/fcp/Shutdown.java [deleted file]
src/net/pterodactylus/fcp/SimpleProgress.java [deleted file]
src/net/pterodactylus/fcp/StartedCompression.java [deleted file]
src/net/pterodactylus/fcp/SubscribeFeeds.java [deleted file]
src/net/pterodactylus/fcp/SubscribeUSK.java [deleted file]
src/net/pterodactylus/fcp/SubscribedUSKUpdate.java [deleted file]
src/net/pterodactylus/fcp/TestDDAComplete.java [deleted file]
src/net/pterodactylus/fcp/TestDDAReply.java [deleted file]
src/net/pterodactylus/fcp/TestDDARequest.java [deleted file]
src/net/pterodactylus/fcp/TestDDAResponse.java [deleted file]
src/net/pterodactylus/fcp/URIGenerated.java [deleted file]
src/net/pterodactylus/fcp/UnknownNodeIdentifier.java [deleted file]
src/net/pterodactylus/fcp/UnknownPeerNoteType.java [deleted file]
src/net/pterodactylus/fcp/UploadFrom.java [deleted file]
src/net/pterodactylus/fcp/Verbosity.java [deleted file]
src/net/pterodactylus/fcp/Version.java [deleted file]
src/net/pterodactylus/fcp/WatchGlobal.java [deleted file]
src/net/pterodactylus/fcp/highlevel/FcpClient.java [deleted file]
src/net/pterodactylus/fcp/highlevel/FcpClientListener.java [deleted file]
src/net/pterodactylus/fcp/highlevel/FcpClientListenerManager.java [deleted file]
src/net/pterodactylus/fcp/highlevel/FcpException.java [deleted file]
src/net/pterodactylus/fcp/highlevel/GetRequest.java [deleted file]
src/net/pterodactylus/fcp/highlevel/PutRequest.java [deleted file]
src/net/pterodactylus/fcp/highlevel/Request.java [deleted file]
src/net/pterodactylus/fcp/package-info.java [deleted file]
src/net/pterodactylus/fcp/plugin/WebOfTrustPlugin.java [deleted file]
src/net/pterodactylus/util/event/AbstractListenerManager.java [deleted file]
src/net/pterodactylus/util/filter/Filter.java [deleted file]
src/net/pterodactylus/util/filter/Filters.java [deleted file]
src/net/pterodactylus/util/thread/CurrentThreadExecutor.java [deleted file]
src/net/pterodactylus/util/thread/ObjectWrapper.java [deleted file]
test/main/java/net/pterodactylus/fcp/FcpConnectionTest.java [new file with mode: 0644]
test/net/pterodactylus/fcp/FcpConnectionTest.java [deleted file]

index 159bbf7..b1ff7b3 100644 (file)
@@ -1,8 +1,8 @@
 <?xml version="1.0" encoding="UTF-8"?>
 <classpath>
-       <classpathentry kind="src" path="src"/>
-       <classpathentry kind="src" path="test"/>
-       <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/>
-       <classpathentry kind="con" path="org.eclipse.jdt.junit.JUNIT_CONTAINER/3"/>
-       <classpathentry kind="output" path="bin"/>
+       <classpathentry kind="src" output="target/classes" path="src/main/java"/>
+       <classpathentry kind="src" path="test/main/java"/>
+       <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/J2SE-1.5"/>
+       <classpathentry kind="con" path="org.maven.ide.eclipse.MAVEN2_CLASSPATH_CONTAINER"/>
+       <classpathentry kind="output" path="target/classes"/>
 </classpath>
index e9a2520..157656e 100644 (file)
--- a/.project
+++ b/.project
                        <arguments>
                        </arguments>
                </buildCommand>
+               <buildCommand>
+                       <name>org.maven.ide.eclipse.maven2Builder</name>
+                       <arguments>
+                       </arguments>
+               </buildCommand>
        </buildSpec>
        <natures>
+               <nature>org.maven.ide.eclipse.maven2Nature</nature>
                <nature>org.eclipse.jdt.core.javanature</nature>
                <nature>edu.umd.cs.findbugs.plugin.eclipse.findbugsNature</nature>
        </natures>
diff --git a/src/main/java/net/pterodactylus/fcp/ARK.java b/src/main/java/net/pterodactylus/fcp/ARK.java
new file mode 100644 (file)
index 0000000..498252d
--- /dev/null
@@ -0,0 +1,99 @@
+/*
+ * jFCPlib - ARK.java - Copyright © 2008 David Roden
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+package net.pterodactylus.fcp;
+
+/**
+ * Container for ARKs (address resolution keys).
+ *
+ * @author David ‘Bombe’ Roden &lt;bombe@freenetproject.org&gt;
+ */
+public class ARK {
+
+       /** The public URI of the ARK. */
+       private final String publicURI;
+
+       /** The private URI of the ARK. */
+       private final String privateURI;
+
+       /** The number of the ARK. */
+       private final int number;
+
+       /**
+        * Creates a new ARK with the given URI and number.
+        *
+        * @param publicURI
+        *            The public URI of the ARK
+        * @param number
+        *            The number of the ARK
+        */
+       public ARK(String publicURI, String number) {
+               this(publicURI, null, number);
+       }
+
+       /**
+        * Creates a new ARK with the given URIs and number.
+        *
+        * @param publicURI
+        *            The public URI of the ARK
+        * @param privateURI
+        *            The private URI of the ARK
+        * @param number
+        *            The number of the ARK
+        */
+       public ARK(String publicURI, String privateURI, String number) {
+               if ((publicURI == null) || (number == null)) {
+                       throw new NullPointerException(((publicURI == null) ? "publicURI" : "number") + " must not be null");
+               }
+               this.publicURI = publicURI;
+               this.privateURI = privateURI;
+               try {
+                       this.number = Integer.valueOf(number);
+               } catch (NumberFormatException nfe1) {
+                       throw new IllegalArgumentException("number must be numeric", nfe1);
+               }
+       }
+
+       /**
+        * Returns the public URI of the ARK.
+        *
+        * @return The public URI of the ARK
+        */
+       public String getPublicURI() {
+               return publicURI;
+       }
+
+       /**
+        * Returns the private URI of the ARK.
+        *
+        * @return The private URI of the ARK
+        */
+       public String getPrivateURI() {
+               return privateURI;
+       }
+
+       /**
+        * Returns the number of the ARK.
+        *
+        * @return The number of the ARK
+        */
+       public int getNumber() {
+               return number;
+       }
+
+}
diff --git a/src/main/java/net/pterodactylus/fcp/AbstractSendFeedMessage.java b/src/main/java/net/pterodactylus/fcp/AbstractSendFeedMessage.java
new file mode 100644 (file)
index 0000000..86a4078
--- /dev/null
@@ -0,0 +1,44 @@
+/*
+ * jFCPlib - AbstractSendFeedMessage.java - Copyright © 2009 David Roden
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+package net.pterodactylus.fcp;
+
+/**
+ * Abstract base implementation for the {@code Send*Feed} commands.
+ *
+ * @author David ‘Bombe’ Roden &lt;bombe@freenetproject.org&gt;
+ */
+public abstract class AbstractSendFeedMessage extends FcpMessage {
+
+       /**
+        * Creates a new “Send*Feed” command.
+        *
+        * @param name
+        *            The name of the command
+        * @param identifier
+        *            The identifier of the request
+        * @param nodeIdentifier
+        *            The identifier of the peer node
+        */
+       protected AbstractSendFeedMessage(String name, String identifier, String nodeIdentifier) {
+               super(name);
+               setField("Identifier", identifier);
+               setField("NodeIdentifier", nodeIdentifier);
+       }
+
+}
diff --git a/src/main/java/net/pterodactylus/fcp/AddPeer.java b/src/main/java/net/pterodactylus/fcp/AddPeer.java
new file mode 100644 (file)
index 0000000..e9ad80d
--- /dev/null
@@ -0,0 +1,101 @@
+/*
+ * jFCPlib - AddPeer.java - Copyright © 2008 David Roden
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+package net.pterodactylus.fcp;
+
+import java.net.URL;
+
+/**
+ * The “AddPeer” request adds a peer to the node.
+ *
+ * @author David ‘Bombe’ Roden &lt;bombe@freenetproject.org&gt;
+ */
+public class AddPeer extends FcpMessage {
+
+       /**
+        * Creates a new “AddPeer” request.
+        */
+       private AddPeer() {
+               super("AddPeer");
+       }
+
+       /**
+        * Creates a new “AddPeer” request that reads the noderef of the peer from
+        * the given file.
+        *
+        * @param file
+        *            The file to read the noderef from
+        */
+       public AddPeer(String file) {
+               this();
+               setField("File", file);
+       }
+
+       /**
+        * Creates a new “AddPeer” request that reads the noderef of the peer from
+        * the given URL.
+        *
+        * @param url
+        *            The URL to read the noderef from
+        */
+       public AddPeer(URL url) {
+               this();
+               setField("URL", String.valueOf(url));
+       }
+
+       /**
+        * Creates a new “AddPeer” request that adds the peer given by the noderef.
+        *
+        * @param nodeRef
+        *            The noderef of the peer
+        */
+       public AddPeer(NodeRef nodeRef) {
+               this();
+               setNodeRef(nodeRef);
+       }
+
+       //
+       // PRIVATE METHODS
+       //
+
+       /**
+        * Sets the noderef of the peer to add.
+        *
+        * @param nodeRef
+        *            The noderef of the peer
+        */
+       private void setNodeRef(NodeRef nodeRef) {
+               setField("lastGoodVersion", nodeRef.getLastGoodVersion().toString());
+               setField("opennet", String.valueOf(nodeRef.isOpennet()));
+               setField("identity", nodeRef.getIdentity());
+               setField("myName", nodeRef.getMyName());
+               setField("location", String.valueOf(nodeRef.getLocation()));
+               setField("testnet", String.valueOf(nodeRef.isTestnet()));
+               setField("version", String.valueOf(nodeRef.getVersion()));
+               setField("physical.udp", nodeRef.getPhysicalUDP());
+               setField("ark.pubURI", nodeRef.getARK().getPublicURI());
+               setField("ark.number", String.valueOf(nodeRef.getARK().getNumber()));
+               setField("dsaPubKey.y", nodeRef.getDSAPublicKey());
+               setField("dsaGroup.g", nodeRef.getDSAGroup().getBase());
+               setField("dsaGroup.p", nodeRef.getDSAGroup().getPrime());
+               setField("dsaGroup.q", nodeRef.getDSAGroup().getSubprime());
+               setField("auth.negTypes", FcpUtils.encodeMultiIntegerField(nodeRef.getNegotiationTypes()));
+               setField("sig", nodeRef.getSignature());
+       }
+
+}
diff --git a/src/main/java/net/pterodactylus/fcp/AllData.java b/src/main/java/net/pterodactylus/fcp/AllData.java
new file mode 100644 (file)
index 0000000..d1541bf
--- /dev/null
@@ -0,0 +1,102 @@
+/*
+ * jFCPlib - AllData.java - Copyright © 2008 David Roden
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+package net.pterodactylus.fcp;
+
+import java.io.InputStream;
+
+/**
+ * The “AllData” message carries the payload of a successful {@link ClientGet}
+ * request. You will only received this message if the {@link ClientGet} request
+ * was started with a return type of {@link ReturnType#direct}. If you get this
+ * message and decide that the data is for you, call
+ * {@link #getPayloadInputStream()} to get the data. If an AllData message
+ * passes through all registered {@link FcpListener}s without the payload being
+ * consumed, the payload is discarded!
+ *
+ * @author David ‘Bombe’ Roden &lt;bombe@freenetproject.org&gt;
+ */
+public class AllData extends BaseMessage {
+
+       /** The payload. */
+       private InputStream payloadInputStream;
+
+       /**
+        * Creates an “AllData” message that wraps the received message.
+        *
+        * @param receivedMessage
+        *            The received message
+        * @param payloadInputStream
+        *            The payload
+        */
+       AllData(FcpMessage receivedMessage, InputStream payloadInputStream) {
+               super(receivedMessage);
+               this.payloadInputStream = payloadInputStream;
+       }
+
+       /**
+        * Returns the identifier of the request.
+        *
+        * @return The identifier of the request
+        */
+       public String getIdentifier() {
+               return getField("Identifier");
+       }
+
+       /**
+        * Returns the length of the data.
+        *
+        * @return The length of the data, or <code>-1</code> if the length could
+        *         not be parsed
+        */
+       public long getDataLength() {
+               return FcpUtils.safeParseLong(getField("DataLength"));
+       }
+
+       /**
+        * Returns the startup time of the request.
+        *
+        * @return The startup time of the request (in milliseconds since Jan 1,
+        *         1970 UTC), or <code>-1</code> if the time could not be parsed
+        */
+       public long getStartupTime() {
+               return FcpUtils.safeParseLong(getField("StartupTime"));
+       }
+
+       /**
+        * Returns the completion time of the request.
+        *
+        * @return The completion time of the request (in milliseconds since Jan 1,
+        *         1970 UTC), or <code>-1</code> if the time could not be parsed
+        */
+       public long getCompletionTime() {
+               return FcpUtils.safeParseLong(getField("CompletionTime"));
+       }
+
+       /**
+        * Returns the payload input stream. You <strong>have</strong> consume the
+        * input stream before returning from the
+        * {@link FcpListener#receivedAllData(FcpConnection, AllData)} method!
+        *
+        * @return The payload
+        */
+       public InputStream getPayloadInputStream() {
+               return payloadInputStream;
+       }
+
+}
diff --git a/src/main/java/net/pterodactylus/fcp/BaseMessage.java b/src/main/java/net/pterodactylus/fcp/BaseMessage.java
new file mode 100644 (file)
index 0000000..a5ea020
--- /dev/null
@@ -0,0 +1,74 @@
+/*
+ * jFCPlib - BaseMessage.java - Copyright © 2008 David Roden
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+package net.pterodactylus.fcp;
+
+import java.util.Map;
+
+/**
+ * A basic message abstraction that wraps a received FCP message.
+ *
+ * @author David ‘Bombe’ Roden &lt;bombe@freenetproject.org&gt;
+ */
+public class BaseMessage {
+
+       /** The received message, wrapped here. */
+       private final FcpMessage receivedMessage;
+
+       /**
+        * Creates a new base message that wraps the given message.
+        *
+        * @param receivedMessage
+        *            The FCP message that was received
+        */
+       BaseMessage(FcpMessage receivedMessage) {
+               this.receivedMessage = receivedMessage;
+       }
+
+       /**
+        * Returns the name of the message.
+        *
+        * @return The name of the message
+        */
+       public String getName() {
+               return receivedMessage.getName();
+       }
+
+       /**
+        * Returns the content of the field.
+        *
+        * @param field
+        *            The name of the field
+        * @return The content of the field, or <code>null</code> if there is no
+        *         such field
+        */
+       protected String getField(String field) {
+               return receivedMessage.getField(field);
+       }
+
+       /**
+        * Returns all fields from the received message.
+        *
+        * @see FcpMessage#getFields()
+        * @return All fields from the message
+        */
+       protected Map<String, String> getFields() {
+               return receivedMessage.getFields();
+       }
+
+}
diff --git a/src/main/java/net/pterodactylus/fcp/ClientGet.java b/src/main/java/net/pterodactylus/fcp/ClientGet.java
new file mode 100644 (file)
index 0000000..8b03ee4
--- /dev/null
@@ -0,0 +1,210 @@
+/*
+ * jFCPlib - ClientGet.java - Copyright © 2008 David Roden
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+package net.pterodactylus.fcp;
+
+/**
+ * A “ClientGet” request is used for download files from the Freenet node.
+ *
+ * @author David ‘Bombe’ Roden &lt;bombe@freenetproject.org&gt;
+ */
+public class ClientGet extends FcpMessage {
+
+       /**
+        * Creates a new “ClientGet” request.
+        *
+        * @param uri
+        *            The URI to get
+        * @param identifier
+        *            The identifier of the request
+        */
+       public ClientGet(String uri, String identifier) {
+               this(uri, identifier, ReturnType.direct);
+       }
+
+       /**
+        * Creates a new “ClientGet” request.
+        *
+        * @param uri
+        *            The URI to get
+        * @param identifier
+        *            The identifier of the request
+        * @param returnType
+        *            The return type of the request
+        */
+       public ClientGet(String uri, String identifier, ReturnType returnType) {
+               super("ClientGet");
+               setField("URI", uri);
+               setField("Identifier", identifier);
+               setField("ReturnType", String.valueOf(returnType));
+       }
+
+       /**
+        * Sets whether the local data store should be ignored when searching for a
+        * key.
+        *
+        * @param ignoreDataStore
+        *            <code>true</code> to ignore the local data store,
+        *            <code>false</code> to include it
+        */
+       public void setIgnoreDataStore(boolean ignoreDataStore) {
+               setField("IgnoreDS", String.valueOf(ignoreDataStore));
+       }
+
+       /**
+        * Sets whether the search for the key should be restricted to the local
+        * data store only.
+        *
+        * @param dsOnly
+        *            <code>true</code> to restrict the search to the local data
+        *            store, <code>false</code> to search on other nodes, too
+        */
+       public void setDataStoreOnly(boolean dsOnly) {
+               setField("DSonly", String.valueOf(dsOnly));
+       }
+
+       /**
+        * Sets the verbosity of the request.
+        *
+        * @param verbosity
+        *            The verbosity of the request
+        */
+       public void setVerbosity(Verbosity verbosity) {
+               setField("Verbosity", String.valueOf(verbosity));
+       }
+
+       /**
+        * Sets the maximum size of the file to retrieve. If the file is larger than
+        * this size the request will fail!
+        *
+        * @param maxSize
+        *            The maximum size of the file to retrieve
+        */
+       public void setMaxSize(long maxSize) {
+               setField("MaxSize", String.valueOf(maxSize));
+       }
+
+       /**
+        * Sets the maximum size of temporary files created by the node. If a
+        * temporary file is larger than this size the request will fail!
+        *
+        * @param maxTempSize
+        *            The maximum size of temporary files
+        */
+       public void setMaxTempSize(long maxTempSize) {
+               setField("MaxTempSize", String.valueOf(maxTempSize));
+       }
+
+       /**
+        * The maximum number of retries in case a block can not be retrieved.
+        *
+        * @param maxRetries
+        *            The maximum number of retries for failed blocks,
+        *            <code>-1</code> to try forever
+        */
+       public void setMaxRetries(int maxRetries) {
+               setField("MaxRetries", String.valueOf(maxRetries));
+       }
+
+       /**
+        * Sets the priority of the request.
+        *
+        * @param priority
+        *            The priority of the request
+        */
+       public void setPriority(Priority priority) {
+               setField("PriorityClass", String.valueOf(priority));
+       }
+
+       /**
+        * Sets the persistence of the request.
+        *
+        * @param persistence
+        *            The persistence of the request
+        */
+       public void setPersistence(Persistence persistence) {
+               setField("Persistence", String.valueOf(persistence));
+       }
+
+       /**
+        * Sets the client token of the request.
+        *
+        * @param clientToken
+        *            The client token of the request
+        */
+       public void setClientToken(String clientToken) {
+               setField("ClientToken", clientToken);
+       }
+
+       /**
+        * Sets whether the request should be visible on the global queue.
+        *
+        * @param global
+        *            <code>true</code> to make the request visible on the global
+        *            queue, <code>false</code> for client-local queue only
+        */
+       public void setGlobal(boolean global) {
+               setField("Global", String.valueOf(global));
+       }
+
+       /**
+        * Sets whether to request the “binary blob” for a key.
+        *
+        * @param binaryBlob
+        *            <code>true</code> to request the binary blob,
+        *            <code>false</code> to get the “real thing”
+        */
+       public void setBinaryBlob(boolean binaryBlob) {
+               setField("BinaryBlob", String.valueOf(binaryBlob));
+       }
+
+       /**
+        * Sets the allowed MIME types of the requested file. If the MIME type of
+        * the file does not match one of the given MIME types the request will
+        * fail!
+        *
+        * @param allowedMimeTypes
+        *            The allowed MIME types
+        */
+       public void setAllowedMimeTypes(String... allowedMimeTypes) {
+               setField("AllowedMIMETypes", FcpUtils.encodeMultiStringField(allowedMimeTypes));
+       }
+
+       /**
+        * Sets the filename to download the file to. You should only call this
+        * method if your return type is {@link ReturnType#disk}!
+        *
+        * @param filename
+        *            The filename to download the file to
+        */
+       public void setFilename(String filename) {
+               setField("Filename", filename);
+       }
+
+       /**
+        * Sets the name for the temporary file. You should only call this method if
+        * your return type is {@link ReturnType#disk}!
+        *
+        * @param tempFilename
+        *            The name of the temporary file
+        */
+       public void setTempFilename(String tempFilename) {
+               setField("TempFilename", tempFilename);
+       }
+
+}
diff --git a/src/main/java/net/pterodactylus/fcp/ClientHello.java b/src/main/java/net/pterodactylus/fcp/ClientHello.java
new file mode 100644 (file)
index 0000000..3079807
--- /dev/null
@@ -0,0 +1,58 @@
+/*
+ * jFCPlib - ClientHello.java - Copyright © 2008 David Roden
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+package net.pterodactylus.fcp;
+
+/**
+ * A “ClientHello” message that <i>must</i> be sent to the node first thing
+ * after calling {@link FcpConnection#connect()}.
+ *
+ * @author David ‘Bombe’ Roden &lt;bombe@freenetproject.org&gt;
+ */
+public class ClientHello extends FcpMessage {
+
+       /**
+        * Creates a new “ClientHello” message with the given client name. The
+        * client name has to be unique to the node otherwise you will get a
+        * {@link CloseConnectionDuplicateClientName} response from the node!
+        *
+        * @param clientName
+        *            The unique client name
+        */
+       public ClientHello(String clientName) {
+               this(clientName, "2.0");
+       }
+
+       /**
+        * Creates a new “ClientHello” message with the given client name. The
+        * client name has to be unique to the node otherwise you will get a
+        * {@link CloseConnectionDuplicateClientName} response from the node! The
+        * expected FCP version is currently ignored by the node.
+        *
+        * @param clientName
+        *            The unique client name
+        * @param expectedVersion
+        *            The FCP version that the node is expected to talk
+        */
+       public ClientHello(String clientName, String expectedVersion) {
+               super("ClientHello");
+               setField("Name", clientName);
+               setField("ExpectedVersion", expectedVersion);
+       }
+
+}
diff --git a/src/main/java/net/pterodactylus/fcp/ClientPut.java b/src/main/java/net/pterodactylus/fcp/ClientPut.java
new file mode 100644 (file)
index 0000000..f7dfabc
--- /dev/null
@@ -0,0 +1,231 @@
+/*
+ * jFCPlib - ClientPut.java - Copyright © 2008 David Roden
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+package net.pterodactylus.fcp;
+
+/**
+ * A “ClientPut” requests inserts a single file into freenet, either uploading
+ * it directly with this messge ({@link UploadFrom#direct}), uploading it from
+ * disk ({@link UploadFrom#disk}) or by creating a redirect to another URI (
+ * {@link UploadFrom#redirect}).
+ *
+ * @author David ‘Bombe’ Roden &lt;bombe@freenetproject.org&gt;
+ */
+public class ClientPut extends FcpMessage {
+
+       /**
+        * Creates a new “ClientPut” message that inserts a file to the given URI.
+        * The file data <em>has</em> to be supplied to this message using
+        * {@link #setPayloadInputStream(java.io.InputStream)}! Using this
+        * constructor is the same as using
+        * {@link #ClientPut(String, String, UploadFrom)} with
+        * {@link UploadFrom#direct} as third parameter.
+        *
+        * @param uri
+        *            The URI to insert the file to
+        * @param identifier
+        *            The identifier of the request
+        */
+       public ClientPut(String uri, String identifier) {
+               this(uri, identifier, UploadFrom.direct);
+       }
+
+       /**
+        * Creates a new “ClientPut” message that inserts a file to the given URI.
+        * Depending on <code>uploadFrom</code> the file data has to be supplied in
+        * different ways: If <code>uploadFrom</code> is {@link UploadFrom#direct},
+        * use {@link #setPayloadInputStream(java.io.InputStream)} to supply the
+        * input data. If <code>uploadFrom</code> is {@link UploadFrom#disk}, use
+        * {@link #setFilename(String)} to supply the file to upload. You have to
+        * test your direct-disk access (see {@link TestDDARequest},
+        * {@link TestDDAReply}, {@link TestDDAResponse}, {@link TestDDAComplete})
+        * before using this option! If <code>uploadFrom</code> is
+        * {@link UploadFrom#redirect}, use {@link #setTargetURI(String)} to set the
+        * target URI of the redirect.
+        *
+        * @param uri
+        *            The URI to insert to
+        * @param identifier
+        *            The identifier of the insert
+        * @param uploadFrom
+        *            The source of the upload
+        */
+       public ClientPut(String uri, String identifier, UploadFrom uploadFrom) {
+               super("ClientPut");
+               setField("URI", uri);
+               setField("Identifier", identifier);
+               setField("UploadFrom", String.valueOf(uploadFrom));
+       }
+
+       /**
+        * The MIME type of the content.
+        *
+        * @param metadataContentType
+        *            The MIME type of the content
+        */
+       public void setMetadataContentType(String metadataContentType) {
+               setField("Metadata.ContentType", metadataContentType);
+       }
+
+       /**
+        * The verbosity of the request. Depending on this parameter you will
+        * received only the bare minimum of messages for the request (i.e. “it
+        * completed”) or a whole lot more.
+        *
+        * @see Verbosity
+        * @param verbosity
+        *            The verbosity of the request
+        */
+       public void setVerbosity(Verbosity verbosity) {
+               setField("Verbosity", String.valueOf(verbosity));
+       }
+
+       /**
+        * The number of retries for a request if the initial try failed.
+        *
+        * @param maxRetries
+        *            The maximum number of retries after failure, or
+        *            <code>-1</code> to retry forever.
+        */
+       public void setMaxRetries(int maxRetries) {
+               setField("MaxRetries", String.valueOf(maxRetries));
+       }
+
+       /**
+        * Sets the priority of the request.
+        *
+        * @param priority
+        *            The priority of the request
+        */
+       public void setPriority(Priority priority) {
+               setField("PriorityClass", String.valueOf(priority));
+       }
+
+       /**
+        * Determines whether the node should really insert the data or generate the
+        * final CHK only.
+        *
+        * @param getCHKOnly
+        *            <code>true</code> to generate the final CHK only,
+        *            <code>false</code> to really insert the data
+        */
+       public void setGetCHKOnly(boolean getCHKOnly) {
+               setField("GetCHKOnly", String.valueOf(getCHKOnly));
+       }
+
+       /**
+        * Determines whether this request appears on the global queue.
+        *
+        * @param global
+        *            <code>true</code> to put the request on the global queue,
+        *            <code>false</code> for the client-local queue.
+        */
+       public void setGlobal(boolean global) {
+               setField("Global", String.valueOf(global));
+       }
+
+       /**
+        * Determines whether the node should skip compression because the file has
+        * already been compressed.
+        *
+        * @param dontCompress
+        *            <code>true</code> to skip compression of the data in the node,
+        *            <code>false</code> to allow compression
+        */
+       public void setDontCompress(boolean dontCompress) {
+               setField("DontCompress", String.valueOf(dontCompress));
+       }
+
+       /**
+        * Sets an optional client token. This client token is mentioned in progress
+        * and other request-related messages and can be used to identify this
+        * request.
+        *
+        * @param clientToken
+        *            The client token
+        */
+       public void setClientToken(String clientToken) {
+               setField("ClientToken", clientToken);
+       }
+
+       /**
+        * Sets the persistence of this request.
+        *
+        * @param persistence
+        *            The persistence of this request
+        */
+       public void setPersistence(Persistence persistence) {
+               setField("Persistence", String.valueOf(persistence));
+       }
+
+       /**
+        * Sets the target filename of the inserted file. This value is ignored for
+        * all inserts that do not have “CHK@” as a target.
+        *
+        * @param targetFilename
+        *            The filename of the target
+        */
+       public void setTargetFilename(String targetFilename) {
+               setField("TargetFilename", targetFilename);
+       }
+
+       /**
+        * Determines whether to encode the complete file early in the life of the
+        * request.
+        *
+        * @param earlyEncode
+        *            <code>true</code> to generate the final key long before the
+        *            file is completely fetchable
+        */
+       public void setEarlyEncode(boolean earlyEncode) {
+               setField("EarlyEncode", String.valueOf(earlyEncode));
+       }
+
+       /**
+        * Sets the length of the data that will be transferred after this message
+        * if <code>uploadFrom</code> is {@link UploadFrom#direct} is used.
+        *
+        * @param dataLength
+        *            The length of the data
+        */
+       public void setDataLength(long dataLength) {
+               setField("DataLength", String.valueOf(dataLength));
+       }
+
+       /**
+        * Sets the name of the file to upload the data from.
+        *
+        * @param filename
+        *            The filename to upload
+        */
+       public void setFilename(String filename) {
+               setField("Filename", filename);
+       }
+
+       /**
+        * If <code>uploadFrom</code> is {@link UploadFrom#redirect}, use this
+        * method to determine that target of the redirect.
+        *
+        * @param targetURI
+        *            The target URI to redirect to
+        */
+       public void setTargetURI(String targetURI) {
+               setField("TargetURI", targetURI);
+       }
+
+}
diff --git a/src/main/java/net/pterodactylus/fcp/ClientPutComplexDir.java b/src/main/java/net/pterodactylus/fcp/ClientPutComplexDir.java
new file mode 100644 (file)
index 0000000..55e5779
--- /dev/null
@@ -0,0 +1,220 @@
+/*
+ * jFCPlib - ClientPutComplexDir.java - Copyright © 2008 David Roden
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+package net.pterodactylus.fcp;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.io.SequenceInputStream;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+import java.util.Map;
+import java.util.Map.Entry;
+
+import net.pterodactylus.fcp.FileEntry.DirectFileEntry;
+
+/**
+ * The “ClientPutComplexDir” lets you upload a directory with different sources
+ * for each file.
+ *
+ * @see FileEntry
+ * @author David ‘Bombe’ Roden &lt;bombe@freenetproject.org&gt;
+ */
+public class ClientPutComplexDir extends FcpMessage {
+
+       /** The index for added file entries. */
+       private int fileIndex = 0;
+
+       /** The input streams from {@link DirectFileEntry}s. */
+       private final List<InputStream> directFileInputStreams = new ArrayList<InputStream>();
+
+       /**
+        * Creates a new “ClientPutComplexDir” with the given identifier and URI.
+        *
+        * @param identifier
+        *            The identifier of the request
+        * @param uri
+        *            The URI to insert the directory to
+        */
+       public ClientPutComplexDir(String identifier, String uri) {
+               super("ClientPutComplexDir");
+               setField("Identifier", identifier);
+               setField("URI", uri);
+       }
+
+       /**
+        * Sets the verbosity of the request.
+        *
+        * @param verbosity
+        *            The verbosity of the request
+        */
+       public void setVerbosity(Verbosity verbosity) {
+               setField("Verbosity", String.valueOf(verbosity));
+       }
+
+       /**
+        * Sets the maximum number of retries for failed blocks.
+        *
+        * @param maxRetries
+        *            The maximum number of retries for failed blocks, or
+        *            <code>-1</code> to retry endlessly
+        */
+       public void setMaxRetries(int maxRetries) {
+               setField("MaxRetries", String.valueOf(maxRetries));
+       }
+
+       /**
+        * Sets the priority of the request.
+        *
+        * @param priority
+        *            The priority of the request
+        */
+       public void setPriority(Priority priority) {
+               setField("PriorityClass", String.valueOf(priority));
+       }
+
+       /**
+        * Sets whether to generate the final URI only.
+        *
+        * @param getCHKOnly
+        *            <code>true</code> to generate the final CHK only,
+        *            <code>false</code> to complete the insert
+        */
+       public void setGetCHKOnly(boolean getCHKOnly) {
+               setField("GetCHKOnly", String.valueOf(getCHKOnly));
+       }
+
+       /**
+        * Sets whether the request is on the global queue.
+        *
+        * @param global
+        *            <code>true</code> to put the request on the global queue,
+        *            <code>false</code> to put it on the client-local queue
+        */
+       public void setGlobal(boolean global) {
+               setField("Global", String.valueOf(global));
+       }
+
+       /**
+        * Sets whether the node should not try to compress the data.
+        *
+        * @param dontCompress
+        *            <code>true</code> to skip compression of the data,
+        *            <code>false</code> to try and compress the data
+        */
+       public void setDontCompress(boolean dontCompress) {
+               setField("DontCompress", String.valueOf(dontCompress));
+       }
+
+       /**
+        * Sets the client token of the request.
+        *
+        * @param clientToken
+        *            The client token of the request
+        */
+       public void setClientToken(String clientToken) {
+               setField("ClientToken", clientToken);
+       }
+
+       /**
+        * Sets the persistence of the request.
+        *
+        * @param persistence
+        *            The persistence of the request
+        */
+       public void setPersistence(Persistence persistence) {
+               setField("Persistence", String.valueOf(persistence));
+       }
+
+       /**
+        * Sets the target filename of the request. This is useful for inserts that
+        * go to “CHK@” only and creates a manifest with a single file.
+        *
+        * @param targetFilename
+        *            The target filename
+        */
+       public void setTargetFilename(String targetFilename) {
+               setField("TargetFilename", targetFilename);
+       }
+
+       /**
+        * Sets whether to encode the complete data early to generate the
+        * {@link URIGenerated} message early.
+        *
+        * @param earlyEncode
+        *            <code>true</code> to encode the complete data early,
+        *            <code>false</code> otherwise
+        */
+       public void setEarlyEncode(boolean earlyEncode) {
+               setField("EarlyEncode", String.valueOf(earlyEncode));
+       }
+
+       /**
+        * Sets the default name. This is the name of the file that should be shown
+        * if no file was specified.
+        *
+        * @param defaultName
+        *            The default name
+        */
+       public void setDefaultName(String defaultName) {
+               setField("DefaultName", defaultName);
+       }
+
+       /**
+        * Adds an entry for a file.
+        *
+        * @param fileEntry
+        *            The file entry to add
+        */
+       public void addFileEntry(FileEntry fileEntry) {
+               Map<String, String> fields = fileEntry.getFields();
+               for (Entry<String, String> fieldEntry : fields.entrySet()) {
+                       setField("Files." + fileIndex + "." + fieldEntry.getKey(), fieldEntry.getValue());
+               }
+               fileIndex++;
+               if (fileEntry instanceof FileEntry.DirectFileEntry) {
+                       directFileInputStreams.add(((DirectFileEntry) fileEntry).getInputStream());
+               }
+       }
+
+       /**
+        * {@inheritDoc}
+        * <p>
+        * Do not call this method to add input streams! The input streams, if any,
+        * will be taken directly from the {@link FileEntry}s and the stream you set
+        * here will be overridden!
+        */
+       @Override
+       public void setPayloadInputStream(InputStream payloadInputStream) {
+               /* do nothing. */
+       }
+
+       /**
+        * {@inheritDoc}
+        */
+       @Override
+       public void write(OutputStream outputStream) throws IOException {
+               /* create payload stream. */
+               setPayloadInputStream(new SequenceInputStream(Collections.enumeration(directFileInputStreams)));
+               /* write out all the fields. */
+               super.write(outputStream);
+       }
+
+}
diff --git a/src/main/java/net/pterodactylus/fcp/ClientPutDiskDir.java b/src/main/java/net/pterodactylus/fcp/ClientPutDiskDir.java
new file mode 100644 (file)
index 0000000..d9b3924
--- /dev/null
@@ -0,0 +1,160 @@
+/*
+ * jFCPlib - ClientPutDiskDir.java - Copyright © 2008 David Roden
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+package net.pterodactylus.fcp;
+
+/**
+ * The “ClientPutDiskDir” message is used to insert a complete directory from
+ * the disk to a single key.
+ *
+ * @author David ‘Bombe’ Roden &lt;bombe@freenetproject.org&gt;
+ */
+public class ClientPutDiskDir extends FcpMessage {
+
+       /**
+        * Creates a new “ClientPutDiskDir” message.
+        *
+        * @param uri
+        *            The URI to insert the file to
+        * @param identifier
+        *            The identifier of the request
+        * @param directory
+        *            The name of the directory to insert
+        */
+       public ClientPutDiskDir(String uri, String identifier, String directory) {
+               super("ClientPutDiskDir");
+               setField("URI", uri);
+               setField("Identifier", identifier);
+               setField("Filename", directory);
+       }
+
+       /**
+        * The verbosity of the request. Depending on this parameter you will
+        * received only the bare minimum of messages for the request (i.e. “it
+        * completed”) or a whole lot more.
+        *
+        * @see Verbosity
+        * @param verbosity
+        *            The verbosity of the request
+        */
+       public void setVerbosity(Verbosity verbosity) {
+               setField("Verbosity", String.valueOf(verbosity));
+       }
+
+       /**
+        * The number of retries for a request if the initial try failed.
+        *
+        * @param maxRetries
+        *            The maximum number of retries after failure, or
+        *            <code>-1</code> to retry forever.
+        */
+       public void setMaxRetries(int maxRetries) {
+               setField("MaxRetries", String.valueOf(maxRetries));
+       }
+
+       /**
+        * Sets the priority of the request.
+        *
+        * @param priority
+        *            The priority of the request
+        */
+       public void setPriority(Priority priority) {
+               setField("PriorityClass", String.valueOf(priority));
+       }
+
+       /**
+        * Determines whether the node should really insert the data or generate the
+        * final CHK only.
+        *
+        * @param getCHKOnly
+        *            <code>true</code> to generate the final CHK only,
+        *            <code>false</code> to really insert the data
+        */
+       public void setGetCHKOnly(boolean getCHKOnly) {
+               setField("GetCHKOnly", String.valueOf(getCHKOnly));
+       }
+
+       /**
+        * Determines whether this request appears on the global queue.
+        *
+        * @param global
+        *            <code>true</code> to put the request on the global queue,
+        *            <code>false</code> for the client-local queue.
+        */
+       public void setGlobal(boolean global) {
+               setField("Global", String.valueOf(global));
+       }
+
+       /**
+        * Determines whether the node should skip compression because the file has
+        * already been compressed.
+        *
+        * @param dontCompress
+        *            <code>true</code> to skip compression of the data in the node,
+        *            <code>false</code> to allow compression
+        */
+       public void setDontCompress(boolean dontCompress) {
+               setField("DontCompress", String.valueOf(dontCompress));
+       }
+
+       /**
+        * Sets an optional client token. This client token is mentioned in progress
+        * and other request-related messages and can be used to identify this
+        * request.
+        *
+        * @param clientToken
+        *            The client token
+        */
+       public void setClientToken(String clientToken) {
+               setField("ClientToken", clientToken);
+       }
+
+       /**
+        * Sets the persistence of this request.
+        *
+        * @param persistence
+        *            The persistence of this request
+        */
+       public void setPersistence(Persistence persistence) {
+               setField("Persistence", String.valueOf(persistence));
+       }
+
+       /**
+        * Sets the name of the default file. The default file is shown when the key
+        * is requested with an additional name.
+        *
+        * @param defaultName
+        *            The name of the default file
+        */
+       public void setDefaultName(String defaultName) {
+               setField("DefaultName", defaultName);
+       }
+
+       /**
+        * Sets whether unreadable files allow the insert to continue.
+        *
+        * @param allowUnreadableFiles
+        *            <code>true</code> to just ignore unreadable files,
+        *            <code>false</code> to let the insert fail when an unreadable
+        *            file is encountered
+        */
+       public void setAllowUnreadableFiles(boolean allowUnreadableFiles) {
+               setField("AllowUnreadableFiles", String.valueOf(allowUnreadableFiles));
+       }
+
+}
diff --git a/src/main/java/net/pterodactylus/fcp/CloseConnectionDuplicateClientName.java b/src/main/java/net/pterodactylus/fcp/CloseConnectionDuplicateClientName.java
new file mode 100644 (file)
index 0000000..db0ff0d
--- /dev/null
@@ -0,0 +1,39 @@
+/*
+ * jFCPlib - CloseConnectionDuplicateClientName.java - Copyright © 2008 David Roden
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+package net.pterodactylus.fcp;
+
+/**
+ * A “CloseConnectionDuplicateClientName” message.
+ *
+ * @author David ‘Bombe’ Roden &lt;bombe@freenetproject.org&gt;
+ */
+public class CloseConnectionDuplicateClientName extends BaseMessage {
+
+       /**
+        * Creates a new CloseConnectionDuplicateClientName message that wraps the
+        * given message.
+        *
+        * @param receivedMessage
+        *            The received message
+        */
+       CloseConnectionDuplicateClientName(FcpMessage receivedMessage) {
+               super(receivedMessage);
+       }
+
+}
diff --git a/src/main/java/net/pterodactylus/fcp/ConfigData.java b/src/main/java/net/pterodactylus/fcp/ConfigData.java
new file mode 100644 (file)
index 0000000..4eb7954
--- /dev/null
@@ -0,0 +1,128 @@
+/*
+ * jFCPlib - ConfigData.java - Copyright © 2008 David Roden
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+package net.pterodactylus.fcp;
+
+/**
+ * A “ConfigData” message contains various aspects of the node’s configuration.
+ *
+ * @see GetConfig
+ * @author David ‘Bombe’ Roden &lt;bombe@freenetproject.org&gt;
+ */
+public class ConfigData extends BaseMessage {
+
+       /**
+        * Creates a new “ConfigData” message that wraps the received message.
+        *
+        * @param receivedMessage
+        *            The received message
+        */
+       ConfigData(FcpMessage receivedMessage) {
+               super(receivedMessage);
+       }
+
+       /**
+        * Returns the current value of the given option.
+        *
+        * @param option
+        *            The name of the option
+        * @return The current value of the option
+        */
+       public String getCurrent(String option) {
+               return getField("current." + option);
+       }
+
+       /**
+        * Returns the short description of the given option.
+        *
+        * @param option
+        *            The name of the option
+        * @return The short description of the option
+        */
+       public String getShortDescription(String option) {
+               return getField("shortDescription." + option);
+       }
+
+       /**
+        * Returns the long description of the given option.
+        *
+        * @param option
+        *            The name of the option
+        * @return The long description of the option
+        */
+       public String getLongDescription(String option) {
+               return getField("longDescription." + option);
+       }
+
+       /**
+        * Returns the data type of the given option.
+        *
+        * @param option
+        *            The name of the option
+        * @return The data type of the option
+        */
+       public String getDataType(String option) {
+               return getField("dataType." + option);
+       }
+
+       /**
+        * Returns the default value of the given option.
+        *
+        * @param option
+        *            The name of the option
+        * @return The default value of the option
+        */
+       public String getDefault(String option) {
+               return getField("default." + option);
+       }
+
+       /**
+        * Returns the sort order of the given option.
+        *
+        * @param option
+        *            The name of the option
+        * @return The sort order of the option, or <code>-1</code> if the sort
+        *         order could not be parsed
+        */
+       public int getSortOrder(String option) {
+               return FcpUtils.safeParseInt(getField("sortOrder." + option));
+       }
+
+       /**
+        * Returns the expert flag of the given option.
+        *
+        * @param option
+        *            The name of the option
+        * @return The expert flag of the option
+        */
+       public boolean getExpertFlag(String option) {
+               return Boolean.valueOf(getField("expertFlag." + option));
+       }
+
+       /**
+        * Returns the force-write flag of the given option
+        *
+        * @param option
+        *            The name of the option
+        * @return The force-write flag of the given option
+        */
+       public boolean getForceWriteFlag(String option) {
+               return Boolean.valueOf(getField("forceWriteFlag." + option));
+       }
+
+}
diff --git a/src/main/java/net/pterodactylus/fcp/DSAGroup.java b/src/main/java/net/pterodactylus/fcp/DSAGroup.java
new file mode 100644 (file)
index 0000000..4674e66
--- /dev/null
@@ -0,0 +1,85 @@
+/*
+ * jFCPlib - DSAGroup.java - Copyright © 2008 David Roden
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+package net.pterodactylus.fcp;
+
+import java.security.interfaces.DSAParams;
+
+/**
+ * Container for the DSA group of a peer. A DSA group consists of a base (called
+ * “g”), a prime (called “p”) and a subprime (called “q”).
+ *
+ * @see DSAParams
+ * @author David ‘Bombe’ Roden &lt;bombe@freenetproject.org&gt;
+ */
+public class DSAGroup {
+
+       /** The base of the DSA group. */
+       private final String base;
+
+       /** The prime of the DSA group. */
+       private final String prime;
+
+       /** The subprime of the DSA group. */
+       private final String subprime;
+
+       /**
+        * Creates a new DSA group with the given base (“g”), prime (“p”), and
+        * subprime (“q”).
+        *
+        * @param base
+        *            The base of the DSA group
+        * @param prime
+        *            The prime of the DSA group
+        * @param subprime
+        *            The subprime of the DSA group
+        */
+       public DSAGroup(String base, String prime, String subprime) {
+               this.base = base;
+               this.prime = prime;
+               this.subprime = subprime;
+       }
+
+       /**
+        * Returns the base (“g”) of the DSA group.
+        *
+        * @return The base of the DSA group
+        */
+       public String getBase() {
+               return base;
+       }
+
+       /**
+        * Returns the prime (“p”) of the DSA group.
+        *
+        * @return The prime of the DSA group
+        */
+       public String getPrime() {
+               return prime;
+       }
+
+       /**
+        * Returns the subprime (“q”) of the DSA group.
+        *
+        * @return The subprime of the DSA group
+        */
+       public String getSubprime() {
+               return subprime;
+       }
+
+}
diff --git a/src/main/java/net/pterodactylus/fcp/DataFound.java b/src/main/java/net/pterodactylus/fcp/DataFound.java
new file mode 100644 (file)
index 0000000..81318c1
--- /dev/null
@@ -0,0 +1,77 @@
+/*
+ * jFCPlib - DataFound.java - Copyright © 2008 David Roden
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+package net.pterodactylus.fcp;
+
+/**
+ * A “DataFound” message signals the client that the data requested by a
+ * {@link ClientGet} operation has been found. This message does not include the
+ * actual data, though.
+ *
+ * @author David ‘Bombe’ Roden &lt;bombe@freenetproject.org&gt;
+ */
+public class DataFound extends BaseMessage {
+
+       /**
+        * Creates a new “DataFound” message that wraps the received message.
+        *
+        * @param receivedMessage
+        *            The received message
+        */
+       DataFound(FcpMessage receivedMessage) {
+               super(receivedMessage);
+       }
+
+       /**
+        * Returns whether the request is on the global queue.
+        *
+        * @return <code>true</code> if the request is on the global queue,
+        *         <code>false</code> if the request is on the client-local queue
+        */
+       public boolean isGlobal() {
+               return Boolean.valueOf(getField("Global"));
+       }
+
+       /**
+        * Returns the identifier of the request.
+        *
+        * @return The identifier of the request
+        */
+       public String getIdentifier() {
+               return getField("Identifier");
+       }
+
+       /**
+        * Returns the content type of the data.
+        *
+        * @return The content type of the data
+        */
+       public String getMetadataContentType() {
+               return getField("Metadata.ContentType");
+       }
+
+       /**
+        * Returns the length of the data.
+        *
+        * @return The length of the data
+        */
+       public long getDataLength() {
+               return FcpUtils.safeParseLong(getField("DataLength"));
+       }
+
+}
diff --git a/src/main/java/net/pterodactylus/fcp/EndListPeerNotes.java b/src/main/java/net/pterodactylus/fcp/EndListPeerNotes.java
new file mode 100644 (file)
index 0000000..5c381f6
--- /dev/null
@@ -0,0 +1,39 @@
+/*
+ * jFCPlib - EndListPeerNotes.java - Copyright © 2008 David Roden
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+package net.pterodactylus.fcp;
+
+/**
+ * The “EndListPeerNotes” message signals the end of a list of “PeerNote”
+ * messages.
+ *
+ * @author David ‘Bombe’ Roden &lt;bombe@freenetproject.org&gt;
+ */
+public class EndListPeerNotes extends BaseMessage {
+
+       /**
+        * Creates a new “EndListPeerNotes” message that wraps the received message.
+        *
+        * @param fcpMessage
+        *            The received message
+        */
+       EndListPeerNotes(FcpMessage fcpMessage) {
+               super(fcpMessage);
+       }
+
+}
diff --git a/src/main/java/net/pterodactylus/fcp/EndListPeers.java b/src/main/java/net/pterodactylus/fcp/EndListPeers.java
new file mode 100644 (file)
index 0000000..c0cf82f
--- /dev/null
@@ -0,0 +1,47 @@
+/*
+ * jFCPlib - EndListPeers.java - Copyright © 2008 David Roden
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+package net.pterodactylus.fcp;
+
+/**
+ * This message marks the end of a list of “Peer” replies.
+ *
+ * @author David ‘Bombe’ Roden &lt;bombe@freenetproject.org&gt;
+ */
+public class EndListPeers extends BaseMessage {
+
+       /**
+        * Creates a new “EndListPeers” message that wraps the received message.
+        *
+        * @param receivedMessage
+        *            The message that was received
+        */
+       EndListPeers(FcpMessage receivedMessage) {
+               super(receivedMessage);
+       }
+
+       /**
+        * Returns the identifier of the request.
+        *
+        * @return The identifier of the request
+        */
+       public String getIdentifier() {
+               return getField("Identifier");
+       }
+
+}
diff --git a/src/main/java/net/pterodactylus/fcp/EndListPersistentRequests.java b/src/main/java/net/pterodactylus/fcp/EndListPersistentRequests.java
new file mode 100644 (file)
index 0000000..893f2f1
--- /dev/null
@@ -0,0 +1,40 @@
+/*
+ * jFCPlib - EndListPersistentRequests.java - Copyright © 2008 David Roden
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+package net.pterodactylus.fcp;
+
+/**
+ * The “EndListPersistentRequests” message signals the end of a list of
+ * {@link PersistentGet} and {@link PersistentPut} requests.
+ *
+ * @author David ‘Bombe’ Roden &lt;bombe@freenetproject.org&gt;
+ */
+public class EndListPersistentRequests extends BaseMessage {
+
+       /**
+        * Creates a new “EndListPersistentRequests” message that wraps the received
+        * message.
+        *
+        * @param receivedMessage
+        *            The received message
+        */
+       EndListPersistentRequests(FcpMessage receivedMessage) {
+               super(receivedMessage);
+       }
+
+}
diff --git a/src/main/java/net/pterodactylus/fcp/FCPPluginMessage.java b/src/main/java/net/pterodactylus/fcp/FCPPluginMessage.java
new file mode 100644 (file)
index 0000000..c167411
--- /dev/null
@@ -0,0 +1,76 @@
+/*
+ * jFCPlib - PluginMessage.java - Copyright © 2008 David Roden
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+package net.pterodactylus.fcp;
+
+/**
+ * An “CPPluginMessage” sends a message with custom parameters and (optional)
+ * payload to a plugin.
+ *
+ * @author David ‘Bombe’ Roden &lt;bombe@freenetproject.org&gt;
+ */
+public class FCPPluginMessage extends FcpMessage {
+
+       /**
+        * Creates a new “FCPPluginMessage” message for the given plugin.
+        *
+        * @param pluginClass
+        *            The name of the plugin class
+        */
+       public FCPPluginMessage(String pluginClass) {
+               super("FCPPluginMessage");
+               setField("PluginName", pluginClass);
+       }
+
+       /**
+        * Sets the identifier of the request. Though this is still optional you are
+        * encouraged to include it because the plugin might reply in random order
+        * to requests.
+        *
+        * @param identifier
+        *            The identifier of the request
+        */
+       public void setIdentifier(String identifier) {
+               setField("Identifier", identifier);
+       }
+
+       /**
+        * Sets a custom parameter for the plugin.
+        *
+        * @param key
+        *            The key of the parameter
+        * @param value
+        *            The value of the parameter
+        */
+       public void setParameter(String key, String value) {
+               setField("Param." + key, value);
+       }
+
+       /**
+        * Sets the length of data of the optional payload. If you call this method
+        * you also have to call {@link #setPayloadInputStream(java.io.InputStream)}
+        * !
+        *
+        * @param dataLength
+        *            The length of data in the payload input stream
+        */
+       public void setDataLength(long dataLength) {
+               setField("DataLength", String.valueOf(dataLength));
+       }
+
+}
diff --git a/src/main/java/net/pterodactylus/fcp/FCPPluginReply.java b/src/main/java/net/pterodactylus/fcp/FCPPluginReply.java
new file mode 100644 (file)
index 0000000..c3b5281
--- /dev/null
@@ -0,0 +1,117 @@
+/*
+ * jFCPlib - FCPPluginReply.java - Copyright © 2008 David Roden
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+package net.pterodactylus.fcp;
+
+import java.io.InputStream;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Map.Entry;
+
+/**
+ * The “FCPPluginReply” is sent by a plugin as a response to a
+ * {@link FCPPluginMessage} message.
+ *
+ * @author David ‘Bombe’ Roden &lt;bombe@freenetproject.org&gt;
+ */
+public class FCPPluginReply extends BaseMessage {
+
+       /** The payload input stream. */
+       private final InputStream payloadInputStream;
+
+       /**
+        * Creates a new “FCPPluginReply” message that wraps the received message.
+        *
+        * @param receivedMessage
+        *            The received message
+        * @param payloadInputStream
+        *            The optional input stream for the payload
+        */
+       FCPPluginReply(FcpMessage receivedMessage, InputStream payloadInputStream) {
+               super(receivedMessage);
+               this.payloadInputStream = payloadInputStream;
+       }
+
+       /**
+        * Returns the name of the plugin.
+        *
+        * @return The name of the plugin
+        */
+       public String getPluginName() {
+               return getField("PluginName");
+       }
+
+       /**
+        * Returns the identifier of the request.
+        *
+        * @return The identifier of the request
+        */
+       public String getIdentifier() {
+               return getField("Identifier");
+       }
+
+       /**
+        * Returns the length of the optional payload.
+        *
+        * @return The length of the payload, or <code>-1</code> if there is no
+        *         payload or the length could not be parsed
+        */
+       public long getDataLength() {
+               return FcpUtils.safeParseLong(getField("DataLength"));
+       }
+
+       /**
+        * Returns a reply from the plugin.
+        *
+        * @param key
+        *            The name of the reply
+        * @return The value of the reply
+        */
+       public String getReply(String key) {
+               return getField("Replies." + key);
+       }
+
+       /**
+        * Returns all replies from the plugin. The plugin sends replies as normal
+        * message fields prefixed by “Replies.”. The keys of the returned map do
+        * not contain this prefix!
+        *
+        * @return All replies from the plugin
+        */
+       public Map<String, String> getReplies() {
+               Map<String, String> fields = getFields();
+               Map<String, String> replies = new HashMap<String, String>();
+               for (Entry<String, String> field : fields.entrySet()) {
+                       if (field.getKey().startsWith("Replies.")) {
+                               replies.put(field.getKey().substring(8), field.getValue());
+                       }
+               }
+               return replies;
+       }
+
+       /**
+        * Returns the optional payload.
+        *
+        * @return The payload of the reply, or <code>null</code> if there is no
+        *         payload
+        */
+       public InputStream getPayloadInputStream() {
+               return payloadInputStream;
+       }
+
+}
diff --git a/src/main/java/net/pterodactylus/fcp/FcpAdapter.java b/src/main/java/net/pterodactylus/fcp/FcpAdapter.java
new file mode 100644 (file)
index 0000000..a358d4c
--- /dev/null
@@ -0,0 +1,305 @@
+/*
+ * jFCPlib - FcpAdapter.java - Copyright © 2008 David Roden
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+package net.pterodactylus.fcp;
+
+/**
+ * Adapter for {@link FcpListener}.
+ *
+ * @author David ‘Bombe’ Roden &lt;bombe@freenetproject.org&gt;
+ */
+public class FcpAdapter implements FcpListener {
+
+       /**
+        * {@inheritDoc}
+        */
+       public void receivedNodeHello(FcpConnection fcpConnection, NodeHello nodeHello) {
+               /* empty. */
+       }
+
+       /**
+        * {@inheritDoc}
+        */
+       public void receivedCloseConnectionDuplicateClientName(FcpConnection fcpConnection, CloseConnectionDuplicateClientName closeConnectionDuplicateClientName) {
+               /* empty. */
+       }
+
+       /**
+        * {@inheritDoc}
+        */
+       public void receivedSSKKeypair(FcpConnection fcpConnection, SSKKeypair sskKeypair) {
+               /* empty. */
+       }
+
+       /**
+        * {@inheritDoc}
+        */
+       public void receivedPeer(FcpConnection fcpConnection, Peer peer) {
+               /* empty. */
+       }
+
+       /**
+        * {@inheritDoc}
+        */
+       public void receivedEndListPeers(FcpConnection fcpConnection, EndListPeers endListPeers) {
+               /* empty. */
+       }
+
+       /**
+        * {@inheritDoc}
+        */
+       public void receivedPeerNote(FcpConnection fcpConnection, PeerNote peerNote) {
+               /* empty. */
+       }
+
+       /**
+        * {@inheritDoc}
+        */
+       public void receivedEndListPeerNotes(FcpConnection fcpConnection, EndListPeerNotes endListPeerNotes) {
+               /* empty. */
+       }
+
+       /**
+        * {@inheritDoc}
+        */
+       public void receivedPeerRemoved(FcpConnection fcpConnection, PeerRemoved peerRemoved) {
+               /* empty. */
+       }
+
+       /**
+        * {@inheritDoc}
+        *
+        * @see FcpListener#receivedNodeData(FcpConnection, NodeData)
+        */
+       public void receivedNodeData(FcpConnection fcpConnection, NodeData nodeData) {
+               /* empty. */
+       }
+
+       /**
+        * {@inheritDoc}
+        *
+        * @see FcpListener#receivedTestDDAReply(FcpConnection, TestDDAReply)
+        */
+       public void receivedTestDDAReply(FcpConnection fcpConnection, TestDDAReply testDDAReply) {
+               /* empty. */
+       }
+
+       /**
+        * {@inheritDoc}
+        */
+       public void receivedTestDDAComplete(FcpConnection fcpConnection, TestDDAComplete testDDAComplete) {
+               /* empty. */
+       }
+
+       /**
+        * {@inheritDoc}
+        */
+       public void receivedPersistentGet(FcpConnection fcpConnection, PersistentGet persistentGet) {
+               /* empty. */
+       }
+
+       /**
+        * {@inheritDoc}
+        */
+       public void receivedPersistentPut(FcpConnection fcpConnection, PersistentPut persistentPut) {
+               /* empty. */
+       }
+
+       /**
+        * {@inheritDoc}
+        */
+       public void receivedEndListPersistentRequests(FcpConnection fcpConnection, EndListPersistentRequests endListPersistentRequests) {
+               /* empty. */
+       }
+
+       /**
+        * {@inheritDoc}
+        */
+       public void receivedURIGenerated(FcpConnection fcpConnection, URIGenerated uriGenerated) {
+               /* empty. */
+       }
+
+       /**
+        * {@inheritDoc}
+        */
+       public void receivedDataFound(FcpConnection fcpConnection, DataFound dataFound) {
+               /* empty. */
+       }
+
+       /**
+        * {@inheritDoc}
+        */
+       public void receivedAllData(FcpConnection fcpConnection, AllData allData) {
+               /* empty. */
+       }
+
+       /**
+        * {@inheritDoc}
+        */
+       public void receivedSimpleProgress(FcpConnection fcpConnection, SimpleProgress simpleProgress) {
+               /* empty. */
+       }
+
+       /**
+        * {@inheritDoc}
+        */
+       public void receivedStartedCompression(FcpConnection fcpConnection, StartedCompression startedCompression) {
+               /* empty. */
+       }
+
+       /**
+        * {@inheritDoc}
+        */
+       public void receivedFinishedCompression(FcpConnection fcpConnection, FinishedCompression finishedCompression) {
+               /* empty. */
+       }
+
+       /**
+        * {@inheritDoc}
+        */
+       public void receivedUnknownPeerNoteType(FcpConnection fcpConnection, UnknownPeerNoteType unknownPeerNoteType) {
+               /* empty. */
+       }
+
+       /**
+        * {@inheritDoc}
+        */
+       public void receivedUnknownNodeIdentifier(FcpConnection fcpConnection, UnknownNodeIdentifier unknownNodeIdentifier) {
+               /* empty. */
+       }
+
+       /**
+        * {@inheritDoc}
+        */
+       public void receivedConfigData(FcpConnection fcpConnection, ConfigData configData) {
+               /* empty. */
+       }
+
+       /**
+        * {@inheritDoc}
+        */
+       public void receivedGetFailed(FcpConnection fcpConnection, GetFailed getFailed) {
+               /* empty. */
+       }
+
+       /**
+        * {@inheritDoc}
+        */
+       public void receivedPutFailed(FcpConnection fcpConnection, PutFailed putFailed) {
+               /* empty. */
+       }
+
+       /**
+        * {@inheritDoc}
+        */
+       public void receivedIdentifierCollision(FcpConnection fcpConnection, IdentifierCollision identifierCollision) {
+               /* empty. */
+       }
+
+       /**
+        * {@inheritDoc}
+        */
+       public void receivedPersistentPutDir(FcpConnection fcpConnection, PersistentPutDir persistentPutDir) {
+               /* empty. */
+       }
+
+       /**
+        * {@inheritDoc}
+        */
+       public void receivedPersistentRequestRemoved(FcpConnection fcpConnection, PersistentRequestRemoved persistentRequestRemoved) {
+               /* empty. */
+       }
+
+       /**
+        * {@inheritDoc}
+        */
+       public void receivedSubscribedUSKUpdate(FcpConnection fcpConnection, SubscribedUSKUpdate subscribedUSKUpdate) {
+               /* empty. */
+       }
+
+       /**
+        * {@inheritDoc}
+        */
+       public void receivedPluginInfo(FcpConnection fcpConnection, PluginInfo pluginInfo) {
+               /* empty. */
+       }
+
+       /**
+        * {@inheritDoc}
+        */
+       public void receivedFCPPluginReply(FcpConnection fcpConnection, FCPPluginReply fcpPluginReply) {
+               /* empty. */
+       }
+
+       /**
+        * {@inheritDoc}
+        */
+       public void receivedPersistentRequestModified(FcpConnection fcpConnection, PersistentRequestModified persistentRequestModified) {
+               /* empty. */
+       }
+
+       /**
+        * {@inheritDoc}
+        */
+       public void receivedPutSuccessful(FcpConnection fcpConnection, PutSuccessful putSuccessful) {
+               /* empty. */
+       }
+
+       /**
+        * {@inheritDoc}
+        */
+       public void receivedPutFetchable(FcpConnection fcpConnection, PutFetchable putFetchable) {
+               /* empty. */
+       }
+
+       /**
+        * {@inheritDoc}
+        */
+       public void receivedProtocolError(FcpConnection fcpConnection, ProtocolError protocolError) {
+               /* empty. */
+       }
+
+       /**
+        * {@inheritDoc}
+        */
+       public void receivedSentFeed(FcpConnection source, SentFeed sentFeed) {
+               /* empty. */
+       }
+
+       /**
+        * {@inheritDoc}
+        */
+       public void receivedBookmarkFeed(FcpConnection fcpConnection, ReceivedBookmarkFeed receivedBookmarkFeed) {
+               /* empty. */
+       }
+
+       /**
+        * {@inheritDoc}
+        */
+       public void receivedMessage(FcpConnection fcpConnection, FcpMessage fcpMessage) {
+               /* empty. */
+       }
+
+       /**
+        * {@inheritDoc}
+        */
+       public void connectionClosed(FcpConnection fcpConnection, Throwable throwable) {
+               /* empty. */
+       }
+
+}
diff --git a/src/main/java/net/pterodactylus/fcp/FcpConnection.java b/src/main/java/net/pterodactylus/fcp/FcpConnection.java
new file mode 100644 (file)
index 0000000..2f40785
--- /dev/null
@@ -0,0 +1,496 @@
+/*
+ * jFCPlib - FpcConnection.java - Copyright © 2008 David Roden
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+package net.pterodactylus.fcp;
+
+import java.io.Closeable;
+import java.io.FilterInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.net.InetAddress;
+import java.net.Socket;
+import java.net.UnknownHostException;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.logging.Logger;
+
+/**
+ * An FCP connection to a Freenet node.
+ *
+ * @author David ‘Bombe’ Roden &lt;bombe@freenetproject.org&gt;
+ */
+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;
+
+       /** Listener management. */
+       private final FcpListenerManager fcpListenerManager = new FcpListenerManager(this);
+
+       /** The address of the node. */
+       private final InetAddress address;
+
+       /** The port number of the node’s FCP port. */
+       private final int port;
+
+       /** The remote socket. */
+       private Socket remoteSocket;
+
+       /** The input stream from the node. */
+       private InputStream remoteInputStream;
+
+       /** The output stream to the node. */
+       private OutputStream remoteOutputStream;
+
+       /** The connection handler. */
+       private FcpConnectionHandler connectionHandler;
+
+       /** Incoming message statistics. */
+       private Map<String, Integer> incomingMessageStatistics = Collections.synchronizedMap(new HashMap<String, Integer>());
+
+       /**
+        * Creates a new FCP connection to the freenet node running on localhost,
+        * using the default port.
+        *
+        * @throws UnknownHostException
+        *             if the hostname can not be resolved
+        */
+       public FcpConnection() throws UnknownHostException {
+               this(InetAddress.getLocalHost());
+       }
+
+       /**
+        * Creates a new FCP connection to the Freenet node running on the given
+        * host, listening on the default port.
+        *
+        * @param host
+        *            The hostname of the Freenet node
+        * @throws UnknownHostException
+        *             if <code>host</code> can not be resolved
+        */
+       public FcpConnection(String host) throws UnknownHostException {
+               this(host, DEFAULT_PORT);
+       }
+
+       /**
+        * Creates a new FCP connection to the Freenet node running on the given
+        * host, listening on the given port.
+        *
+        * @param host
+        *            The hostname of the Freenet node
+        * @param port
+        *            The port number of the node’s FCP port
+        * @throws UnknownHostException
+        *             if <code>host</code> can not be resolved
+        */
+       public FcpConnection(String host, int port) throws UnknownHostException {
+               this(InetAddress.getByName(host), port);
+       }
+
+       /**
+        * Creates a new FCP connection to the Freenet node running at the given
+        * address, listening on the default port.
+        *
+        * @param address
+        *            The address of the Freenet node
+        */
+       public FcpConnection(InetAddress address) {
+               this(address, DEFAULT_PORT);
+       }
+
+       /**
+        * Creates a new FCP connection to the Freenet node running at the given
+        * address, listening on the given port.
+        *
+        * @param address
+        *            The address of the Freenet node
+        * @param port
+        *            The port number of the node’s FCP port
+        */
+       public FcpConnection(InetAddress address, int port) {
+               this.address = address;
+               this.port = port;
+       }
+
+       //
+       // LISTENER MANAGEMENT
+       //
+
+       /**
+        * Adds the given listener to the list of listeners.
+        *
+        * @param fcpListener
+        *            The listener to add
+        */
+       public void addFcpListener(FcpListener fcpListener) {
+               fcpListenerManager.addListener(fcpListener);
+       }
+
+       /**
+        * Removes the given listener from the list of listeners.
+        *
+        * @param fcpListener
+        *            The listener to remove
+        */
+       public void removeFcpListener(FcpListener fcpListener) {
+               fcpListenerManager.removeListener(fcpListener);
+       }
+
+       //
+       // ACTIONS
+       //
+
+       /**
+        * Connects to the node.
+        *
+        * @throws IOException
+        *             if an I/O error occurs
+        * @throws IllegalStateException
+        *             if there is already a connection to the node
+        */
+       public synchronized void connect() throws IOException, IllegalStateException {
+               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();
+               new Thread(connectionHandler = new FcpConnectionHandler(this, remoteInputStream)).start();
+       }
+
+       /**
+        * 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() {
+               close();
+       }
+
+       /**
+        * Closes the connection. If there is no connection to the node, this method
+        * does nothing.
+        */
+       public void close() {
+               handleDisconnect(null);
+       }
+
+       /**
+        * Sends the given FCP message.
+        *
+        * @param fcpMessage
+        *            The FCP message to send
+        * @throws IOException
+        *             if an I/O error occurs
+        */
+       public synchronized void sendMessage(FcpMessage fcpMessage) throws IOException {
+               logger.fine("sending message: " + fcpMessage.getName());
+               fcpMessage.write(remoteOutputStream);
+       }
+
+       //
+       // PACKAGE-PRIVATE METHODS
+       //
+
+       /**
+        * Handles the given message, notifying listeners. This message should only
+        * be called by {@link FcpConnectionHandler}.
+        *
+        * @param fcpMessage
+        *            The received message
+        */
+       void handleMessage(FcpMessage fcpMessage) {
+               logger.fine("received message: " + fcpMessage.getName());
+               String messageName = fcpMessage.getName();
+               countMessage(messageName);
+               if ("SimpleProgress".equals(messageName)) {
+                       fcpListenerManager.fireReceivedSimpleProgress(new SimpleProgress(fcpMessage));
+               } else if ("ProtocolError".equals(messageName)) {
+                       fcpListenerManager.fireReceivedProtocolError(new ProtocolError(fcpMessage));
+               } else if ("PersistentGet".equals(messageName)) {
+                       fcpListenerManager.fireReceivedPersistentGet(new PersistentGet(fcpMessage));
+               } else if ("PersistentPut".equals(messageName)) {
+                       fcpListenerManager.fireReceivedPersistentPut(new PersistentPut(fcpMessage));
+               } else if ("PersistentPutDir".equals(messageName)) {
+                       fcpListenerManager.fireReceivedPersistentPutDir(new PersistentPutDir(fcpMessage));
+               } else if ("URIGenerated".equals(messageName)) {
+                       fcpListenerManager.fireReceivedURIGenerated(new URIGenerated(fcpMessage));
+               } else if ("EndListPersistentRequests".equals(messageName)) {
+                       fcpListenerManager.fireReceivedEndListPersistentRequests(new EndListPersistentRequests(fcpMessage));
+               } else if ("Peer".equals(messageName)) {
+                       fcpListenerManager.fireReceivedPeer(new Peer(fcpMessage));
+               } else if ("PeerNote".equals(messageName)) {
+                       fcpListenerManager.fireReceivedPeerNote(new PeerNote(fcpMessage));
+               } else if ("StartedCompression".equals(messageName)) {
+                       fcpListenerManager.fireReceivedStartedCompression(new StartedCompression(fcpMessage));
+               } else if ("FinishedCompression".equals(messageName)) {
+                       fcpListenerManager.fireReceivedFinishedCompression(new FinishedCompression(fcpMessage));
+               } else if ("GetFailed".equals(messageName)) {
+                       fcpListenerManager.fireReceivedGetFailed(new GetFailed(fcpMessage));
+               } else if ("PutFetchable".equals(messageName)) {
+                       fcpListenerManager.fireReceivedPutFetchable(new PutFetchable(fcpMessage));
+               } else if ("PutSuccessful".equals(messageName)) {
+                       fcpListenerManager.fireReceivedPutSuccessful(new PutSuccessful(fcpMessage));
+               } else if ("PutFailed".equals(messageName)) {
+                       fcpListenerManager.fireReceivedPutFailed(new PutFailed(fcpMessage));
+               } else if ("DataFound".equals(messageName)) {
+                       fcpListenerManager.fireReceivedDataFound(new DataFound(fcpMessage));
+               } else if ("SubscribedUSKUpdate".equals(messageName)) {
+                       fcpListenerManager.fireReceivedSubscribedUSKUpdate(new SubscribedUSKUpdate(fcpMessage));
+               } else if ("IdentifierCollision".equals(messageName)) {
+                       fcpListenerManager.fireReceivedIdentifierCollision(new IdentifierCollision(fcpMessage));
+               } else if ("AllData".equals(messageName)) {
+                       LimitedInputStream payloadInputStream = getInputStream(FcpUtils.safeParseLong(fcpMessage.getField("DataLength")));
+                       fcpListenerManager.fireReceivedAllData(new AllData(fcpMessage, payloadInputStream));
+                       try {
+                               payloadInputStream.consume();
+                       } catch (IOException ioe1) {
+                               /* well, ignore. when the connection handler fails, all fails. */
+                       }
+               } else if ("EndListPeerNotes".equals(messageName)) {
+                       fcpListenerManager.fireReceivedEndListPeerNotes(new EndListPeerNotes(fcpMessage));
+               } else if ("EndListPeers".equals(messageName)) {
+                       fcpListenerManager.fireReceivedEndListPeers(new EndListPeers(fcpMessage));
+               } else if ("SSKKeypair".equals(messageName)) {
+                       fcpListenerManager.fireReceivedSSKKeypair(new SSKKeypair(fcpMessage));
+               } else if ("PeerRemoved".equals(messageName)) {
+                       fcpListenerManager.fireReceivedPeerRemoved(new PeerRemoved(fcpMessage));
+               } else if ("PersistentRequestModified".equals(messageName)) {
+                       fcpListenerManager.fireReceivedPersistentRequestModified(new PersistentRequestModified(fcpMessage));
+               } else if ("PersistentRequestRemoved".equals(messageName)) {
+                       fcpListenerManager.fireReceivedPersistentRequestRemoved(new PersistentRequestRemoved(fcpMessage));
+               } else if ("UnknownPeerNoteType".equals(messageName)) {
+                       fcpListenerManager.fireReceivedUnknownPeerNoteType(new UnknownPeerNoteType(fcpMessage));
+               } else if ("UnknownNodeIdentifier".equals(messageName)) {
+                       fcpListenerManager.fireReceivedUnknownNodeIdentifier(new UnknownNodeIdentifier(fcpMessage));
+               } else if ("FCPPluginReply".equals(messageName)) {
+                       LimitedInputStream payloadInputStream = getInputStream(FcpUtils.safeParseLong(fcpMessage.getField("DataLength")));
+                       fcpListenerManager.fireReceivedFCPPluginReply(new FCPPluginReply(fcpMessage, payloadInputStream));
+                       try {
+                               payloadInputStream.consume();
+                       } catch (IOException ioe1) {
+                               /* ignore. */
+                       }
+               } else if ("PluginInfo".equals(messageName)) {
+                       fcpListenerManager.fireReceivedPluginInfo(new PluginInfo(fcpMessage));
+               } else if ("NodeData".equals(messageName)) {
+                       fcpListenerManager.fireReceivedNodeData(new NodeData(fcpMessage));
+               } else if ("TestDDAReply".equals(messageName)) {
+                       fcpListenerManager.fireReceivedTestDDAReply(new TestDDAReply(fcpMessage));
+               } else if ("TestDDAComplete".equals(messageName)) {
+                       fcpListenerManager.fireReceivedTestDDAComplete(new TestDDAComplete(fcpMessage));
+               } else if ("ConfigData".equals(messageName)) {
+                       fcpListenerManager.fireReceivedConfigData(new ConfigData(fcpMessage));
+               } else if ("NodeHello".equals(messageName)) {
+                       fcpListenerManager.fireReceivedNodeHello(new NodeHello(fcpMessage));
+               } else if ("CloseConnectionDuplicateClientName".equals(messageName)) {
+                       fcpListenerManager.fireReceivedCloseConnectionDuplicateClientName(new CloseConnectionDuplicateClientName(fcpMessage));
+               } else if ("SentFeed".equals(messageName)) {
+                       fcpListenerManager.fireSentFeed(new SentFeed(fcpMessage));
+               } else if ("ReceivedBookmarkFeed".equals(messageName)) {
+                       fcpListenerManager.fireReceivedBookmarkFeed(new ReceivedBookmarkFeed(fcpMessage));
+               } else {
+                       fcpListenerManager.fireMessageReceived(fcpMessage);
+               }
+       }
+
+       /**
+        * 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(Throwable throwable) {
+               FcpUtils.close(remoteInputStream);
+               FcpUtils.close(remoteOutputStream);
+               FcpUtils.close(remoteSocket);
+               if (connectionHandler != null) {
+                       connectionHandler.stop();
+                       connectionHandler = null;
+                       fcpListenerManager.fireConnectionClosed(throwable);
+               }
+       }
+
+       //
+       // PRIVATE METHODS
+       //
+
+       /**
+        * Incremets the counter in {@link #incomingMessageStatistics} by
+        * <cod>1</code> for the given message name.
+        *
+        * @param name
+        *            The name of the message to count
+        */
+       private void countMessage(String name) {
+               int oldValue = 0;
+               if (incomingMessageStatistics.containsKey(name)) {
+                       oldValue = incomingMessageStatistics.get(name);
+               }
+               incomingMessageStatistics.put(name, oldValue + 1);
+               logger.finest("count for " + name + ": " + (oldValue + 1));
+       }
+
+       /**
+        * Returns a limited input stream from the node’s input stream.
+        *
+        * @param dataLength
+        *            The length of the stream
+        * @return The limited input stream
+        */
+       private synchronized LimitedInputStream getInputStream(long dataLength) {
+               if (dataLength <= 0) {
+                       return new LimitedInputStream(null, 0);
+               }
+               return new LimitedInputStream(remoteInputStream, dataLength);
+       }
+
+       /**
+        * A wrapper around an {@link InputStream} that only supplies a limit number
+        * of bytes from the underlying input stream.
+        *
+        * @author David ‘Bombe’ Roden &lt;bombe@freenetproject.org&gt;
+        */
+       private static class LimitedInputStream extends FilterInputStream {
+
+               /** The remaining number of bytes that can be read. */
+               private long remaining;
+
+               /**
+                * Creates a new LimitedInputStream that supplies at most
+                * <code>length</code> bytes from the given input stream.
+                *
+                * @param inputStream
+                *            The input stream
+                * @param length
+                *            The number of bytes to read
+                */
+               public LimitedInputStream(InputStream inputStream, long length) {
+                       super(inputStream);
+                       remaining = length;
+               }
+
+               /**
+                * @see java.io.FilterInputStream#available()
+                */
+               @Override
+               public synchronized int available() throws IOException {
+                       if (remaining == 0) {
+                               return 0;
+                       }
+                       return (int) Math.min(super.available(), Math.min(Integer.MAX_VALUE, remaining));
+               }
+
+               /**
+                * @see java.io.FilterInputStream#read()
+                */
+               @Override
+               public synchronized int read() throws IOException {
+                       int read = -1;
+                       if (remaining > 0) {
+                               read = super.read();
+                               remaining--;
+                       }
+                       return read;
+               }
+
+               /**
+                * @see java.io.FilterInputStream#read(byte[], int, int)
+                */
+               @Override
+               public synchronized int read(byte[] b, int off, int len) throws IOException {
+                       if (remaining == 0) {
+                               return -1;
+                       }
+                       int toCopy = (int) Math.min(len, Math.min(remaining, Integer.MAX_VALUE));
+                       int read = super.read(b, off, toCopy);
+                       remaining -= read;
+                       return read;
+               }
+
+               /**
+                * @see java.io.FilterInputStream#skip(long)
+                */
+               @Override
+               public synchronized long skip(long n) throws IOException {
+                       if ((n < 0) || (remaining == 0)) {
+                               return 0;
+                       }
+                       long skipped = super.skip(Math.min(n, remaining));
+                       remaining -= skipped;
+                       return skipped;
+               }
+
+               /**
+                * {@inheritDoc} This method does nothing, as {@link #mark(int)} and
+                * {@link #reset()} are not supported.
+                *
+                * @see java.io.FilterInputStream#mark(int)
+                */
+               @Override
+               public void mark(int readlimit) {
+                       /* do nothing. */
+               }
+
+               /**
+                * {@inheritDoc}
+                *
+                * @see java.io.FilterInputStream#markSupported()
+                * @return <code>false</code>
+                */
+               @Override
+               public boolean markSupported() {
+                       return false;
+               }
+
+               /**
+                * {@inheritDoc} This method does nothing, as {@link #mark(int)} and
+                * {@link #reset()} are not supported.
+                *
+                * @see java.io.FilterInputStream#reset()
+                */
+               @Override
+               public void reset() throws IOException {
+                       /* do nothing. */
+               }
+
+               /**
+                * Consumes the input stream, i.e. read all bytes until the limit is
+                * reached.
+                *
+                * @throws IOException
+                *             if an I/O error occurs
+                */
+               public synchronized void consume() throws IOException {
+                       while (remaining > 0) {
+                               skip(remaining);
+                       }
+               }
+
+       }
+
+}
diff --git a/src/main/java/net/pterodactylus/fcp/FcpConnectionHandler.java b/src/main/java/net/pterodactylus/fcp/FcpConnectionHandler.java
new file mode 100644 (file)
index 0000000..dbf0969
--- /dev/null
@@ -0,0 +1,160 @@
+/*
+ * jFCPlib - FcpConnectionHandler.java - Copyright © 2008 David Roden
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+package net.pterodactylus.fcp;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.nio.ByteBuffer;
+import java.nio.charset.Charset;
+
+/**
+ * Handles an FCP connection to a node.
+ *
+ * @author David ‘Bombe’ Roden &lt;bombe@freenetproject.org&gt;
+ */
+class FcpConnectionHandler implements Runnable {
+
+       /** The underlying connection. */
+       private final FcpConnection fcpConnection;
+
+       /** The input stream from the node. */
+       private final InputStream remoteInputStream;
+
+       /** Whether to stop the connection handler. */
+       private boolean shouldStop;
+
+       /** Whether the next read line feed should be ignored. */
+       private boolean ignoreNextLinefeed;
+
+       /**
+        * Creates a new connection handler that operates on the given connection
+        * and input stream.
+        *
+        * @param fcpConnection
+        *            The underlying FCP connection
+        * @param remoteInputStream
+        *            The input stream from the node
+        */
+       public FcpConnectionHandler(FcpConnection fcpConnection, InputStream remoteInputStream) {
+               this.fcpConnection = fcpConnection;
+               this.remoteInputStream = remoteInputStream;
+       }
+
+       /**
+        * {@inheritDoc}
+        */
+       public void run() {
+               FcpMessage fcpMessage = null;
+               Throwable throwable = null;
+               while (true) {
+                       synchronized (this) {
+                               if (shouldStop) {
+                                       break;
+                               }
+                       }
+                       try {
+                               String line = readLine();
+                               System.out.println("read line: " + line);
+                               if (line == null) {
+                                       break;
+                               }
+                               if (line.length() == 0) {
+                                       continue;
+                               }
+                               line = line.trim();
+                               if (fcpMessage == null) {
+                                       fcpMessage = new FcpMessage(line);
+                                       continue;
+                               }
+                               if ("EndMessage".equalsIgnoreCase(line) || "Data".equalsIgnoreCase(line)) {
+                                       fcpConnection.handleMessage(fcpMessage);
+                                       fcpMessage = null;
+                               }
+                               int equalSign = line.indexOf('=');
+                               if (equalSign == -1) {
+                                       /* something's fishy! */
+                                       continue;
+                               }
+                               String field = line.substring(0, equalSign);
+                               String value = line.substring(equalSign + 1);
+                               assert fcpMessage != null: "fcp message is null";
+                               fcpMessage.setField(field, value);
+                       } catch (IOException ioe1) {
+                               throwable = ioe1;
+                               break;
+                       }
+               }
+               fcpConnection.handleDisconnect(throwable);
+       }
+
+       /**
+        * Stops the connection handler.
+        */
+       public void stop() {
+               synchronized (this) {
+                       shouldStop = true;
+               }
+       }
+
+       //
+       // PRIVATE METHODS
+       //
+
+       /**
+        * Reads bytes from {@link #remoteInputStream} until ‘\r’ or ‘\n’ are
+        * encountered and decodes the read bytes using UTF-8.
+        *
+        * @return The decoded line
+        * @throws IOException
+        *             if an I/O error occurs
+        */
+       private String readLine() throws IOException {
+               byte[] readBytes = new byte[512];
+               int readIndex = 0;
+               while (true) {
+                       int nextByte = remoteInputStream.read();
+                       if (nextByte == -1) {
+                               if (readIndex == 0) {
+                                       return null;
+                               }
+                               break;
+                       }
+                       if (nextByte == 10) {
+                               if (!ignoreNextLinefeed) {
+                                       break;
+                               }
+                       }
+                       ignoreNextLinefeed = false;
+                       if (nextByte == 13) {
+                               ignoreNextLinefeed = true;
+                               break;
+                       }
+                       if (readIndex == readBytes.length) {
+                               /* recopy & enlarge array */
+                               byte[] newReadBytes = new byte[readBytes.length * 2];
+                               System.arraycopy(readBytes, 0, newReadBytes, 0, readBytes.length);
+                               readBytes = newReadBytes;
+                       }
+                       readBytes[readIndex++] = (byte) nextByte;
+               }
+               ByteBuffer byteBuffer = ByteBuffer.wrap(readBytes, 0, readIndex);
+               return Charset.forName("UTF-8").decode(byteBuffer).toString();
+       }
+
+}
diff --git a/src/main/java/net/pterodactylus/fcp/FcpKeyPair.java b/src/main/java/net/pterodactylus/fcp/FcpKeyPair.java
new file mode 100644 (file)
index 0000000..4b9ba05
--- /dev/null
@@ -0,0 +1,65 @@
+/*
+ * jFCPlib - FcpKeyPair.java - Copyright © 2008 David Roden
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+package net.pterodactylus.fcp;
+
+/**
+ * Container for an SSK keypair.
+ *
+ * @author David ‘Bombe’ Roden &lt;bombe@freenetproject.org&gt;
+ */
+public class FcpKeyPair {
+
+       /** The public key. */
+       private final String publicKey;
+
+       /** The private key. */
+       private final String privateKey;
+
+       /**
+        * Creates a new keypair from the given keys.
+        *
+        * @param publicKey
+        *            The public key
+        * @param privateKey
+        *            The private key
+        */
+       public FcpKeyPair(String publicKey, String privateKey) {
+               this.publicKey = publicKey;
+               this.privateKey = privateKey;
+       }
+
+       /**
+        * Returns the public key of this keypair.
+        *
+        * @return The public key
+        */
+       public String getPublicKey() {
+               return publicKey;
+       }
+
+       /**
+        * Returns the private key of this keypair.
+        *
+        * @return The private key
+        */
+       public String getPrivateKey() {
+               return privateKey;
+       }
+
+}
diff --git a/src/main/java/net/pterodactylus/fcp/FcpListener.java b/src/main/java/net/pterodactylus/fcp/FcpListener.java
new file mode 100644 (file)
index 0000000..4f0c77a
--- /dev/null
@@ -0,0 +1,428 @@
+/*
+ * jFCPlib - FpcListener.java - Copyright © 2008 David Roden
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+package net.pterodactylus.fcp;
+
+import java.util.EventListener;
+
+/**
+ * Interface for objects that want to be notified on certain FCP events.
+ *
+ * @author David ‘Bombe’ Roden &lt;bombe@freenetproject.org&gt;
+ */
+public interface FcpListener extends EventListener {
+
+       /**
+        * Notifies a listener that a “NodeHello” message was received.
+        *
+        * @param fcpConnection
+        *            The connection that received the message
+        * @param nodeHello
+        *            The “NodeHello” message
+        */
+       public void receivedNodeHello(FcpConnection fcpConnection, NodeHello nodeHello);
+
+       /**
+        * Notifies a listener that a “CloseConnectionDuplicateClientName” message
+        * was received.
+        *
+        * @param fcpConnection
+        *            The connection that received the message
+        * @param closeConnectionDuplicateClientName
+        *            The “CloseConnectionDuplicateClientName” message
+        */
+       public void receivedCloseConnectionDuplicateClientName(FcpConnection fcpConnection, CloseConnectionDuplicateClientName closeConnectionDuplicateClientName);
+
+       /**
+        * Notifies a listener that a “SSKKeypair” message was received.
+        *
+        * @param fcpConnection
+        *            The connection that received themessage
+        * @param sskKeypair
+        *            The “SSKKeypair” message
+        */
+       public void receivedSSKKeypair(FcpConnection fcpConnection, SSKKeypair sskKeypair);
+
+       /**
+        * Notifies a listener that a “Peer” message was received.
+        *
+        * @param fcpConnection
+        *            The connection that received the message
+        * @param peer
+        *            The “Peer” message
+        */
+       public void receivedPeer(FcpConnection fcpConnection, Peer peer);
+
+       /**
+        * Notifies a listener that an “EndListPeers” message was received.
+        *
+        * @param fcpConnection
+        *            The connection that recevied the message
+        * @param endListPeers
+        *            The “EndListPeers” message
+        */
+       public void receivedEndListPeers(FcpConnection fcpConnection, EndListPeers endListPeers);
+
+       /**
+        * Notifies a listener that a “PeerNote” message was received.
+        *
+        * @param fcpConnection
+        *            The connection that received the message
+        * @param peerNote
+        *            The “PeerNote” message
+        */
+       public void receivedPeerNote(FcpConnection fcpConnection, PeerNote peerNote);
+
+       /**
+        * Notifies a listener that an “EndListPeerNotes” message was received.
+        *
+        * @param fcpConnection
+        *            The connection that received the message
+        * @param endListPeerNotes
+        *            The “EndListPeerNotes” message
+        */
+       public void receivedEndListPeerNotes(FcpConnection fcpConnection, EndListPeerNotes endListPeerNotes);
+
+       /**
+        * Notifies a listener that a “PeerRemoved” message was received.
+        *
+        * @param fcpConnection
+        *            The connection that received the message
+        * @param peerRemoved
+        *            The “PeerRemoved” message
+        */
+       public void receivedPeerRemoved(FcpConnection fcpConnection, PeerRemoved peerRemoved);
+
+       /**
+        * Notifies a listener that a “NodeData” message was received.
+        *
+        * @param fcpConnection
+        *            The connection that received the message
+        * @param nodeData
+        *            The “NodeData” message
+        */
+       public void receivedNodeData(FcpConnection fcpConnection, NodeData nodeData);
+
+       /**
+        * Notifies a listener that a “TestDDAReply” message was received.
+        *
+        * @param fcpConnection
+        *            The connection that received the message
+        * @param testDDAReply
+        *            The “TestDDAReply” message
+        */
+       public void receivedTestDDAReply(FcpConnection fcpConnection, TestDDAReply testDDAReply);
+
+       /**
+        * Notifies a listener that a “TestDDAComplete” was received.
+        *
+        * @param fcpConnection
+        *            The connection that received the message
+        * @param testDDAComplete
+        *            The “TestDDAComplete” message
+        */
+       public void receivedTestDDAComplete(FcpConnection fcpConnection, TestDDAComplete testDDAComplete);
+
+       /**
+        * Notifies a listener that a “PersistentGet” was received.
+        *
+        * @param fcpConnection
+        *            The connection that received the message
+        * @param persistentGet
+        *            The “PersistentGet” message
+        */
+       public void receivedPersistentGet(FcpConnection fcpConnection, PersistentGet persistentGet);
+
+       /**
+        * Notifies a listener that a “PersistentPut” was received.
+        *
+        * @param fcpConnection
+        *            The connection that received the message
+        * @param persistentPut
+        *            The “PersistentPut” message
+        */
+       public void receivedPersistentPut(FcpConnection fcpConnection, PersistentPut persistentPut);
+
+       /**
+        * Notifies a listener that a “EndListPersistentRequests” was received.
+        *
+        * @param fcpConnection
+        *            The connection that received the message
+        * @param endListPersistentRequests
+        *            The “EndListPersistentRequests” message
+        */
+       public void receivedEndListPersistentRequests(FcpConnection fcpConnection, EndListPersistentRequests endListPersistentRequests);
+
+       /**
+        * Notifies a listener that a “URIGenerated” was received.
+        *
+        * @param fcpConnection
+        *            The connection that received the message
+        * @param uriGenerated
+        *            The “URIGenerated” message
+        */
+       public void receivedURIGenerated(FcpConnection fcpConnection, URIGenerated uriGenerated);
+
+       /**
+        * Notifies a listener that a “DataFound” was received.
+        *
+        * @param fcpConnection
+        *            The connection that received the message
+        * @param dataFound
+        *            The “DataFound” message
+        */
+       public void receivedDataFound(FcpConnection fcpConnection, DataFound dataFound);
+
+       /**
+        * Notifies a listener that an “AllData” was received.
+        *
+        * @param fcpConnection
+        *            The connection that received the message
+        * @param allData
+        *            The “AllData” message
+        */
+       public void receivedAllData(FcpConnection fcpConnection, AllData allData);
+
+       /**
+        * Notifies a listener that a “SimpleProgress” was received.
+        *
+        * @param fcpConnection
+        *            The connection that received the message
+        * @param simpleProgress
+        *            The “SimpleProgress” message
+        */
+       public void receivedSimpleProgress(FcpConnection fcpConnection, SimpleProgress simpleProgress);
+
+       /**
+        * Notifies a listener that a “StartedCompression” was received.
+        *
+        * @param fcpConnection
+        *            The connection that received the message
+        * @param startedCompression
+        *            The “StartedCompression” message
+        */
+       public void receivedStartedCompression(FcpConnection fcpConnection, StartedCompression startedCompression);
+
+       /**
+        * Notifies a listener that a “FinishedCompression” was received.
+        *
+        * @param fcpConnection
+        *            The connection that received the message
+        * @param finishedCompression
+        *            The “FinishedCompression” message
+        */
+       public void receivedFinishedCompression(FcpConnection fcpConnection, FinishedCompression finishedCompression);
+
+       /**
+        * Notifies a listener that an “UnknownPeerNoteType” was received.
+        *
+        * @param fcpConnection
+        *            The connection that received the message
+        * @param unknownPeerNoteType
+        *            The “UnknownPeerNoteType” message
+        */
+       public void receivedUnknownPeerNoteType(FcpConnection fcpConnection, UnknownPeerNoteType unknownPeerNoteType);
+
+       /**
+        * Notifies a listener that a “UnknownNodeIdentifier” message was received.
+        *
+        * @param fcpConnection
+        *            The connection that received the message
+        * @param unknownNodeIdentifier
+        *            The “UnknownNodeIdentifier” message
+        */
+       public void receivedUnknownNodeIdentifier(FcpConnection fcpConnection, UnknownNodeIdentifier unknownNodeIdentifier);
+
+       /**
+        * Notifies a listener that a “ConfigData” message was received.
+        *
+        * @param fcpConnection
+        *            The connection that received the message
+        * @param configData
+        *            The “ConfigData” message
+        */
+       public void receivedConfigData(FcpConnection fcpConnection, ConfigData configData);
+
+       /**
+        * Notifies a listener that a “GetFailed” message was recevied.
+        *
+        * @param fcpConnection
+        *            The connection that received the message
+        * @param getFailed
+        *            The “GetFailed” message
+        */
+       public void receivedGetFailed(FcpConnection fcpConnection, GetFailed getFailed);
+
+       /**
+        * Notifies a listener that a “PutFailed” message was received.
+        *
+        * @param fcpConnection
+        *            The connection that received the message
+        * @param putFailed
+        *            The “PutFailed” message
+        */
+       public void receivedPutFailed(FcpConnection fcpConnection, PutFailed putFailed);
+
+       /**
+        * Notifies a listener that an “IdentifierCollision” message was receied.
+        *
+        * @param fcpConnection
+        *            The connection that received the message
+        * @param identifierCollision
+        *            The “IdentifierCollision” message
+        */
+       public void receivedIdentifierCollision(FcpConnection fcpConnection, IdentifierCollision identifierCollision);
+
+       /**
+        * Notifies a listener that a “PersistentPutDir” message was received.
+        *
+        * @param fcpConnection
+        *            The connection that received the message
+        * @param persistentPutDir
+        *            The “PersistentPutDir” message
+        */
+       public void receivedPersistentPutDir(FcpConnection fcpConnection, PersistentPutDir persistentPutDir);
+
+       /**
+        * Notifies a listener that a “PersistentRequestRemoved” message was
+        * received.
+        *
+        * @param fcpConnection
+        *            The connection that received the message
+        * @param persistentRequestRemoved
+        *            The “PersistentRequestRemoved” message
+        */
+       public void receivedPersistentRequestRemoved(FcpConnection fcpConnection, PersistentRequestRemoved persistentRequestRemoved);
+
+       /**
+        * Notifies a listener that a “SubscribedUSKUpdate” message was received.
+        *
+        * @param fcpConnection
+        *            The connection that recevied the message
+        * @param subscribedUSKUpdate
+        *            The “SubscribedUSKUpdate” message
+        */
+       public void receivedSubscribedUSKUpdate(FcpConnection fcpConnection, SubscribedUSKUpdate subscribedUSKUpdate);
+
+       /**
+        * Notifies a listener that a “PluginInfo” message was received.
+        *
+        * @param fcpConnection
+        *            The connection that received the message
+        * @param pluginInfo
+        *            The “PluginInfo” message
+        */
+       public void receivedPluginInfo(FcpConnection fcpConnection, PluginInfo pluginInfo);
+
+       /**
+        * Notifies a listener that an “FCPPluginReply“ message was received.
+        *
+        * @param fcpConnection
+        *            The connection that received the message
+        * @param fcpPluginReply
+        *            The “FCPPluginReply” message
+        */
+       public void receivedFCPPluginReply(FcpConnection fcpConnection, FCPPluginReply fcpPluginReply);
+
+       /**
+        * Notifies a listener that a “PersistentRequestModified” message was
+        * received.
+        *
+        * @param fcpConnection
+        *            The connection that received the message
+        * @param persistentRequestModified
+        *            The “PersistentRequestModified” message
+        */
+       public void receivedPersistentRequestModified(FcpConnection fcpConnection, PersistentRequestModified persistentRequestModified);
+
+       /**
+        * Notifies a listener that a “PutSuccessful” message was received.
+        *
+        * @param fcpConnection
+        *            The connection that received the message
+        * @param putSuccessful
+        *            The “PutSuccessful” message
+        */
+       public void receivedPutSuccessful(FcpConnection fcpConnection, PutSuccessful putSuccessful);
+
+       /**
+        * Notifies a listener that a “PutFetchable” message was received.
+        *
+        * @param fcpConnection
+        *            The connection that received the message
+        * @param putFetchable
+        *            The “PutFetchable” message
+        */
+       public void receivedPutFetchable(FcpConnection fcpConnection, PutFetchable putFetchable);
+
+       /**
+        * Notifies a listener that a feed was sent to a peer.
+        *
+        * @param source
+        *            The connection that received the message
+        * @param sentFeed
+        *            The “SentFeed” message
+        */
+       public void receivedSentFeed(FcpConnection source, SentFeed sentFeed);
+
+       /**
+        * Notifies a listener that a bookmark was updated.
+        *
+        * @param fcpConnection
+        *            The connection that received the message
+        * @param receivedBookmarkFeed
+        *            The “ReceivedBookmarkFeed” message
+        */
+       public void receivedBookmarkFeed(FcpConnection fcpConnection, ReceivedBookmarkFeed receivedBookmarkFeed);
+
+       /**
+        * Notifies a listener that a “ProtocolError” was received.
+        *
+        * @param fcpConnection
+        *            The connection that received the message
+        * @param protocolError
+        *            The “ProtocolError” message
+        */
+       public void receivedProtocolError(FcpConnection fcpConnection, ProtocolError protocolError);
+
+       /**
+        * Notifies a listener that a message has been received. This method is only
+        * called if {@link FcpConnection#handleMessage(FcpMessage)} does not
+        * recognize the message. Should that ever happen, please file a bug report!
+        *
+        * @param fcpConnection
+        *            The connection that received the message
+        * @param fcpMessage
+        *            The message that was received
+        */
+       public void receivedMessage(FcpConnection fcpConnection, FcpMessage fcpMessage);
+
+       /**
+        * Notifies a listener that a connection was closed. A closed connection can
+        * be reestablished by calling {@link FcpConnection#connect()} on the same
+        * object again.
+        *
+        * @param fcpConnection
+        *            The connection that was closed.
+        * @param throwable
+        *            The exception that caused the disconnect, or <code>null</code>
+        *            if there was no exception
+        */
+       public void connectionClosed(FcpConnection fcpConnection, Throwable throwable);
+
+}
diff --git a/src/main/java/net/pterodactylus/fcp/FcpListenerManager.java b/src/main/java/net/pterodactylus/fcp/FcpListenerManager.java
new file mode 100644 (file)
index 0000000..4e1cce6
--- /dev/null
@@ -0,0 +1,568 @@
+/*
+ * jFCPlib - FcpListenerManager.java - Copyright © 2009 David Roden
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+package net.pterodactylus.fcp;
+
+import net.pterodactylus.util.event.AbstractListenerManager;
+
+/**
+ * Manages FCP listeners and event firing.
+ *
+ * @author David ‘Bombe’ Roden &lt;bombe@pterodactylus.net&gt;
+ */
+public class FcpListenerManager extends AbstractListenerManager<FcpConnection, FcpListener> {
+
+       /**
+        * Creates a new listener manager.
+        *
+        * @param fcpConnection
+        *            The source FCP connection
+        */
+       public FcpListenerManager(FcpConnection fcpConnection) {
+               super(fcpConnection);
+       }
+
+       /**
+        * Notifies listeners that a “NodeHello” message was received.
+        *
+        * @see FcpListener#receivedNodeHello(FcpConnection, NodeHello)
+        * @param nodeHello
+        *            The “NodeHello” message
+        */
+       public void fireReceivedNodeHello(NodeHello nodeHello) {
+               for (FcpListener fcpListener : getListeners()) {
+                       fcpListener.receivedNodeHello(getSource(), nodeHello);
+               }
+       }
+
+       /**
+        * Notifies listeners that a “CloseConnectionDuplicateClientName” message
+        * was received.
+        *
+        * @see FcpListener#receivedCloseConnectionDuplicateClientName(FcpConnection,
+        *      CloseConnectionDuplicateClientName)
+        * @param closeConnectionDuplicateClientName
+        *            The “CloseConnectionDuplicateClientName” message
+        */
+       public void fireReceivedCloseConnectionDuplicateClientName(CloseConnectionDuplicateClientName closeConnectionDuplicateClientName) {
+               for (FcpListener fcpListener : getListeners()) {
+                       fcpListener.receivedCloseConnectionDuplicateClientName(getSource(), closeConnectionDuplicateClientName);
+               }
+       }
+
+       /**
+        * Notifies listeners that a “SSKKeypair” message was received.
+        *
+        * @see FcpListener#receivedSSKKeypair(FcpConnection, SSKKeypair)
+        * @param sskKeypair
+        *            The “SSKKeypair” message
+        */
+       public void fireReceivedSSKKeypair(SSKKeypair sskKeypair) {
+               for (FcpListener fcpListener : getListeners()) {
+                       fcpListener.receivedSSKKeypair(getSource(), sskKeypair);
+               }
+       }
+
+       /**
+        * Notifies listeners that a “Peer” message was received.
+        *
+        * @see FcpListener#receivedPeer(FcpConnection, Peer)
+        * @param peer
+        *            The “Peer” message
+        */
+       public void fireReceivedPeer(Peer peer) {
+               for (FcpListener fcpListener : getListeners()) {
+                       fcpListener.receivedPeer(getSource(), peer);
+               }
+       }
+
+       /**
+        * Notifies all listeners that an “EndListPeers” message was received.
+        *
+        * @see FcpListener#receivedEndListPeers(FcpConnection, EndListPeers)
+        * @param endListPeers
+        *            The “EndListPeers” message
+        */
+       public void fireReceivedEndListPeers(EndListPeers endListPeers) {
+               for (FcpListener fcpListener : getListeners()) {
+                       fcpListener.receivedEndListPeers(getSource(), endListPeers);
+               }
+       }
+
+       /**
+        * Notifies all listeners that a “PeerNote” message was received.
+        *
+        * @see FcpListener#receivedPeerNote(FcpConnection, PeerNote)
+        * @param peerNote
+        */
+       public void fireReceivedPeerNote(PeerNote peerNote) {
+               for (FcpListener fcpListener : getListeners()) {
+                       fcpListener.receivedPeerNote(getSource(), peerNote);
+               }
+       }
+
+       /**
+        * Notifies all listeners that an “EndListPeerNotes” message was received.
+        *
+        * @see FcpListener#receivedEndListPeerNotes(FcpConnection,
+        *      EndListPeerNotes)
+        * @param endListPeerNotes
+        *            The “EndListPeerNotes” message
+        */
+       public void fireReceivedEndListPeerNotes(EndListPeerNotes endListPeerNotes) {
+               for (FcpListener fcpListener : getListeners()) {
+                       fcpListener.receivedEndListPeerNotes(getSource(), endListPeerNotes);
+               }
+       }
+
+       /**
+        * Notifies all listeners that a “PeerRemoved” message was received.
+        *
+        * @see FcpListener#receivedPeerRemoved(FcpConnection, PeerRemoved)
+        * @param peerRemoved
+        *            The “PeerRemoved” message
+        */
+       public void fireReceivedPeerRemoved(PeerRemoved peerRemoved) {
+               for (FcpListener fcpListener : getListeners()) {
+                       fcpListener.receivedPeerRemoved(getSource(), peerRemoved);
+               }
+       }
+
+       /**
+        * Notifies all listeners that a “NodeData” message was received.
+        *
+        * @see FcpListener#receivedNodeData(FcpConnection, NodeData)
+        * @param nodeData
+        *            The “NodeData” message
+        */
+       public void fireReceivedNodeData(NodeData nodeData) {
+               for (FcpListener fcpListener : getListeners()) {
+                       fcpListener.receivedNodeData(getSource(), nodeData);
+               }
+       }
+
+       /**
+        * Notifies all listeners that a “TestDDAReply” message was received.
+        *
+        * @see FcpListener#receivedTestDDAReply(FcpConnection, TestDDAReply)
+        * @param testDDAReply
+        *            The “TestDDAReply” message
+        */
+       public void fireReceivedTestDDAReply(TestDDAReply testDDAReply) {
+               for (FcpListener fcpListener : getListeners()) {
+                       fcpListener.receivedTestDDAReply(getSource(), testDDAReply);
+               }
+       }
+
+       /**
+        * Notifies all listeners that a “TestDDAComplete” message was received.
+        *
+        * @see FcpListener#receivedTestDDAComplete(FcpConnection, TestDDAComplete)
+        * @param testDDAComplete
+        *            The “TestDDAComplete” message
+        */
+       public void fireReceivedTestDDAComplete(TestDDAComplete testDDAComplete) {
+               for (FcpListener fcpListener : getListeners()) {
+                       fcpListener.receivedTestDDAComplete(getSource(), testDDAComplete);
+               }
+       }
+
+       /**
+        * Notifies all listeners that a “PersistentGet” message was received.
+        *
+        * @see FcpListener#receivedPersistentGet(FcpConnection, PersistentGet)
+        * @param persistentGet
+        *            The “PersistentGet” message
+        */
+       public void fireReceivedPersistentGet(PersistentGet persistentGet) {
+               for (FcpListener fcpListener : getListeners()) {
+                       fcpListener.receivedPersistentGet(getSource(), persistentGet);
+               }
+       }
+
+       /**
+        * Notifies all listeners that a “PersistentPut” message was received.
+        *
+        * @see FcpListener#receivedPersistentPut(FcpConnection, PersistentPut)
+        * @param persistentPut
+        *            The “PersistentPut” message
+        */
+       public void fireReceivedPersistentPut(PersistentPut persistentPut) {
+               for (FcpListener fcpListener : getListeners()) {
+                       fcpListener.receivedPersistentPut(getSource(), persistentPut);
+               }
+       }
+
+       /**
+        * Notifies all listeners that a “EndListPersistentRequests” message was
+        * received.
+        *
+        * @see FcpListener#receivedEndListPersistentRequests(FcpConnection,
+        *      EndListPersistentRequests)
+        * @param endListPersistentRequests
+        *            The “EndListPersistentRequests” message
+        */
+       public void fireReceivedEndListPersistentRequests(EndListPersistentRequests endListPersistentRequests) {
+               for (FcpListener fcpListener : getListeners()) {
+                       fcpListener.receivedEndListPersistentRequests(getSource(), endListPersistentRequests);
+               }
+       }
+
+       /**
+        * Notifies all listeners that a “URIGenerated” message was received.
+        *
+        * @see FcpListener#receivedURIGenerated(FcpConnection, URIGenerated)
+        * @param uriGenerated
+        *            The “URIGenerated” message
+        */
+       public void fireReceivedURIGenerated(URIGenerated uriGenerated) {
+               for (FcpListener fcpListener : getListeners()) {
+                       fcpListener.receivedURIGenerated(getSource(), uriGenerated);
+               }
+       }
+
+       /**
+        * Notifies all listeners that a “DataFound” message was received.
+        *
+        * @see FcpListener#receivedDataFound(FcpConnection, DataFound)
+        * @param dataFound
+        *            The “DataFound” message
+        */
+       public void fireReceivedDataFound(DataFound dataFound) {
+               for (FcpListener fcpListener : getListeners()) {
+                       fcpListener.receivedDataFound(getSource(), dataFound);
+               }
+       }
+
+       /**
+        * Notifies all listeners that an “AllData” message was received.
+        *
+        * @see FcpListener#receivedAllData(FcpConnection, AllData)
+        * @param allData
+        *            The “AllData” message
+        */
+       public void fireReceivedAllData(AllData allData) {
+               for (FcpListener fcpListener : getListeners()) {
+                       fcpListener.receivedAllData(getSource(), allData);
+               }
+       }
+
+       /**
+        * Notifies all listeners that a “SimpleProgress” message was received.
+        *
+        * @see FcpListener#receivedSimpleProgress(FcpConnection, SimpleProgress)
+        * @param simpleProgress
+        *            The “SimpleProgress” message
+        */
+       public void fireReceivedSimpleProgress(SimpleProgress simpleProgress) {
+               for (FcpListener fcpListener : getListeners()) {
+                       fcpListener.receivedSimpleProgress(getSource(), simpleProgress);
+               }
+       }
+
+       /**
+        * Notifies all listeners that a “StartedCompression” message was received.
+        *
+        * @see FcpListener#receivedStartedCompression(FcpConnection,
+        *      StartedCompression)
+        * @param startedCompression
+        *            The “StartedCompression” message
+        */
+       public void fireReceivedStartedCompression(StartedCompression startedCompression) {
+               for (FcpListener fcpListener : getListeners()) {
+                       fcpListener.receivedStartedCompression(getSource(), startedCompression);
+               }
+       }
+
+       /**
+        * Notifies all listeners that a “FinishedCompression” message was received.
+        *
+        * @see FcpListener#receivedFinishedCompression(FcpConnection,
+        *      FinishedCompression)
+        * @param finishedCompression
+        *            The “FinishedCompression” message
+        */
+       public void fireReceivedFinishedCompression(FinishedCompression finishedCompression) {
+               for (FcpListener fcpListener : getListeners()) {
+                       fcpListener.receivedFinishedCompression(getSource(), finishedCompression);
+               }
+       }
+
+       /**
+        * Notifies all listeners that an “UnknownPeerNoteType” message was
+        * received.
+        *
+        * @see FcpListener#receivedUnknownPeerNoteType(FcpConnection,
+        *      UnknownPeerNoteType)
+        * @param unknownPeerNoteType
+        *            The “UnknownPeerNoteType” message
+        */
+       public void fireReceivedUnknownPeerNoteType(UnknownPeerNoteType unknownPeerNoteType) {
+               for (FcpListener fcpListener : getListeners()) {
+                       fcpListener.receivedUnknownPeerNoteType(getSource(), unknownPeerNoteType);
+               }
+       }
+
+       /**
+        * Notifies all listeners that an “UnknownNodeIdentifier” message was
+        * received.
+        *
+        * @see FcpListener#receivedUnknownNodeIdentifier(FcpConnection,
+        *      UnknownNodeIdentifier)
+        * @param unknownNodeIdentifier
+        *            The “UnknownNodeIdentifier” message
+        */
+       public void fireReceivedUnknownNodeIdentifier(UnknownNodeIdentifier unknownNodeIdentifier) {
+               for (FcpListener fcpListener : getListeners()) {
+                       fcpListener.receivedUnknownNodeIdentifier(getSource(), unknownNodeIdentifier);
+               }
+       }
+
+       /**
+        * Notifies all listeners that a “ConfigData” message was received.
+        *
+        * @see FcpListener#receivedConfigData(FcpConnection, ConfigData)
+        * @param configData
+        *            The “ConfigData” message
+        */
+       public void fireReceivedConfigData(ConfigData configData) {
+               for (FcpListener fcpListener : getListeners()) {
+                       fcpListener.receivedConfigData(getSource(), configData);
+               }
+       }
+
+       /**
+        * Notifies all listeners that a “GetFailed” message was received.
+        *
+        * @see FcpListener#receivedGetFailed(FcpConnection, GetFailed)
+        * @param getFailed
+        *            The “GetFailed” message
+        */
+       public void fireReceivedGetFailed(GetFailed getFailed) {
+               for (FcpListener fcpListener : getListeners()) {
+                       fcpListener.receivedGetFailed(getSource(), getFailed);
+               }
+       }
+
+       /**
+        * Notifies all listeners that a “PutFailed” message was received.
+        *
+        * @see FcpListener#receivedPutFailed(FcpConnection, PutFailed)
+        * @param putFailed
+        *            The “PutFailed” message
+        */
+       public void fireReceivedPutFailed(PutFailed putFailed) {
+               for (FcpListener fcpListener : getListeners()) {
+                       fcpListener.receivedPutFailed(getSource(), putFailed);
+               }
+       }
+
+       /**
+        * Notifies all listeners that an “IdentifierCollision” message was
+        * received.
+        *
+        * @see FcpListener#receivedIdentifierCollision(FcpConnection,
+        *      IdentifierCollision)
+        * @param identifierCollision
+        *            The “IdentifierCollision” message
+        */
+       public void fireReceivedIdentifierCollision(IdentifierCollision identifierCollision) {
+               for (FcpListener fcpListener : getListeners()) {
+                       fcpListener.receivedIdentifierCollision(getSource(), identifierCollision);
+               }
+       }
+
+       /**
+        * Notifies all listeners that an “PersistentPutDir” message was received.
+        *
+        * @see FcpListener#receivedPersistentPutDir(FcpConnection,
+        *      PersistentPutDir)
+        * @param persistentPutDir
+        *            The “PersistentPutDir” message
+        */
+       public void fireReceivedPersistentPutDir(PersistentPutDir persistentPutDir) {
+               for (FcpListener fcpListener : getListeners()) {
+                       fcpListener.receivedPersistentPutDir(getSource(), persistentPutDir);
+               }
+       }
+
+       /**
+        * Notifies all listeners that a “PersistentRequestRemoved” message was
+        * received.
+        *
+        * @see FcpListener#receivedPersistentRequestRemoved(FcpConnection,
+        *      PersistentRequestRemoved)
+        * @param persistentRequestRemoved
+        *            The “PersistentRequestRemoved” message
+        */
+       public void fireReceivedPersistentRequestRemoved(PersistentRequestRemoved persistentRequestRemoved) {
+               for (FcpListener fcpListener : getListeners()) {
+                       fcpListener.receivedPersistentRequestRemoved(getSource(), persistentRequestRemoved);
+               }
+       }
+
+       /**
+        * Notifies all listeners that a “SubscribedUSKUpdate” message was received.
+        *
+        * @see FcpListener#receivedSubscribedUSKUpdate(FcpConnection,
+        *      SubscribedUSKUpdate)
+        * @param subscribedUSKUpdate
+        *            The “SubscribedUSKUpdate” message
+        */
+       public void fireReceivedSubscribedUSKUpdate(SubscribedUSKUpdate subscribedUSKUpdate) {
+               for (FcpListener fcpListener : getListeners()) {
+                       fcpListener.receivedSubscribedUSKUpdate(getSource(), subscribedUSKUpdate);
+               }
+       }
+
+       /**
+        * Notifies all listeners that a “PluginInfo” message was received.
+        *
+        * @see FcpListener#receivedPluginInfo(FcpConnection, PluginInfo)
+        * @param pluginInfo
+        *            The “PluginInfo” message
+        */
+       public void fireReceivedPluginInfo(PluginInfo pluginInfo) {
+               for (FcpListener fcpListener : getListeners()) {
+                       fcpListener.receivedPluginInfo(getSource(), pluginInfo);
+               }
+       }
+
+       /**
+        * Notifies all listeners that an “FCPPluginReply” message was received.
+        *
+        * @see FcpListener#receivedFCPPluginReply(FcpConnection, FCPPluginReply)
+        * @param fcpPluginReply
+        *            The “FCPPluginReply” message
+        */
+       public void fireReceivedFCPPluginReply(FCPPluginReply fcpPluginReply) {
+               for (FcpListener fcpListener : getListeners()) {
+                       fcpListener.receivedFCPPluginReply(getSource(), fcpPluginReply);
+               }
+       }
+
+       /**
+        * Notifies all listeners that a “PersistentRequestModified” message was
+        * received.
+        *
+        * @see FcpListener#receivedPersistentRequestModified(FcpConnection,
+        *      PersistentRequestModified)
+        * @param persistentRequestModified
+        *            The “PersistentRequestModified” message
+        */
+       public void fireReceivedPersistentRequestModified(PersistentRequestModified persistentRequestModified) {
+               for (FcpListener fcpListener : getListeners()) {
+                       fcpListener.receivedPersistentRequestModified(getSource(), persistentRequestModified);
+               }
+       }
+
+       /**
+        * Notifies all listeners that a “PutSuccessful” message was received.
+        *
+        * @see FcpListener#receivedPutSuccessful(FcpConnection, PutSuccessful)
+        * @param putSuccessful
+        *            The “PutSuccessful” message
+        */
+       public void fireReceivedPutSuccessful(PutSuccessful putSuccessful) {
+               for (FcpListener fcpListener : getListeners()) {
+                       fcpListener.receivedPutSuccessful(getSource(), putSuccessful);
+               }
+       }
+
+       /**
+        * Notifies all listeners that a “PutFetchable” message was received.
+        *
+        * @see FcpListener#receivedPutFetchable(FcpConnection, PutFetchable)
+        * @param putFetchable
+        *            The “PutFetchable” message
+        */
+       public void fireReceivedPutFetchable(PutFetchable putFetchable) {
+               for (FcpListener fcpListener : getListeners()) {
+                       fcpListener.receivedPutFetchable(getSource(), putFetchable);
+               }
+       }
+
+       /**
+        * Notifies all listeners that a “ProtocolError” message was received.
+        *
+        * @see FcpListener#receivedProtocolError(FcpConnection, ProtocolError)
+        * @param protocolError
+        *            The “ProtocolError” message
+        */
+       public void fireReceivedProtocolError(ProtocolError protocolError) {
+               for (FcpListener fcpListener : getListeners()) {
+                       fcpListener.receivedProtocolError(getSource(), protocolError);
+               }
+       }
+
+       /**
+        * Notifies all listeners that a “SentFeed” message was received.
+        *
+        * @see FcpListener#receivedSentFeed(FcpConnection, SentFeed)
+        * @param sentFeed
+        *            The “SentFeed” message.
+        */
+       public void fireSentFeed(SentFeed sentFeed) {
+               for (FcpListener fcpListener : getListeners()) {
+                       fcpListener.receivedSentFeed(getSource(), sentFeed);
+               }
+       }
+
+       /**
+        * Notifies all listeners that a “ReceivedBookmarkFeed” message was
+        * received.
+        *
+        * @see FcpListener#receivedBookmarkFeed(FcpConnection,
+        *      ReceivedBookmarkFeed)
+        * @param receivedBookmarkFeed
+        *            The “ReceivedBookmarkFeed” message
+        */
+       public void fireReceivedBookmarkFeed(ReceivedBookmarkFeed receivedBookmarkFeed) {
+               for (FcpListener fcpListener : getListeners()) {
+                       fcpListener.receivedBookmarkFeed(getSource(), receivedBookmarkFeed);
+               }
+       }
+
+       /**
+        * Notifies all registered listeners that a message has been received.
+        *
+        * @see FcpListener#receivedMessage(FcpConnection, FcpMessage)
+        * @param fcpMessage
+        *            The message that was received
+        */
+       public void fireMessageReceived(FcpMessage fcpMessage) {
+               for (FcpListener fcpListener : getListeners()) {
+                       fcpListener.receivedMessage(getSource(), fcpMessage);
+               }
+       }
+
+       /**
+        * Notifies all listeners that the connection to the node was closed.
+        *
+        * @param throwable
+        *            The exception that caused the disconnect, or <code>null</code>
+        *            if there was no exception
+        * @see FcpListener#connectionClosed(FcpConnection, Throwable)
+        */
+       public void fireConnectionClosed(Throwable throwable) {
+               for (FcpListener fcpListener : getListeners()) {
+                       fcpListener.connectionClosed(getSource(), throwable);
+               }
+       }
+
+}
diff --git a/src/main/java/net/pterodactylus/fcp/FcpMessage.java b/src/main/java/net/pterodactylus/fcp/FcpMessage.java
new file mode 100644 (file)
index 0000000..b238db3
--- /dev/null
@@ -0,0 +1,195 @@
+/*
+ * jFCPlib - FcpMessage.java - Copyright © 2008 David Roden
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+package net.pterodactylus.fcp;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.Map;
+import java.util.Map.Entry;
+
+/**
+ * An FCP message. FCP messages consist of a name, an arbitrary amount of
+ * “fields” (i.e. key-value pairs), a message end marker, and optional payload
+ * data that follows the marker.
+ *
+ * @author David ‘Bombe’ Roden &lt;bombe@freenetproject.org&gt;
+ */
+public class FcpMessage implements Iterable<String> {
+
+       /** Constant for the linefeed. */
+       private static final String LINEFEED = "\r\n";
+
+       /** The name of the message. */
+       private final String name;
+
+       /** The fields of the message. */
+       private final Map<String, String> fields = new HashMap<String, String>();
+
+       /** The optional payload input stream. */
+       private InputStream payloadInputStream;
+
+       /**
+        * Creates a new FCP message with the given name.
+        *
+        * @param name
+        *            The name of the FCP message
+        */
+       public FcpMessage(String name) {
+               this(name, null);
+       }
+
+       /**
+        * Creates a new FCP message with the given name and the given payload input
+        * stream. The payload input stream is not read until the message is sent to
+        * the node using {@link FcpConnection#sendMessage(FcpMessage)}.
+        *
+        * @param name
+        *            The name of the message
+        * @param payloadInputStream
+        *            The payload of the message
+        */
+       public FcpMessage(String name, InputStream payloadInputStream) {
+               this.name = name;
+               this.payloadInputStream = payloadInputStream;
+       }
+
+       /**
+        * Returns the name of the message.
+        *
+        * @return The name of the message
+        */
+       public String getName() {
+               return name;
+       }
+
+       /**
+        * Checks whether this message has a field with the given name.
+        *
+        * @param field
+        *            The name of the field to check for
+        * @return <code>true</code> if the message has a field with the given name,
+        *         <code>false</code> otherwise
+        */
+       public boolean hasField(String field) {
+               return fields.containsKey(field);
+       }
+
+       /**
+        * Sets the field with the given name to the given value. If the field
+        * already exists in this message it is overwritten.
+        *
+        * @param field
+        *            The name of the field
+        * @param value
+        *            The value of the field
+        */
+       public void setField(String field, String value) {
+               if ((field == null) || (value == null)) {
+                       throw new NullPointerException(((field == null) ? "field " : "value ") + "must not be null");
+               }
+               fields.put(field, value);
+       }
+
+       /**
+        * Returns the value of the given field.
+        *
+        * @param field
+        *            The name of the field
+        * @return The value of the field, or <code>null</code> if there is no such
+        *         field
+        */
+       public String getField(String field) {
+               return fields.get(field);
+       }
+
+       /**
+        * Returns all fields of this message.
+        *
+        * @return All fields of this message
+        */
+       public Map<String, String> getFields() {
+               return Collections.unmodifiableMap(fields);
+       }
+
+       /**
+        * {@inheritDoc}
+        */
+       public Iterator<String> iterator() {
+               return fields.keySet().iterator();
+       }
+
+       /**
+        * Sets the payload input stream of the message.
+        *
+        * @param payloadInputStream
+        *            The payload input stream
+        */
+       public void setPayloadInputStream(InputStream payloadInputStream) {
+               this.payloadInputStream = payloadInputStream;
+       }
+
+       /**
+        * Writes this message to the given output stream. If the message has a
+        * payload (i.e. {@link #payloadInputStream} is not <code>null</code>) the
+        * payload is written to the given output stream after the message as well.
+        * That means that this method can only be called once because on the second
+        * invocation the payload input stream could not be read (again).
+        *
+        * @param outputStream
+        *            The output stream to write the message to
+        * @throws IOException
+        *             if an I/O error occurs
+        */
+       public void write(OutputStream outputStream) throws IOException {
+               writeLine(outputStream, name);
+               for (Entry<String, String> fieldEntry : fields.entrySet()) {
+                       writeLine(outputStream, fieldEntry.getKey() + "=" + fieldEntry.getValue());
+               }
+               writeLine(outputStream, "EndMessage");
+               outputStream.flush();
+               if (payloadInputStream != null) {
+                       FcpUtils.copy(payloadInputStream, outputStream);
+                       outputStream.flush();
+               }
+       }
+
+       //
+       // PRIVATE METHODS
+       //
+
+       /**
+        * Writes the given line (followed by {@link #LINEFEED} to the given output
+        * stream, using UTF-8 as encoding.
+        *
+        * @param outputStream
+        *            The output stream to write to
+        * @param line
+        *            The line to write
+        * @throws IOException
+        *             if an I/O error occurs
+        */
+       private void writeLine(OutputStream outputStream, String line) throws IOException {
+               outputStream.write((line + LINEFEED).getBytes("UTF-8"));
+       }
+
+}
diff --git a/src/main/java/net/pterodactylus/fcp/FcpTest.java b/src/main/java/net/pterodactylus/fcp/FcpTest.java
new file mode 100644 (file)
index 0000000..6c51848
--- /dev/null
@@ -0,0 +1,92 @@
+/*
+ * jFCPlib - FcpTest.java - Copyright © 2008 David Roden
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+package net.pterodactylus.fcp;
+
+import java.io.IOException;
+
+import junit.framework.TestCase;
+
+/**
+ * Tests various commands and the FCP connection.
+ *
+ * @author David ‘Bombe’ Roden &lt;bombe@freenetproject.org&gt;
+ */
+public class FcpTest extends TestCase {
+
+       /** The FCP connection. */
+       private FcpConnection fcpConnection;
+
+       /**
+        * {@inheritDoc}
+        */
+       @Override
+       protected void setUp() throws Exception {
+               fcpConnection = new FcpConnection("wing");
+               fcpConnection.connect();
+               fcpConnection.sendMessage(new ClientHello("FcpTest"));
+       }
+
+       /**
+        * {@inheritDoc}
+        */
+       @Override
+       protected void tearDown() throws Exception {
+               fcpConnection.close();
+       }
+
+       /**
+        * Tests the FCP connection be simply {@link #setUp() setting it up} and
+        * {@link #tearDown() tearing it down} again.
+        */
+       public void testFcpConnection() {
+               /* do nothing. */
+       }
+
+       /**
+        * Generates an SSK key pair.
+        *
+        * @throws IOException
+        *             if an I/O error occurs
+        * @throws InterruptedException
+        *             if {@link Object#wait()} wakes up spuriously
+        */
+       public void testGenerateSSK() throws IOException, InterruptedException {
+               final SSKKeypair[] keypair = new SSKKeypair[1];
+               FcpAdapter fcpAdapter = new FcpAdapter() {
+
+                       /**
+                        * {@inheritDoc}
+                        */
+                       @Override
+                       public void receivedSSKKeypair(FcpConnection fcpConnection, SSKKeypair sskKeypair) {
+                               keypair[0] = sskKeypair;
+                               synchronized (this) {
+                                       notify();
+                               }
+                       }
+               };
+               fcpConnection.addFcpListener(fcpAdapter);
+               synchronized (fcpAdapter) {
+                       fcpConnection.sendMessage(new GenerateSSK());
+                       fcpAdapter.wait();
+               }
+               assertNotNull("ssk keypair", keypair[0]);
+       }
+
+}
diff --git a/src/main/java/net/pterodactylus/fcp/FcpUtils.java b/src/main/java/net/pterodactylus/fcp/FcpUtils.java
new file mode 100644 (file)
index 0000000..0957083
--- /dev/null
@@ -0,0 +1,469 @@
+/*
+ * jFCPlib - FcpUtils.java - Copyright © 2008 David Roden
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+package net.pterodactylus.fcp;
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.Closeable;
+import java.io.EOFException;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.net.Socket;
+import java.util.StringTokenizer;
+import java.util.concurrent.atomic.AtomicLong;
+
+/**
+ * Helper class with utility methods for the FCP protocol.
+ *
+ * @author David ‘Bombe’ Roden &lt;bombe@freenetproject.org&gt;
+ */
+public class FcpUtils {
+
+       /** Counter for unique identifiers. */
+       private static AtomicLong counter = new AtomicLong();
+
+       /**
+        * Returns a unique identifier.
+        *
+        * @return A unique identifier
+        */
+       public static String getUniqueIdentifier() {
+               return new StringBuilder().append(System.currentTimeMillis()).append('-').append(counter.getAndIncrement()).toString();
+       }
+
+       /**
+        * Parses an integer field, separated by ‘;’ and returns the parsed values.
+        *
+        * @param field
+        *            The field to parse
+        * @return An array with the parsed values
+        * @throws NumberFormatException
+        *             if a value can not be converted to a number
+        */
+       public static int[] decodeMultiIntegerField(String field) throws NumberFormatException {
+               StringTokenizer fieldTokens = new StringTokenizer(field, ";");
+               int[] result = new int[fieldTokens.countTokens()];
+               int counter = 0;
+               while (fieldTokens.hasMoreTokens()) {
+                       String fieldToken = fieldTokens.nextToken();
+                       result[counter++] = Integer.valueOf(fieldToken);
+               }
+               return result;
+       }
+
+       /**
+        * Encodes the given integer array into a string, separating the values by
+        * ‘;’.
+        *
+        * @param values
+        *            The values to encode
+        * @return The encoded values
+        */
+       public static String encodeMultiIntegerField(int[] values) {
+               StringBuilder encodedField = new StringBuilder();
+               for (int value : values) {
+                       if (encodedField.length() > 0) {
+                               encodedField.append(';');
+                       }
+                       encodedField.append(value);
+               }
+               return encodedField.toString();
+       }
+
+       /**
+        * Encodes the given string array into a string, separating the values by
+        * ‘;’.
+        *
+        * @param values
+        *            The values to encode
+        * @return The encoded values
+        */
+       public static String encodeMultiStringField(String[] values) {
+               StringBuilder encodedField = new StringBuilder();
+               for (String value : values) {
+                       if (encodedField.length() > 0) {
+                               encodedField.append(';');
+                       }
+                       encodedField.append(value);
+               }
+               return encodedField.toString();
+       }
+
+       /**
+        * Tries to parse the given string into an int, returning <code>-1</code> if
+        * the string can not be parsed.
+        *
+        * @param value
+        *            The string to parse
+        * @return The parsed int, or <code>-1</code>
+        */
+       public static int safeParseInt(String value) {
+               return safeParseInt(value, -1);
+       }
+
+       /**
+        * Tries to parse the given string into an int, returning
+        * <code>defaultValue</code> if the string can not be parsed.
+        *
+        * @param value
+        *            The string to parse
+        * @param defaultValue
+        *            The value to return if the string can not be parsed.
+        * @return The parsed int, or <code>defaultValue</code>
+        */
+       public static int safeParseInt(String value, int defaultValue) {
+               try {
+                       return Integer.valueOf(value);
+               } catch (NumberFormatException nfe1) {
+                       return defaultValue;
+               }
+       }
+
+       /**
+        * Tries to parse the given string into an long, returning <code>-1</code>
+        * if the string can not be parsed.
+        *
+        * @param value
+        *            The string to parse
+        * @return The parsed long, or <code>-1</code>
+        */
+       public static long safeParseLong(String value) {
+               return safeParseLong(value, -1);
+       }
+
+       /**
+        * Tries to parse the given string into an long, returning
+        * <code>defaultValue</code> if the string can not be parsed.
+        *
+        * @param value
+        *            The string to parse
+        * @param defaultValue
+        *            The value to return if the string can not be parsed.
+        * @return The parsed long, or <code>defaultValue</code>
+        */
+       public static long safeParseLong(String value, long defaultValue) {
+               try {
+                       return Integer.valueOf(value);
+               } catch (NumberFormatException nfe1) {
+                       return defaultValue;
+               }
+       }
+
+       /**
+        * Closes the given socket.
+        *
+        * @param socket
+        *            The socket to close
+        */
+       public static void close(Socket socket) {
+               if (socket != null) {
+                       try {
+                               socket.close();
+                       } catch (IOException ioe1) {
+                               /* ignore. */
+                       }
+               }
+       }
+
+       /**
+        * Closes the given Closeable.
+        *
+        * @param closeable
+        *            The Closeable to close
+        */
+       public static void close(Closeable closeable) {
+               if (closeable != null) {
+                       try {
+                               closeable.close();
+                       } catch (IOException ioe1) {
+                               /* ignore. */
+                       }
+               }
+       }
+
+       /**
+        * Copies as many bytes as possible (i.e. until {@link InputStream#read()}
+        * returns <code>-1</code>) from the source input stream to the destination
+        * output stream.
+        *
+        * @param source
+        *            The input stream to read from
+        * @param destination
+        *            The output stream to write to
+        * @throws IOException
+        *             if an I/O error occurs
+        */
+       public static void copy(InputStream source, OutputStream destination) throws IOException {
+               copy(source, destination, -1);
+       }
+
+       /**
+        * Copies <code>length</code> bytes from the source input stream to the
+        * destination output stream. If <code>length</code> is <code>-1</code> as
+        * much bytes as possible will be copied (i.e. until
+        * {@link InputStream#read()} returns <code>-1</code> to signal the end of
+        * the stream).
+        *
+        * @param source
+        *            The input stream to read from
+        * @param destination
+        *            The output stream to write to
+        * @param length
+        *            The number of bytes to copy
+        * @throws IOException
+        *             if an I/O error occurs
+        */
+       public static void copy(InputStream source, OutputStream destination, long length) throws IOException {
+               copy(source, destination, length, 1 << 16);
+       }
+
+       /**
+        * Copies <code>length</code> bytes from the source input stream to the
+        * destination output stream. If <code>length</code> is <code>-1</code> as
+        * much bytes as possible will be copied (i.e. until
+        * {@link InputStream#read()} returns <code>-1</code> to signal the end of
+        * the stream).
+        *
+        * @param source
+        *            The input stream to read from
+        * @param destination
+        *            The output stream to write to
+        * @param length
+        *            The number of bytes to copy
+        * @param bufferSize
+        *            The buffer size
+        * @throws IOException
+        *             if an I/O error occurs
+        */
+       public static void copy(InputStream source, OutputStream destination, long length, int bufferSize) throws IOException {
+               long remaining = length;
+               byte[] buffer = new byte[bufferSize];
+               int read = 0;
+               while ((remaining == -1) || (remaining > 0)) {
+                       read = source.read(buffer, 0, ((remaining > bufferSize) || (remaining == -1)) ? bufferSize : (int) remaining);
+                       if (read == -1) {
+                               if (length == -1) {
+                                       return;
+                               }
+                               throw new EOFException("stream reached eof");
+                       }
+                       destination.write(buffer, 0, read);
+                       remaining -= read;
+               }
+       }
+
+       /**
+        * This input stream stores the content of another input stream either in a
+        * file or in memory, depending on the length of the input stream.
+        *
+        * @author David ‘Bombe’ Roden &lt;bombe@freenetproject.org&gt;
+        */
+       public static class TempInputStream extends InputStream {
+
+               /** The default maximum lenght for in-memory storage. */
+               public static final long MAX_LENGTH_MEMORY = 65536;
+
+               /** The temporary file to read from. */
+               private final File tempFile;
+
+               /** The input stream that reads from the file. */
+               private final InputStream fileInputStream;
+
+               /** The input stream that reads from memory. */
+               private final InputStream memoryInputStream;
+
+               /**
+                * Creates a new temporary input stream that stores the given input
+                * stream in a temporary file.
+                *
+                * @param originalInputStream
+                *            The original input stream
+                * @throws IOException
+                *             if an I/O error occurs
+                */
+               public TempInputStream(InputStream originalInputStream) throws IOException {
+                       this(originalInputStream, -1);
+               }
+
+               /**
+                * Creates a new temporary input stream that stores the given input
+                * stream in memory if it is shorter than {@link #MAX_LENGTH_MEMORY},
+                * otherwise it is stored in a file.
+                *
+                * @param originalInputStream
+                *            The original input stream
+                * @param length
+                *            The length of the input stream
+                * @throws IOException
+                *             if an I/O error occurs
+                */
+               public TempInputStream(InputStream originalInputStream, long length) throws IOException {
+                       this(originalInputStream, length, MAX_LENGTH_MEMORY);
+               }
+
+               /**
+                * Creates a new temporary input stream that stores the given input
+                * stream in memory if it is shorter than <code>maxMemoryLength</code>,
+                * otherwise it is stored in a file.
+                *
+                * @param originalInputStream
+                *            The original input stream
+                * @param length
+                *            The length of the input stream
+                * @param maxMemoryLength
+                *            The maximum length to store in memory
+                * @throws IOException
+                *             if an I/O error occurs
+                */
+               public TempInputStream(InputStream originalInputStream, long length, long maxMemoryLength) throws IOException {
+                       if ((length > -1) && (length <= maxMemoryLength)) {
+                               ByteArrayOutputStream memoryOutputStream = new ByteArrayOutputStream((int) length);
+                               try {
+                                       FcpUtils.copy(originalInputStream, memoryOutputStream, length, (int) length);
+                               } finally {
+                                       memoryOutputStream.close();
+                               }
+                               tempFile = null;
+                               fileInputStream = null;
+                               memoryInputStream = new ByteArrayInputStream(memoryOutputStream.toByteArray());
+                       } else {
+                               tempFile = File.createTempFile("temp-", ".bin");
+                               tempFile.deleteOnExit();
+                               FileOutputStream fileOutputStream = null;
+                               try {
+                                       fileOutputStream = new FileOutputStream(tempFile);
+                                       FcpUtils.copy(originalInputStream, fileOutputStream);
+                                       fileInputStream = new FileInputStream(tempFile);
+                               } finally {
+                                       FcpUtils.close(fileOutputStream);
+                               }
+                               memoryInputStream = null;
+                       }
+               }
+
+               /**
+                * {@inheritDoc}
+                */
+               @Override
+               public int available() throws IOException {
+                       if (memoryInputStream != null) {
+                               return memoryInputStream.available();
+                       }
+                       return fileInputStream.available();
+               }
+
+               /**
+                * {@inheritDoc}
+                */
+               @Override
+               public void close() throws IOException {
+                       if (memoryInputStream != null) {
+                               memoryInputStream.close();
+                               return;
+                       }
+                       tempFile.delete();
+                       fileInputStream.close();
+               }
+
+               /**
+                * {@inheritDoc}
+                */
+               @Override
+               public synchronized void mark(int readlimit) {
+                       if (memoryInputStream != null) {
+                               memoryInputStream.mark(readlimit);
+                               return;
+                       }
+                       fileInputStream.mark(readlimit);
+               }
+
+               /**
+                * {@inheritDoc}
+                */
+               @Override
+               public boolean markSupported() {
+                       if (memoryInputStream != null) {
+                               return memoryInputStream.markSupported();
+                       }
+                       return fileInputStream.markSupported();
+               }
+
+               /**
+                * {@inheritDoc}
+                */
+               @Override
+               public int read() throws IOException {
+                       if (memoryInputStream != null) {
+                               return memoryInputStream.read();
+                       }
+                       return fileInputStream.read();
+               }
+
+               /**
+                * {@inheritDoc}
+                */
+               @Override
+               public int read(byte[] b) throws IOException {
+                       if (memoryInputStream != null) {
+                               return memoryInputStream.read(b);
+                       }
+                       return fileInputStream.read(b);
+               }
+
+               /**
+                * {@inheritDoc}
+                */
+               @Override
+               public int read(byte[] b, int off, int len) throws IOException {
+                       if (memoryInputStream != null) {
+                               return memoryInputStream.read(b, off, len);
+                       }
+                       return fileInputStream.read(b, off, len);
+               }
+
+               /**
+                * {@inheritDoc}
+                */
+               @Override
+               public synchronized void reset() throws IOException {
+                       if (memoryInputStream != null) {
+                               memoryInputStream.reset();
+                               return;
+                       }
+                       fileInputStream.reset();
+               }
+
+               /**
+                * {@inheritDoc}
+                */
+               @Override
+               public long skip(long n) throws IOException {
+                       if (memoryInputStream != null) {
+                               return memoryInputStream.skip(n);
+                       }
+                       return fileInputStream.skip(n);
+               }
+
+       }
+
+}
diff --git a/src/main/java/net/pterodactylus/fcp/FileEntry.java b/src/main/java/net/pterodactylus/fcp/FileEntry.java
new file mode 100644 (file)
index 0000000..f939d78
--- /dev/null
@@ -0,0 +1,294 @@
+/*
+ * jFCPlib - FileEntry.java - Copyright © 2008 David Roden
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+package net.pterodactylus.fcp;
+
+import java.io.InputStream;
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * Container class for file entry data.
+ *
+ * @see ClientPutComplexDir#addFileEntry(FileEntry)
+ * @author David ‘Bombe’ Roden &lt;bombe@freenetproject.org&gt;
+ */
+public abstract class FileEntry {
+
+       /** The name of the file. */
+       protected final String name;
+
+       /** The upload source of the file. */
+       protected final UploadFrom uploadFrom;
+
+       /**
+        * Creates a new file entry with the given name and upload source.
+        *
+        * @param name
+        *            The name of the file
+        * @param uploadFrom
+        *            The upload source of the file
+        */
+       protected FileEntry(String name, UploadFrom uploadFrom) {
+               this.name = name;
+               this.uploadFrom = uploadFrom;
+       }
+
+       /**
+        * Creates a new file entry for a file that should be transmitted to the
+        * node in the payload of the message.
+        *
+        * @param name
+        *            The name of the file
+        * @param contentType
+        *            The content type of the file, or <code>null</code> to let the
+        *            node auto-detect it
+        * @param length
+        *            The length of the file
+        * @param dataInputStream
+        *            The input stream of the file
+        * @return A file entry
+        */
+       public static FileEntry createDirectFileEntry(String name, String contentType, long length, InputStream dataInputStream) {
+               return new DirectFileEntry(name, contentType, length, dataInputStream);
+       }
+
+       /**
+        * Creates a new file entry for a file that should be uploaded from disk.
+        *
+        * @param name
+        *            The name of the file
+        * @param filename
+        *            The name of the file on disk
+        * @param contentType
+        *            The content type of the file, or <code>null</code> to let the
+        *            node auto-detect it
+        * @param length
+        *            The length of the file, or <code>-1</code> to not specify a
+        *            size
+        * @return A file entry
+        */
+       public static FileEntry createDiskFileEntry(String name, String filename, String contentType, long length) {
+               return new DiskFileEntry(name, filename, contentType, length);
+       }
+
+       /**
+        * Creates a new file entry for a file that redirects to another URI.
+        *
+        * @param name
+        *            The name of the file
+        * @param targetURI
+        *            The target URI of the redirect
+        * @return A file entry
+        */
+       public static FileEntry createRedirectFileEntry(String name, String targetURI) {
+               return new RedirectFileEntry(name, targetURI);
+       }
+
+       /**
+        * Returns the fields for this file entry.
+        *
+        * @return The fields for this file entry
+        */
+       abstract Map<String, String> getFields();
+
+       /**
+        * A file entry for a file that should be transmitted in the payload of the
+        * {@link ClientPutComplexDir} message.
+        *
+        * @author David ‘Bombe’ Roden &lt;bombe@freenetproject.org&gt;
+        */
+       static class DirectFileEntry extends FileEntry {
+
+               /** The content type of the data. */
+               private final String contentType;
+
+               /** The length of the data. */
+               private final long length;
+
+               /** The input stream of the data. */
+               private final InputStream inputStream;
+
+               /**
+                * Creates a new direct file entry with content type auto-detection.
+                *
+                * @param name
+                *            The name of the file
+                * @param length
+                *            The length of the file
+                * @param inputStream
+                *            The input stream of the file
+                */
+               public DirectFileEntry(String name, long length, InputStream inputStream) {
+                       this(name, null, length, inputStream);
+               }
+
+               /**
+                * Creates a new direct file entry.
+                *
+                * @param name
+                *            The name of the file
+                * @param contentType
+                *            The content type of the file, or <code>null</code> to let
+                *            the node auto-detect it
+                * @param length
+                *            The length of the file
+                * @param inputStream
+                *            The input stream of the file
+                */
+               public DirectFileEntry(String name, String contentType, long length, InputStream inputStream) {
+                       super(name, UploadFrom.direct);
+                       this.contentType = contentType;
+                       this.length = length;
+                       this.inputStream = inputStream;
+               }
+
+               /**
+                * {@inheritDoc}
+                */
+               @Override
+               Map<String, String> getFields() {
+                       Map<String, String> fields = new HashMap<String, String>();
+                       fields.put("Name", name);
+                       fields.put("UploadFrom", String.valueOf(uploadFrom));
+                       fields.put("DataLength", String.valueOf(length));
+                       if (contentType != null) {
+                               fields.put("Metadata.ContentType", contentType);
+                       }
+                       return fields;
+               }
+
+               /**
+                * Returns the input stream of the file.
+                *
+                * @return The input stream of the file
+                */
+               InputStream getInputStream() {
+                       return inputStream;
+               }
+
+       }
+
+       /**
+        * A file entry for a file that should be uploaded from the disk.
+        *
+        * @author David ‘Bombe’ Roden &lt;bombe@freenetproject.org&gt;
+        */
+       static class DiskFileEntry extends FileEntry {
+
+               /** The name of the on-disk file. */
+               private final String filename;
+
+               /** The content type of the file. */
+               private final String contentType;
+
+               /** The length of the file. */
+               private final long length;
+
+               /**
+                * Creates a new disk file entry.
+                *
+                * @param name
+                *            The name of the file
+                * @param filename
+                *            The name of the on-disk file
+                * @param length
+                *            The length of the file
+                */
+               public DiskFileEntry(String name, String filename, long length) {
+                       this(name, filename, null, length);
+               }
+
+               /**
+                * Creates a new disk file entry.
+                *
+                * @param name
+                *            The name of the file
+                * @param filename
+                *            The name of the on-disk file
+                * @param contentType
+                *            The content type of the file, or <code>null</code> to let
+                *            the node auto-detect it
+                * @param length
+                *            The length of the file
+                */
+               public DiskFileEntry(String name, String filename, String contentType, long length) {
+                       super(name, UploadFrom.disk);
+                       this.filename = filename;
+                       this.contentType = contentType;
+                       this.length = length;
+               }
+
+               /**
+                * {@inheritDoc}
+                */
+               @Override
+               Map<String, String> getFields() {
+                       Map<String, String> fields = new HashMap<String, String>();
+                       fields.put("Name", name);
+                       fields.put("UploadFrom", String.valueOf(uploadFrom));
+                       fields.put("Filename", filename);
+                       if (length > -1) {
+                               fields.put("DataSize", String.valueOf(length));
+                       }
+                       if (contentType != null) {
+                               fields.put("Metadata.ContentType", contentType);
+                       }
+                       return fields;
+               }
+
+       }
+
+       /**
+        * A file entry for a file that redirects to another URI.
+        *
+        * @author David ‘Bombe’ Roden &lt;bombe@freenetproject.org&gt;
+        */
+       static class RedirectFileEntry extends FileEntry {
+
+               /** The target URI of the redirect. */
+               private String targetURI;
+
+               /**
+                * Creates a new redirect file entry.
+                *
+                * @param name
+                *            The name of the file
+                * @param targetURI
+                *            The target URI of the redirect
+                */
+               public RedirectFileEntry(String name, String targetURI) {
+                       super(name, UploadFrom.redirect);
+                       this.targetURI = targetURI;
+               }
+
+               /**
+                * {@inheritDoc}
+                */
+               @Override
+               Map<String, String> getFields() {
+                       Map<String, String> fields = new HashMap<String, String>();
+                       fields.put("Name", name);
+                       fields.put("UploadFrom", String.valueOf(uploadFrom));
+                       fields.put("TargetURI", targetURI);
+                       return fields;
+               }
+
+       }
+
+}
diff --git a/src/main/java/net/pterodactylus/fcp/FinishedCompression.java b/src/main/java/net/pterodactylus/fcp/FinishedCompression.java
new file mode 100644 (file)
index 0000000..9d09d62
--- /dev/null
@@ -0,0 +1,76 @@
+/*
+ * jFCPlib - FinishedCompression.java - Copyright © 2008 David Roden
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+package net.pterodactylus.fcp;
+
+/**
+ * A “FinishedCompression” message signals the client that the compression of
+ * the request data has been finished.
+ *
+ * @author David ‘Bombe’ Roden &lt;bombe@freenetproject.org&gt;
+ */
+public class FinishedCompression extends BaseMessage {
+
+       /**
+        * Creates a new “FinishedCompression” message that wraps the received
+        * message.
+        *
+        * @param receivedMessage
+        *            The message that was recevied
+        */
+       FinishedCompression(FcpMessage receivedMessage) {
+               super(receivedMessage);
+       }
+
+       /**
+        * Returns the identifier of the request.
+        *
+        * @return The identifier of the request
+        */
+       public String getIdentifier() {
+               return getField("Identifier");
+       }
+
+       /**
+        * Returns the ID of the codec that was used for compression.
+        *
+        * @return The ID of the codec that was used for compression
+        */
+       public int getCodec() {
+               return FcpUtils.safeParseInt(getField("Codec"));
+       }
+
+       /**
+        * Returns the original size of the data (i.e. before compression).
+        *
+        * @return The original size of the data
+        */
+       public long getOriginalSize() {
+               return FcpUtils.safeParseLong(getField("OriginalSize"));
+       }
+
+       /**
+        * Returns the compressed size of the data (i.e. after compression).
+        *
+        * @return The compressed size of the data
+        */
+       public long getCompressedSize() {
+               return FcpUtils.safeParseLong(getField("CompressedSize"));
+       }
+
+}
diff --git a/src/main/java/net/pterodactylus/fcp/GenerateSSK.java b/src/main/java/net/pterodactylus/fcp/GenerateSSK.java
new file mode 100644 (file)
index 0000000..5e33c6c
--- /dev/null
@@ -0,0 +1,47 @@
+/*
+ * jFCPlib - GenerateSSK.java - Copyright © 2008 David Roden
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+package net.pterodactylus.fcp;
+
+/**
+ * A “GenerateSSK” message. This message tells the node to generate a new SSK
+ * key pair.
+ *
+ * @author David ‘Bombe’ Roden &lt;bombe@freenetproject.org&gt;
+ */
+public class GenerateSSK extends FcpMessage {
+
+       /**
+        * Creates a new “GenerateSSK” message.
+        */
+       public GenerateSSK() {
+               this(FcpUtils.getUniqueIdentifier());
+       }
+
+       /**
+        * Creates a new “GenerateSSK” message with the given client identifier.
+        *
+        * @param clientIdentifier
+        *            The client identifier
+        */
+       public GenerateSSK(String clientIdentifier) {
+               super("GenerateSSK");
+               setField("Identifier", clientIdentifier);
+       }
+
+}
diff --git a/src/main/java/net/pterodactylus/fcp/GetConfig.java b/src/main/java/net/pterodactylus/fcp/GetConfig.java
new file mode 100644 (file)
index 0000000..11e4cc6
--- /dev/null
@@ -0,0 +1,132 @@
+/*
+ * jFCPlib - GetConfig.java - Copyright © 2008 David Roden
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+package net.pterodactylus.fcp;
+
+/**
+ * The “GetConfig” command tells the node to send its configuration to the
+ * client.
+ *
+ * @author David ‘Bombe’ Roden &lt;bombe@freenetproject.org&gt;
+ */
+public class GetConfig extends FcpMessage {
+
+       /**
+        * Creates a new “GetConfig” command.
+        */
+       public GetConfig() {
+               super("GetConfig");
+       }
+
+       /**
+        * Sets whether the {@link ConfigData} result message shall include the
+        * current values.
+        *
+        * @param withCurrent
+        *            <code>true</code> to include current values in the result,
+        *            <code>false</code> otherwise
+        */
+       public void setWithCurrent(boolean withCurrent) {
+               setField("WithCurrent", String.valueOf(withCurrent));
+       }
+
+       /**
+        * Sets whether the {@link ConfigData} result message shall include the
+        * short descriptions.
+        *
+        * @param withShortDescription
+        *            <code>true</code> to include the short descriptions in the
+        *            result, <code>false</code> otherwise
+        */
+       public void setWithShortDescription(boolean withShortDescription) {
+               setField("WithShortDescription", String.valueOf(withShortDescription));
+       }
+
+       /**
+        * Sets whether the {@link ConfigData} result message shall include the long
+        * descriptions.
+        *
+        * @param withLongDescription
+        *            <code>true</code> to include the long descriptions in the
+        *            result, <code>false</code> otherwise
+        */
+       public void setWithLongDescription(boolean withLongDescription) {
+               setField("WithLongDescription", String.valueOf(withLongDescription));
+       }
+
+       /**
+        * Sets whether the {@link ConfigData} result message shall include the data
+        * types.
+        *
+        * @param withDataTypes
+        *            <code>true</code> to include the data types in the result,
+        *            <code>false</code> otherwise
+        */
+       public void setWithDataTypes(boolean withDataTypes) {
+               setField("WithDataTypes", String.valueOf(withDataTypes));
+       }
+
+       /**
+        * Sets whether the {@link ConfigData} result message shall include the
+        * defaults.
+        *
+        * @param setWithDefaults
+        *            <code>true</code> to include the defaults in the result,
+        *            <code>false</code> otherwise
+        */
+       public void setWithDefaults(boolean setWithDefaults) {
+               setField("WithDefaults", String.valueOf(setWithDefaults));
+       }
+
+       /**
+        * Sets whether the {@link ConfigData} result message shall include the sort
+        * order.
+        *
+        * @param withSortOrder
+        *            <code>true</code> to include the sort order in the result,
+        *            <code>false</code> otherwise
+        */
+       public void setWithSortOrder(boolean withSortOrder) {
+               setField("WithSortOrder", String.valueOf(withSortOrder));
+       }
+
+       /**
+        * Sets whether the {@link ConfigData} result message shall include the
+        * expert flag.
+        *
+        * @param withExpertFlag
+        *            <code>true</code> to include the expert flag in the result,
+        *            <code>false</code> otherwise
+        */
+       public void setWithExpertFlag(boolean withExpertFlag) {
+               setField("WithExpertFlag", String.valueOf(withExpertFlag));
+       }
+
+       /**
+        * Sets whether the {@link ConfigData} result message shall include the
+        * force-write flag.
+        *
+        * @param withForceWriteFlag
+        *            <code>true</code> to include the force-write flag in the
+        *            result, <code>false</code> otherwise
+        */
+       public void setWithForceWriteFlag(boolean withForceWriteFlag) {
+               setField("WithForceWriteFlag", String.valueOf(withForceWriteFlag));
+       }
+
+}
diff --git a/src/main/java/net/pterodactylus/fcp/GetFailed.java b/src/main/java/net/pterodactylus/fcp/GetFailed.java
new file mode 100644 (file)
index 0000000..c01bf2b
--- /dev/null
@@ -0,0 +1,210 @@
+/*
+ * jFCPlib - GetFailed.java - Copyright © 2008 David Roden
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+package net.pterodactylus.fcp;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+import java.util.Map.Entry;
+
+/**
+ * The “GetFailed” message signals the client that a {@link ClientGet} request
+ * has failed. This also means that no further progress messages for that
+ * request will be sent.
+ *
+ * @author David ‘Bombe’ Roden &lt;bombe@freenetproject.org&gt;
+ */
+public class GetFailed extends BaseMessage {
+
+       /**
+        * Creates a new “GetFailed” message that wraps the received message.
+        *
+        * @param receivedMessage
+        *            The received message
+        */
+       GetFailed(FcpMessage receivedMessage) {
+               super(receivedMessage);
+       }
+
+       /**
+        * Returns the code of the error.
+        *
+        * @return The code of the error, or <code>-1</code> if the error code could
+        *         not be parsed
+        */
+       public int getCode() {
+               return FcpUtils.safeParseInt(getField("Code"));
+       }
+
+       /**
+        * Returns the identifier of the request.
+        *
+        * @return The identifier of the request
+        */
+       public String getIdentifier() {
+               return getField("Identifier");
+       }
+
+       /**
+        * Returns whether the request is on the global queue.
+        *
+        * @return <code>true</code> if the request is on the global queue,
+        *         <code>false</code> if it is on the client-local queue
+        */
+       public boolean isGlobal() {
+               return Boolean.valueOf(getField("Global"));
+       }
+
+       /**
+        * Returns the description of the error code.
+        *
+        * @return The description of the error code
+        */
+       public String getCodeDescription() {
+               return getField("CodeDescription");
+       }
+
+       /**
+        * Returns the extra description of the error.
+        *
+        * @return The extra description of the error
+        */
+       public String getExtraDescription() {
+               return getField("ExtraDescription");
+       }
+
+       /**
+        * Returns the short description of the error.
+        *
+        * @return The short description of the error
+        */
+       public String getShortCodeDescription() {
+               return getField("ShortCodeDescription");
+       }
+
+       /**
+        * Returns the expected data length, if already knows.
+        *
+        * @return The expected data length, or <code>-1</code> if the length could
+        *         not be parsed
+        */
+       public long getExpectedDataLength() {
+               return FcpUtils.safeParseLong(getField("ExpectedDataLength"));
+       }
+
+       /**
+        * Returns the expected content type of the request.
+        *
+        * @return The expected content type
+        */
+       public String getExpectedMetadataContentType() {
+               return getField("ExpectedMetadata.ContentType");
+       }
+
+       /**
+        * Returns whether the expected values (see {@link #getExpectedDataLength()}
+        * and {@link #getExpectedMetadataContentType()}) have already been
+        * finalized and can be trusted. If the values have not been finalized that
+        * can change over time.
+        *
+        * @return <code>true</code> if the expected values have already been
+        *         finalized, <code>false</code> otherwise
+        */
+       public boolean isFinalizedExpected() {
+               return Boolean.valueOf(getField("FinalizedExpected"));
+       }
+
+       /**
+        * Returns the URI the request is redirected to (in case of a request for a
+        * USK). This is returned so that client applications know that the URI of
+        * the key has updated.
+        *
+        * @return The URI the request was redirected to
+        */
+       public String getRedirectURI() {
+               return getField("RedirectURI");
+       }
+
+       /**
+        * Returns whether the request failed fatally. If a request fails fatally it
+        * can never complete, even with inifinite retries.
+        *
+        * @return <code>true</code> if the request failed fatally,
+        *         <code>false</code> otherwise
+        */
+       public boolean isFatal() {
+               return Boolean.valueOf(getField("Fatal"));
+       }
+
+       /**
+        * Returns a list of complex error codes with the message. Use
+        * {@link #getComplexErrorDescription(int)} and
+        * {@link #getComplexErrorCount(int)} to get details.
+        *
+        * @return A list of complex error codes
+        */
+       public int[] getComplexErrorCodes() {
+               Map<String, String> allFields = getFields();
+               List<Integer> errorCodeList = new ArrayList<Integer>();
+               for (Entry<String, String> field : allFields.entrySet()) {
+                       String fieldKey = field.getKey();
+                       if (fieldKey.startsWith("Errors.")) {
+                               int nextDot = fieldKey.indexOf('.', 7);
+                               if (nextDot > -1) {
+                                       int errorCode = FcpUtils.safeParseInt(fieldKey.substring(7, nextDot));
+                                       if (errorCode != -1) {
+                                               errorCodeList.add(errorCode);
+                                       }
+                               }
+                       }
+               }
+               int[] errorCodes = new int[errorCodeList.size()];
+               int errorIndex = 0;
+               for (int errorCode : errorCodeList) {
+                       errorCodes[errorIndex++] = errorCode;
+               }
+               return errorCodes;
+       }
+
+       /**
+        * Returns the description of the complex error. You should only hand it
+        * error codes you got from {@link #getComplexErrorCodes()}!
+        *
+        * @param errorCode
+        *            The error code
+        * @return The description of the complex error
+        */
+       public String getComplexErrorDescription(int errorCode) {
+               return getField("Errors." + errorCode + ".Description");
+       }
+
+       /**
+        * Returns the count of the complex error. You should only hand it error
+        * codes you got from {@link #getComplexErrorCodes()}!
+        *
+        * @param errorCode
+        *            The error code
+        * @return The count of the complex error, or <code>-1</code> if the count
+        *         could not be parsed
+        */
+       public int getComplexErrorCount(int errorCode) {
+               return FcpUtils.safeParseInt(getField("Errors." + errorCode + ".Count"));
+       }
+
+}
diff --git a/src/main/java/net/pterodactylus/fcp/GetNode.java b/src/main/java/net/pterodactylus/fcp/GetNode.java
new file mode 100644 (file)
index 0000000..799b44b
--- /dev/null
@@ -0,0 +1,63 @@
+/*
+ * jFCPlib - GetNode.java - Copyright © 2008 David Roden
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+package net.pterodactylus.fcp;
+
+/**
+ * The “GetNode” command returns the darknet or opennet noderef of the node,
+ * optionally including private and volatile data.
+ *
+ * @author David ‘Bombe’ Roden &lt;bombe@freenetproject.org&gt;
+ */
+public class GetNode extends FcpMessage {
+
+       /**
+        * Creates a “GetNode” command that returns the darknet noderef of the node.
+        */
+       public GetNode() {
+               this(null, null, null);
+       }
+
+       /**
+        * Creates a “GetNode” command that returns the request noderef of the node,
+        * including private and volatile data, if requested. If any of the Boolean
+        * parameters are <code>null</code> the parameter is ignored and the node’s
+        * default value is used.
+        *
+        * @param giveOpennetRef
+        *            <code>true</code> to request the opennet noderef,
+        *            <code>false</code> for darknet
+        * @param withPrivate
+        *            <code>true</code> to include private data in the noderef
+        * @param withVolatile
+        *            <code>true</code> to include volatile data in the noderef
+        */
+       public GetNode(Boolean giveOpennetRef, Boolean withPrivate, Boolean withVolatile) {
+               super("GetNode");
+               if (giveOpennetRef != null) {
+                       setField("GiveOpennetRef", String.valueOf(giveOpennetRef));
+               }
+               if (withPrivate != null) {
+                       setField("WithPrivate", String.valueOf(withPrivate));
+               }
+               if (withVolatile != null) {
+                       setField("WithVolatile", String.valueOf(withVolatile));
+               }
+       }
+
+}
diff --git a/src/main/java/net/pterodactylus/fcp/GetPluginInfo.java b/src/main/java/net/pterodactylus/fcp/GetPluginInfo.java
new file mode 100644 (file)
index 0000000..8ad5392
--- /dev/null
@@ -0,0 +1,54 @@
+/*
+ * jFCPlib - GetPluginInfo.java - Copyright © 2008 David Roden
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+package net.pterodactylus.fcp;
+
+/**
+ * The “GetPluginInfo” message requests information about a plugin from the
+ * node, which will response with a {@link PluginInfo} message.
+ *
+ * @author David ‘Bombe’ Roden &lt;bombe@freenetproject.org&gt;
+ */
+public class GetPluginInfo extends FcpMessage {
+
+       /**
+        * Creates a new “GetPluginInfo” message.
+        *
+        * @param pluginName
+        *            The name of the plugin
+        * @param identifier
+        *            The identifier of the request
+        */
+       public GetPluginInfo(String pluginName, String identifier) {
+               super("GetPluginInfo");
+               setField("PluginName", pluginName);
+               setField("Identifier", identifier);
+       }
+
+       /**
+        * Sets whether detailed information about the plugin is wanted.
+        *
+        * @param detailed
+        *            <code>true</code> to request detailed information about the
+        *            plugin, <code>false</code> otherwise
+        */
+       public void setDetailed(boolean detailed) {
+               setField("Detailed", String.valueOf(detailed));
+       }
+
+}
diff --git a/src/main/java/net/pterodactylus/fcp/GetRequestStatus.java b/src/main/java/net/pterodactylus/fcp/GetRequestStatus.java
new file mode 100644 (file)
index 0000000..5e2d63b
--- /dev/null
@@ -0,0 +1,64 @@
+/*
+ * jFCPlib - GetRequestStatus.java - Copyright © 2008 David Roden
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+package net.pterodactylus.fcp;
+
+/**
+ * The “GetRequestStatus” message is used request status information about a
+ * running request. It is also the only way to trigger a download of a persisted
+ * completed {@link ClientGet} with a return type of {@link ReturnType#direct}.
+ *
+ * @author David ‘Bombe’ Roden &lt;bombe@freenetproject.org&gt;
+ */
+public class GetRequestStatus extends FcpMessage {
+
+       /**
+        * Creates a new “GetRequestStatus” message.
+        *
+        * @param identifier
+        *            The identifier of the request
+        */
+       public GetRequestStatus(String identifier) {
+               super("GetRequestStatus");
+               setField("Identifier", identifier);
+       }
+
+       /**
+        * Sets whether the request is on the global queue.
+        *
+        * @param global
+        *            <code>true</code> if the request is on the global queue,
+        *            <code>false</code> if it is on the client-local queue
+        */
+       public void setGlobal(boolean global) {
+               setField("Global", String.valueOf(global));
+       }
+
+       /**
+        * Sets whether the omit the transmission of the request data in a
+        * {@link AllData} message.
+        *
+        * @param onlyData
+        *            <code>true</code> to skip transmission of data,
+        *            <code>false</code> to download data
+        */
+       public void setOnlyData(boolean onlyData) {
+               setField("OnlyData", String.valueOf(onlyData));
+       }
+
+}
diff --git a/src/main/java/net/pterodactylus/fcp/IdentifierCollision.java b/src/main/java/net/pterodactylus/fcp/IdentifierCollision.java
new file mode 100644 (file)
index 0000000..bc96a70
--- /dev/null
@@ -0,0 +1,59 @@
+/*
+ * jFCPlib - IdentifierCollision.java - Copyright © 2008 David Roden
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+package net.pterodactylus.fcp;
+
+/**
+ * The “IdentifierCollision” message signals the client that the identifier
+ * chosen for a request is already existing.
+ *
+ * @author David ‘Bombe’ Roden &lt;bombe@freenetproject.org&gt;
+ */
+public class IdentifierCollision extends BaseMessage {
+
+       /**
+        * Creates a new “IdentifierCollision” message that wraps the received
+        * message.
+        *
+        * @param receivedMessage
+        *            The received message
+        */
+       IdentifierCollision(FcpMessage receivedMessage) {
+               super(receivedMessage);
+       }
+
+       /**
+        * Returns the identifier of the request.
+        *
+        * @return The identifier of the request
+        */
+       public String getIdentifier() {
+               return getField("Identifier");
+       }
+
+       /**
+        * Returns whether the request is on the global queue.
+        *
+        * @return <code>true</code> if the request is on the global queue,
+        *         <code>false</code> if it is on the client-local queue
+        */
+       public boolean isGlobal() {
+               return Boolean.valueOf(getField("Global"));
+       }
+
+}
diff --git a/src/main/java/net/pterodactylus/fcp/ListPeer.java b/src/main/java/net/pterodactylus/fcp/ListPeer.java
new file mode 100644 (file)
index 0000000..f16f385
--- /dev/null
@@ -0,0 +1,42 @@
+/*
+ * jFCPlib - ListPeer.java - Copyright © 2008 David Roden
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+package net.pterodactylus.fcp;
+
+/**
+ * The “ListPeer” request asks the node about the details of a given peer.
+ *
+ * @author David ‘Bombe’ Roden &lt;bombe@freenetproject.org&gt;
+ */
+public class ListPeer extends FcpMessage {
+
+       /**
+        * Creates a new “ListPeer” request that returns information about the node
+        * specified by <code>nodeIdentifier</code>. <code>nodeIdentifier</code> can
+        * be of several formats: The node’s name, its identity, or its IP address
+        * and port (connection with a ‘:’).
+        *
+        * @param nodeIdentifier
+        *            The identifier of the node to get details about
+        */
+       public ListPeer(String nodeIdentifier) {
+               super("ListPeer");
+               setField("NodeIdentifier", nodeIdentifier);
+       }
+
+}
diff --git a/src/main/java/net/pterodactylus/fcp/ListPeerNotes.java b/src/main/java/net/pterodactylus/fcp/ListPeerNotes.java
new file mode 100644 (file)
index 0000000..82e3399
--- /dev/null
@@ -0,0 +1,41 @@
+/*
+ * jFCPlib - ListPeerNotes.java - Copyright © 2008 David Roden
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+package net.pterodactylus.fcp;
+
+/**
+ * A “ListPeerNodes” request tells the node to list all notes that have been
+ * entered for a node. Note that notes are only supported for darknet nodes.
+ *
+ * @author David ‘Bombe’ Roden &lt;bombe@freenetproject.org&gt;
+ */
+public class ListPeerNotes extends FcpMessage {
+
+       /**
+        * Creates a new “ListPeerNotes” request that lists all notes of the
+        * specified node.
+        *
+        * @param nodeIdentifier
+        *            The identifier of the node
+        */
+       public ListPeerNotes(String nodeIdentifier) {
+               super("ListPeerNotes");
+               setField("NodeIdentifier", nodeIdentifier);
+       }
+
+}
diff --git a/src/main/java/net/pterodactylus/fcp/ListPeers.java b/src/main/java/net/pterodactylus/fcp/ListPeers.java
new file mode 100644 (file)
index 0000000..b0cbd1b
--- /dev/null
@@ -0,0 +1,58 @@
+/*
+ * jFCPlib - ListPeers.java - Copyright © 2008 David Roden
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+package net.pterodactylus.fcp;
+
+/**
+ * The “ListPeer” requests asks the node for a list of all peers it has.
+ *
+ * @author David ‘Bombe’ Roden &lt;bombe@freenetproject.org&gt;
+ */
+public class ListPeers extends FcpMessage {
+
+       /**
+        * Creates a new “ListPeers” request that only includes basic data of the
+        * peers.
+        *
+        * @param identifier
+        *            The identifier of the request
+        */
+       public ListPeers(String identifier) {
+               this(identifier, false, false);
+       }
+
+       /**
+        * Creates a new “ListPeers” request that includes wanted data of the peers.
+        *
+        * @param identifier
+        *            The identifier of the request
+        * @param withMetadata
+        *            If <code>true</code> metadata of the peers is included in the
+        *            reply
+        * @param withVolatile
+        *            if <code>true</code> volatile data of the peers is included in
+        *            the reply
+        */
+       public ListPeers(String identifier, boolean withMetadata, boolean withVolatile) {
+               super("ListPeers");
+               setField("Identifier", identifier);
+               setField("WithMetadata", String.valueOf(withMetadata));
+               setField("WithVolatile", String.valueOf(withVolatile));
+       }
+
+}
diff --git a/src/main/java/net/pterodactylus/fcp/ListPersistentRequests.java b/src/main/java/net/pterodactylus/fcp/ListPersistentRequests.java
new file mode 100644 (file)
index 0000000..645205c
--- /dev/null
@@ -0,0 +1,38 @@
+/*
+ * jFCPlib - ListPersistentRequests.java - Copyright © 2008 David Roden
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+package net.pterodactylus.fcp;
+
+/**
+ * Command to tell the node to list all persistent requests from the current
+ * queue, which is either the global queue or the client-local queue, depending
+ * on your {@link WatchGlobal} status.
+ *
+ * @author David ‘Bombe’ Roden &lt;bombe@freenetproject.org&gt;
+ */
+public class ListPersistentRequests extends FcpMessage {
+
+       /**
+        * Creates a new “ListPersistentRequests” command that lists all persistent
+        * requests in the current queue.
+        */
+       public ListPersistentRequests() {
+               super("ListPersistentRequests");
+       }
+
+}
diff --git a/src/main/java/net/pterodactylus/fcp/ModifyConfig.java b/src/main/java/net/pterodactylus/fcp/ModifyConfig.java
new file mode 100644 (file)
index 0000000..412b818
--- /dev/null
@@ -0,0 +1,50 @@
+/*
+ * jFCPlib - ModifyConfig.java - Copyright © 2008 David Roden
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+package net.pterodactylus.fcp;
+
+/**
+ * The “ModifyConfig” message is used to change the node’s configuration.
+ *
+ * @author David ‘Bombe’ Roden &lt;bombe@freenetproject.org&gt;
+ */
+public class ModifyConfig extends FcpMessage {
+
+       /**
+        * Creates a new “ModifyConfig” message.
+        */
+       public ModifyConfig() {
+               super("ModifyConfig");
+       }
+
+       /**
+        * Sets the option with the given name to the given value.
+        *
+        * @param option
+        *            The name of the option
+        * @param value
+        *            The value of the option
+        */
+       public void setOption(String option, String value) {
+               if (option.indexOf('.') == -1) {
+                       throw new IllegalArgumentException("invalid option name");
+               }
+               setField(option, value);
+       }
+
+}
diff --git a/src/main/java/net/pterodactylus/fcp/ModifyPeer.java b/src/main/java/net/pterodactylus/fcp/ModifyPeer.java
new file mode 100644 (file)
index 0000000..dc9af6b
--- /dev/null
@@ -0,0 +1,56 @@
+/*
+ * jFCPlib - ModifyPeer.java - Copyright © 2008 David Roden
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+package net.pterodactylus.fcp;
+
+/**
+ * The “ModifyPeer” request lets you modify certain properties of a peer.
+ *
+ * @author David ‘Bombe’ Roden &lt;bombe@freenetproject.org&gt;
+ */
+public class ModifyPeer extends FcpMessage {
+
+       /**
+        * Creates a new “ModifyPeer” request. All Boolean parameters may be null to
+        * not influence the current setting.
+        *
+        * @param nodeIdentifier
+        *            The identifier of the node, i.e. name, identity, or IP address
+        *            and port
+        * @param allowLocalAddresses
+        *            Whether to allow local addresses from this node
+        * @param disabled
+        *            Whether the node is disabled
+        * @param listenOnly
+        *            Whether your node should not try to connect the node
+        */
+       public ModifyPeer(String nodeIdentifier, Boolean allowLocalAddresses, Boolean disabled, Boolean listenOnly) {
+               super("ModifyPeer");
+               setField("NodeIdentifier", nodeIdentifier);
+               if (allowLocalAddresses != null) {
+                       setField("AllowLocalAddresses", String.valueOf(allowLocalAddresses));
+               }
+               if (disabled != null) {
+                       setField("IsDisabled", String.valueOf(disabled));
+               }
+               if (listenOnly != null) {
+                       setField("IsListenOnly", String.valueOf(listenOnly));
+               }
+       }
+
+}
diff --git a/src/main/java/net/pterodactylus/fcp/ModifyPeerNote.java b/src/main/java/net/pterodactylus/fcp/ModifyPeerNote.java
new file mode 100644 (file)
index 0000000..dbb2ea7
--- /dev/null
@@ -0,0 +1,49 @@
+/*
+ * jFCPlib - ModifyPeerNote.java - Copyright © 2008 David Roden
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+package net.pterodactylus.fcp;
+
+/**
+ * The “ModifyPeerNote” command modifies a peer note.
+ *
+ * @author David ‘Bombe’ Roden &lt;bombe@freenetproject.org&gt;
+ */
+public class ModifyPeerNote extends FcpMessage {
+
+       /**
+        * Creates a new “ModifyPeerNote” request that changes peer note of the
+        * given type and node to the given text.
+        *
+        * @see PeerNote
+        * @param nodeIdentifier
+        *            The identifier of the node, i.e. name, identity, or IP address
+        *            and port
+        * @param noteText
+        *            The base64-encoded text
+        * @param peerNoteType
+        *            The type of the note to change, possible values are only
+        *            {@link PeerNote#TYPE_PRIVATE_PEER_NOTE} at the moment
+        */
+       public ModifyPeerNote(String nodeIdentifier, String noteText, int peerNoteType) {
+               super("ModifyPeer");
+               setField("NodeIdentifier", nodeIdentifier);
+               setField("NoteText", noteText);
+               setField("PeerNoteType", String.valueOf(peerNoteType));
+       }
+
+}
diff --git a/src/main/java/net/pterodactylus/fcp/ModifyPersistentRequest.java b/src/main/java/net/pterodactylus/fcp/ModifyPersistentRequest.java
new file mode 100644 (file)
index 0000000..cc71829
--- /dev/null
@@ -0,0 +1,65 @@
+/*
+ * jFCPlib - ModifyPersistentRequest.java - Copyright © 2008 David Roden
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+package net.pterodactylus.fcp;
+
+/**
+ * A “ModifyPersistentRequest” is used to modify certain properties of a
+ * persistent request while it is running.
+ *
+ * @author David ‘Bombe’ Roden &lt;bombe@freenetproject.org&gt;
+ */
+public class ModifyPersistentRequest extends FcpMessage {
+
+       /**
+        * Creates a new “ModifyPersistentRequest” that changes the specified
+        * request.
+        *
+        * @param requestIdentifier
+        *            The identifier of the request
+        * @param global
+        *            <code>true</code> if the request is on the global queue,
+        *            <code>false</code> if it is on the client-local queue
+        */
+       public ModifyPersistentRequest(String requestIdentifier, boolean global) {
+               super("ModifyPersistentRequest");
+               setField("Identifier", requestIdentifier);
+               setField("Global", String.valueOf(global));
+       }
+
+       /**
+        * Sets the new client token of the request.
+        *
+        * @param newClientToken
+        *            The new client token of the request
+        */
+       public void setClientToken(String newClientToken) {
+               setField("ClientToken", newClientToken);
+       }
+
+       /**
+        * Sets the new priority of the request.
+        *
+        * @param newPriority
+        *            The new priority of the request
+        */
+       public void setPriority(Priority newPriority) {
+               setField("PriorityClass", String.valueOf(newPriority));
+       }
+
+}
diff --git a/src/main/java/net/pterodactylus/fcp/NodeData.java b/src/main/java/net/pterodactylus/fcp/NodeData.java
new file mode 100644 (file)
index 0000000..5425833
--- /dev/null
@@ -0,0 +1,176 @@
+/*
+ * jFCPlib - NodeData.java - Copyright © 2008 David Roden
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+package net.pterodactylus.fcp;
+
+/**
+ * The “NodeData” contains the noderef of the node, along with additional data.
+ *
+ * @author David ‘Bombe’ Roden &lt;bombe@freenetproject.org&gt;
+ */
+public class NodeData extends BaseMessage {
+
+       /** The noderef of the node. */
+       private final NodeRef nodeRef;
+
+       /**
+        * Creates a new “NodeData” message that wraps the received message.
+        *
+        * @param receivedMessage
+        *            The received message
+        */
+       NodeData(FcpMessage receivedMessage) {
+               super(receivedMessage);
+               nodeRef = new NodeRef(receivedMessage);
+       }
+
+       /**
+        * Returns the noderef of the node.
+        *
+        * @return The noderef of the node
+        */
+       public NodeRef getNodeRef() {
+               return nodeRef;
+       }
+
+       /**
+        * Returns the last good version, i.e. the oldest version the node will
+        * connect to.
+        *
+        * @return The last good version
+        */
+       public Version getLastGoodVersion() {
+               return nodeRef.getLastGoodVersion();
+       }
+
+       /**
+        * Returns the signature of the noderef.
+        *
+        * @return The signature of the noderef
+        */
+       public String getSignature() {
+               return nodeRef.getSignature();
+       }
+
+       /**
+        * Returns whether the noderef is the opennet noderef of the node
+        *
+        * @return <code>true</code> if the noderef is the opennet noderef of the
+        *         node, <code>false</code> otherwise
+        */
+       public boolean isOpennet() {
+               return nodeRef.isOpennet();
+       }
+
+       /**
+        * Returns the identity of the node
+        *
+        * @return The identity of the node
+        */
+       public String getIdentity() {
+               return nodeRef.getIdentity();
+       }
+
+       /**
+        * Returns the name of the node.
+        *
+        * @return The name of the node
+        */
+       public String getMyName() {
+               return nodeRef.getMyName();
+       }
+
+       /**
+        * Returns the version of the node.
+        *
+        * @return The version of the node
+        */
+       public Version getVersion() {
+               return nodeRef.getVersion();
+       }
+
+       /**
+        * Returns IP addresses and port number of the node.
+        *
+        * @return The IP addresses and port numbers of the node
+        */
+       public String getPhysicalUDP() {
+               return nodeRef.getPhysicalUDP();
+       }
+
+       /**
+        * Returns the ARK of the node.
+        *
+        * @return The ARK of the node
+        */
+       public ARK getARK() {
+               return nodeRef.getARK();
+       }
+
+       /**
+        * Returns the public key of the node.
+        *
+        * @return The public key of the node
+        */
+       public String getDSAPublicKey() {
+               return nodeRef.getDSAPublicKey();
+       }
+
+       /**
+        * Returns the private key of the node.
+        *
+        * @return The private key of the node
+        */
+       public String getDSKPrivateKey() {
+               return getField("dsaPrivKey.x");
+       }
+
+       /**
+        * Returns the DSA group of the node.
+        *
+        * @return The DSA group of the node
+        */
+       public DSAGroup getDSAGroup() {
+               return nodeRef.getDSAGroup();
+       }
+
+       /**
+        * Returns the negotiation types supported by the node.
+        *
+        * @return The node’s supported negotiation types
+        */
+       public int[] getNegotiationTypes() {
+               return nodeRef.getNegotiationTypes();
+       }
+
+       /**
+        * Returns one of the volatile fields from the message. The given field name
+        * is prepended with “volatile.” so if you want to get the value of the
+        * field with the name “volatile.freeJavaMemory” you only need to specify
+        * “freeJavaMemory”.
+        *
+        * @param field
+        *            The name of the field
+        * @return The value of the field, or <code>null</code> if there is no such
+        *         field
+        */
+       public String getVolatile(String field) {
+               return getField("volatile." + field);
+       }
+
+}
diff --git a/src/main/java/net/pterodactylus/fcp/NodeHello.java b/src/main/java/net/pterodactylus/fcp/NodeHello.java
new file mode 100644 (file)
index 0000000..01b0515
--- /dev/null
@@ -0,0 +1,191 @@
+/*
+ * jFCPlib - NodeHello.java - Copyright © 2008 David Roden
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+package net.pterodactylus.fcp;
+
+/**
+ * Some convenience methods for parsing a “NodeHello” message from the node.
+ *
+ * @author David ‘Bombe’ Roden &lt;bombe@freenetproject.org&gt;
+ */
+public class NodeHello extends BaseMessage {
+
+       /**
+        * Createa a new “NodeHello” message that wraps the received message.
+        *
+        * @param receivedMessage
+        *            The received FCP message
+        */
+       NodeHello(FcpMessage receivedMessage) {
+               super(receivedMessage);
+       }
+
+       /**
+        * Returns the build of the node. This may not be a number but also a string
+        * like “@custom@” in case you built the node yourself.
+        *
+        * @return The build of the node
+        */
+       public String getBuild() {
+               return getField("Build");
+       }
+
+       /**
+        * Returns the build number of the node. This may not be a number but also a
+        * string like “@custom@” in case you built the node yourself.
+        *
+        * @return The build number of the node, or <code>-1</code> if the build
+        *         number could not be determined
+        */
+       public int getBuildNumber() {
+               return FcpUtils.safeParseInt(getBuild());
+       }
+
+       /**
+        * Returns the number of compression codecs.
+        *
+        * @return The number of compression codecs
+        */
+       public String getCompressionCodecs() {
+               return getField("CompressionCodecs");
+       }
+
+       /**
+        * Returns the number of compression codecs.
+        *
+        * @return The number of compression codecs, or <code>-1</code> if the
+        *         number of compression codecs could not be determined
+        */
+       public int getCompressionCodecsNumber() {
+               return FcpUtils.safeParseInt(getCompressionCodecs());
+       }
+
+       /**
+        * Returns the unique connection identifier.
+        *
+        * @return The connection identifier
+        */
+       public String getConnectionIdentifier() {
+               return getField("ConnectionIdentifier");
+       }
+
+       /**
+        * Returns the build of the external library file.
+        *
+        * @return The build of the external library file
+        */
+       public String getExtBuild() {
+               return getField("ExtBuild");
+       }
+
+       /**
+        * Returns the build number of the external library file.
+        *
+        * @return The build number of the external library file, or <code>-1</code>
+        *         if the build number could not be determined
+        */
+       public int getExtBuildNumber() {
+               return FcpUtils.safeParseInt(getExtBuild());
+       }
+
+       /**
+        * Returns the revision of the external library file.
+        *
+        * @return The revision of the external library file
+        */
+       public String getExtRevision() {
+               return getField("ExtRevision");
+       }
+
+       /**
+        * Returns the revision number of the external library file.
+        *
+        * @return The revision number of the external library file, or
+        *         <code>-1</code> if the revision number could not be determined
+        */
+       public int getExtRevisionNumber() {
+               return FcpUtils.safeParseInt(getExtRevision());
+       }
+
+       /**
+        * Returns the FCP version the node speaks.
+        *
+        * @return The FCP version the node speaks
+        */
+       public String getFCPVersion() {
+               return getField("FCPVersion");
+       }
+
+       /**
+        * Returns the make of the node, e.g. “Fred” (freenet reference
+        * implementation).
+        *
+        * @return The make of the node
+        */
+       public String getNode() {
+               return getField("Node");
+       }
+
+       /**
+        * Returns the language of the node as 2-letter code, e.g. “en” or “de”.
+        *
+        * @return The language of the node
+        */
+       public String getNodeLanguage() {
+               return getField("NodeLanguage");
+       }
+
+       /**
+        * Returns the revision of the node.
+        *
+        * @return The revision of the node
+        */
+       public String getRevision() {
+               return getField("Revision");
+       }
+
+       /**
+        * Returns the revision number of the node.
+        *
+        * @return The revision number of the node, or <code>-1</code> if the
+        *         revision number coult not be determined
+        */
+       public int getRevisionNumber() {
+               return FcpUtils.safeParseInt(getRevision());
+       }
+
+       /**
+        * Returns whether the node is currently is testnet mode.
+        *
+        * @return <code>true</code> if the node is currently in testnet mode,
+        *         <code>false</code> otherwise
+        */
+       public boolean getTestnet() {
+               return Boolean.valueOf(getField("Testnet"));
+       }
+
+       /**
+        * Returns the version of the node.
+        *
+        * @return The version of the node
+        */
+       public String getVersion() {
+               return getField("Version");
+       }
+
+}
diff --git a/src/main/java/net/pterodactylus/fcp/NodeRef.java b/src/main/java/net/pterodactylus/fcp/NodeRef.java
new file mode 100644 (file)
index 0000000..64ca56c
--- /dev/null
@@ -0,0 +1,353 @@
+/*
+ * jFCPlib - NodeRef.java - Copyright © 2008 David Roden
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+package net.pterodactylus.fcp;
+
+/**
+ * A reference for a node. The noderef contains all data that is necessary to
+ * establish a trusted and secure connection to the node.
+ *
+ * @author David ‘Bombe’ Roden &lt;bombe@freenetproject.org&gt;
+ */
+public class NodeRef {
+
+       /** The identity of the node. */
+       private String identity;
+
+       /** Whether the node is an opennet peer. */
+       private boolean opennet;
+
+       /** The name of the node. */
+       private String name;
+
+       /** The location of the node. */
+       private double location;
+
+       /** The IP addresses and ports of the node. */
+       private String physicalUDP;
+
+       /** The ARK of the node. */
+       private ARK ark;
+
+       /** The public DSA key of the node. */
+       private String dsaPublicKey;
+
+       /** The DSA group of the node. */
+       private DSAGroup dsaGroup;
+
+       /** The node’s supported negotiation types. */
+       private int[] negotiationTypes;
+
+       /** The version of the node. */
+       private Version version;
+
+       /** The oldest version the node will connect to. */
+       private Version lastGoodVersion;
+
+       /** Whether the node is a testnet node. */
+       private boolean testnet;
+
+       /** The signature of the reference. */
+       private String signature;
+
+       /**
+        * Creates a new, empty noderef.
+        */
+       public NodeRef() {
+               /* intentionally left blank. */
+       }
+
+       /**
+        * Creates a new noderef that is initialized with fields from the given
+        * message.
+        *
+        * @param fromMessage
+        *            The message to get initial values for the noderef from
+        */
+       public NodeRef(FcpMessage fromMessage) {
+               identity = fromMessage.getField("identity");
+               opennet = Boolean.valueOf(fromMessage.getField("opennet"));
+               name = fromMessage.getField("myName");
+               if (fromMessage.hasField("location")) {
+                       location = Double.valueOf(fromMessage.getField("location"));
+               }
+               physicalUDP = fromMessage.getField("physical.udp");
+               ark = new ARK(fromMessage.getField("ark.pubURI"), fromMessage.getField("ark.privURI"), fromMessage.getField("ark.number"));
+               dsaPublicKey = fromMessage.getField("dsaPubKey.y");
+               dsaGroup = new DSAGroup(fromMessage.getField("dsaGroup.b"), fromMessage.getField("dsaGroup.p"), fromMessage.getField("dsaGroup.q"));
+               negotiationTypes = FcpUtils.decodeMultiIntegerField(fromMessage.getField("auth.negTypes"));
+               version = new Version(fromMessage.getField("version"));
+               lastGoodVersion = new Version(fromMessage.getField("lastGoodVersion"));
+               testnet = Boolean.valueOf(fromMessage.getField("testnet"));
+               signature = fromMessage.getField("sig");
+       }
+
+       /**
+        * Returns the identity of the node.
+        *
+        * @return The identity of the node
+        */
+       public String getIdentity() {
+               return identity;
+       }
+
+       /**
+        * Sets the identity of the node.
+        *
+        * @param identity
+        *            The identity of the node
+        */
+       public void setIdentity(String identity) {
+               this.identity = identity;
+       }
+
+       /**
+        * Returns whether the node is an opennet peer.
+        *
+        * @return <code>true</code> if the node is an opennet peer,
+        *         <code>false</code> otherwise
+        */
+       public boolean isOpennet() {
+               return opennet;
+       }
+
+       /**
+        * Sets whether the node is an opennet peer.
+        *
+        * @param opennet
+        *            <code>true</code> if the node is an opennet peer,
+        *            <code>false</code> otherwise
+        */
+       public void setOpennet(boolean opennet) {
+               this.opennet = opennet;
+       }
+
+       /**
+        * Returns the name of the node. If the node is an opennet peer, it will not
+        * have a name!
+        *
+        * @return The name of the node, or <code>null</code> if the node is an
+        *         opennet peer
+        */
+       public String getMyName() {
+               return name;
+       }
+
+       /**
+        * Sets the name of the peer.
+        *
+        * @param name
+        *            The name of the peer
+        */
+       public void setName(String name) {
+               this.name = name;
+       }
+
+       /**
+        * Returns the location of the node.
+        *
+        * @return The location of the node
+        */
+       public double getLocation() {
+               return location;
+       }
+
+       /**
+        * Sets the location of the node
+        *
+        * @param location
+        *            The location of the node
+        */
+       public void setLocation(double location) {
+               this.location = location;
+       }
+
+       /**
+        * Returns the IP addresses and port numbers of the node.
+        *
+        * @return The IP addresses and port numbers of the node
+        */
+       public String getPhysicalUDP() {
+               return physicalUDP;
+       }
+
+       /**
+        * Sets the IP addresses and port numbers of the node.
+        *
+        * @param physicalUDP
+        *            The IP addresses and port numbers of the node
+        */
+       public void setPhysicalUDP(String physicalUDP) {
+               this.physicalUDP = physicalUDP;
+       }
+
+       /**
+        * Returns the ARK of the node.
+        *
+        * @return The ARK of the node
+        */
+       public ARK getARK() {
+               return ark;
+       }
+
+       /**
+        * Sets the ARK of the node.
+        *
+        * @param ark
+        *            The ARK of the node
+        */
+       public void setARK(ARK ark) {
+               this.ark = ark;
+       }
+
+       /**
+        * Returns the public DSA key of the node.
+        *
+        * @return The public DSA key of the node
+        */
+       public String getDSAPublicKey() {
+               return dsaPublicKey;
+       }
+
+       /**
+        * Sets the public DSA key of the node.
+        *
+        * @param dsaPublicKey
+        *            The public DSA key of the node
+        */
+       public void setDSAPublicKey(String dsaPublicKey) {
+               this.dsaPublicKey = dsaPublicKey;
+       }
+
+       /**
+        * Returns the DSA group of the node.
+        *
+        * @return The DSA group of the node
+        */
+       public DSAGroup getDSAGroup() {
+               return dsaGroup;
+       }
+
+       /**
+        * Sets the DSA group of the node.
+        *
+        * @param dsaGroup
+        *            The DSA group of the node
+        */
+       public void setDSAGroup(DSAGroup dsaGroup) {
+               this.dsaGroup = dsaGroup;
+       }
+
+       /**
+        * Returns the negotiation types supported by the node.
+        *
+        * @return The node’s supported negotiation types
+        */
+       public int[] getNegotiationTypes() {
+               return negotiationTypes;
+       }
+
+       /**
+        * Sets the negotiation types supported by the node.
+        *
+        * @param negotiationTypes
+        *            The node’s supported negotiation types
+        */
+       public void setNegotiationTypes(int[] negotiationTypes) {
+               this.negotiationTypes = negotiationTypes;
+       }
+
+       /**
+        * Returns the version of the node.
+        *
+        * @return The version of the node
+        */
+       public Version getVersion() {
+               return version;
+       }
+
+       /**
+        * Sets the version of the node.
+        *
+        * @param version
+        *            The version of the node
+        */
+       public void setVersion(Version version) {
+               this.version = version;
+       }
+
+       /**
+        * Returns the last good version of the node.
+        *
+        * @return The oldest version the node will connect to
+        */
+       public Version getLastGoodVersion() {
+               return lastGoodVersion;
+       }
+
+       /**
+        * Sets the last good version of the node.
+        *
+        * @param lastGoodVersion
+        *            The oldest version the node will connect to
+        */
+       public void setLastGoodVersion(Version lastGoodVersion) {
+               this.lastGoodVersion = lastGoodVersion;
+       }
+
+       /**
+        * Returns whether the node is a testnet node.
+        *
+        * @return <code>true</code> if the node is a testnet node,
+        *         <code>false</code> otherwise
+        */
+       public boolean isTestnet() {
+               return testnet;
+       }
+
+       /**
+        * Sets whether this node is a testnet node.
+        *
+        * @param testnet
+        *            <code>true</code> if the node is a testnet node,
+        *            <code>false</code> otherwise
+        */
+       public void setTestnet(boolean testnet) {
+               this.testnet = testnet;
+       }
+
+       /**
+        * Returns the signature of the noderef.
+        *
+        * @return The signature of the noderef
+        */
+       public String getSignature() {
+               return signature;
+       }
+
+       /**
+        * Sets the signature of the noderef.
+        *
+        * @param signature
+        *            The signature of the noderef
+        */
+       public void setSignature(String signature) {
+               this.signature = signature;
+       }
+
+}
diff --git a/src/main/java/net/pterodactylus/fcp/Peer.java b/src/main/java/net/pterodactylus/fcp/Peer.java
new file mode 100644 (file)
index 0000000..3cfa856
--- /dev/null
@@ -0,0 +1,258 @@
+/*
+ * jFCPlib - Peer.java - Copyright © 2008 David Roden
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+package net.pterodactylus.fcp;
+
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Map.Entry;
+
+/**
+ * The “Peer” reply by the node contains information about a peer.
+ *
+ * @author David ‘Bombe’ Roden &lt;bombe@freenetproject.org&gt;
+ */
+public class Peer extends BaseMessage {
+
+       /**
+        * Creates a new “Peer” reply from the received message.
+        *
+        * @param receivedMessage
+        *            The received message
+        */
+       Peer(FcpMessage receivedMessage) {
+               super(receivedMessage);
+       }
+
+       /**
+        * Returns a collection of fields as a node reference.
+        *
+        * @return The node reference contained within this message
+        */
+       public NodeRef getNodeRef() {
+               NodeRef nodeRef = new NodeRef();
+               nodeRef.setARK(getARK());
+               nodeRef.setDSAGroup(getDSAGroup());
+               nodeRef.setDSAPublicKey(getDSAPublicKey());
+               nodeRef.setIdentity(getIdentity());
+               nodeRef.setLastGoodVersion(getLastGoodVersion());
+               nodeRef.setLocation(getLocation());
+               nodeRef.setName(getMyName());
+               nodeRef.setNegotiationTypes(getNegotiationTypes());
+               nodeRef.setOpennet(isOpennet());
+               nodeRef.setPhysicalUDP(getPhysicalUDP());
+               nodeRef.setVersion(getVersion());
+               return nodeRef;
+       }
+
+       /**
+        * Returns the identifier of the request.
+        *
+        * @return The identifier of the request
+        */
+       public String getIdentifier() {
+               return getField("Identifier");
+       }
+
+       /**
+        * Returns the “physical.udp” line from the message. It contains all IP
+        * addresses and port numbers of the peer.
+        *
+        * @return The IP addresses and port numbers of the peer
+        */
+       public String getPhysicalUDP() {
+               return getField("physical.udp");
+       }
+
+       /**
+        * Returns whether the listed peer is an opennet peer.
+        *
+        * @return <code>true</code> if the peer is an opennet peer,
+        *         <code>false</code> if the peer is a darknet peer
+        */
+       public boolean isOpennet() {
+               return Boolean.valueOf(getField("opennet"));
+       }
+
+       /**
+        * Returns whether this peer is a seed.
+        *
+        * @return <code>true</code> if the peer is a seed, <code>false</code>
+        *         otherwise
+        */
+       public boolean isSeed() {
+               return Boolean.valueOf(getField("seed"));
+       }
+
+       /**
+        * Returns the “y” part of the peer’s public DSA key.
+        *
+        * @return The public DSA key
+        */
+       public String getDSAPublicKey() {
+               return getField("dsaPubKey.y");
+       }
+
+       /**
+        * Returns the DSA group of the peer.
+        *
+        * @return The DSA group of the peer
+        */
+       public DSAGroup getDSAGroup() {
+               return new DSAGroup(getField("dsaGroup.g"), getField("dsaGroup.p"), getField("dsaGroup.q"));
+       }
+
+       /**
+        * Returns the last good version of the peer, i.e. the oldest version the
+        * peer will connect to.
+        *
+        * @return The last good version of the peer
+        */
+       public Version getLastGoodVersion() {
+               return new Version(getField("lastGoodVersion"));
+       }
+
+       /**
+        * Returns the ARK of the peer.
+        *
+        * @return The ARK of the peer
+        */
+       public ARK getARK() {
+               return new ARK(getField("ark.pubURI"), getField("ark.number"));
+       }
+
+       /**
+        * Returns the identity of the peer.
+        *
+        * @return The identity of the peer
+        */
+       public String getIdentity() {
+               return getField("identity");
+       }
+
+       /**
+        * Returns the name of the peer. If the peer is not a darknet peer it will
+        * have no name.
+        *
+        * @return The name of the peer, or <code>null</code> if the peer is an
+        *         opennet peer
+        */
+       public String getMyName() {
+               return getField("myName");
+       }
+
+       /**
+        * Returns the location of the peer.
+        *
+        * @return The location of the peer
+        * @throws NumberFormatException
+        *             if the field can not be parsed
+        */
+       public double getLocation() throws NumberFormatException {
+               return Double.valueOf(getField("location"));
+       }
+
+       /**
+        * Returns whether the peer is a testnet node.
+        *
+        * @return <code>true</code> if the peer is a testnet node,
+        *         <code>false</code> otherwise
+        */
+       public boolean isTestnet() {
+               return Boolean.valueOf("testnet");
+       }
+
+       /**
+        * Returns the version of the peer.
+        *
+        * @return The version of the peer
+        */
+       public Version getVersion() {
+               return new Version(getField("version"));
+       }
+
+       /**
+        * Returns the negotiation types the peer supports.
+        *
+        * @return The supported negotiation types
+        */
+       public int[] getNegotiationTypes() {
+               return FcpUtils.decodeMultiIntegerField(getField("auth.negTypes"));
+       }
+
+       /**
+        * Returns all volatile fields from the message.
+        *
+        * @return All volatile files
+        */
+       public Map<String, String> getVolatileFields() {
+               Map<String, String> volatileFields = new HashMap<String, String>();
+               for (Entry<String, String> field : getFields().entrySet()) {
+                       if (field.getKey().startsWith("volatile.")) {
+                               volatileFields.put(field.getKey(), field.getValue());
+                       }
+               }
+               return Collections.unmodifiableMap(volatileFields);
+       }
+
+       /**
+        * Returns one of the volatile fields from the message. The given field name
+        * is prepended with “volatile.” so if you want to get the value of the
+        * field with the name “volatile.status” you only need to specify “status”.
+        *
+        * @param field
+        *            The name of the field
+        * @return The value of the field, or <code>null</code> if there is no such
+        *         field
+        */
+       public String getVolatile(String field) {
+               return getField("volatile." + field);
+       }
+
+       /**
+        * Returns all metadata fields from the message.
+        *
+        * @return All volatile files
+        */
+       public Map<String, String> getMetadataFields() {
+               Map<String, String> metadataFields = new HashMap<String, String>();
+               for (Entry<String, String> field : getFields().entrySet()) {
+                       if (field.getKey().startsWith("metadata.")) {
+                               metadataFields.put(field.getKey(), field.getValue());
+                       }
+               }
+               return Collections.unmodifiableMap(metadataFields);
+       }
+
+       /**
+        * Returns one of the metadata fields from the message. The given field name
+        * is prepended with “metadata.” so if you want to get the value of the
+        * field with the name “metadata.timeLastRoutable” you only need to specify
+        * “timeLastRoutable”.
+        *
+        * @param field
+        *            The name of the field
+        * @return The value of the field, or <code>null</code> if there is no such
+        *         field
+        */
+       public String getMetadata(String field) {
+               return getField("metadata." + field);
+       }
+
+}
diff --git a/src/main/java/net/pterodactylus/fcp/PeerNote.java b/src/main/java/net/pterodactylus/fcp/PeerNote.java
new file mode 100644 (file)
index 0000000..7b32207
--- /dev/null
@@ -0,0 +1,70 @@
+/*
+ * jFCPlib - PeerNote.java - Copyright © 2008 David Roden
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+package net.pterodactylus.fcp;
+
+/**
+ * The “PeerNote” message contains a private note that has been entered for a
+ * darknet peer.
+ *
+ * @author David ‘Bombe’ Roden &lt;bombe@freenetproject.org&gt;
+ */
+public class PeerNote extends BaseMessage {
+
+       /** The type for base64 encoded peer notes. */
+       public static final int TYPE_PRIVATE_PEER_NOTE = 1;
+
+       /**
+        * Creates a “PeerNote” message that wraps the recevied message.
+        *
+        * @param receivedMessage
+        *            The received message
+        */
+       PeerNote(FcpMessage receivedMessage) {
+               super(receivedMessage);
+       }
+
+       /**
+        * Returns the identifier of the node this note belongs to.
+        *
+        * @return The note’s node’s identifier
+        */
+       public String getNodeIdentifier() {
+               return getField("NodeIdentifier");
+       }
+
+       /**
+        * Returns the base64-encoded note text.
+        *
+        * @return The note text
+        */
+       public String getNoteText() {
+               return getField("NoteText");
+       }
+
+       /**
+        * Returns the type of the peer note.
+        *
+        * @return The type of the peer note, or <code>-1</code> if the type can not
+        *         be parsed
+        */
+       public int getPeerNoteType() {
+               return FcpUtils.safeParseInt(getField("PeerNoteType"));
+       }
+
+}
diff --git a/src/main/java/net/pterodactylus/fcp/PeerRemoved.java b/src/main/java/net/pterodactylus/fcp/PeerRemoved.java
new file mode 100644 (file)
index 0000000..61aa08d
--- /dev/null
@@ -0,0 +1,56 @@
+/*
+ * jFCPlib - PeerRemoved.java - Copyright © 2008 David Roden
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+package net.pterodactylus.fcp;
+
+/**
+ * A “PeerRemoved” message is sent by the node when a peer has been removed.
+ *
+ * @author David ‘Bombe’ Roden &lt;bombe@freenetproject.org&gt;
+ */
+public class PeerRemoved extends BaseMessage {
+
+       /**
+        * Creates a new “PeerRemoved” message that wraps the received message.
+        *
+        * @param receivedMessage
+        *            The received message
+        */
+       PeerRemoved(FcpMessage receivedMessage) {
+               super(receivedMessage);
+       }
+
+       /**
+        * Returns the identity of the removed peer.
+        *
+        * @return The identity of the removed peer
+        */
+       public String getIdentity() {
+               return getField("Identity");
+       }
+
+       /**
+        * Returns the node identifier of the removed peer.
+        *
+        * @return The node identifier of the removed peer
+        */
+       public String getNodeIdentifier() {
+               return getField("NodeIdentifier");
+       }
+
+}
diff --git a/src/main/java/net/pterodactylus/fcp/Persistence.java b/src/main/java/net/pterodactylus/fcp/Persistence.java
new file mode 100644 (file)
index 0000000..44c5e62
--- /dev/null
@@ -0,0 +1,46 @@
+/*
+ * jFCPlib - Persistence.java - Copyright © 2008 David Roden
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+package net.pterodactylus.fcp;
+
+/**
+ * Convenience class for persistence values.
+ *
+ * @author David ‘Bombe’ Roden &lt;bombe@freenetproject.org&gt;
+ */
+public enum Persistence {
+
+       /**
+        * Connection persistence. A request with this persistence will die as soon
+        * as the connection goes down.
+        */
+       connection,
+
+       /**
+        * Reboot persistence. A request with this persistence will live until the
+        * node is restarted.
+        */
+       reboot,
+
+       /** Forever persistence. A request with this persistence will live forever. */
+       forever,
+
+       /** Unknown persistence. */
+       unknown;
+
+}
diff --git a/src/main/java/net/pterodactylus/fcp/PersistentGet.java b/src/main/java/net/pterodactylus/fcp/PersistentGet.java
new file mode 100644 (file)
index 0000000..7489801
--- /dev/null
@@ -0,0 +1,153 @@
+/*
+ * jFCPlib - PersistentGet.java - Copyright © 2008 David Roden
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+package net.pterodactylus.fcp;
+
+/**
+ * The “PersistentGet” message is sent to the client to inform it about a
+ * persistent download, either in the client-local queue or in the global queue.
+ *
+ * @author David ‘Bombe’ Roden &lt;bombe@freenetproject.org&gt;
+ */
+public class PersistentGet extends BaseMessage {
+
+       /**
+        * Creates a new “PersistentGet” message that wraps the received message.
+        *
+        * @param receivedMessage
+        *            The received message
+        */
+       PersistentGet(FcpMessage receivedMessage) {
+               super(receivedMessage);
+       }
+
+       /**
+        * Returns the identifier of the request.
+        *
+        * @return The identifier of the request
+        */
+       public String getIdentifier() {
+               return getField("Identifier");
+       }
+
+       /**
+        * Returns the URI of the request.
+        *
+        * @return The URI of the request
+        */
+       public String getURI() {
+               return getField("URI");
+       }
+
+       /**
+        * Returns the verbosity of the request.
+        *
+        * @return The verbosity of the request
+        */
+       public Verbosity getVerbosity() {
+               return Verbosity.valueOf(getField("Verbosity"));
+       }
+
+       /**
+        * Returns the return type of the request.
+        *
+        * @return The return type of the request
+        */
+       public ReturnType getReturnType() {
+               try {
+                       return ReturnType.valueOf(getField("ReturnType"));
+               } catch (IllegalArgumentException iae1) {
+                       return ReturnType.unknown;
+               }
+       }
+
+       /**
+        * Returns the name of the file the data is downloaded to. This field will
+        * only be set if {@link #getReturnType()} is {@link ReturnType#disk}.
+        *
+        * @return The name of the file the data is downloaded to
+        */
+       public String getFilename() {
+               return getField("Filename");
+       }
+
+       /**
+        * Returns the name of the temporary file. This field will only be set if
+        * {@link #getReturnType()} is {@link ReturnType#disk}.
+        *
+        * @return The name of the temporary file
+        */
+       public String getTempFilename() {
+               return getField("TempFilename");
+       }
+
+       /**
+        * Returns the client token of the request.
+        *
+        * @return The client token of the request
+        */
+       public String getClientToken() {
+               return getField("ClientToken");
+       }
+
+       /**
+        * Returns the priority of the request.
+        *
+        * @return The priority of the request
+        */
+       public Priority getPriority() {
+               return Priority.values()[FcpUtils.safeParseInt(getField("PriorityClass"), Priority.unknown.ordinal())];
+       }
+
+       /**
+        * Returns the persistence of the request.
+        *
+        * @return The persistence of the request, or {@link Persistence#unknown} if
+        *         the persistence could not be parsed
+        */
+       public Persistence getPersistence() {
+               try {
+                       return Persistence.valueOf(getField("Persistence"));
+               } catch (IllegalArgumentException iae1) {
+                       return Persistence.unknown;
+               }
+       }
+
+       /**
+        * Returns whether this request is on the global queue or on the
+        * client-local queue.
+        *
+        * @return <code>true</code> if the request is on the global queue,
+        *         <code>false</code> if the request is on the client-local queue
+        */
+       public boolean isGlobal() {
+               return Boolean.valueOf(getField("Global"));
+       }
+
+       /**
+        * Returns the maximum number of retries for a failed block.
+        *
+        * @return The maximum number of retries for a failed block, <code>-1</code>
+        *         for endless retries, <code>-2</code> if the number could not be
+        *         parsed
+        */
+       public int getMaxRetries() {
+               return FcpUtils.safeParseInt(getField("MaxRetries"), -2);
+       }
+
+}
diff --git a/src/main/java/net/pterodactylus/fcp/PersistentPut.java b/src/main/java/net/pterodactylus/fcp/PersistentPut.java
new file mode 100644 (file)
index 0000000..383ea93
--- /dev/null
@@ -0,0 +1,163 @@
+/*
+ * jFCPlib - PersistentPut.java - Copyright © 2008 David Roden
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+package net.pterodactylus.fcp;
+
+/**
+ * A “PersistentPut” message notifies a client about a persistent
+ * {@link ClientPut} request.
+ *
+ * @author David ‘Bombe’ Roden &lt;bombe@freenetproject.org&gt;
+ */
+public class PersistentPut extends BaseMessage {
+
+       /**
+        * Creates a new “PersistentPut” message that wraps the received message.
+        *
+        * @param receivedMessage
+        *            The received message
+        */
+       PersistentPut(FcpMessage receivedMessage) {
+               super(receivedMessage);
+       }
+
+       /**
+        * Returns the client token of the request.
+        *
+        * @return The client token of the request
+        */
+       public String getClientToken() {
+               return getField("ClientToken");
+       }
+
+       /**
+        * Returns the data length of the request.
+        *
+        * @return The data length of the request, or <code>-1</code> if the length
+        *         could not be parsed
+        */
+       public long getDataLength() {
+               return FcpUtils.safeParseLong(getField("DataLength"));
+       }
+
+       /**
+        * Returns whether the request is on the global queue.
+        *
+        * @return <code>true</code> if the request is on the global queue,
+        *         <code>false</code> otherwise
+        */
+       public boolean isGlobal() {
+               return Boolean.valueOf(getField("Global"));
+       }
+
+       /**
+        * Returns the identifier of the request.
+        *
+        * @return The identifier of the request
+        */
+       public String getIdentifier() {
+               return getField("Identifier");
+       }
+
+       /**
+        * Returns the maximum number of retries for failed blocks. When
+        * <code>-1</code> is returned each block is tried forever.
+        *
+        * @return The maximum number of retries for failed blocks, or
+        *         <code>-1</code> for unlimited retries, or <code>-2</code> if the
+        *         number of retries could not be parsed
+        */
+       public int getMaxRetries() {
+               return FcpUtils.safeParseInt(getField("MaxRetries"));
+       }
+
+       /**
+        * Returns the content type of the data.
+        *
+        * @return The content type
+        */
+       public String getMetadataContentType() {
+               return getField("Metadata.ContentType");
+       }
+
+       /**
+        * Returns the persistence of the request.
+        *
+        * @return The persistence of the request
+        */
+       public Persistence getPersistence() {
+               return Persistence.valueOf(getField("Persistence"));
+       }
+
+       /**
+        * Returns the priority of the request.
+        *
+        * @return The priority of the request, or {@link Priority#unknown} if the
+        *         priority could not be parsed
+        */
+       public Priority getPriority() {
+               return Priority.values()[FcpUtils.safeParseInt(getField("PriorityClass"), Priority.unknown.ordinal())];
+       }
+
+       /**
+        * Returns whether this request has started.
+        *
+        * @return <code>true</code> if the request has started, <code>false</code>
+        *         otherwise
+        */
+       public boolean isStarted() {
+               return Boolean.valueOf(getField("Started"));
+       }
+
+       /**
+        * Returns the target filename of the request.
+        *
+        * @return The target filename of the request
+        */
+       public String getTargetFilename() {
+               return getField("TargetFilename");
+       }
+
+       /**
+        * Returns the upload source of the request.
+        *
+        * @return The upload source of the request
+        */
+       public UploadFrom getUploadFrom() {
+               return UploadFrom.valueOf(getField("UploadFrom"));
+       }
+
+       /**
+        * Returns the target URI of the request.
+        *
+        * @return The target URI of the request
+        */
+       public String getURI() {
+               return getField("URI");
+       }
+
+       /**
+        * Returns the verbosity of the request.
+        *
+        * @return The verbosity of the request
+        */
+       public Verbosity getVerbosity() {
+               return Verbosity.valueOf(getField("Verbosity"));
+       }
+
+}
diff --git a/src/main/java/net/pterodactylus/fcp/PersistentPutDir.java b/src/main/java/net/pterodactylus/fcp/PersistentPutDir.java
new file mode 100644 (file)
index 0000000..47c3d8d
--- /dev/null
@@ -0,0 +1,170 @@
+/*
+ * jFCPlib - PersistentPutDir.java - Copyright © 2008 David Roden
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+package net.pterodactylus.fcp;
+
+/**
+ * A “PersistentPutDir” is the response to a {@link ClientPutDiskDir} message.
+ * It is also sent as a possible response to a {@link ListPersistentRequests}
+ * message.
+ *
+ * @author David ‘Bombe’ Roden &lt;bombe@freenetproject.org&gt;
+ */
+public class PersistentPutDir extends BaseMessage {
+
+       /**
+        * Creates a new “PersistentPutDir” message that wraps the received message.
+        *
+        * @param receivedMessage
+        *            The received message
+        */
+       PersistentPutDir(FcpMessage receivedMessage) {
+               super(receivedMessage);
+       }
+
+       /**
+        * Returns the identifier of the request.
+        *
+        * @return The identifier of the request
+        */
+       public String getIdentifier() {
+               return getField("Identifier");
+       }
+
+       /**
+        * Returns the URI of the request.
+        *
+        * @return The URI of the request
+        */
+       public String getURI() {
+               return getField("URI");
+       }
+
+       /**
+        * Returns the verbosity of the request.
+        *
+        * @return The verbosity of the request
+        */
+       public Verbosity getVerbosity() {
+               return Verbosity.valueOf(getField("Verbosity"));
+       }
+
+       /**
+        * Returns the priority of the request.
+        *
+        * @return The priority of the request
+        */
+       public Priority getPriority() {
+               return Priority.values()[FcpUtils.safeParseInt(getField("PriorityClass"), Priority.unknown.ordinal())];
+       }
+
+       /**
+        * Returns whether the request is on the global queue.
+        *
+        * @return <code>true</code> if the request is on the global queue,
+        *         <code>false</code> if it is on the client-local queue
+        */
+       public boolean isGlobal() {
+               return Boolean.valueOf(getField("Global"));
+       }
+
+       /**
+        * Returns the maximum number of retries for failed blocks.
+        *
+        * @return The maximum number of retries, or <code>-1</code> for endless
+        *         retries, or <code>-2</code> if the number could not be parsed
+        */
+       public int getMaxRetries() {
+               return FcpUtils.safeParseInt(getField("MaxRetries"), -2);
+       }
+
+       /**
+        * Returns the number of files in the request.
+        *
+        * @return The number of files in the request
+        */
+       public int getFileCount() {
+               int fileCount = -1;
+               while (getField("Files." + ++fileCount + ".UploadFrom") != null) {
+                       /* do nothing. */
+               }
+               return fileCount;
+       }
+
+       /**
+        * Returns the name of the file at the given index. The index is counted
+        * from <code>0</code>.
+        *
+        * @param fileIndex
+        *            The index of the file
+        * @return The name of the file at the given index
+        */
+       public String getFileName(int fileIndex) {
+               return getField("Files." + fileIndex + ".Name");
+       }
+
+       /**
+        * Returns the length of the file at the given index. The index is counted
+        * from <code>0</code>.
+        *
+        * @param fileIndex
+        *            The index of the file
+        * @return The length of the file at the given index
+        */
+       public long getFileDataLength(int fileIndex) {
+               return FcpUtils.safeParseLong(getField("Files." + fileIndex + ".DataLength"));
+       }
+
+       /**
+        * Returns the upload source of the file at the given index. The index is
+        * counted from <code>0</code>.
+        *
+        * @param fileIndex
+        *            The index of the file
+        * @return The upload source of the file at the given index
+        */
+       public UploadFrom getFileUploadFrom(int fileIndex) {
+               return UploadFrom.valueOf(getField("Files." + fileIndex + ".UploadFrom"));
+       }
+
+       /**
+        * Returns the content type of the file at the given index. The index is
+        * counted from <code>0</code>.
+        *
+        * @param fileIndex
+        *            The index of the file
+        * @return The content type of the file at the given index
+        */
+       public String getFileMetadataContentType(int fileIndex) {
+               return getField("Files." + fileIndex + ".Metadata.ContentType");
+       }
+
+       /**
+        * Returns the filename of the file at the given index. This value is only
+        * returned if {@link #getFileUploadFrom(int)} is returning
+        * {@link UploadFrom#disk}. The index is counted from <code>0</code>.
+        *
+        * @param fileIndex
+        *            The index of the file
+        * @return The filename of the file at the given index
+        */
+       public String getFileFilename(int fileIndex) {
+               return getField("Files." + fileIndex + ".Filename");
+       }
+
+}
diff --git a/src/main/java/net/pterodactylus/fcp/PersistentRequestModified.java b/src/main/java/net/pterodactylus/fcp/PersistentRequestModified.java
new file mode 100644 (file)
index 0000000..ea8d1ac
--- /dev/null
@@ -0,0 +1,79 @@
+/*
+ * jFCPlib - PersistentRequestModified.java - Copyright © 2008 David Roden
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+package net.pterodactylus.fcp;
+
+/**
+ * The “PersistentRequestModified” message is a reply to
+ * {@link ModifyPersistentRequest}.
+ *
+ * @author David ‘Bombe’ Roden &lt;bombe@freenetproject.org&gt;
+ */
+public class PersistentRequestModified extends BaseMessage {
+
+       /**
+        * Creates a new “PersistentRequestModified” message that wraps the received
+        * message.
+        *
+        * @param receivedMessage
+        *            The received message
+        */
+       PersistentRequestModified(FcpMessage receivedMessage) {
+               super(receivedMessage);
+       }
+
+       /**
+        * Returns the identifier of the changed request.
+        *
+        * @return The identifier of the request
+        */
+       public String getIdentifier() {
+               return getField("Identifier");
+       }
+
+       /**
+        * Returns whether the request is on the global queue.
+        *
+        * @return <code>true</code> if the request is on the global queue,
+        *         <code>false</code> if it is on a client-local queue
+        */
+       public boolean isGlobal() {
+               return Boolean.valueOf(getField("Global"));
+       }
+
+       /**
+        * Returns the client token, if it was changed.
+        *
+        * @return The new client token, or <code>null</code> if the client token
+        *         was not changed
+        */
+       public String getClientToken() {
+               return getField("ClientToken");
+       }
+
+       /**
+        * Returns the priority of the request, if it was changed.
+        *
+        * @return The new priority of the request, or {@link Priority#unknown} if
+        *         the priority was not changed
+        */
+       public Priority getPriority() {
+               return Priority.values()[FcpUtils.safeParseInt(getField("PriorityClass"), Priority.unknown.ordinal())];
+       }
+
+}
diff --git a/src/main/java/net/pterodactylus/fcp/PersistentRequestRemoved.java b/src/main/java/net/pterodactylus/fcp/PersistentRequestRemoved.java
new file mode 100644 (file)
index 0000000..154c88c
--- /dev/null
@@ -0,0 +1,60 @@
+/*
+ * jFCPlib - PersistentRequestRemoved.java - Copyright © 2008 David Roden
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+package net.pterodactylus.fcp;
+
+/**
+ * A “PersistentRequestRemoved” message signals that a persistent request was
+ * removed from either the global or the client-local queue.
+ *
+ * @author David ‘Bombe’ Roden &lt;bombe@freenetproject.org&gt;
+ */
+public class PersistentRequestRemoved extends BaseMessage {
+
+       /**
+        * Creates a new “PersistentRequestRemoved” message that wraps the received
+        * message.
+        *
+        * @param receivedMessage
+        *            The received message
+        */
+       PersistentRequestRemoved(FcpMessage receivedMessage) {
+               super(receivedMessage);
+       }
+
+       /**
+        * Returns the identifier of the request.
+        *
+        * @return The identifier of the request
+        */
+       public String getIdentifier() {
+               return getField("Identifier");
+       }
+
+       /**
+        * Returns whether the request was removed from the global queue.
+        *
+        * @return <code>true</code> if the request was removed from the global
+        *         queue, <code>false</code> if it was removed from the client-local
+        *         queue
+        */
+       public boolean isGlobal() {
+               return Boolean.valueOf(getField("Global"));
+       }
+
+}
diff --git a/src/main/java/net/pterodactylus/fcp/PluginInfo.java b/src/main/java/net/pterodactylus/fcp/PluginInfo.java
new file mode 100644 (file)
index 0000000..84ddaea
--- /dev/null
@@ -0,0 +1,75 @@
+/*
+ * jFCPlib - PluginInfo.java - Copyright © 2008 David Roden
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+package net.pterodactylus.fcp;
+
+/**
+ * The “PluginInfo” message is a reply to the {@link GetPluginInfo} request.
+ *
+ * @author David ‘Bombe’ Roden &lt;bombe@freenetproject.org&gt;
+ */
+public class PluginInfo extends BaseMessage {
+
+       /**
+        * Creates a new “PluginInfo” message that wraps the received message.
+        *
+        * @param receivedMessage
+        *            The received message
+        */
+       PluginInfo(FcpMessage receivedMessage) {
+               super(receivedMessage);
+       }
+
+       /**
+        * Returns the name of the plugin.
+        *
+        * @return The name of the plugin
+        */
+       public String getPluginName() {
+               return getField("PluginName");
+       }
+
+       /**
+        * Returns the identifier of the request.
+        *
+        * @return The identifier of the request
+        */
+       public String getIdentifier() {
+               return getField("Identifier");
+       }
+
+       /**
+        * Returns the original URI of the plugin.
+        *
+        * @return The original URI of the plugin
+        */
+       public String getOriginalURI() {
+               return getField("OriginalUri");
+       }
+
+       /**
+        * Returns whether the plugin is started.
+        *
+        * @return <code>true</code> if the plugin is started, <code>false</code>
+        *         otherwise
+        */
+       public boolean isStarted() {
+               return Boolean.valueOf("Started");
+       }
+
+}
diff --git a/src/main/java/net/pterodactylus/fcp/Priority.java b/src/main/java/net/pterodactylus/fcp/Priority.java
new file mode 100644 (file)
index 0000000..45560db
--- /dev/null
@@ -0,0 +1,60 @@
+/*
+ * jFCPlib - Priority.java - Copyright © 2008 David Roden
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+package net.pterodactylus.fcp;
+
+/**
+ * The priority classes used by the Freenet node.
+ *
+ * @author David ‘Bombe’ Roden &lt;bombe@freenetproject.org&gt;
+ */
+public enum Priority {
+
+       /** Maximum priority. */
+       maximum,
+
+       /** Priority for interactive request, i.e. FProxy. */
+       interactive,
+
+       /** Priority for splitfile manifests. */
+       immediateSplitfile,
+
+       /** Priority for USK searches. */
+       update,
+
+       /** Priority for splitfile blocks. */
+       bulkSplitfile,
+
+       /** Priority for prefetching blocks. */
+       prefetch,
+
+       /** Minimum priority. */
+       minimum,
+
+       /** Unknown priority. */
+       unknown;
+
+       /**
+        * @see java.lang.Enum#toString()
+        */
+       @Override
+       public String toString() {
+               return String.valueOf(ordinal());
+       }
+
+}
diff --git a/src/main/java/net/pterodactylus/fcp/ProtocolError.java b/src/main/java/net/pterodactylus/fcp/ProtocolError.java
new file mode 100644 (file)
index 0000000..f59d1fe
--- /dev/null
@@ -0,0 +1,96 @@
+/*
+ * jFCPlib - ProtocolError.java - Copyright © 2008 David Roden
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+package net.pterodactylus.fcp;
+
+/**
+ * The “ProtocolError” message signals that something has gone really wrong.
+ *
+ * @author David ‘Bombe’ Roden &lt;bombe@freenetproject.org&gt;
+ */
+public class ProtocolError extends BaseMessage {
+
+       /**
+        * Creates a new “ProtocolError” message that wraps the received message.
+        *
+        * @param receivedMessage
+        *            The received message
+        */
+       ProtocolError(FcpMessage receivedMessage) {
+               super(receivedMessage);
+       }
+
+       /**
+        * Returns whether the causing message had the “Global” flag set.
+        *
+        * @return <code>true</code> if the causing message had the “Global” flag
+        *         set
+        */
+       public boolean isGlobal() {
+               return Boolean.valueOf(getField("Global"));
+       }
+
+       /**
+        * Returns the error code.
+        *
+        * @return The error code, or <code>-1</code> if the error code could not be
+        *         parsed
+        */
+       public int getCode() {
+               return FcpUtils.safeParseInt(getField("Code"));
+       }
+
+       /**
+        * Returns the description of the error.
+        *
+        * @return The description of the error
+        */
+       public String getCodeDescription() {
+               return getField("CodeDescription");
+       }
+
+       /**
+        * Returns some extra description of the error.
+        *
+        * @return Extra description of the error, or <code>null</code> if there is
+        *         none
+        */
+       public String getExtraDescription() {
+               return getField("ExtraDescription");
+       }
+
+       /**
+        * Returns whether the connection to the node can stay open.
+        *
+        * @return <code>true</code> when the connection has to be closed,
+        *         <code>false</code> otherwise
+        */
+       public boolean isFatal() {
+               return Boolean.valueOf(getField("Fatal"));
+       }
+
+       /**
+        * The identifier of the causing request, if any.
+        *
+        * @return The identifier of the causing request
+        */
+       public String getIdentifier() {
+               return getField("Identifier");
+       }
+
+}
diff --git a/src/main/java/net/pterodactylus/fcp/PutFailed.java b/src/main/java/net/pterodactylus/fcp/PutFailed.java
new file mode 100644 (file)
index 0000000..b6916f4
--- /dev/null
@@ -0,0 +1,176 @@
+/*
+ * jFCPlib - GetFailed.java - Copyright © 2008 David Roden
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+package net.pterodactylus.fcp;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+import java.util.Map.Entry;
+
+/**
+ * The “PutFailed” message signals the client that a {@link ClientPut} request
+ * has failed. This also means that no further progress messages for that
+ * request will be sent.
+ *
+ * @author David ‘Bombe’ Roden &lt;bombe@freenetproject.org&gt;
+ */
+public class PutFailed extends BaseMessage {
+
+       /**
+        * Creates a new “PutFailed” message that wraps the received message.
+        *
+        * @param receivedMessage
+        *            The received message
+        */
+       PutFailed(FcpMessage receivedMessage) {
+               super(receivedMessage);
+       }
+
+       /**
+        * Returns the code of the error.
+        *
+        * @return The code of the error, or <code>-1</code> if the error code could
+        *         not be parsed
+        */
+       public int getCode() {
+               return FcpUtils.safeParseInt(getField("Code"));
+       }
+
+       /**
+        * Returns the identifier of the request.
+        *
+        * @return The identifier of the request
+        */
+       public String getIdentifier() {
+               return getField("Identifier");
+       }
+
+       /**
+        * Returns whether the request is on the global queue.
+        *
+        * @return <code>true</code> if the request is on the global queue,
+        *         <code>false</code> if it is on the client-local queue
+        */
+       public boolean isGlobal() {
+               return Boolean.valueOf(getField("Global"));
+       }
+
+       /**
+        * Returns the description of the error code.
+        *
+        * @return The description of the error code
+        */
+       public String getCodeDescription() {
+               return getField("CodeDescription");
+       }
+
+       /**
+        * Returns the extra description of the error.
+        *
+        * @return The extra description of the error
+        */
+       public String getExtraDescription() {
+               return getField("ExtraDescription");
+       }
+
+       /**
+        * Returns the short description of the error.
+        *
+        * @return The short description of the error
+        */
+       public String getShortCodeDescription() {
+               return getField("ShortCodeDescription");
+       }
+
+       /**
+        * Returns the expected URI of the request.
+        *
+        * @return The expected URI
+        */
+       public String getExpectedURI() {
+               return getField("ExpectedURI");
+       }
+
+       /**
+        * Returns whether the request failed fatally. If a request fails fatally it
+        * can never complete, even with inifinite retries.
+        *
+        * @return <code>true</code> if the request failed fatally,
+        *         <code>false</code> otherwise
+        */
+       public boolean isFatal() {
+               return Boolean.valueOf(getField("Fatal"));
+       }
+
+       /**
+        * Returns a list of complex error codes with the message. Use
+        * {@link #getComplexErrorDescription(int)} and
+        * {@link #getComplexErrorCount(int)} to get details.
+        *
+        * @return A list of complex error codes
+        */
+       public int[] getComplexErrorCodes() {
+               Map<String, String> allFields = getFields();
+               List<Integer> errorCodeList = new ArrayList<Integer>();
+               for (Entry<String, String> field : allFields.entrySet()) {
+                       String fieldKey = field.getKey();
+                       if (fieldKey.startsWith("Errors.")) {
+                               int nextDot = fieldKey.indexOf('.', 7);
+                               if (nextDot > -1) {
+                                       int errorCode = FcpUtils.safeParseInt(fieldKey.substring(7, nextDot));
+                                       if (errorCode != -1) {
+                                               errorCodeList.add(errorCode);
+                                       }
+                               }
+                       }
+               }
+               int[] errorCodes = new int[errorCodeList.size()];
+               int errorIndex = 0;
+               for (int errorCode : errorCodeList) {
+                       errorCodes[errorIndex++] = errorCode;
+               }
+               return errorCodes;
+       }
+
+       /**
+        * Returns the description of the complex error. You should only hand it
+        * error codes you got from {@link #getComplexErrorCodes()}!
+        *
+        * @param errorCode
+        *            The error code
+        * @return The description of the complex error
+        */
+       public String getComplexErrorDescription(int errorCode) {
+               return getField("Errors." + errorCode + ".Description");
+       }
+
+       /**
+        * Returns the count of the complex error. You should only hand it error
+        * codes you got from {@link #getComplexErrorCodes()}!
+        *
+        * @param errorCode
+        *            The error code
+        * @return The count of the complex error, or <code>-1</code> if the count
+        *         could not be parsed
+        */
+       public int getComplexErrorCount(int errorCode) {
+               return FcpUtils.safeParseInt(getField("Errors." + errorCode + ".Count"));
+       }
+
+}
diff --git a/src/main/java/net/pterodactylus/fcp/PutFetchable.java b/src/main/java/net/pterodactylus/fcp/PutFetchable.java
new file mode 100644 (file)
index 0000000..0c4e941
--- /dev/null
@@ -0,0 +1,68 @@
+/*
+ * jFCPlib - PutFetchable.java - Copyright © 2008 David Roden
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+package net.pterodactylus.fcp;
+
+/**
+ * The “PutFetchable” message informs a client that a {@link ClientPut} request
+ * has progressed far enough that the resulting final URI might already be
+ * fetchable.
+ *
+ * @author David ‘Bombe’ Roden &lt;bombe@freenetproject.org&gt;
+ */
+public class PutFetchable extends BaseMessage {
+
+       /**
+        * Creates a new “PutFetchable” message that wraps the received message.
+        *
+        * @param receivedMessage
+        *            The received message
+        */
+       PutFetchable(FcpMessage receivedMessage) {
+               super(receivedMessage);
+       }
+
+       /**
+        * Returns the identifier of the request.
+        *
+        * @return The identifier of the request
+        */
+       public String getIdentifier() {
+               return getField("Identifier");
+       }
+
+       /**
+        * Returns whether the request is on the global queue.
+        *
+        * @return <code>true</code> if the request is on the global queue,
+        *         <code>false</code> if it is on the client-local queue
+        */
+       public boolean isGlobal() {
+               return Boolean.valueOf(getField("Global"));
+       }
+
+       /**
+        * Returns the URI of the request.
+        *
+        * @return The URI of the request
+        */
+       public String getURI() {
+               return getField("URI");
+       }
+
+}
diff --git a/src/main/java/net/pterodactylus/fcp/PutSuccessful.java b/src/main/java/net/pterodactylus/fcp/PutSuccessful.java
new file mode 100644 (file)
index 0000000..cea36ee
--- /dev/null
@@ -0,0 +1,87 @@
+/*
+ * jFCPlib - PutSuccessful.java - Copyright © 2008 David Roden
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+package net.pterodactylus.fcp;
+
+/**
+ * The “PutSuccessful” message informs a client about a successfully finished
+ * {@link ClientPut} (or similar) request.
+ *
+ * @author David ‘Bombe’ Roden &lt;bombe@freenetproject.org&gt;
+ */
+public class PutSuccessful extends BaseMessage {
+
+       /**
+        * Creates a new “PutSuccessful” message that wraps the received message.
+        *
+        * @param receivedMessage
+        *            The received message
+        */
+       PutSuccessful(FcpMessage receivedMessage) {
+               super(receivedMessage);
+       }
+
+       /**
+        * Returns the identifier of the request.
+        *
+        * @return The identifier of the request
+        */
+       public String getIdentifier() {
+               return getField("Identifier");
+       }
+
+       /**
+        * Returns whether the request is on the global queue.
+        *
+        * @return <code>true</code> if the request is on the global queue,
+        *         <code>false</code> if it is on the client-local queue
+        */
+       public boolean isGlobal() {
+               return Boolean.valueOf(getField("Global"));
+       }
+
+       /**
+        * Returns the final URI of the {@link ClientPut} request.
+        *
+        * @return The final URI of the request
+        */
+       public String getURI() {
+               return getField("URI");
+       }
+
+       /**
+        * Returns the time the insert started.
+        *
+        * @return The time the insert started (in milliseconds since Jan 1, 1970
+        *         UTC), or <code>-1</code> if the time could not be parsed
+        */
+       public long getStartupTime() {
+               return FcpUtils.safeParseLong(getField("StartupTime"));
+       }
+
+       /**
+        * Returns the time the insert completed.
+        *
+        * @return The time the insert completed (in milliseconds since Jan 1, 1970
+        *         UTC), or <code>-1</code> if the time could not be parsed
+        */
+       public long getCompletionTime() {
+               return FcpUtils.safeParseLong(getField("CompletionTime"));
+       }
+
+}
diff --git a/src/main/java/net/pterodactylus/fcp/ReceivedBookmarkFeed.java b/src/main/java/net/pterodactylus/fcp/ReceivedBookmarkFeed.java
new file mode 100644 (file)
index 0000000..02369f0
--- /dev/null
@@ -0,0 +1,78 @@
+/*
+ * jFCPlib - ReceivedBookmarkFeed.java - Copyright © 2009 David Roden
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+package net.pterodactylus.fcp;
+
+/**
+ * Implementation of the “ReceivedBookmarkFeed” FCP message. This message
+ * notifies an FCP client that an update for a bookmark has been found.
+ *
+ * @author David ‘Bombe’ Roden &lt;bombe@freenetproject.org&gt;
+ */
+public class ReceivedBookmarkFeed extends BaseMessage {
+
+       /**
+        * Creates a new “ReceivedBookmarkFeed” message.
+        *
+        * @param fcpMessage
+        *            The FCP message to get the fields from
+        */
+       public ReceivedBookmarkFeed(FcpMessage fcpMessage) {
+               super(fcpMessage);
+       }
+
+       /**
+        * Returns the name of the bookmark.
+        *
+        * @return The bookmark’s name
+        */
+       public String getBookmarkName() {
+               return getField("Name");
+       }
+
+       /**
+        * Returns the URI of the updated bookmark.
+        *
+        * @return The bookmark’s URI
+        */
+       public String getURI() {
+               return getField("URI");
+       }
+
+       /**
+        * Returns whether the bookmark has an active link image.
+        *
+        * @return {@code true} if the bookmark has an active link image, {@code
+        *         false} otherwise
+        */
+       public boolean hasActiveLink() {
+               return Boolean.parseBoolean(getField("HasAnActiveLink"));
+       }
+
+       /**
+        * Returns the description of the bookmark. Note that the description may be
+        * {@code null} and if it is not, it is base64-encoded!
+        *
+        * @return The bookmark’s description, or {@code null} if the bookmark has
+        *         no description
+        */
+       public String getDescription() {
+               return getField("Description");
+       }
+
+}
diff --git a/src/main/java/net/pterodactylus/fcp/RemovePeer.java b/src/main/java/net/pterodactylus/fcp/RemovePeer.java
new file mode 100644 (file)
index 0000000..5eae728
--- /dev/null
@@ -0,0 +1,40 @@
+/*
+ * jFCPlib - RemovePeer.java - Copyright © 2008 David Roden
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+package net.pterodactylus.fcp;
+
+/**
+ * The “RemovePeer” command removes a peer.
+ *
+ * @author David ‘Bombe’ Roden &lt;bombe@freenetproject.org&gt;
+ */
+public class RemovePeer extends FcpMessage {
+
+       /**
+        * Creates a new “RemovePeer” command that removes the given peer.
+        *
+        * @param nodeIdentifier
+        *            The identifier of the node, i.e. its name, identity, or IP
+        *            address and port pair
+        */
+       public RemovePeer(String nodeIdentifier) {
+               super("RemovePeer");
+               setField("NodeIdentifier", nodeIdentifier);
+       }
+
+}
diff --git a/src/main/java/net/pterodactylus/fcp/RemovePersistentRequest.java b/src/main/java/net/pterodactylus/fcp/RemovePersistentRequest.java
new file mode 100644 (file)
index 0000000..e5686b9
--- /dev/null
@@ -0,0 +1,52 @@
+/*
+ * jFCPlib - RemovePersistentRequest.java - Copyright © 2008 David Roden
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+package net.pterodactylus.fcp;
+
+/**
+ * The “RemovePersistentRequest” message tells the node to remove a persistent
+ * request, cancelling it first (resulting in a {@link GetFailed} or
+ * {@link PutFailed} message), if necessary.
+ *
+ * @author David ‘Bombe’ Roden &lt;bombe@freenetproject.org&gt;
+ */
+public class RemovePersistentRequest extends FcpMessage {
+
+       /**
+        * Creates a new “RemovePersistentRequest” message.
+        *
+        * @param identifier
+        *            The identifier of the request
+        */
+       public RemovePersistentRequest(String identifier) {
+               super("RemovePersistentRequest");
+               setField("Identifier", identifier);
+       }
+
+       /**
+        * Sets whether the request is on the global queue.
+        *
+        * @param global
+        *            <code>true</code> if the request is on the global queue,
+        *            <code>false</code> if it is on the client-local queue
+        */
+       public void setGlobal(boolean global) {
+               setField("Global", String.valueOf(global));
+       }
+
+}
diff --git a/src/main/java/net/pterodactylus/fcp/ReturnType.java b/src/main/java/net/pterodactylus/fcp/ReturnType.java
new file mode 100644 (file)
index 0000000..a3ffbcd
--- /dev/null
@@ -0,0 +1,40 @@
+/*
+ * jFCPlib - ReturnType.java - Copyright © 2008 David Roden
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+package net.pterodactylus.fcp;
+
+/**
+ * The different return types for {@link ClientGet} requests.
+ *
+ * @author David ‘Bombe’ Roden &lt;bombe@freenetproject.org&gt;
+ */
+public enum ReturnType {
+
+       /** Don't transfer the data at all. */
+       none,
+
+       /** Transfer the data directly after the message. */
+       direct,
+
+       /** Copy the data to disk. */
+       disk,
+
+       /** Unknown return type. */
+       unknown;
+
+}
diff --git a/src/main/java/net/pterodactylus/fcp/SSKKeypair.java b/src/main/java/net/pterodactylus/fcp/SSKKeypair.java
new file mode 100644 (file)
index 0000000..fd0b40a
--- /dev/null
@@ -0,0 +1,66 @@
+/*
+ * jFCPlib - SSKKeypair.java - Copyright © 2008 David Roden
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+package net.pterodactylus.fcp;
+
+/**
+ * An “SSKKeypair” message that is sent as a response to a {@link GenerateSSK}
+ * message.
+ *
+ * @author David ‘Bombe’ Roden &lt;bombe@freenetproject.org&gt;
+ */
+public class SSKKeypair extends BaseMessage {
+
+       /**
+        * Creates a new “SSKKeypair” message that wraps the received message.
+        *
+        * @param receivedMessage
+        *            The received message
+        */
+       SSKKeypair(FcpMessage receivedMessage) {
+               super(receivedMessage);
+       }
+
+       /**
+        * Returns the identifier of the request.
+        *
+        * @return The identifier of the request
+        */
+       public String getIdentifier() {
+               return getField("Identifier");
+       }
+
+       /**
+        * Returns the URI that must be used to insert data.
+        *
+        * @return The insert URI
+        */
+       public String getInsertURI() {
+               return getField("InsertURI");
+       }
+
+       /**
+        * Returns the URI that must be used to request data.
+        *
+        * @return The request URI
+        */
+       public String getRequestURI() {
+               return getField("RequestURI");
+       }
+
+}
diff --git a/src/main/java/net/pterodactylus/fcp/SendBookmarkFeed.java b/src/main/java/net/pterodactylus/fcp/SendBookmarkFeed.java
new file mode 100644 (file)
index 0000000..522e830
--- /dev/null
@@ -0,0 +1,53 @@
+/*
+ * jFCPlib - SendBookmarkFeed.java - Copyright © 2009 David Roden
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+package net.pterodactylus.fcp;
+
+/**
+ * The “SendBookmarkFeed” command sends a bookmark to a peer.
+ *
+ * @author David ‘Bombe’ Roden &lt;bombe@freenetproject.org&gt;
+ */
+public class SendBookmarkFeed extends AbstractSendFeedMessage {
+
+       /**
+        * Creates a new “SendBookmarkFeed” command.
+        *
+        * @param identifier
+        *            The identifier of the request
+        * @param nodeIdentifier
+        *            The identifier of the peer node
+        * @param name
+        *            The name of the bookmark
+        * @param uri
+        *            The URI of the bookmark
+        * @param description
+        *            The description of the bookmark (may be {@code null})
+        * @param hasActiveLink
+        *            {@code true} if the bookmark has an activelink image, {@code
+        *            false} otherwise
+        */
+       public SendBookmarkFeed(String identifier, String nodeIdentifier, String name, String uri, String description, boolean hasActiveLink) {
+               super("SendBookmarkFeed", identifier, nodeIdentifier);
+               setField("Name", name);
+               setField("URI", uri);
+               setField("Description", description);
+               setField("HasActiveLink", String.valueOf(hasActiveLink));
+       }
+
+}
diff --git a/src/main/java/net/pterodactylus/fcp/SendDownloadFeed.java b/src/main/java/net/pterodactylus/fcp/SendDownloadFeed.java
new file mode 100644 (file)
index 0000000..ccaa000
--- /dev/null
@@ -0,0 +1,47 @@
+/*
+ * jFCPlib - SendDownloadFeed.java - Copyright © 2009 David Roden
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+package net.pterodactylus.fcp;
+
+/**
+ * The “SendDownloadFeed” command sends information about a download to a peer
+ * node.
+ *
+ * @author David ‘Bombe’ Roden &lt;bombe@freenetproject.org&gt;
+ */
+public class SendDownloadFeed extends AbstractSendFeedMessage {
+
+       /**
+        * Creates a new “SendDownloadFeed” to a peer node.
+        *
+        * @param identifier
+        *            The identifier of the request
+        * @param nodeIdentifier
+        *            The identifier of the peer node
+        * @param uri
+        *            The URI of the download to send
+        * @param description
+        *            The description of the download (may be {@code null})
+        */
+       public SendDownloadFeed(String identifier, String nodeIdentifier, String uri, String description) {
+               super("SendDownloadFeed", identifier, nodeIdentifier);
+               setField("URI", uri);
+               setField("Description", description);
+       }
+
+}
diff --git a/src/main/java/net/pterodactylus/fcp/SendTextFeed.java b/src/main/java/net/pterodactylus/fcp/SendTextFeed.java
new file mode 100644 (file)
index 0000000..339324d
--- /dev/null
@@ -0,0 +1,43 @@
+/*
+ * jFCPlib - SendTextFeed.java - Copyright © 2009 David Roden
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+package net.pterodactylus.fcp;
+
+/**
+ * The “SendTextFeed” command sends an arbitrary text to a peer node.
+ *
+ * @author David ‘Bombe’ Roden &lt;bombe@freenetproject.org&gt;
+ */
+public class SendTextFeed extends AbstractSendFeedMessage {
+
+       /**
+        * Creates a new “SendTextFeed” command.
+        *
+        * @param identifier
+        *            The identifier of the request
+        * @param nodeIdentifier
+        *            The identifier of the peer node
+        * @param text
+        *            The text to send
+        */
+       public SendTextFeed(String identifier, String nodeIdentifier, String text) {
+               super("SendTextFeed", identifier, nodeIdentifier);
+               setField("Text", text);
+       }
+
+}
diff --git a/src/main/java/net/pterodactylus/fcp/SentFeed.java b/src/main/java/net/pterodactylus/fcp/SentFeed.java
new file mode 100644 (file)
index 0000000..eb7ca0a
--- /dev/null
@@ -0,0 +1,76 @@
+/*
+ * jFCPlib - SentFeed.java - Copyright © 2009 David Roden
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+package net.pterodactylus.fcp;
+
+/**
+ * The “SentFeed” message signals that a feed was successfully sent to a peer.
+ *
+ * @author David ‘Bombe’ Roden &lt;bombe@freenetproject.org&gt;
+ */
+public class SentFeed extends BaseMessage {
+
+       /**
+        * Creates a new “SentFeed” message from the given FCP message.
+        *
+        * @param fcpMessage
+        *            The FCP message containing the “SentFeed” message
+        */
+       public SentFeed(FcpMessage fcpMessage) {
+               super(fcpMessage);
+       }
+
+       /**
+        * Returns the identifier of the sent feed. The identifier of this message
+        * matches the identifier that was given when a {@link SendBookmarkFeed},
+        * {@link SendDownloadFeed}, or {@link SendTextFeed} command was created.
+        *
+        * @return The send feed’s identifier
+        */
+       public String getIdentifier() {
+               return getField("Identifier");
+       }
+
+       /**
+        * Returns the node status of the peer. The node status is definied in
+        * {@code freenet.node.PeerManager}.
+        * <p>
+        * <ol start="1">
+        * <li>Connected</li>
+        * <li>Backed off</li>
+        * <li>Version too new</li>
+        * <li>Version too old</li>
+        * <li>Disconnected</li>
+        * <li>Never connected</li>
+        * <li>Disabled</li>
+        * <li>Bursting</li>
+        * <li>Listening</li>
+        * <li>Listening only</li>
+        * <li>Clock problem</li>
+        * <li>Connection error</li>
+        * <li>Disconnecting</li>
+        * <li>Routing disabled</li>
+        * </ol>
+        *
+        * @return The node’s status
+        */
+       public int getNodeStatus() {
+               return FcpUtils.safeParseInt(getField("NodeStatus"));
+       }
+
+}
diff --git a/src/main/java/net/pterodactylus/fcp/Shutdown.java b/src/main/java/net/pterodactylus/fcp/Shutdown.java
new file mode 100644 (file)
index 0000000..3841c4d
--- /dev/null
@@ -0,0 +1,35 @@
+/*
+ * jFCPlib - Shutdown.java - Copyright © 2008 David Roden
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+package net.pterodactylus.fcp;
+
+/**
+ * Command that shuts down the node.
+ *
+ * @author David ‘Bombe’ Roden &lt;bombe@freenetproject.org&gt;
+ */
+public class Shutdown extends FcpMessage {
+
+       /**
+        * Creates a new “Shutdown” message.
+        */
+       public Shutdown() {
+               super("Shutdown");
+       }
+
+}
diff --git a/src/main/java/net/pterodactylus/fcp/SimpleProgress.java b/src/main/java/net/pterodactylus/fcp/SimpleProgress.java
new file mode 100644 (file)
index 0000000..4d93512
--- /dev/null
@@ -0,0 +1,111 @@
+/*
+ * jFCPlib - SimpleProgress.java - Copyright © 2008 David Roden
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+package net.pterodactylus.fcp;
+
+/**
+ * A “SimpleProgress” message tells the client about the progress of a
+ * {@link ClientGet} or {@link ClientPut} operation.
+ *
+ * @author David ‘Bombe’ Roden &lt;bombe@freenetproject.org&gt;
+ */
+public class SimpleProgress extends BaseMessage {
+
+       /**
+        * Creates a new “SimpleProgress” message that wraps the received message.
+        *
+        * @param receivedMessage
+        *            The received message
+        */
+       SimpleProgress(FcpMessage receivedMessage) {
+               super(receivedMessage);
+       }
+
+       /**
+        * Returns the total number of blocks. This number may increase as long as
+        * {@link #isFinalizedTotal()} returns <code>false</code>.
+        *
+        * @return The total number of blocks
+        */
+       public int getTotal() {
+               return FcpUtils.safeParseInt(getField("Total"));
+       }
+
+       /**
+        * Returns the number of blocks that are required to completet the request.
+        * This number might actually be lower than {@link #getTotal} because of
+        * redundancy information. This number may also increase as long as
+        * {@link #isFinalizedTotal()} returns <code>false</code>.
+        *
+        * @return The number of required blocks
+        */
+       public int getRequired() {
+               return FcpUtils.safeParseInt(getField("Required"));
+       }
+
+       /**
+        * Returns the number of blocks that have failed and run out of retries.
+        *
+        * @return The number of failed blocks
+        */
+       public int getFailed() {
+               return FcpUtils.safeParseInt(getField("Failed"));
+       }
+
+       /**
+        * Returns the number of fatally failed blocks. A block that failed fatally
+        * can never be completed, even with infinite retries.
+        *
+        * @return The number of fatally failed blocks
+        */
+       public int getFatallyFailed() {
+               return FcpUtils.safeParseInt(getField("FatallyFailed"));
+       }
+
+       /**
+        * Returns the number of blocks that have been successfully processed.
+        *
+        * @return The number of succeeded blocks
+        */
+       public int getSucceeded() {
+               return FcpUtils.safeParseInt(getField("Succeeded"));
+       }
+
+       /**
+        * Returns whether the total number of blocks (see {@link #getTotal()} has
+        * been finalized. Once the total number of blocks has been finalized for a
+        * request it will not change any more, and this method of every further
+        * SimpleProgress message will always return <code>true</code>.
+        *
+        * @return <code>true</code> if the number of total blocks has been
+        *         finalized, <code>false</code> otherwise
+        */
+       public boolean isFinalizedTotal() {
+               return Boolean.valueOf(getField("FinalizedTotal"));
+       }
+
+       /**
+        * Returns the identifier of the request.
+        *
+        * @return The identifier of the request
+        */
+       public String getIdentifier() {
+               return getField("Identifier");
+       }
+
+}
diff --git a/src/main/java/net/pterodactylus/fcp/StartedCompression.java b/src/main/java/net/pterodactylus/fcp/StartedCompression.java
new file mode 100644 (file)
index 0000000..a7c4fa2
--- /dev/null
@@ -0,0 +1,59 @@
+/*
+ * jFCPlib - StartedCompression.java - Copyright © 2008 David Roden
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+package net.pterodactylus.fcp;
+
+/**
+ * The “StartedCompression” message signals the client the compressing for a
+ * request has started.
+ *
+ * @author David ‘Bombe’ Roden &lt;bombe@freenetproject.org&gt;
+ */
+public class StartedCompression extends BaseMessage {
+
+       /**
+        * Creates a new “StartedCompression” message that wraps the received
+        * message.
+        *
+        * @param receivedMessage
+        *            The received message
+        */
+       StartedCompression(FcpMessage receivedMessage) {
+               super(receivedMessage);
+       }
+
+       /**
+        * Returns the identifier of the request.
+        *
+        * @return The identifier of the request
+        */
+       public String getIdentifier() {
+               return getField("Identifier");
+       }
+
+       /**
+        * Returns the number of the codec that is used for compression.
+        *
+        * @return The codec used for the compression, or <code>-1</code> if the
+        *         codec could not be parsed
+        */
+       public int getCodec() {
+               return FcpUtils.safeParseInt(getField("Codec"));
+       }
+
+}
diff --git a/src/main/java/net/pterodactylus/fcp/SubscribeFeeds.java b/src/main/java/net/pterodactylus/fcp/SubscribeFeeds.java
new file mode 100644 (file)
index 0000000..1f18620
--- /dev/null
@@ -0,0 +1,40 @@
+/*
+ * jFCPlib - SubscribeFeeds.java - Copyright © 2009 David Roden
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+package net.pterodactylus.fcp;
+
+/**
+ * The “SubscribeFeeds” command tells the node that the client is interested in
+ * receiving the feeds sent by peer nodes.
+ *
+ * @author David ‘Bombe’ Roden &lt;bombe@freenetproject.org&gt;
+ */
+public class SubscribeFeeds extends FcpMessage {
+
+       /**
+        * Creates a new “SubscribeFeeds” command.
+        *
+        * @param identifier
+        *            The identifier of the request
+        */
+       public SubscribeFeeds(String identifier) {
+               super("SubscribeFeeds");
+               setField("Identifier", identifier);
+       }
+
+}
diff --git a/src/main/java/net/pterodactylus/fcp/SubscribeUSK.java b/src/main/java/net/pterodactylus/fcp/SubscribeUSK.java
new file mode 100644 (file)
index 0000000..6a18333
--- /dev/null
@@ -0,0 +1,55 @@
+/*
+ * jFCPlib - SubscribeUSK.java - Copyright © 2008 David Roden
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+package net.pterodactylus.fcp;
+
+/**
+ * With a “SubscribeUSK” a client requests to be notified if the edition number
+ * of a USK changes.
+ *
+ * @author David ‘Bombe’ Roden &lt;bombe@freenetproject.org&gt;
+ */
+public class SubscribeUSK extends FcpMessage {
+
+       /**
+        * Creates a new “SubscribeUSK” message.
+        *
+        * @param uri
+        *            The URI to watch for changes
+        * @param identifier
+        *            The identifier of the request
+        */
+       public SubscribeUSK(String uri, String identifier) {
+               super("SubscribeUSK");
+               setField("URI", uri);
+               setField("Identifier", identifier);
+       }
+
+       /**
+        * Sets whether updates for the USK are actively searched.
+        *
+        * @param active
+        *            <code>true</code> to actively search for newer editions,
+        *            <code>false</code> to only watch for newer editions that are
+        *            found from other requests
+        */
+       public void setActive(boolean active) {
+               setField("DontPoll", String.valueOf(!active));
+       }
+
+}
diff --git a/src/main/java/net/pterodactylus/fcp/SubscribedUSKUpdate.java b/src/main/java/net/pterodactylus/fcp/SubscribedUSKUpdate.java
new file mode 100644 (file)
index 0000000..e616b5d
--- /dev/null
@@ -0,0 +1,70 @@
+/*
+ * jFCPlib - SubscribedUSKUpdate.java - Copyright © 2008 David Roden
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+package net.pterodactylus.fcp;
+
+/**
+ * A “SubscribedUSKUpdate” message is sent each time a new edition of a USK that
+ * was previously subscribed to with {@link SubscribeUSK} was found. Note that
+ * if the new edition that was found is several editions ahead of the currently
+ * last known edition, you will received a SubscribedUSKUpdate for each edition
+ * inbetween as welL!
+ *
+ * @author David ‘Bombe’ Roden &lt;bombe@freenetproject.org&gt;
+ */
+public class SubscribedUSKUpdate extends BaseMessage {
+
+       /**
+        * Creates a new “SubscribedUSKUpdate” message that wraps the received
+        * message.
+        *
+        * @param receivedMessage
+        *            The received message
+        */
+       SubscribedUSKUpdate(FcpMessage receivedMessage) {
+               super(receivedMessage);
+       }
+
+       /**
+        * Returns the identifier of the subscription.
+        *
+        * @return The identifier of the subscription
+        */
+       public String getIdentifier() {
+               return getField("Identifier");
+       }
+
+       /**
+        * Returns the new edition that was found.
+        *
+        * @return The new edition
+        */
+       public int getEdition() {
+               return FcpUtils.safeParseInt(getField("Edition"));
+       }
+
+       /**
+        * Returns the complete URI, including the new edition.
+        *
+        * @return The complete URI
+        */
+       public String getURI() {
+               return getField("URI");
+       }
+
+}
diff --git a/src/main/java/net/pterodactylus/fcp/TestDDAComplete.java b/src/main/java/net/pterodactylus/fcp/TestDDAComplete.java
new file mode 100644 (file)
index 0000000..bea91d9
--- /dev/null
@@ -0,0 +1,68 @@
+/*
+ * jFCPlib - TestDDAComplete.java - Copyright © 2008 David Roden
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+package net.pterodactylus.fcp;
+
+/**
+ * The “TestDDAComplete” message signals that the node has finished checking
+ * your read and write access to a certain directory.
+ *
+ * @author David ‘Bombe’ Roden &lt;bombe@freenetproject.org&gt;
+ */
+public class TestDDAComplete extends BaseMessage {
+
+       /**
+        * Creates a new “TestDDAComplete” message that wraps the received message.
+        *
+        * @param receivedMessage
+        *            The received message
+        */
+       TestDDAComplete(FcpMessage receivedMessage) {
+               super(receivedMessage);
+       }
+
+       /**
+        * Returns the directory the authorization is given for.
+        *
+        * @return The directory that was tested for read and/or write access
+        */
+       public String getDirectory() {
+               return getField("Directory");
+       }
+
+       /**
+        * Returns whether read access to the directory is allowed.
+        *
+        * @return <code>true</code> if the client is allowed to read from that
+        *         directory, <code>false</code> otherwise
+        */
+       public boolean isReadDirectoryAllowed() {
+               return Boolean.valueOf(getField("ReadDirectoryAllowed"));
+       }
+
+       /**
+        * Returns whether write access to the directory is allowed.
+        *
+        * @return <code>true</code> if the client is allowed to write into that
+        *         directory, <code>false</code> otherwise
+        */
+       public boolean isWriteDirectoryAllowed() {
+               return Boolean.valueOf(getField("WriteDirectoryAllowed"));
+       }
+
+}
diff --git a/src/main/java/net/pterodactylus/fcp/TestDDAReply.java b/src/main/java/net/pterodactylus/fcp/TestDDAReply.java
new file mode 100644 (file)
index 0000000..bf102d6
--- /dev/null
@@ -0,0 +1,82 @@
+/*
+ * jFCPlib - TestDDAReply.java - Copyright © 2008 David Roden
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+package net.pterodactylus.fcp;
+
+/**
+ * The “TestDDAReply” is sent as a response to {@link TestDDARequest}. If you
+ * specified that you wanted to read files from that directory
+ * {@link #getReadFilename()} will give you a filename. Similarly, if you
+ * specified that you want to write in the directory {@link #getWriteFilename()}
+ * will give you a filename to write {@link #getContentToWrite()} to.
+ *
+ * @author David ‘Bombe’ Roden &lt;bombe@freenetproject.org&gt;
+ */
+public class TestDDAReply extends BaseMessage {
+
+       /**
+        * Creates a “TestDDAReply” message that wraps the received message.
+        *
+        * @param receivedMessage
+        *            The received message
+        */
+       TestDDAReply(FcpMessage receivedMessage) {
+               super(receivedMessage);
+       }
+
+       /**
+        * Returns the directory the TestDDRequest was made for.
+        *
+        * @return The directory to test
+        */
+       public String getDirectory() {
+               return getField("Directory");
+       }
+
+       /**
+        * Returns the filename you have to read to proof your ability to read that
+        * specific directory.
+        *
+        * @return The name of the file to read
+        */
+       public String getReadFilename() {
+               return getField("ReadFilename");
+       }
+
+       /**
+        * Returns the filename you have to write to to proof your ability to write
+        * to that specific directory.
+        *
+        * @return The name of the file write to
+        */
+       public String getWriteFilename() {
+               return getField("WriteFilename");
+       }
+
+       /**
+        * If you requested a test for writing permissions you have to write the
+        * return value of this method to the file given by
+        * {@link #getWriteFilename()}.
+        *
+        * @return The content to write to the file
+        */
+       public String getContentToWrite() {
+               return getField("ContentToWrite");
+       }
+
+}
diff --git a/src/main/java/net/pterodactylus/fcp/TestDDARequest.java b/src/main/java/net/pterodactylus/fcp/TestDDARequest.java
new file mode 100644 (file)
index 0000000..89a0202
--- /dev/null
@@ -0,0 +1,45 @@
+/*
+ * jFCPlib - TestDDARequest.java - Copyright © 2008 David Roden
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+package net.pterodactylus.fcp;
+
+/**
+ * The “TestDDARequest” initiates a DDA test sequence.
+ *
+ * @author David ‘Bombe’ Roden &lt;bombe@freenetproject.org&gt;
+ */
+public class TestDDARequest extends FcpMessage {
+
+       /**
+        * Creates a new “TestDDARequest” command that initiates a DDA test.
+        *
+        * @param directory
+        *            The directory you want to access files in
+        * @param wantReadDirectory
+        *            <code>true</code> if you want to read files from the directory
+        * @param wantWriteDirectory
+        *            <code>true</code> if you want to write files to the directory
+        */
+       public TestDDARequest(String directory, boolean wantReadDirectory, boolean wantWriteDirectory) {
+               super("TestDDARequest");
+               setField("Directory", directory);
+               setField("WantReadDirectory", String.valueOf(wantReadDirectory));
+               setField("WantWriteDirectory", String.valueOf(wantWriteDirectory));
+       }
+
+}
diff --git a/src/main/java/net/pterodactylus/fcp/TestDDAResponse.java b/src/main/java/net/pterodactylus/fcp/TestDDAResponse.java
new file mode 100644 (file)
index 0000000..76660c5
--- /dev/null
@@ -0,0 +1,63 @@
+/*
+ * jFCPlib - TestDDAResponse.java - Copyright © 2008 David Roden
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+package net.pterodactylus.fcp;
+
+/**
+ * A “TestDDAResponse” is sent to let the node know that either created a file
+ * with the content from {@link TestDDAReply#getContentToWrite()} or that you
+ * read the content of the file given by {@link TestDDAReply#getReadFilename()}.
+ *
+ * @author David ‘Bombe’ Roden &lt;bombe@freenetproject.org&gt;
+ */
+public class TestDDAResponse extends FcpMessage {
+
+       /**
+        * Creates a new “TestDDAResponse” message that signals that you created the
+        * file given by {@link TestDDAReply#getWriteFilename()} and wrote the
+        * contents given by {@link TestDDAReply#getContentToWrite()} to it.
+        *
+        * @param directory
+        *            The directory from the {@link TestDDARequest} command
+        */
+       public TestDDAResponse(String directory) {
+               this(directory, null);
+       }
+
+       /**
+        * Creates a new “TestDDAResponse” message that signals that you created the
+        * file given by {@link TestDDAReply#getWriteFilename()} with the contents
+        * given by {@link TestDDAReply#getContentToWrite()} to it (when you
+        * specified that you want to write to the directory) and/or that you read
+        * the file given by {@link TestDDAReply#getReadFilename()} (when you
+        * specified you wanted to read the directory).
+        *
+        * @param directory
+        *            The directory from the {@link TestDDARequest} command
+        * @param readContent
+        *            The read content, or <code>null</code> if you did not request
+        *            read access
+        */
+       public TestDDAResponse(String directory, String readContent) {
+               super("TestDDAResponse");
+               if (readContent != null) {
+                       setField("ReadContent", readContent);
+               }
+       }
+
+}
diff --git a/src/main/java/net/pterodactylus/fcp/URIGenerated.java b/src/main/java/net/pterodactylus/fcp/URIGenerated.java
new file mode 100644 (file)
index 0000000..06d3888
--- /dev/null
@@ -0,0 +1,69 @@
+/*
+ * jFCPlib - URIGenerated.java - Copyright © 2008 David Roden
+ *
+ * This program is free software; you can redistribute it and/or modify it under
+ * the terms of the GNU General Public License as published by the Free Software
+ * Foundation; either version 2 of the License, or (at your option) any later
+ * version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+ * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
+ * details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc., 59 Temple
+ * Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+package net.pterodactylus.fcp;
+
+/**
+ * The “URIGenerated” message signals the client that an URI was generated for a
+ * {@link ClientPut} (or {@link ClientPutDiskDir} or {@link ClientPutComplexDir}
+ * ) request.
+ *
+ * @author David ‘Bombe’ Roden &lt;bombe@freenetproject.org&gt;
+ */
+public class URIGenerated extends BaseMessage {
+
+       /**
+        * Creates a new “URIGenerated” message that wraps the received message.
+        *
+        * @param receivedMessage
+        *            The received message
+        */
+       URIGenerated(FcpMessage receivedMessage) {
+               super(receivedMessage);
+       }
+
+       /**
+        * Returns the identifier of the request that generated an URI.
+        *
+        * @return The identifier of the request
+        */
+       public String getIdentifier() {
+               return getField("Identifier");
+       }
+
+       /**
+        * Returns the URI that was generated by the request.
+        *
+        * @return The URI that was generated by the request
+        */
+       public String getURI() {
+               return getField("URI");
+       }
+
+       /**
+        * Returns whether the request that generated the URI is on the global queue
+        * or on the client-local queue.
+        *
+        * @return <code>true</code> if the request is on the global queue,
+        *         <code>false</code> if it is on the client-local queue
+        */
+       public boolean isGlobal() {
+               return Boolean.parseBoolean(getField("Global"));
+       }
+
+}
diff --git a/src/main/java/net/pterodactylus/fcp/UnknownNodeIdentifier.java b/src/main/java/net/pterodactylus/fcp/UnknownNodeIdentifier.java
new file mode 100644 (file)
index 0000000..af7b2f5
--- /dev/null
@@ -0,0 +1,49 @@
+/*
+ * jFCPlib - UnknownNodeIdentifier.java - Copyright © 2008 David Roden
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+package net.pterodactylus.fcp;
+
+/**
+ * The “UnknownNodeIdentifier” message signals the client that the node
+ * identifier given in a command like {@link ListPeer} is unknown.
+ *
+ * @author David ‘Bombe’ Roden &lt;bombe@freenetproject.org&gt;
+ */
+public class UnknownNodeIdentifier extends BaseMessage {
+
+       /**
+        * Creates a new “UnknownNodeIdentifier” message that wraps the received
+        * message.
+        *
+        * @param receivedMessage
+        *            The received message
+        */
+       UnknownNodeIdentifier(FcpMessage receivedMessage) {
+               super(receivedMessage);
+       }
+
+       /**
+        * Returns the unknown node identifier.
+        *
+        * @return The unknown node identifier
+        */
+       public String getNodeIdentifier() {
+               return getField("NodeIdentifier");
+       }
+
+}
diff --git a/src/main/java/net/pterodactylus/fcp/UnknownPeerNoteType.java b/src/main/java/net/pterodactylus/fcp/UnknownPeerNoteType.java
new file mode 100644 (file)
index 0000000..b36c4ee
--- /dev/null
@@ -0,0 +1,49 @@
+/*
+ * jFCPlib - UnknownPeerNoteType.java - Copyright © 2008 David Roden
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+package net.pterodactylus.fcp;
+
+/**
+ * The ”UnknownPeerNoteType” message signals the client that the type of peer
+ * note used in a previous {@link ModifyPeerNote} is unknown.
+ *
+ * @author David ‘Bombe’ Roden &lt;bombe@freenetproject.org&gt;
+ */
+public class UnknownPeerNoteType extends BaseMessage {
+
+       /**
+        * Creates a new ”UnknownPeerNoteType” message that wraps the received
+        * message.
+        *
+        * @param receivedMessage
+        *            The received message
+        */
+       public UnknownPeerNoteType(FcpMessage receivedMessage) {
+               super(receivedMessage);
+       }
+
+       /**
+        * Returns the type of peer note that is unkown.
+        *
+        * @return The unknown peer note type
+        */
+       public int getPeerNoteType() {
+               return FcpUtils.safeParseInt(getField("PeerNoteType"));
+       }
+
+}
diff --git a/src/main/java/net/pterodactylus/fcp/UploadFrom.java b/src/main/java/net/pterodactylus/fcp/UploadFrom.java
new file mode 100644 (file)
index 0000000..fff6d19
--- /dev/null
@@ -0,0 +1,38 @@
+/*
+ * jFCPlib - UploadFrom.java - Copyright © 2008 David Roden
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+package net.pterodactylus.fcp;
+
+/**
+ * Enumeration for the different values for the “UploadFrom” field in
+ * {@link ClientPut} and {@link ClientGet} requests.
+ *
+ * @author David ‘Bombe’ Roden &lt;bombe@freenetproject.org&gt;
+ */
+public enum UploadFrom {
+
+       /** Request data follows the request. */
+       direct,
+
+       /** Request data is written to or read from disk. */
+       disk,
+
+       /** Request data is just a redirect. */
+       redirect;
+
+}
diff --git a/src/main/java/net/pterodactylus/fcp/Verbosity.java b/src/main/java/net/pterodactylus/fcp/Verbosity.java
new file mode 100644 (file)
index 0000000..62a2da8
--- /dev/null
@@ -0,0 +1,105 @@
+/*
+ * jFCPlib - Verbosity.java - Copyright © 2008 David Roden
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+package net.pterodactylus.fcp;
+
+/**
+ * Convenicence class for verbosity handling. This might come in handy with the
+ * {@link ClientPut} and {@link ClientGet} requests. The verbosity is a bit-mask
+ * that can be composed of several bits. {@link #PROGRESS} and
+ * {@link #COMPRESSION} are single bits in that mask and can be combined into a
+ * new verbosity using {@link #add(Verbosity)}.
+ *
+ * @author David ‘Bombe’ Roden &lt;bombe@freenetproject.org&gt;
+ */
+public class Verbosity {
+
+       /** Constant for no verbosity at all. */
+       public static final Verbosity NONE = new Verbosity(0);
+
+       /** Constant for progress message verbosity. */
+       public static final Verbosity PROGRESS = new Verbosity(1);
+
+       /** Constant for compression message verbosity. */
+       public static final Verbosity COMPRESSION = new Verbosity(512);
+
+       /** Constant for all events. */
+       public static final Verbosity ALL = new Verbosity(-1);
+
+       /** The verbosity level. */
+       private final int level;
+
+       /**
+        * Creates a new verbosity with the given level.
+        *
+        * @param level
+        *            The verbosity level
+        */
+       private Verbosity(int level) {
+               this.level = level;
+       }
+
+       /**
+        * Adds the given verbosity to this verbosity and returns a verbosity with
+        * the new value. The value of this verbosity is not changed.
+        *
+        * @param verbosity
+        *            The verbosity to add to this verbosity
+        * @return The verbosity with the new level.
+        */
+       public Verbosity add(Verbosity verbosity) {
+               return new Verbosity(level | verbosity.level);
+       }
+
+       /**
+        * Checks whether this Verbosity contains all bits of the given Verbosity.
+        *
+        * @param verbosity
+        *            The verbosity to check for in this Verbosity
+        * @return <code>true</code> if and only if all set bits in the given
+        *         Verbosity are also set in this Verbosity
+        */
+       public boolean contains(Verbosity verbosity) {
+               return (level & verbosity.level) == verbosity.level;
+       }
+
+       /**
+        * @see java.lang.Object#toString()
+        */
+       @Override
+       public String toString() {
+               return String.valueOf(level);
+       }
+
+       /**
+        * Parses the given string and creates a Verbosity with the given level.
+        *
+        * @param s
+        *            The string to parse
+        * @return The parsed verbosity, or {@link #NONE} if the string could not be
+        *         parsed
+        */
+       public static Verbosity valueOf(String s) {
+               try {
+                       return new Verbosity(Integer.valueOf(s));
+               } catch (NumberFormatException nfe1) {
+                       return NONE;
+               }
+       }
+
+}
diff --git a/src/main/java/net/pterodactylus/fcp/Version.java b/src/main/java/net/pterodactylus/fcp/Version.java
new file mode 100644 (file)
index 0000000..0f1d5cb
--- /dev/null
@@ -0,0 +1,135 @@
+/*
+ * jFCPlib - Version.java - Copyright © 2008 David Roden
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+package net.pterodactylus.fcp;
+
+import java.util.StringTokenizer;
+
+/**
+ * Container for the “lastGoodVersion” field.
+ *
+ * @author David ‘Bombe’ Roden &lt;bombe@freenetproject.org&gt;
+ */
+public class Version {
+
+       /** The name of the node implementation. */
+       private final String nodeName;
+
+       /** The tree version of the node. */
+       private final String treeVersion;
+
+       /** The protocol version of the node. */
+       private final String protocolVersion;
+
+       /** The build number of the node. */
+       private final int buildNumber;
+
+       /**
+        * Creates a new Version from the given string. The string consists of the
+        * four required fields node name, tree version, protocol version, and build
+        * number, separated by a comma.
+        *
+        * @param version
+        *            The version string
+        * @throws NullPointerException
+        *             if <code>version</code> is <code>null</code>
+        * @throws IllegalArgumentException
+        *             if <code>version</code> is not in the right format
+        */
+       public Version(String version) {
+               if (version == null) {
+                       throw new NullPointerException("version must not be null");
+               }
+               StringTokenizer versionTokens = new StringTokenizer(version, ",");
+               if (versionTokens.countTokens() != 4) {
+                       throw new IllegalArgumentException("version must consist of four fields");
+               }
+               this.nodeName = versionTokens.nextToken();
+               this.treeVersion = versionTokens.nextToken();
+               this.protocolVersion = versionTokens.nextToken();
+               try {
+                       this.buildNumber = Integer.valueOf(versionTokens.nextToken());
+               } catch (NumberFormatException nfe1) {
+                       throw new IllegalArgumentException("last part of version must be numeric", nfe1);
+               }
+       }
+
+       /**
+        * Creates a new Version from the given parts.
+        *
+        * @param nodeName
+        *            The name of the node implementation
+        * @param treeVersion
+        *            The tree version
+        * @param protocolVersion
+        *            The protocol version
+        * @param buildNumber
+        *            The build number of the node
+        */
+       public Version(String nodeName, String treeVersion, String protocolVersion, int buildNumber) {
+               this.nodeName = nodeName;
+               this.treeVersion = treeVersion;
+               this.protocolVersion = protocolVersion;
+               this.buildNumber = buildNumber;
+       }
+
+       /**
+        * Returns the name of the node implementation.
+        *
+        * @return The node name
+        */
+       public String getNodeName() {
+               return nodeName;
+       }
+
+       /**
+        * The tree version of the node.
+        *
+        * @return The tree version of the node
+        */
+       public String getTreeVersion() {
+               return treeVersion;
+       }
+
+       /**
+        * The protocol version of the node
+        *
+        * @return The protocol version of the node
+        */
+       public String getProtocolVersion() {
+               return protocolVersion;
+       }
+
+       /**
+        * The build number of the node.
+        *
+        * @return The build number of the node
+        */
+       public int getBuildNumber() {
+               return buildNumber;
+       }
+
+       /**
+        * @see java.lang.Object#toString()
+        */
+       @Override
+       public String toString() {
+               return nodeName + "," + treeVersion + "," + protocolVersion + "," + buildNumber;
+       }
+
+}
diff --git a/src/main/java/net/pterodactylus/fcp/WatchGlobal.java b/src/main/java/net/pterodactylus/fcp/WatchGlobal.java
new file mode 100644 (file)
index 0000000..b973679
--- /dev/null
@@ -0,0 +1,58 @@
+/*
+ * jFCPlib - WatchGlobal.java - Copyright © 2008 David Roden
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+package net.pterodactylus.fcp;
+
+/**
+ * The “WatchGlobal” messages enables clients to watch the global queue in
+ * addition to the client-local queue.
+ *
+ * @author David ‘Bombe’ Roden &lt;bombe@freenetproject.org&gt;
+ */
+public class WatchGlobal extends FcpMessage {
+
+       /**
+        * Enables or disables watching the global queue.
+        *
+        * @param enabled
+        *            <code>true</code> to watch the global queue and the
+        *            client-local queue, <code>false</code> to watch only the
+        *            client-local queue
+        */
+       public WatchGlobal(boolean enabled) {
+               this(enabled, Verbosity.ALL);
+       }
+
+       /**
+        * Enables or disables watching the global queue, optionally masking out
+        * certain events.
+        *
+        * @param enabled
+        *            <code>true</code> to watch the global queue and the
+        *            client-local queue, <code>false</code> to watch only the
+        *            client-local queue
+        * @param verbosityMask
+        *            A verbosity mask that determines which events are received
+        */
+       public WatchGlobal(boolean enabled, Verbosity verbosityMask) {
+               super("WatchGlobal");
+               setField("Enabled", String.valueOf(enabled));
+               setField("VerbosityMask", String.valueOf(verbosityMask));
+       }
+
+}
diff --git a/src/main/java/net/pterodactylus/fcp/highlevel/FcpClient.java b/src/main/java/net/pterodactylus/fcp/highlevel/FcpClient.java
new file mode 100644 (file)
index 0000000..3012e00
--- /dev/null
@@ -0,0 +1,1120 @@
+/*
+ * jFCPlib - FcpClient.java - Copyright © 2009 David Roden
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+package net.pterodactylus.fcp.highlevel;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.net.InetAddress;
+import java.net.URL;
+import java.net.UnknownHostException;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Set;
+import java.util.Map.Entry;
+import java.util.concurrent.CountDownLatch;
+
+import net.pterodactylus.fcp.AddPeer;
+import net.pterodactylus.fcp.ClientHello;
+import net.pterodactylus.fcp.CloseConnectionDuplicateClientName;
+import net.pterodactylus.fcp.DataFound;
+import net.pterodactylus.fcp.EndListPeerNotes;
+import net.pterodactylus.fcp.EndListPeers;
+import net.pterodactylus.fcp.EndListPersistentRequests;
+import net.pterodactylus.fcp.FCPPluginMessage;
+import net.pterodactylus.fcp.FCPPluginReply;
+import net.pterodactylus.fcp.FcpAdapter;
+import net.pterodactylus.fcp.FcpConnection;
+import net.pterodactylus.fcp.FcpListener;
+import net.pterodactylus.fcp.GenerateSSK;
+import net.pterodactylus.fcp.GetFailed;
+import net.pterodactylus.fcp.GetNode;
+import net.pterodactylus.fcp.ListPeerNotes;
+import net.pterodactylus.fcp.ListPeers;
+import net.pterodactylus.fcp.ListPersistentRequests;
+import net.pterodactylus.fcp.ModifyPeer;
+import net.pterodactylus.fcp.ModifyPeerNote;
+import net.pterodactylus.fcp.NodeData;
+import net.pterodactylus.fcp.NodeHello;
+import net.pterodactylus.fcp.NodeRef;
+import net.pterodactylus.fcp.Peer;
+import net.pterodactylus.fcp.PeerNote;
+import net.pterodactylus.fcp.PeerRemoved;
+import net.pterodactylus.fcp.PersistentGet;
+import net.pterodactylus.fcp.PersistentPut;
+import net.pterodactylus.fcp.ProtocolError;
+import net.pterodactylus.fcp.RemovePeer;
+import net.pterodactylus.fcp.SSKKeypair;
+import net.pterodactylus.fcp.SimpleProgress;
+import net.pterodactylus.fcp.WatchGlobal;
+import net.pterodactylus.util.filter.Filter;
+import net.pterodactylus.util.filter.Filters;
+import net.pterodactylus.util.thread.ObjectWrapper;
+
+/**
+ * High-level FCP client that hides the details of the underlying FCP
+ * implementation.
+ *
+ * @author David ‘Bombe’ Roden &lt;bombe@freenetproject.org&gt;
+ */
+public class FcpClient {
+
+       /** Object used for synchronization. */
+       private final Object syncObject = new Object();
+
+       /** Listener management. */
+       private final FcpClientListenerManager fcpClientListenerManager = new FcpClientListenerManager(this);
+
+       /** The name of this client. */
+       private final String name;
+
+       /** The underlying FCP connection. */
+       private final FcpConnection fcpConnection;
+
+       /** Whether the client is currently connected. */
+       private volatile boolean connected;
+
+       /**
+        * Creates an FCP client with the given name.
+        *
+        * @param name
+        *            The name of the FCP client
+        * @throws UnknownHostException
+        *             if the hostname “localhost” is unknown
+        */
+       public FcpClient(String name) throws UnknownHostException {
+               this(name, "localhost");
+       }
+
+       /**
+        * Creates an FCP client.
+        *
+        * @param name
+        *            The name of the FCP client
+        * @param hostname
+        *            The hostname of the Freenet node
+        * @throws UnknownHostException
+        *             if the given hostname can not be resolved
+        */
+       public FcpClient(String name, String hostname) throws UnknownHostException {
+               this(name, hostname, FcpConnection.DEFAULT_PORT);
+       }
+
+       /**
+        * Creates an FCP client.
+        *
+        * @param name
+        *            The name of the FCP client
+        * @param hostname
+        *            The hostname of the Freenet node
+        * @param port
+        *            The Freenet node’s FCP port
+        * @throws UnknownHostException
+        *             if the given hostname can not be resolved
+        */
+       public FcpClient(String name, String hostname, int port) throws UnknownHostException {
+               this(name, InetAddress.getByName(hostname), port);
+       }
+
+       /**
+        * Creates an FCP client.
+        *
+        * @param name
+        *            The name of the FCP client
+        * @param host
+        *            The host address of the Freenet node
+        */
+       public FcpClient(String name, InetAddress host) {
+               this(name, host, FcpConnection.DEFAULT_PORT);
+       }
+
+       /**
+        * Creates an FCP client.
+        *
+        * @param name
+        *            The name of the FCP client
+        * @param host
+        *            The host address of the Freenet node
+        * @param port
+        *            The Freenet node’s FCP port
+        */
+       public FcpClient(String name, InetAddress host, int port) {
+               this.name = name;
+               fcpConnection = new FcpConnection(host, port);
+               fcpConnection.addFcpListener(new FcpAdapter() {
+
+                       /**
+                        * {@inheritDoc}
+                        */
+                       @Override
+                       @SuppressWarnings("synthetic-access")
+                       public void connectionClosed(FcpConnection fcpConnection, Throwable throwable) {
+                               connected = false;
+                               fcpClientListenerManager.fireFcpClientDisconnected();
+                       }
+               });
+       }
+
+       //
+       // LISTENER MANAGEMENT
+       //
+
+       /**
+        * Adds an FCP listener to the underlying connection.
+        *
+        * @param fcpListener
+        *            The FCP listener to add
+        */
+       public void addFcpListener(FcpListener fcpListener) {
+               fcpConnection.addFcpListener(fcpListener);
+       }
+
+       /**
+        * Removes an FCP listener from the underlying connection.
+        *
+        * @param fcpListener
+        *            The FCP listener to remove
+        */
+       public void removeFcpListener(FcpListener fcpListener) {
+               fcpConnection.removeFcpListener(fcpListener);
+       }
+
+       /**
+        * Adds an FCP client listener to the list of registered listeners.
+        *
+        * @param fcpClientListener
+        *            The FCP client listener to add
+        */
+       public void addFcpClientListener(FcpClientListener fcpClientListener) {
+               fcpClientListenerManager.addListener(fcpClientListener);
+       }
+
+       /**
+        * Removes an FCP client listener from the list of registered listeners.
+        *
+        * @param fcpClientListener
+        *            The FCP client listener to remove
+        */
+       public void removeFcpClientListener(FcpClientListener fcpClientListener) {
+               fcpClientListenerManager.removeListener(fcpClientListener);
+       }
+
+       //
+       // ACTIONS
+       //
+
+       /**
+        * Connects the FCP client.
+        *
+        * @throws IOException
+        *             if an I/O error occurs
+        * @throws FcpException
+        *             if an FCP error occurs
+        */
+       public void connect() throws IOException, FcpException {
+               checkConnected(false);
+               connected = true;
+               new ExtendedFcpAdapter() {
+
+                       /**
+                        * {@inheritDoc}
+                        */
+                       @Override
+                       @SuppressWarnings("synthetic-access")
+                       public void run() throws IOException {
+                               fcpConnection.connect();
+                               ClientHello clientHello = new ClientHello(name);
+                               fcpConnection.sendMessage(clientHello);
+                               WatchGlobal watchGlobal = new WatchGlobal(true);
+                               fcpConnection.sendMessage(watchGlobal);
+                       }
+
+                       /**
+                        * {@inheritDoc}
+                        */
+                       @Override
+                       public void receivedNodeHello(FcpConnection fcpConnection, NodeHello nodeHello) {
+                               completionLatch.countDown();
+                       }
+               }.execute();
+       }
+
+       /**
+        * Disconnects the FCP client.
+        */
+       public void disconnect() {
+               synchronized (syncObject) {
+                       fcpConnection.close();
+                       syncObject.notifyAll();
+               }
+       }
+
+       /**
+        * Returns whether this client is currently connected.
+        *
+        * @return {@code true} if the client is currently connected, {@code false}
+        *         otherwise
+        */
+       public boolean isConnected() {
+               return connected;
+       }
+
+       //
+       // PEER MANAGEMENT
+       //
+
+       /**
+        * Returns all peers that the node has.
+        *
+        * @param withMetadata
+        *            <code>true</code> to include peer metadata
+        * @param withVolatile
+        *            <code>true</code> to include volatile peer data
+        * @return A set containing the node’s peers
+        * @throws IOException
+        *             if an I/O error occurs
+        * @throws FcpException
+        *             if an FCP error occurs
+        */
+       public Collection<Peer> getPeers(final boolean withMetadata, final boolean withVolatile) throws IOException, FcpException {
+               final Set<Peer> peers = Collections.synchronizedSet(new HashSet<Peer>());
+               new ExtendedFcpAdapter() {
+
+                       /** The ID of the “ListPeers” request. */
+                       @SuppressWarnings("synthetic-access")
+                       private String identifier = createIdentifier("list-peers");
+
+                       /**
+                        * {@inheritDoc}
+                        */
+                       @Override
+                       @SuppressWarnings("synthetic-access")
+                       public void run() throws IOException {
+                               fcpConnection.sendMessage(new ListPeers(identifier, withMetadata, withVolatile));
+                       }
+
+                       /**
+                        * {@inheritDoc}
+                        */
+                       @Override
+                       public void receivedPeer(FcpConnection fcpConnection, Peer peer) {
+                               if (peer.getIdentifier().equals(identifier)) {
+                                       peers.add(peer);
+                               }
+                       }
+
+                       /**
+                        * {@inheritDoc}
+                        */
+                       @Override
+                       public void receivedEndListPeers(FcpConnection fcpConnection, EndListPeers endListPeers) {
+                               if (endListPeers.getIdentifier().equals(identifier)) {
+                                       completionLatch.countDown();
+                               }
+                       }
+               }.execute();
+               return peers;
+       }
+
+       /**
+        * Returns all darknet peers.
+        *
+        * @param withMetadata
+        *            <code>true</code> to include peer metadata
+        * @param withVolatile
+        *            <code>true</code> to include volatile peer data
+        * @return A set containing the node’s darknet peers
+        * @throws IOException
+        *             if an I/O error occurs
+        * @throws FcpException
+        *             if an FCP error occurs
+        */
+       public Collection<Peer> getDarknetPeers(boolean withMetadata, boolean withVolatile) throws IOException, FcpException {
+               Collection<Peer> allPeers = getPeers(withMetadata, withVolatile);
+               Collection<Peer> darknetPeers = new HashSet<Peer>();
+               for (Peer peer : allPeers) {
+                       if (!peer.isOpennet() && !peer.isSeed()) {
+                               darknetPeers.add(peer);
+                       }
+               }
+               return darknetPeers;
+       }
+
+       /**
+        * Returns all opennet peers.
+        *
+        * @param withMetadata
+        *            <code>true</code> to include peer metadata
+        * @param withVolatile
+        *            <code>true</code> to include volatile peer data
+        * @return A set containing the node’s opennet peers
+        * @throws IOException
+        *             if an I/O error occurs
+        * @throws FcpException
+        *             if an FCP error occurs
+        */
+       public Collection<Peer> getOpennetPeers(boolean withMetadata, boolean withVolatile) throws IOException, FcpException {
+               Collection<Peer> allPeers = getPeers(withMetadata, withVolatile);
+               Collection<Peer> opennetPeers = new HashSet<Peer>();
+               for (Peer peer : allPeers) {
+                       if (peer.isOpennet() && !peer.isSeed()) {
+                               opennetPeers.add(peer);
+                       }
+               }
+               return opennetPeers;
+       }
+
+       /**
+        * Returns all seed peers.
+        *
+        * @param withMetadata
+        *            <code>true</code> to include peer metadata
+        * @param withVolatile
+        *            <code>true</code> to include volatile peer data
+        * @return A set containing the node’s seed peers
+        * @throws IOException
+        *             if an I/O error occurs
+        * @throws FcpException
+        *             if an FCP error occurs
+        */
+       public Collection<Peer> getSeedPeers(boolean withMetadata, boolean withVolatile) throws IOException, FcpException {
+               Collection<Peer> allPeers = getPeers(withMetadata, withVolatile);
+               Collection<Peer> seedPeers = new HashSet<Peer>();
+               for (Peer peer : allPeers) {
+                       if (peer.isSeed()) {
+                               seedPeers.add(peer);
+                       }
+               }
+               return seedPeers;
+       }
+
+       /**
+        * Adds the given peer to the node.
+        *
+        * @param peer
+        *            The peer to add
+        * @throws IOException
+        *             if an I/O error occurs
+        * @throws FcpException
+        *             if an FCP error occurs
+        */
+       public void addPeer(Peer peer) throws IOException, FcpException {
+               addPeer(peer.getNodeRef());
+       }
+
+       /**
+        * Adds the peer defined by the noderef to the node.
+        *
+        * @param nodeRef
+        *            The noderef that defines the new peer
+        * @throws IOException
+        *             if an I/O error occurs
+        * @throws FcpException
+        *             if an FCP error occurs
+        */
+       public void addPeer(NodeRef nodeRef) throws IOException, FcpException {
+               addPeer(new AddPeer(nodeRef));
+       }
+
+       /**
+        * Adds a peer, reading the noderef from the given URL.
+        *
+        * @param url
+        *            The URL to read the noderef from
+        * @throws IOException
+        *             if an I/O error occurs
+        * @throws FcpException
+        *             if an FCP error occurs
+        */
+       public void addPeer(URL url) throws IOException, FcpException {
+               addPeer(new AddPeer(url));
+       }
+
+       /**
+        * Adds a peer, reading the noderef of the peer from the given file.
+        * <strong>Note:</strong> the file to read the noderef from has to reside on
+        * the same machine as the node!
+        *
+        * @param file
+        *            The name of the file containing the peer’s noderef
+        * @throws IOException
+        *             if an I/O error occurs
+        * @throws FcpException
+        *             if an FCP error occurs
+        */
+       public void addPeer(String file) throws IOException, FcpException {
+               addPeer(new AddPeer(file));
+       }
+
+       /**
+        * Sends the given {@link AddPeer} message to the node. This method should
+        * not be called directly. Use one of {@link #addPeer(Peer)},
+        * {@link #addPeer(NodeRef)}, {@link #addPeer(URL)}, or
+        * {@link #addPeer(String)} instead.
+        *
+        * @param addPeer
+        *            The “AddPeer” message
+        * @throws IOException
+        *             if an I/O error occurs
+        * @throws FcpException
+        *             if an FCP error occurs
+        */
+       private void addPeer(final AddPeer addPeer) throws IOException, FcpException {
+               new ExtendedFcpAdapter() {
+
+                       /**
+                        * {@inheritDoc}
+                        */
+                       @Override
+                       @SuppressWarnings("synthetic-access")
+                       public void run() throws IOException {
+                               fcpConnection.sendMessage(addPeer);
+                       }
+
+                       /**
+                        * {@inheritDoc}
+                        */
+                       @Override
+                       public void receivedPeer(FcpConnection fcpConnection, Peer peer) {
+                               completionLatch.countDown();
+                       }
+               }.execute();
+       }
+
+       /**
+        * Modifies the given peer.
+        *
+        * @param peer
+        *            The peer to modify
+        * @param allowLocalAddresses
+        *            <code>true</code> to allow local address, <code>false</code>
+        *            to not allow local address, <code>null</code> to not change
+        *            the setting
+        * @param disabled
+        *            <code>true</code> to disable the peer, <code>false</code> to
+        *            enable the peer, <code>null</code> to not change the setting
+        * @param listenOnly
+        *            <code>true</code> to enable “listen only” for the peer,
+        *            <code>false</code> to disable it, <code>null</code> to not
+        *            change it
+        * @throws IOException
+        *             if an I/O error occurs
+        * @throws FcpException
+        *             if an FCP error occurs
+        */
+       public void modifyPeer(final Peer peer, final Boolean allowLocalAddresses, final Boolean disabled, final Boolean listenOnly) throws IOException, FcpException {
+               new ExtendedFcpAdapter() {
+
+                       /**
+                        * {@inheritDoc}
+                        */
+                       @Override
+                       @SuppressWarnings("synthetic-access")
+                       public void run() throws IOException {
+                               fcpConnection.sendMessage(new ModifyPeer(peer.getIdentity(), allowLocalAddresses, disabled, listenOnly));
+                       }
+
+                       /**
+                        * {@inheritDoc}
+                        */
+                       @Override
+                       public void receivedPeer(FcpConnection fcpConnection, Peer peer) {
+                               completionLatch.countDown();
+                       }
+               }.execute();
+       }
+
+       /**
+        * Removes the given peer.
+        *
+        * @param peer
+        *            The peer to remove
+        * @throws IOException
+        *             if an I/O error occurs
+        * @throws FcpException
+        *             if an FCP error occurs
+        */
+       public void removePeer(final Peer peer) throws IOException, FcpException {
+               new ExtendedFcpAdapter() {
+
+                       /**
+                        * {@inheritDoc}
+                        */
+                       @Override
+                       @SuppressWarnings("synthetic-access")
+                       public void run() throws IOException {
+                               fcpConnection.sendMessage(new RemovePeer(peer.getIdentity()));
+                       }
+
+                       /**
+                        * {@inheritDoc}
+                        */
+                       @Override
+                       public void receivedPeerRemoved(FcpConnection fcpConnection, PeerRemoved peerRemoved) {
+                               completionLatch.countDown();
+                       }
+               }.execute();
+       }
+
+       //
+       // PEER NOTES MANAGEMENT
+       //
+
+       /**
+        * Returns the peer note of the given peer.
+        *
+        * @param peer
+        *            The peer to get the note for
+        * @return The peer’s note
+        * @throws IOException
+        *             if an I/O error occurs
+        * @throws FcpException
+        *             if an FCP error occurs
+        */
+       public PeerNote getPeerNote(final Peer peer) throws IOException, FcpException {
+               final ObjectWrapper<PeerNote> objectWrapper = new ObjectWrapper<PeerNote>();
+               new ExtendedFcpAdapter() {
+
+                       /**
+                        * {@inheritDoc}
+                        */
+                       @Override
+                       @SuppressWarnings("synthetic-access")
+                       public void run() throws IOException {
+                               fcpConnection.sendMessage(new ListPeerNotes(peer.getIdentity()));
+                       }
+
+                       /**
+                        * {@inheritDoc}
+                        */
+                       @Override
+                       public void receivedPeerNote(FcpConnection fcpConnection, PeerNote peerNote) {
+                               if (peerNote.getNodeIdentifier().equals(peer.getIdentity())) {
+                                       objectWrapper.set(peerNote);
+                               }
+                       }
+
+                       /**
+                        * {@inheritDoc}
+                        */
+                       @Override
+                       public void receivedEndListPeerNotes(FcpConnection fcpConnection, EndListPeerNotes endListPeerNotes) {
+                               completionLatch.countDown();
+                       }
+               }.execute();
+               return objectWrapper.get();
+       }
+
+       /**
+        * Replaces the peer note for the given peer.
+        *
+        * @param peer
+        *            The peer
+        * @param noteText
+        *            The new base64-encoded note text
+        * @param noteType
+        *            The type of the note (currently only <code>1</code> is
+        *            allowed)
+        * @throws IOException
+        *             if an I/O error occurs
+        * @throws FcpException
+        *             if an FCP error occurs
+        */
+       public void modifyPeerNote(final Peer peer, final String noteText, final int noteType) throws IOException, FcpException {
+               new ExtendedFcpAdapter() {
+
+                       /**
+                        * {@inheritDoc}
+                        */
+                       @Override
+                       @SuppressWarnings("synthetic-access")
+                       public void run() throws IOException {
+                               fcpConnection.sendMessage(new ModifyPeerNote(peer.getIdentity(), noteText, noteType));
+                       }
+
+                       /**
+                        * {@inheritDoc}
+                        */
+                       @Override
+                       public void receivedPeer(FcpConnection fcpConnection, Peer receivedPeer) {
+                               if (receivedPeer.getIdentity().equals(peer.getIdentity())) {
+                                       completionLatch.countDown();
+                               }
+                       }
+               }.execute();
+       }
+
+       //
+       // KEY GENERATION
+       //
+
+       /**
+        * Generates a new SSK key pair.
+        *
+        * @return The generated key pair
+        * @throws IOException
+        *             if an I/O error occurs
+        * @throws FcpException
+        *             if an FCP error occurs
+        */
+       public SSKKeypair generateKeyPair() throws IOException, FcpException {
+               final ObjectWrapper<SSKKeypair> sskKeypairWrapper = new ObjectWrapper<SSKKeypair>();
+               new ExtendedFcpAdapter() {
+
+                       /**
+                        * {@inheritDoc}
+                        */
+                       @Override
+                       @SuppressWarnings("synthetic-access")
+                       public void run() throws IOException {
+                               fcpConnection.sendMessage(new GenerateSSK());
+                       }
+
+                       /**
+                        * {@inheritDoc}
+                        */
+                       @Override
+                       public void receivedSSKKeypair(FcpConnection fcpConnection, SSKKeypair sskKeypair) {
+                               sskKeypairWrapper.set(sskKeypair);
+                               completionLatch.countDown();
+                       }
+               }.execute();
+               return sskKeypairWrapper.get();
+       }
+
+       //
+       // REQUEST MANAGEMENT
+       //
+
+       /**
+        * Returns all currently visible persistent get requests.
+        *
+        * @param global
+        *            <code>true</code> to return get requests from the global
+        *            queue, <code>false</code> to only show requests from the
+        *            client-local queue
+        * @return All get requests
+        * @throws IOException
+        *             if an I/O error occurs
+        * @throws FcpException
+        *             if an FCP error occurs
+        */
+       public Collection<Request> getGetRequests(final boolean global) throws IOException, FcpException {
+               return Filters.filteredCollection(getRequests(global), new Filter<Request>() {
+
+                       /**
+                        * {@inheritDoc}
+                        */
+                       public boolean filterObject(Request request) {
+                               return request instanceof GetRequest;
+                       }
+               });
+       }
+
+       /**
+        * Returns all currently visible persistent put requests.
+        *
+        * @param global
+        *            <code>true</code> to return put requests from the global
+        *            queue, <code>false</code> to only show requests from the
+        *            client-local queue
+        * @return All put requests
+        * @throws IOException
+        *             if an I/O error occurs
+        * @throws FcpException
+        *             if an FCP error occurs
+        */
+       public Collection<Request> getPutRequests(final boolean global) throws IOException, FcpException {
+               return Filters.filteredCollection(getRequests(global), new Filter<Request>() {
+
+                       /**
+                        * {@inheritDoc}
+                        */
+                       public boolean filterObject(Request request) {
+                               return request instanceof PutRequest;
+                       }
+               });
+       }
+
+       /**
+        * Returns all currently visible persistent requests.
+        *
+        * @param global
+        *            <code>true</code> to return requests from the global queue,
+        *            <code>false</code> to only show requests from the client-local
+        *            queue
+        * @return All requests
+        * @throws IOException
+        *             if an I/O error occurs
+        * @throws FcpException
+        *             if an FCP error occurs
+        */
+       public Collection<Request> getRequests(final boolean global) throws IOException, FcpException {
+               final Map<String, Request> requests = Collections.synchronizedMap(new HashMap<String, Request>());
+               new ExtendedFcpAdapter() {
+
+                       /**
+                        * {@inheritDoc}
+                        */
+                       @Override
+                       @SuppressWarnings("synthetic-access")
+                       public void run() throws IOException {
+                               fcpConnection.sendMessage(new ListPersistentRequests());
+                       }
+
+                       /**
+                        * {@inheritDoc}
+                        */
+                       @Override
+                       public void receivedPersistentGet(FcpConnection fcpConnection, PersistentGet persistentGet) {
+                               if (!persistentGet.isGlobal() || global) {
+                                       GetRequest getRequest = new GetRequest(persistentGet);
+                                       requests.put(persistentGet.getIdentifier(), getRequest);
+                               }
+                       }
+
+                       /**
+                        * {@inheritDoc}
+                        *
+                        * @see net.pterodactylus.fcp.FcpAdapter#receivedDataFound(net.pterodactylus.fcp.FcpConnection,
+                        *      net.pterodactylus.fcp.DataFound)
+                        */
+                       @Override
+                       public void receivedDataFound(FcpConnection fcpConnection, DataFound dataFound) {
+                               Request getRequest = requests.get(dataFound.getIdentifier());
+                               if (getRequest == null) {
+                                       return;
+                               }
+                               getRequest.setComplete(true);
+                               getRequest.setLength(dataFound.getDataLength());
+                               getRequest.setContentType(dataFound.getMetadataContentType());
+                       }
+
+                       /**
+                        * {@inheritDoc}
+                        *
+                        * @see net.pterodactylus.fcp.FcpAdapter#receivedGetFailed(net.pterodactylus.fcp.FcpConnection,
+                        *      net.pterodactylus.fcp.GetFailed)
+                        */
+                       @Override
+                       public void receivedGetFailed(FcpConnection fcpConnection, GetFailed getFailed) {
+                               Request getRequest = requests.get(getFailed.getIdentifier());
+                               if (getRequest == null) {
+                                       return;
+                               }
+                               getRequest.setComplete(true);
+                               getRequest.setFailed(true);
+                               getRequest.setFatal(getFailed.isFatal());
+                               getRequest.setErrorCode(getFailed.getCode());
+                       }
+
+                       /**
+                        * {@inheritDoc}
+                        *
+                        * @see net.pterodactylus.fcp.FcpAdapter#receivedPersistentPut(net.pterodactylus.fcp.FcpConnection,
+                        *      net.pterodactylus.fcp.PersistentPut)
+                        */
+                       @Override
+                       public void receivedPersistentPut(FcpConnection fcpConnection, PersistentPut persistentPut) {
+                               if (!persistentPut.isGlobal() || global) {
+                                       PutRequest putRequest = new PutRequest(persistentPut);
+                                       requests.put(persistentPut.getIdentifier(), putRequest);
+                               }
+                       }
+
+                       /**
+                        * {@inheritDoc}
+                        *
+                        * @see net.pterodactylus.fcp.FcpAdapter#receivedSimpleProgress(net.pterodactylus.fcp.FcpConnection,
+                        *      net.pterodactylus.fcp.SimpleProgress)
+                        */
+                       @Override
+                       public void receivedSimpleProgress(FcpConnection fcpConnection, SimpleProgress simpleProgress) {
+                               Request request = requests.get(simpleProgress.getIdentifier());
+                               if (request == null) {
+                                       return;
+                               }
+                               request.setTotalBlocks(simpleProgress.getTotal());
+                               request.setRequiredBlocks(simpleProgress.getRequired());
+                               request.setFailedBlocks(simpleProgress.getFailed());
+                               request.setFatallyFailedBlocks(simpleProgress.getFatallyFailed());
+                               request.setSucceededBlocks(simpleProgress.getSucceeded());
+                               request.setFinalizedTotal(simpleProgress.isFinalizedTotal());
+                       }
+
+                       /**
+                        * {@inheritDoc}
+                        */
+                       @Override
+                       public void receivedEndListPersistentRequests(FcpConnection fcpConnection, EndListPersistentRequests endListPersistentRequests) {
+                               completionLatch.countDown();
+                       }
+               }.execute();
+               return requests.values();
+       }
+
+       /**
+        * Sends a message to a plugin and waits for the response.
+        *
+        * @param pluginClass
+        *            The name of the plugin class
+        * @param parameters
+        *            The parameters for the plugin
+        * @return The responses from the plugin
+        * @throws FcpException
+        *             if an FCP error occurs
+        * @throws IOException
+        *             if an I/O error occurs
+        */
+       public Map<String, String> sendPluginMessage(String pluginClass, Map<String, String> parameters) throws IOException, FcpException {
+               return sendPluginMessage(pluginClass, parameters, 0, null);
+       }
+
+       /**
+        * Sends a message to a plugin and waits for the response.
+        *
+        * @param pluginClass
+        *            The name of the plugin class
+        * @param parameters
+        *            The parameters for the plugin
+        * @param dataLength
+        *            The length of the optional data stream, or {@code 0} if there
+        *            is no optional data stream
+        * @param dataInputStream
+        *            The input stream for the payload, or {@code null} if there is
+        *            no payload
+        * @return The responses from the plugin
+        * @throws FcpException
+        *             if an FCP error occurs
+        * @throws IOException
+        *             if an I/O error occurs
+        */
+       public Map<String, String> sendPluginMessage(final String pluginClass, final Map<String, String> parameters, final long dataLength, final InputStream dataInputStream) throws IOException, FcpException {
+               final Map<String, String> pluginReplies = Collections.synchronizedMap(new HashMap<String, String>());
+               new ExtendedFcpAdapter() {
+
+                       @SuppressWarnings("synthetic-access")
+                       private final String identifier = createIdentifier("FCPPluginMessage");
+
+                       @Override
+                       @SuppressWarnings("synthetic-access")
+                       public void run() throws IOException {
+                               FCPPluginMessage fcpPluginMessage = new FCPPluginMessage(pluginClass);
+                               for (Entry<String, String> parameter : parameters.entrySet()) {
+                                       fcpPluginMessage.setParameter(parameter.getKey(), parameter.getValue());
+                               }
+                               fcpPluginMessage.setIdentifier(identifier);
+                               if ((dataLength > 0) && (dataInputStream != null)) {
+                                       fcpPluginMessage.setDataLength(dataLength);
+                                       fcpPluginMessage.setPayloadInputStream(dataInputStream);
+                               }
+                               fcpConnection.sendMessage(fcpPluginMessage);
+                       }
+
+                       /**
+                        * {@inheritDoc}
+                        */
+                       @Override
+                       public void receivedFCPPluginReply(FcpConnection fcpConnection, FCPPluginReply fcpPluginReply) {
+                               if (!fcpPluginReply.getIdentifier().equals(identifier)) {
+                                       return;
+                               }
+                               pluginReplies.putAll(fcpPluginReply.getReplies());
+                               completionLatch.countDown();
+                       }
+
+               }.execute();
+               return pluginReplies;
+       }
+
+       //
+       // NODE INFORMATION
+       //
+
+       /**
+        * Returns information about the node.
+        *
+        * @param giveOpennetRef
+        *            Whether to return the OpenNet reference
+        * @param withPrivate
+        *            Whether to return private node data
+        * @param withVolatile
+        *            Whether to return volatile node data
+        * @return Node information
+        * @throws FcpException
+        *             if an FCP error occurs
+        * @throws IOException
+        *             if an I/O error occurs
+        */
+       public NodeData getNodeInformation(final Boolean giveOpennetRef, final Boolean withPrivate, final Boolean withVolatile) throws IOException, FcpException {
+               final ObjectWrapper<NodeData> nodeDataWrapper = new ObjectWrapper<NodeData>();
+               new ExtendedFcpAdapter() {
+
+                       @Override
+                       @SuppressWarnings("synthetic-access")
+                       public void run() throws IOException {
+                               GetNode getNodeMessage = new GetNode(giveOpennetRef, withPrivate, withVolatile);
+                               fcpConnection.sendMessage(getNodeMessage);
+                       }
+
+                       /**
+                        * {@inheritDoc}
+                        */
+                       @Override
+                       public void receivedNodeData(FcpConnection fcpConnection, NodeData nodeData) {
+                               nodeDataWrapper.set(nodeData);
+                               completionLatch.countDown();
+                       }
+               }.execute();
+               return nodeDataWrapper.get();
+       }
+
+       //
+       // PRIVATE METHODS
+       //
+
+       /**
+        * Creates a unique request identifier.
+        *
+        * @param basename
+        *            The basename of the request
+        * @return The created request identifier
+        */
+       private String createIdentifier(String basename) {
+               return basename + "-" + System.currentTimeMillis() + "-" + (int) (Math.random() * Integer.MAX_VALUE);
+       }
+
+       /**
+        * Checks whether the connection is in the required state.
+        *
+        * @param connected
+        *            The required connection state
+        * @throws FcpException
+        *             if the connection is not in the required state
+        */
+       private void checkConnected(boolean connected) throws FcpException {
+               if (this.connected != connected) {
+                       throw new FcpException("Client is " + (connected ? "not" : "already") + " connected.");
+               }
+       }
+
+       /**
+        * Tells the client that it is now disconnected. This method is called by
+        * {@link ExtendedFcpAdapter} only.
+        */
+       private void setDisconnected() {
+               connected = false;
+       }
+
+       /**
+        * Implementation of an {@link FcpListener} that can store an
+        * {@link FcpException} and wait for the arrival of a certain command.
+        *
+        * @author David ‘Bombe’ Roden &lt;bombe@freenetproject.org&gt;
+        */
+       private abstract class ExtendedFcpAdapter extends FcpAdapter {
+
+               /** The count down latch used to wait for completion. */
+               protected final CountDownLatch completionLatch = new CountDownLatch(1);
+
+               /** The FCP exception, if any. */
+               protected FcpException fcpException;
+
+               /**
+                * Creates a new extended FCP adapter.
+                */
+               public ExtendedFcpAdapter() {
+                       /* do nothing. */
+               }
+
+               /**
+                * Executes the FCP commands in {@link #run()}, wrapping the execution
+                * and catching exceptions.
+                *
+                * @throws IOException
+                *             if an I/O error occurs
+                * @throws FcpException
+                *             if an FCP error occurs
+                */
+               @SuppressWarnings("synthetic-access")
+               public void execute() throws IOException, FcpException {
+                       checkConnected(true);
+                       fcpConnection.addFcpListener(this);
+                       try {
+                               run();
+                               while (true) {
+                                       try {
+                                               completionLatch.await();
+                                               break;
+                                       } catch (InterruptedException ie1) {
+                                               /* ignore, we’ll loop. */
+                                       }
+                               }
+                       } catch (IOException ioe1) {
+                               setDisconnected();
+                               throw ioe1;
+                       } finally {
+                               fcpConnection.removeFcpListener(this);
+                       }
+                       if (fcpException != null) {
+                               setDisconnected();
+                               throw fcpException;
+                       }
+               }
+
+               /**
+                * The FCP commands that actually get executed.
+                *
+                * @throws IOException
+                *             if an I/O error occurs
+                */
+               public abstract void run() throws IOException;
+
+               /**
+                * {@inheritDoc}
+                */
+               @Override
+               public void connectionClosed(FcpConnection fcpConnection, Throwable throwable) {
+                       fcpException = new FcpException("Connection closed", throwable);
+                       completionLatch.countDown();
+               }
+
+               /**
+                * {@inheritDoc}
+                */
+               @Override
+               public void receivedCloseConnectionDuplicateClientName(FcpConnection fcpConnection, CloseConnectionDuplicateClientName closeConnectionDuplicateClientName) {
+                       fcpException = new FcpException("Connection closed, duplicate client name");
+                       completionLatch.countDown();
+               }
+
+               /**
+                * {@inheritDoc}
+                */
+               @Override
+               public void receivedProtocolError(FcpConnection fcpConnection, ProtocolError protocolError) {
+                       fcpException = new FcpException("Protocol error (" + protocolError.getCode() + ", " + protocolError.getCodeDescription());
+                       completionLatch.countDown();
+               }
+
+       }
+
+}
diff --git a/src/main/java/net/pterodactylus/fcp/highlevel/FcpClientListener.java b/src/main/java/net/pterodactylus/fcp/highlevel/FcpClientListener.java
new file mode 100644 (file)
index 0000000..2d06094
--- /dev/null
@@ -0,0 +1,38 @@
+/*
+ * jFCPlib - FcpClientListener.java - Copyright © 2009 David Roden
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+package net.pterodactylus.fcp.highlevel;
+
+import java.util.EventListener;
+
+/**
+ * Listener for {@link FcpClient} events.
+ *
+ * @author David ‘Bombe’ Roden &lt;bombe@freenetproject.org&gt;
+ */
+public interface FcpClientListener extends EventListener {
+
+       /**
+        * Notifies a listener that the given FCP client was disconnected.
+        *
+        * @param fcpClient
+        *            The FCP client that was disconnected
+        */
+       public void fcpClientDisconnected(FcpClient fcpClient);
+
+}
diff --git a/src/main/java/net/pterodactylus/fcp/highlevel/FcpClientListenerManager.java b/src/main/java/net/pterodactylus/fcp/highlevel/FcpClientListenerManager.java
new file mode 100644 (file)
index 0000000..aa797e4
--- /dev/null
@@ -0,0 +1,51 @@
+/*
+ * jFCPlib - FcpClientListenerManager.java - Copyright © 2009 David Roden
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+package net.pterodactylus.fcp.highlevel;
+
+import net.pterodactylus.util.event.AbstractListenerManager;
+
+/**
+ * Manages {@link FcpClientListener}s and fires events.
+ *
+ * @author David ‘Bombe’ Roden &lt;bombe@freenetproject.org&gt;
+ */
+public class FcpClientListenerManager extends AbstractListenerManager<FcpClient, FcpClientListener> {
+
+       /**
+        * Creates a new FCP client listener manager.
+        *
+        * @param fcpClient
+        *            The source FCP client
+        */
+       public FcpClientListenerManager(FcpClient fcpClient) {
+               super(fcpClient);
+       }
+
+       /**
+        * Notifies all listeners that the FCP client was disconnected.
+        *
+        * @see FcpClientListener#fcpClientDisconnected(FcpClient)
+        */
+       public void fireFcpClientDisconnected() {
+               for (FcpClientListener fcpClientListener : getListeners()) {
+                       fcpClientListener.fcpClientDisconnected(getSource());
+               }
+       }
+
+}
diff --git a/src/main/java/net/pterodactylus/fcp/highlevel/FcpException.java b/src/main/java/net/pterodactylus/fcp/highlevel/FcpException.java
new file mode 100644 (file)
index 0000000..dffc1f4
--- /dev/null
@@ -0,0 +1,67 @@
+/*
+ * jFCPlib - FcpException.java - Copyright © 2009 David Roden
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+package net.pterodactylus.fcp.highlevel;
+
+/**
+ * Exception that signals an error in the FCP protocol.
+ *
+ * @author David ‘Bombe’ Roden &lt;bombe@freenetproject.org&gt;
+ */
+public class FcpException extends Exception {
+
+       /**
+        * Creates a new FCP exception.
+        */
+       public FcpException() {
+               super();
+       }
+
+       /**
+        * Creates a new FCP exception.
+        *
+        * @param message
+        *            The message of the exception
+        */
+       public FcpException(String message) {
+               super(message);
+       }
+
+       /**
+        * Creates a new FCP exception.
+        *
+        * @param cause
+        *            The cause of the exception
+        */
+       public FcpException(Throwable cause) {
+               super(cause);
+       }
+
+       /**
+        * Creates a new FCP exception.
+        *
+        * @param message
+        *            The message of the exception
+        * @param cause
+        *            The cause of the exception
+        */
+       public FcpException(String message, Throwable cause) {
+               super(message, cause);
+       }
+
+}
diff --git a/src/main/java/net/pterodactylus/fcp/highlevel/GetRequest.java b/src/main/java/net/pterodactylus/fcp/highlevel/GetRequest.java
new file mode 100644 (file)
index 0000000..7204335
--- /dev/null
@@ -0,0 +1,40 @@
+/*
+ * jFCPlib - GetRequest.java - Copyright © 2009 David Roden
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+package net.pterodactylus.fcp.highlevel;
+
+import net.pterodactylus.fcp.PersistentGet;
+
+/**
+ * High-level wrapper around {@link PersistentGet}.
+ *
+ * @author David ‘Bombe’ Roden &lt;bombe@freenetproject.org&gt;
+ */
+public class GetRequest extends Request {
+
+       /**
+        * Creates a new get request.
+        *
+        * @param persistentGet
+        *            The persistent Get request to wrap
+        */
+       GetRequest(PersistentGet persistentGet) {
+               super(persistentGet.getIdentifier(), persistentGet.getClientToken(), persistentGet.isGlobal());
+       }
+
+}
diff --git a/src/main/java/net/pterodactylus/fcp/highlevel/PutRequest.java b/src/main/java/net/pterodactylus/fcp/highlevel/PutRequest.java
new file mode 100644 (file)
index 0000000..cba84a6
--- /dev/null
@@ -0,0 +1,34 @@
+/*
+ * jFCPlib - PutRequest.java - Copyright © 2009 David Roden
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+package net.pterodactylus.fcp.highlevel;
+
+import net.pterodactylus.fcp.PersistentPut;
+
+/**
+ * TODO
+ *
+ * @author David ‘Bombe’ Roden &lt;bombe@freenetproject.org&gt;
+ */
+public class PutRequest extends Request {
+
+       PutRequest(PersistentPut persistentPut) {
+               super(persistentPut.getIdentifier(), persistentPut.getClientToken(), persistentPut.isGlobal());
+       }
+
+}
diff --git a/src/main/java/net/pterodactylus/fcp/highlevel/Request.java b/src/main/java/net/pterodactylus/fcp/highlevel/Request.java
new file mode 100644 (file)
index 0000000..0b0f46e
--- /dev/null
@@ -0,0 +1,346 @@
+/*
+ * jFCPlib - Request.java - Copyright © 2009 David Roden
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+package net.pterodactylus.fcp.highlevel;
+
+import net.pterodactylus.fcp.PersistentGet;
+import net.pterodactylus.fcp.PersistentPut;
+
+/**
+ * Wrapper class around request responses from the node, such as
+ * {@link PersistentGet} or {@link PersistentPut}.
+ *
+ * @author David ‘Bombe’ Roden &lt;bombe@freenetproject.org&gt;
+ */
+public abstract class Request {
+
+       /** The identifier of the request. */
+       private final String identifier;
+
+       /** The client token of the request. */
+       private final String clientToken;
+
+       /** Whether the request is on the global queue. */
+       private final boolean global;
+
+       /** Whether the get request is complete. */
+       private boolean complete;
+
+       /** Whether the get request has failed. */
+       private boolean failed;
+
+       /** The data length. */
+       private long length;
+
+       /** The mime type. */
+       private String contentType;
+
+       /** The error code in case of failure. */
+       private int errorCode;
+
+       /** Whether the failure is fatal. */
+       private boolean fatal;
+
+       /** The total number of blocks. */
+       private int totalBlocks;
+
+       /** The required number of blocks. */
+       private int requiredBlocks;
+
+       /** The successfully processed number of blocks. */
+       private int succeededBlocks;
+
+       /** The number of failed blocks. */
+       private int failedBlocks;
+
+       /** The number of fatally failed blocks. */
+       private int fatallyFailedBlocks;
+
+       /** Whether the total number of blocks is finalized. */
+       private boolean finalizedTotal;
+
+       /**
+        * Creates a new request with the given identifier and client token.
+        *
+        * @param identifier
+        *            The identifier of the request
+        * @param clientToken
+        *            The client token of the request
+        * @param global
+        *            <code>true</code> if the request is on the global queue,
+        *            <code>false</code> otherwise
+        */
+       protected Request(String identifier, String clientToken, boolean global) {
+               this.identifier = identifier;
+               this.clientToken = clientToken;
+               this.global = global;
+       }
+
+       /**
+        * Returns the identifier of the request.
+        *
+        * @return The request’s identifier
+        */
+       public String getIdentifier() {
+               return identifier;
+       }
+
+       /**
+        * Returns the client token of the request.
+        *
+        * @return The request’s client token
+        */
+       public String getClientToken() {
+               return clientToken;
+       }
+
+       /**
+        * Returns whether this request is on the global queue.
+        *
+        * @return <code>true</code> if the request is on the global queue,
+        *         <code>false</code> otherwise
+        */
+       public boolean isGlobal() {
+               return global;
+       }
+
+       /**
+        * Returns whether this request is complete.
+        *
+        * @return <code>true</code> if this request is complete, false otherwise
+        */
+       public boolean isComplete() {
+               return complete;
+       }
+
+       /**
+        * Sets whether this request is complete.
+        *
+        * @param complete
+        *            <code>true</code> if this request is complete, false otherwise
+        */
+       void setComplete(boolean complete) {
+               this.complete = complete;
+       }
+
+       /**
+        * Returns whether this request has failed. This method should only be
+        * called if {@link #isComplete()} returns <code>true</code>.
+        *
+        * @return <code>true</code> if this request failed, <code>false</code>
+        *         otherwise
+        */
+       public boolean hasFailed() {
+               return failed;
+       }
+
+       /**
+        * Sets whether this request has failed.
+        *
+        * @param failed
+        *            <code>true</code> if this request failed, <code>false</code>
+        *            otherwise
+        */
+       void setFailed(boolean failed) {
+               this.failed = failed;
+       }
+
+       /**
+        * Returns the length of the data.
+        *
+        * @return The length of the data
+        */
+       public long getLength() {
+               return length;
+       }
+
+       /**
+        * Sets the length of the data.
+        *
+        * @param length
+        *            The length of the data
+        */
+       void setLength(long length) {
+               this.length = length;
+       }
+
+       /**
+        * Returns the content type of the data.
+        *
+        * @return The content type of the data
+        */
+       public String getContentType() {
+               return contentType;
+       }
+
+       /**
+        * Sets the content type of the data.
+        *
+        * @param contentType
+        *            The content type of the data
+        */
+       void setContentType(String contentType) {
+               this.contentType = contentType;
+       }
+
+       /**
+        * Returns the error code. This method should only be called if
+        * {@link #hasFailed()} returns <code>true</code>.
+        *
+        * @return The error code
+        */
+       public int getErrorCode() {
+               return errorCode;
+       }
+
+       /**
+        * Sets the error code.
+        *
+        * @param errorCode
+        *            The error code
+        */
+       void setErrorCode(int errorCode) {
+               this.errorCode = errorCode;
+       }
+
+       /**
+        * Returns whether this request has fatally failed, i.e. repitition will not
+        * cause the request to succeed.
+        *
+        * @return <code>true</code> if this request can not be made succeed by
+        *         repeating, <code>false</code> otherwise
+        */
+       public boolean isFatal() {
+               return fatal;
+       }
+
+       /**
+        * Sets whether this request has fatally failed.
+        *
+        * @param fatal
+        *            <code>true</code> if this request failed fatally,
+        *            <code>false</code> otherwise
+        */
+       void setFatal(boolean fatal) {
+               this.fatal = fatal;
+       }
+
+       /**
+        * Returns the total number of blocks of this request.
+        *
+        * @return This request’s total number of blocks
+        */
+       public int getTotalBlocks() {
+               return totalBlocks;
+       }
+
+       /**
+        * Sets the total number of blocks of this request.
+        *
+        * @param totalBlocks
+        *            This request’s total number of blocks
+        */
+       public void setTotalBlocks(int totalBlocks) {
+               this.totalBlocks = totalBlocks;
+       }
+
+       /**
+        * TODO
+        *
+        * @return the requiredBlocks
+        */
+       public int getRequiredBlocks() {
+               return requiredBlocks;
+       }
+
+       /**
+        * TODO
+        *
+        * @param requiredBlocks
+        *            the requiredBlocks to set
+        */
+       public void setRequiredBlocks(int requiredBlocks) {
+               this.requiredBlocks = requiredBlocks;
+       }
+
+       /**
+        * TODO
+        *
+        * @return the succeededBlocks
+        */
+       public int getSucceededBlocks() {
+               return succeededBlocks;
+       }
+
+       /**
+        * TODO
+        *
+        * @param succeededBlocks
+        *            the succeededBlocks to set
+        */
+       public void setSucceededBlocks(int succeededBlocks) {
+               this.succeededBlocks = succeededBlocks;
+       }
+
+       /**
+        * TODO
+        *
+        * @return the failedBlocks
+        */
+       public int getFailedBlocks() {
+               return failedBlocks;
+       }
+
+       /**
+        * TODO
+        *
+        * @param failedBlocks
+        *            the failedBlocks to set
+        */
+       public void setFailedBlocks(int failedBlocks) {
+               this.failedBlocks = failedBlocks;
+       }
+
+       /**
+        * TODO
+        *
+        * @return the fatallyFailedBlocks
+        */
+       public int getFatallyFailedBlocks() {
+               return fatallyFailedBlocks;
+       }
+
+       /**
+        * TODO
+        *
+        * @param fatallyFailedBlocks
+        *            the fatallyFailedBlocks to set
+        */
+       public void setFatallyFailedBlocks(int fatallyFailedBlocks) {
+               this.fatallyFailedBlocks = fatallyFailedBlocks;
+       }
+
+       public boolean isFinalizedTotal() {
+               return finalizedTotal;
+       }
+
+       void setFinalizedTotal(boolean finalizedTotal) {
+               this.finalizedTotal = finalizedTotal;
+       }
+
+}
diff --git a/src/main/java/net/pterodactylus/fcp/package-info.java b/src/main/java/net/pterodactylus/fcp/package-info.java
new file mode 100644 (file)
index 0000000..dbda870
--- /dev/null
@@ -0,0 +1,36 @@
+/**
+ * Package that holds all the message types that are used in the communication
+ * with a Freenet Node.
+ * 
+ * <h2>Usage</h2>
+ * 
+ * This library was designed to implement the full range of the Freenet Client
+ * Protocol, Version 2.0. At the moment the library provides a rather low-level
+ * approach, wrapping each FCP message into its own object but some kind of
+ * high-level client that does not require any interfaces to be implemented
+ * will probably provided as well.
+ * 
+ * First, create a connection to the node:
+ * 
+ * <pre>
+ * FcpConnection fcpConnection = new FcpConnection();
+ * </pre>
+ * 
+ * Now implement the {@link net.pterodactylus.fcp.FcpListener} interface
+ * and handle all incoming events.
+ * 
+ * <pre>
+ * public class MyClass implements FcpListener {
+ * 
+ *     public void receivedProtocolError(FcpConnection fcpConnection, ProtocolError protocolError) {
+ *             …
+ *     }
+ * 
+ *     // implement all further methods here
+ * 
+ * }
+ * </pre>
+ */
+
+package net.pterodactylus.fcp;
+
diff --git a/src/main/java/net/pterodactylus/fcp/plugin/WebOfTrustPlugin.java b/src/main/java/net/pterodactylus/fcp/plugin/WebOfTrustPlugin.java
new file mode 100644 (file)
index 0000000..3e99b1e
--- /dev/null
@@ -0,0 +1,661 @@
+/*
+ * jFCPlib - WebOfTrustPlugin.java - Copyright © 2009 David Roden
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+package net.pterodactylus.fcp.plugin;
+
+import java.io.IOException;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Set;
+
+import net.pterodactylus.fcp.highlevel.FcpClient;
+import net.pterodactylus.fcp.highlevel.FcpException;
+
+/**
+ * Simplifies handling of the web-of-trust plugin.
+ *
+ * @author David ‘Bombe’ Roden &lt;bombe@freenetproject.org&gt;
+ */
+public class WebOfTrustPlugin {
+
+       /** The FCP client to use. */
+       private final FcpClient fcpClient;
+
+       /**
+        * Creates a new web-of-trust plugin wrapper around the given FCP client.
+        *
+        * @param fcpClient
+        *            The FCP client to use for communication with the web-of-trust
+        *            plugin
+        */
+       public WebOfTrustPlugin(FcpClient fcpClient) {
+               this.fcpClient = fcpClient;
+       }
+
+       /**
+        * Creates a new identity.
+        *
+        * @param nickname
+        *            The nickname of the new identity
+        * @param context
+        *            The context for the new identity
+        * @param publishTrustList
+        *            {@code true} if the new identity should publish its trust list
+        * @return The new identity
+        * @throws IOException
+        *             if an I/O error occurs
+        * @throws FcpException
+        *             if an FCP error occurs
+        */
+       public OwnIdentity createIdentity(String nickname, String context, boolean publishTrustList) throws IOException, FcpException {
+               return createIdentity(nickname, context, publishTrustList, null, null);
+       }
+
+       /**
+        * Creates a new identity from the given request and insert URI.
+        *
+        * @param nickname
+        *            The nickname of the new identity
+        * @param context
+        *            The context for the new identity
+        * @param publishTrustList
+        *            {@code true} if the new identity should publish its trust list
+        * @param requestUri
+        *            The request URI of the identity
+        * @param insertUri
+        *            The insert URI of the identity
+        * @return The new identity
+        * @throws IOException
+        *             if an I/O error occurs
+        * @throws FcpException
+        *             if an FCP error occurs
+        */
+       public OwnIdentity createIdentity(String nickname, String context, boolean publishTrustList, String requestUri, String insertUri) throws IOException, FcpException {
+               Map<String, String> parameters = new HashMap<String, String>();
+               parameters.put("Message", "CreateIdentity");
+               parameters.put("Nickname", nickname);
+               parameters.put("Context", context);
+               parameters.put("PublishTrustList", String.valueOf(publishTrustList));
+               if ((requestUri != null) && (insertUri != null)) {
+                       parameters.put("RequestURI", requestUri);
+                       parameters.put("InsertURI", insertUri);
+               }
+               Map<String, String> replies = fcpClient.sendPluginMessage("plugins.WoT.WoT", parameters);
+               if (!replies.get("Message").equals("IdentityCreated")) {
+                       throw new FcpException("WebOfTrust Plugin did not reply with “IdentityCreated” message!");
+               }
+               String identifier = replies.get("ID");
+               String newRequestUri = replies.get("RequestURI");
+               String newInsertUri = replies.get("InsertURI");
+               return new OwnIdentity(identifier, nickname, newRequestUri, newInsertUri);
+       }
+
+       /**
+        * Returns all own identities of the web-of-trust plugins. Almost all other
+        * commands require an {@link OwnIdentity} to return meaningful values.
+        *
+        * @return All own identities of the web-of-trust plugin
+        * @throws IOException
+        *             if an I/O error occurs
+        * @throws FcpException
+        *             if an FCP error occurs
+        */
+       public Set<OwnIdentity> getOwnIdentites() throws IOException, FcpException {
+               Map<String, String> replies = fcpClient.sendPluginMessage("plugins.WoT.WoT", createParameters("Message", "GetOwnIdentities"));
+               if (!replies.get("Message").equals("OwnIdentities")) {
+                       throw new FcpException("WebOfTrust Plugin did not reply with “OwnIdentities” message!");
+               }
+               Set<OwnIdentity> ownIdentities = new HashSet<OwnIdentity>();
+               for (int identityIndex = 1; replies.containsKey("Identity" + identityIndex); identityIndex++) {
+                       String identity = replies.get("Identity" + identityIndex);
+                       String nickname = replies.get("Nickname" + identityIndex);
+                       String requestUri = replies.get("RequestURI" + identityIndex);
+                       String insertUri = replies.get("InsertURI" + identityIndex);
+                       ownIdentities.add(new OwnIdentity(identity, nickname, requestUri, insertUri));
+               }
+               return ownIdentities;
+       }
+
+       /**
+        * Returns the trust given to the identity with the given identifier by the
+        * given own identity.
+        *
+        * @param ownIdentity
+        *            The own identity that is used to calculate trust values
+        * @param identifier
+        *            The identifier of the identity whose trust to get
+        * @return The request identity trust
+        * @throws IOException
+        *             if an I/O error occurs
+        * @throws FcpException
+        *             if an FCP error occurs
+        */
+       public CalculatedTrust getIdentityTrust(OwnIdentity ownIdentity, String identifier) throws IOException, FcpException {
+               Map<String, String> replies = fcpClient.sendPluginMessage("plugins.WoT.WoT", createParameters("Message", "GetIdentity", "TreeOwner", ownIdentity.getIdentifier(), "Identity", identifier));
+               if (!replies.get("Message").equals("Identity")) {
+                       throw new FcpException("WebOfTrust Plugin did not reply with “Identity” message!");
+               }
+               Byte trust = null;
+               try {
+                       trust = Byte.valueOf(replies.get("Trust"));
+               } catch (NumberFormatException nfe1) {
+                       /* ignore. */
+               }
+               Integer score = null;
+               try {
+                       score = Integer.valueOf(replies.get("Score"));
+               } catch (NumberFormatException nfe1) {
+                       /* ignore. */
+               }
+               Integer rank = null;
+               try {
+                       rank = Integer.valueOf(replies.get("Rank"));
+               } catch (NumberFormatException nfe1) {
+                       /* ignore. */
+               }
+               return new CalculatedTrust(trust, score, rank);
+       }
+
+       /**
+        * Adds a new identity by its request URI.
+        *
+        * @param requestUri
+        *            The request URI of the identity to add
+        * @return The added identity
+        * @throws IOException
+        *             if an I/O error occurs
+        * @throws FcpException
+        *             if an FCP error occurs
+        */
+       public Identity addIdentity(String requestUri) throws IOException, FcpException {
+               Map<String, String> replies = fcpClient.sendPluginMessage("plugins.WoT.WoT", createParameters("Message", "AddIdentity", "RequestURI", requestUri));
+               if (!replies.get("Message").equals("IdentityAdded")) {
+                       throw new FcpException("WebOfTrust Plugin did not reply with “IdentityAdded” message!");
+               }
+               String identifier = replies.get("ID");
+               String nickname = replies.get("Nickname");
+               return new Identity(identifier, nickname, requestUri);
+       }
+
+       /**
+        * Returns identities by the given score.
+        *
+        * @param ownIdentity
+        *            The own identity
+        * @param context
+        *            The context to get the identities for
+        * @param positive
+        *            {@code null} to return neutrally trusted identities, {@code
+        *            true} to return positively trusted identities, {@code false}
+        *            for negatively trusted identities
+        * @return The trusted identites
+        * @throws IOException
+        *             if an I/O error occurs
+        * @throws FcpException
+        *             if an FCP error occurs
+        */
+       public Set<Identity> getIdentitesByScore(OwnIdentity ownIdentity, String context, Boolean positive) throws IOException, FcpException {
+               Map<String, String> replies = fcpClient.sendPluginMessage("plugins.WoT.WoT", createParameters("Message", "GetIdentitiesByScore", "TreeOwner", ownIdentity.getIdentifier(), "Context", context, "Selection", ((positive == null) ? "0" : (positive ? "+" : "-"))));
+               if (!replies.get("Message").equals("Identities")) {
+                       throw new FcpException("WebOfTrust Plugin did not reply with “Identities” message!");
+               }
+               Set<Identity> identities = new HashSet<Identity>();
+               for (int identityIndex = 1; replies.containsKey("Identity" + identityIndex); identityIndex++) {
+                       String identifier = replies.get("Identity" + identityIndex);
+                       String nickname = replies.get("Nickname" + identityIndex);
+                       String requestUri = replies.get("RequestURI" + identityIndex);
+                       identities.add(new Identity(identifier, nickname, requestUri));
+               }
+               return identities;
+       }
+
+       /**
+        * Returns the identities that trust the given identity.
+        *
+        * @param identity
+        *            The identity to get the trusters for
+        * @param context
+        *            The context to get the trusters for
+        * @return The identities and their trust values
+        * @throws IOException
+        *             if an I/O error occurs
+        * @throws FcpException
+        *             if an FCP error occurs
+        */
+       public Map<Identity, IdentityTrust> getTrusters(Identity identity, String context) throws IOException, FcpException {
+               Map<String, String> replies = fcpClient.sendPluginMessage("plugins.WoT.WoT", createParameters("Message", "GetTrusters", "Identity", identity.getIdentifier(), "Context", context));
+               if (!replies.get("Message").equals("Identities")) {
+                       throw new FcpException("WebOfTrust Plugin did not reply with “Identities” message!");
+               }
+               Map<Identity, IdentityTrust> identityTrusts = new HashMap<Identity, IdentityTrust>();
+               for (int identityIndex = 1; replies.containsKey("Identity" + identityIndex); identityIndex++) {
+                       String identifier = replies.get("Identity" + identityIndex);
+                       String nickname = replies.get("Nickname" + identityIndex);
+                       String requestUri = replies.get("RequestURI" + identityIndex);
+                       byte trust = Byte.parseByte(replies.get("Value" + identityIndex));
+                       String comment = replies.get("Comment" + identityIndex);
+                       identityTrusts.put(new Identity(identifier, nickname, requestUri), new IdentityTrust(trust, comment));
+               }
+               return identityTrusts;
+       }
+
+       /**
+        * Returns the identities that given identity trusts.
+        *
+        * @param identity
+        *            The identity to get the trustees for
+        * @param context
+        *            The context to get the trustees for
+        * @return The identities and their trust values
+        * @throws IOException
+        *             if an I/O error occurs
+        * @throws FcpException
+        *             if an FCP error occurs
+        */
+       public Map<Identity, IdentityTrust> getTrustees(Identity identity, String context) throws IOException, FcpException {
+               Map<String, String> replies = fcpClient.sendPluginMessage("plugins.WoT.WoT", createParameters("Message", "GetTrustees", "Identity", identity.getIdentifier(), "Context", context));
+               if (!replies.get("Message").equals("Identities")) {
+                       throw new FcpException("WebOfTrust Plugin did not reply with “Identities” message!");
+               }
+               Map<Identity, IdentityTrust> identityTrusts = new HashMap<Identity, IdentityTrust>();
+               for (int identityIndex = 1; replies.containsKey("Identity" + identityIndex); identityIndex++) {
+                       String identifier = replies.get("Identity" + identityIndex);
+                       String nickname = replies.get("Nickname" + identityIndex);
+                       String requestUri = replies.get("RequestURI" + identityIndex);
+                       byte trust = Byte.parseByte(replies.get("Value" + identityIndex));
+                       String comment = replies.get("Comment" + identityIndex);
+                       identityTrusts.put(new Identity(identifier, nickname, requestUri), new IdentityTrust(trust, comment));
+               }
+               return identityTrusts;
+       }
+
+       /**
+        * Sets the trust given to the given identify by the given own identity.
+        *
+        * @param ownIdentity
+        *            The identity that gives the trust
+        * @param identity
+        *            The identity that receives the trust
+        * @param trust
+        *            The trust value (ranging from {@code -100} to {@code 100}
+        * @param comment
+        *            The comment for setting the trust
+        * @throws IOException
+        *             if an I/O error occurs
+        * @throws FcpException
+        *             if an FCP error occurs
+        */
+       public void setTrust(OwnIdentity ownIdentity, Identity identity, byte trust, String comment) throws IOException, FcpException {
+               Map<String, String> replies = fcpClient.sendPluginMessage("plugins.WoT.WoT", createParameters("Message", "SetTrust", "Truster", ownIdentity.getIdentifier(), "Trustee", identity.getIdentifier(), "Value", String.valueOf(trust), "Comment", comment));
+               if (!replies.get("Message").equals("TrustSet")) {
+                       throw new FcpException("WebOfTrust Plugin did not reply with “TrustSet” message!");
+               }
+       }
+
+       /**
+        * Adds the given context to the given identity.
+        *
+        * @param ownIdentity
+        *            The identity to add the context to
+        * @param context
+        *            The context to add
+        * @throws IOException
+        *             if an I/O error occurs
+        * @throws FcpException
+        *             if an FCP error occurs
+        */
+       public void addContext(OwnIdentity ownIdentity, String context) throws IOException, FcpException {
+               Map<String, String> replies = fcpClient.sendPluginMessage("plugins.WoT.WoT", createParameters("Message", "AddContext", "Identity", ownIdentity.getIdentifier(), "Context", context));
+               if (!replies.get("Message").equals("ContextAdded")) {
+                       throw new FcpException("WebOfTrust Plugin did not reply with “ContextAdded” message!");
+               }
+       }
+
+       /**
+        * Removes the given context from the given identity.
+        *
+        * @param ownIdentity
+        *            The identity to remove the context from
+        * @param context
+        *            The context to remove
+        * @throws IOException
+        *             if an I/O error occurs
+        * @throws FcpException
+        *             if an FCP error occurs
+        */
+       public void removeContext(OwnIdentity ownIdentity, String context) throws IOException, FcpException {
+               Map<String, String> replies = fcpClient.sendPluginMessage("plugins.WoT.WoT", createParameters("Message", "RemoveContext", "Identity", ownIdentity.getIdentifier(), "Context", context));
+               if (!replies.get("Message").equals("ContextRemoved")) {
+                       throw new FcpException("WebOfTrust Plugin did not reply with “ContextRemoved” message!");
+               }
+       }
+
+       /**
+        * Sets the given property for the given identity.
+        *
+        * @param ownIdentity
+        *            The identity to set a property for
+        * @param property
+        *            The name of the property to set
+        * @param value
+        *            The value of the property to set
+        * @throws IOException
+        *             if an I/O error occurs
+        * @throws FcpException
+        *             if an FCP error occurs
+        */
+       public void setProperty(OwnIdentity ownIdentity, String property, String value) throws IOException, FcpException {
+               Map<String, String> replies = fcpClient.sendPluginMessage("plugins.WoT.WoT", createParameters("Message", "SetProperty", "Identity", ownIdentity.getIdentifier(), "Property", property, "Value", value));
+               if (!replies.get("Message").equals("PropertyAdded")) {
+                       throw new FcpException("WebOfTrust Plugin did not reply with “PropertyAdded” message!");
+               }
+       }
+
+       /**
+        * Returns the value of the given property for the given identity.
+        *
+        * @param ownIdentity
+        *            The identity to get a property for
+        * @param property
+        *            The name of the property to get
+        * @return The value of the property
+        * @throws IOException
+        *             if an I/O error occurs
+        * @throws FcpException
+        *             if an FCP error occurs
+        */
+       public String getProperty(OwnIdentity ownIdentity, String property) throws IOException, FcpException {
+               Map<String, String> replies = fcpClient.sendPluginMessage("plugins.WoT.WoT", createParameters("Message", "GetProperty", "Identity", ownIdentity.getIdentifier(), "Property", property));
+               if (!replies.get("Message").equals("PropertyValue")) {
+                       throw new FcpException("WebOfTrust Plugin did not reply with “PropertyValue” message!");
+               }
+               return replies.get("Property");
+       }
+
+       /**
+        * Removes the given property from the given identity.
+        *
+        * @param ownIdentity
+        *            The identity to remove a property from
+        * @param property
+        *            The name of the property to remove
+        * @throws IOException
+        *             if an I/O error occurs
+        * @throws FcpException
+        *             if an FCP error occurs
+        */
+       public void removeProperty(OwnIdentity ownIdentity, String property) throws IOException, FcpException {
+               Map<String, String> replies = fcpClient.sendPluginMessage("plugins.WoT.WoT", createParameters("Message", "RemoveProperty", "Identity", ownIdentity.getIdentifier(), "Property", property));
+               if (!replies.get("Message").equals("PropertyRemoved")) {
+                       throw new FcpException("WebOfTrust Plugin did not reply with “PropertyRemoved” message!");
+               }
+       }
+
+       //
+       // PRIVATE METHODS
+       //
+
+       /**
+        * Creates a map from each pair of parameters in the given array.
+        *
+        * @param parameters
+        *            The array of parameters
+        * @return The map created from the array
+        * @throws ArrayIndexOutOfBoundsException
+        *             if the given parameter array does not contains an even number
+        *             of elements
+        */
+       private Map<String, String> createParameters(String... parameters) throws ArrayIndexOutOfBoundsException {
+               Map<String, String> parameterMap = new HashMap<String, String>();
+               for (int index = 0; index < parameters.length; index += 2) {
+                       parameterMap.put(parameters[index], parameters[index + 1]);
+               }
+               return parameterMap;
+       }
+
+       /**
+        * Wrapper around a web-of-trust identity.
+        *
+        * @author David ‘Bombe’ Roden &lt;bombe@freenetproject.org&gt;
+        */
+       public static class Identity {
+
+               /** The identity’s identifier. */
+               private final String identifier;
+
+               /** The identity’s nickname. */
+               private final String nickname;
+
+               /** The identity’s request URI. */
+               private final String requestUri;
+
+               /**
+                * Creates a new identity.
+                *
+                * @param identifier
+                *            The identifies of the identity
+                * @param nickname
+                *            The nickname of the identity
+                * @param requestUri
+                *            The request URI of the identity
+                */
+               public Identity(String identifier, String nickname, String requestUri) {
+                       this.identifier = identifier;
+                       this.nickname = nickname;
+                       this.requestUri = requestUri;
+               }
+
+               /**
+                * Returns the identifier of this identity.
+                *
+                * @return This identity’s identifier
+                */
+               public String getIdentifier() {
+                       return identifier;
+               }
+
+               /**
+                * Returns the nickname of this identity.
+                *
+                * @return This identity’s nickname
+                */
+               public String getNickname() {
+                       return nickname;
+               }
+
+               /**
+                * Returns the request URI of this identity.
+                *
+                * @return This identity’s request URI
+                */
+               public String getRequestUri() {
+                       return requestUri;
+               }
+
+               /**
+                * {@inheritDoc}
+                */
+               @Override
+               public boolean equals(Object obj) {
+                       if ((obj == null) || (obj.getClass() != this.getClass())) {
+                               return false;
+                       }
+                       Identity identity = (Identity) obj;
+                       return identifier.equals(identity.identifier);
+               }
+
+               /**
+                * {@inheritDoc}
+                */
+               @Override
+               public int hashCode() {
+                       return identifier.hashCode();
+               }
+
+       }
+
+       /**
+        * Container for the trust given from one identity to another.
+        *
+        * @author David ‘Bombe’ Roden &lt;bombe@freenetproject.org&gt;
+        */
+       public static class IdentityTrust {
+
+               /** The trust given to the identity. */
+               private final byte trust;
+
+               /** The command for the trust value. */
+               private final String comment;
+
+               /**
+                * Creates a new identity trust container.
+                *
+                * @param trust
+                *            The trust given to the identity
+                * @param comment
+                *            The comment for the trust value
+                */
+               public IdentityTrust(byte trust, String comment) {
+                       this.trust = trust;
+                       this.comment = comment;
+               }
+
+               /**
+                * Returns the trust value given to the identity.
+                *
+                * @return The trust value
+                */
+               public byte getTrust() {
+                       return trust;
+               }
+
+               /**
+                * Returns the comment for the trust value.
+                *
+                * @return The comment for the trust value
+                */
+               public String getComment() {
+                       return comment;
+               }
+
+       }
+
+       /**
+        * Container that stores the trust that is calculated by taking all trustees
+        * and their trust lists into account.
+        *
+        * @author David ‘Bombe’ Roden &lt;bombe@freenetproject.org&gt;
+        */
+       public static class CalculatedTrust {
+
+               /** The calculated trust value. */
+               private final Byte trust;
+
+               /** The calculated score value. */
+               private final Integer score;
+
+               /** The calculated rank. */
+               private final Integer rank;
+
+               /**
+                * Creates a new calculated trust container.
+                *
+                * @param trust
+                *            The calculated trust value
+                * @param score
+                *            The calculated score value
+                * @param rank
+                *            The calculated rank of the
+                */
+               public CalculatedTrust(Byte trust, Integer score, Integer rank) {
+                       this.trust = trust;
+                       this.score = score;
+                       this.rank = rank;
+               }
+
+               /**
+                * Returns the calculated trust value.
+                *
+                * @return The calculated trust value, or {@code null} if the trust
+                *         value is not known
+                */
+               public Byte getTrust() {
+                       return trust;
+               }
+
+               /**
+                * Returns the calculated score value.
+                *
+                * @return The calculated score value, or {@code null} if the score
+                *         value is not known
+                */
+               public Integer getScore() {
+                       return score;
+               }
+
+               /**
+                * Returns the calculated rank.
+                *
+                * @return The calculated rank, or {@code null} if the rank is not known
+                */
+               public Integer getRank() {
+                       return rank;
+               }
+
+       }
+
+       /**
+        * Wrapper around a web-of-trust own identity.
+        *
+        * @author David ‘Bombe’ Roden &lt;bombe@freenetproject.org&gt;
+        */
+       public static class OwnIdentity extends Identity {
+
+               /** The identity’s insert URI. */
+               private final String insertUri;
+
+               /**
+                * Creates a new web-of-trust own identity.
+                *
+                * @param identifier
+                *            The identifier of the identity
+                * @param nickname
+                *            The nickname of the identity
+                * @param requestUri
+                *            The request URI of the identity
+                * @param insertUri
+                *            The insert URI of the identity
+                */
+               public OwnIdentity(String identifier, String nickname, String requestUri, String insertUri) {
+                       super(identifier, nickname, requestUri);
+                       this.insertUri = insertUri;
+               }
+
+               /**
+                * Returns the insert URI of this identity.
+                *
+                * @return This identity’s insert URI
+                */
+               public String getInsertUri() {
+                       return insertUri;
+               }
+
+       }
+
+}
diff --git a/src/main/java/net/pterodactylus/util/event/AbstractListenerManager.java b/src/main/java/net/pterodactylus/util/event/AbstractListenerManager.java
new file mode 100644 (file)
index 0000000..fb2d43c
--- /dev/null
@@ -0,0 +1,129 @@
+/*
+ * jFCPlib - AbstractListenerManager.java - Copyright © 2009 David Roden
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+package net.pterodactylus.util.event;
+
+import java.util.EventListener;
+import java.util.List;
+import java.util.concurrent.CopyOnWriteArrayList;
+import java.util.concurrent.Executor;
+
+import net.pterodactylus.util.thread.CurrentThreadExecutor;
+
+/**
+ * Abstract implementation of a listener support class. The listener support
+ * takes care of adding and removing {@link EventListener} implementations, and
+ * subclasses are responsible for firing appropriate events.
+ *
+ * @param <S>
+ *            The type of the source
+ *@param <L>
+ *            The type of the event listeners
+ * @author <a href="mailto:bombe@pterodactylus.net">David ‘Bombe’ Roden</a>
+ */
+public abstract class AbstractListenerManager<S, L extends EventListener> {
+
+       /** The source that emits the events. */
+       private final S source;
+
+       /** The list of listeners. */
+       private final List<L> listeners = new CopyOnWriteArrayList<L>();
+
+       /** Service that executes event threads. */
+       private final Executor executor;
+
+       /**
+        * Creates a new listener support that emits events from the given source.
+        *
+        * @param source
+        *            The source of the events
+        */
+       public AbstractListenerManager(S source) {
+               this(source, new CurrentThreadExecutor());
+       }
+
+       /**
+        * Creates a new listener support that emits events from the given source.
+        *
+        * @param source
+        *            The source of the events
+        * @param executor
+        *            The executor used to fire events
+        */
+       public AbstractListenerManager(S source, Executor executor) {
+               this.source = source;
+               this.executor = executor;
+       }
+
+       /**
+        * Adds the given listener to the list of reigstered listeners.
+        *
+        * @param listener
+        *            The listener to add
+        */
+       public void addListener(L listener) {
+               synchronized (listeners) {
+                       listeners.add(listener);
+               }
+       }
+
+       /**
+        * Removes the given listener from the list of registered listeners.
+        *
+        * @param listener
+        *            The listener to remove
+        */
+       public void removeListener(L listener) {
+               synchronized (listeners) {
+                       listeners.remove(listener);
+               }
+       }
+
+       //
+       // PROTECTED METHODS
+       //
+
+       /**
+        * Returns the source for the events.
+        *
+        * @return The event source
+        */
+       protected S getSource() {
+               return source;
+       }
+
+       /**
+        * Returns the executor for the event firing.
+        *
+        * @return The executor
+        */
+       protected Executor getExecutor() {
+               return executor;
+       }
+
+       /**
+        * Returns a list of all registered listeners. The returned list is a copy
+        * of the original list so structural modifications will never occur when
+        * using the returned list.
+        *
+        * @return The list of all registered listeners
+        */
+       protected List<L> getListeners() {
+               return listeners;
+       }
+
+}
diff --git a/src/main/java/net/pterodactylus/util/filter/Filter.java b/src/main/java/net/pterodactylus/util/filter/Filter.java
new file mode 100644 (file)
index 0000000..90d7699
--- /dev/null
@@ -0,0 +1,41 @@
+/*
+ * jFCPlib - Filter.java - Copyright © 2009 David Roden
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+package net.pterodactylus.util.filter;
+
+/**
+ * Interface for a filter that determines whether a certain action can be
+ * performed on an object based on its properties.
+ *
+ * @param <T>
+ *            The type of the filtered object
+ * @author David ‘Bombe’ Roden &lt;bombe@freenetproject.org&gt;
+ */
+public interface Filter<T> {
+
+       /**
+        * Runs the given object through this filter and return whether the object
+        * matches this filter or not.
+        *
+        * @param object
+        *            The object to analyse
+        * @return <code>true</code> if the object matched this filter,
+        *         <code>false</code> otherwise
+        */
+       public boolean filterObject(T object);
+
+}
diff --git a/src/main/java/net/pterodactylus/util/filter/Filters.java b/src/main/java/net/pterodactylus/util/filter/Filters.java
new file mode 100644 (file)
index 0000000..d2bbb49
--- /dev/null
@@ -0,0 +1,190 @@
+/*
+ * jFCPlib - Filters.java - Copyright © 2009 David Roden
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+package net.pterodactylus.util.filter;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.NoSuchElementException;
+import java.util.Set;
+import java.util.Map.Entry;
+
+/**
+ * Defines various methods to filter {@link Collection}s.
+ *
+ * @author David ‘Bombe’ Roden &lt;bombe@freenetproject.org&gt;
+ */
+public class Filters {
+
+       /**
+        * Returns a list that contains only the elements from the given list that
+        * match the given filter.
+        *
+        * @param <E>
+        *            The type of the list elements
+        * @param list
+        *            The list to filter
+        * @param listFilter
+        *            The list filter
+        * @return The filtered list
+        */
+       public static <E> List<E> filteredList(List<E> list, Filter<E> listFilter) {
+               List<E> filteredList = new ArrayList<E>();
+               for (E element : list) {
+                       if (listFilter.filterObject(element)) {
+                               filteredList.add(element);
+                       }
+               }
+               return filteredList;
+       }
+
+       /**
+        * Returns a set that contains only the elements from the given set that
+        * match the given filter.
+        *
+        * @param <E>
+        *            The type of the set elements
+        * @param set
+        *            The set to filter
+        * @param setFilter
+        *            The set filter
+        * @return The filtered set
+        */
+       public static <E> Set<E> filteredSet(Set<E> set, Filter<E> setFilter) {
+               Set<E> filteredSet = new HashSet<E>();
+               for (E element : set) {
+                       if (setFilter.filterObject(element)) {
+                               filteredSet.add(element);
+                       }
+               }
+               return filteredSet;
+       }
+
+       /**
+        * Returns a map that contains only the elements from the given map that
+        * match the given filter.
+        *
+        * @param <K>
+        *            The type of the map keys
+        * @param <V>
+        *            The type of the map values
+        * @param map
+        *            The map to filter
+        * @param mapFilter
+        *            The map filter
+        * @return The filtered map
+        */
+       public static <K, V> Map<K, V> filteredMap(Map<K, V> map, Filter<Entry<K, V>> mapFilter) {
+               Map<K, V> filteredMap = new HashMap<K, V>();
+               for (Entry<K, V> element : map.entrySet()) {
+                       if (mapFilter.filterObject(element)) {
+                               filteredMap.put(element.getKey(), element.getValue());
+                       }
+               }
+               return filteredMap;
+       }
+
+       /**
+        * Returns a collection that contains only the elements from the given
+        * collection that match the given filter.
+        *
+        * @param <K>
+        *            The type of the collection values
+        * @param collection
+        *            The collection to filter
+        * @param collectionFilter
+        *            The collection filter
+        * @return The filtered collection
+        */
+       public static <K> Collection<K> filteredCollection(Collection<K> collection, Filter<K> collectionFilter) {
+               return filteredList(new ArrayList<K>(collection), collectionFilter);
+       }
+
+       /**
+        * Returns an iterator that contains only the elements from the given
+        * iterator that match the given filter.
+        *
+        * @param <E>
+        *            The type of the iterator elements
+        * @param iterator
+        *            The iterator to filter
+        * @param iteratorFilter
+        *            The iterator filter
+        * @return The filtered iterator
+        */
+       public static <E> Iterator<E> filteredIterator(final Iterator<E> iterator, final Filter<E> iteratorFilter) {
+               return new Iterator<E>() {
+
+                       private boolean gotNextElement = false;
+
+                       private E nextElement;
+
+                       private void getNextElement() {
+                               if (gotNextElement) {
+                                       return;
+                               }
+                               while (iterator.hasNext()) {
+                                       nextElement = iterator.next();
+                                       if (iteratorFilter.filterObject(nextElement)) {
+                                               gotNextElement = true;
+                                               break;
+                                       }
+                               }
+                       }
+
+                       /**
+                        * {@inheritDoc}
+                        *
+                        * @see java.util.Iterator#hasNext()
+                        */
+                       public boolean hasNext() {
+                               getNextElement();
+                               return gotNextElement;
+                       }
+
+                       /**
+                        * {@inheritDoc}
+                        *
+                        * @see java.util.Iterator#next()
+                        */
+                       public E next() {
+                               getNextElement();
+                               if (!gotNextElement) {
+                                       throw new NoSuchElementException("no more elements in iteration");
+                               }
+                               gotNextElement = false;
+                               return nextElement;
+                       }
+
+                       /**
+                        * {@inheritDoc}
+                        *
+                        * @see java.util.Iterator#remove()
+                        */
+                       public void remove() {
+                               throw new UnsupportedOperationException("remove() not supported on this iteration");
+                       }
+
+               };
+       }
+
+}
diff --git a/src/main/java/net/pterodactylus/util/thread/CurrentThreadExecutor.java b/src/main/java/net/pterodactylus/util/thread/CurrentThreadExecutor.java
new file mode 100644 (file)
index 0000000..71d236d
--- /dev/null
@@ -0,0 +1,38 @@
+/*
+ * jFCPlib - CurrentThreadExecutor.java - Copyright © 2009 David Roden
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+package net.pterodactylus.util.thread;
+
+import java.util.concurrent.Executor;
+
+/**
+ * An {@link Executor} that executes {@link Runnable}s in the current thread.
+ *
+ * @author <a href="mailto:bombe@pterodactylus.net">David ‘Bombe’ Roden</a>
+ */
+public class CurrentThreadExecutor implements Executor {
+
+       /**
+        * {@inheritDoc}
+        *
+        * @see java.util.concurrent.Executor#execute(java.lang.Runnable)
+        */
+       public void execute(Runnable command) {
+               command.run();
+       }
+
+}
diff --git a/src/main/java/net/pterodactylus/util/thread/ObjectWrapper.java b/src/main/java/net/pterodactylus/util/thread/ObjectWrapper.java
new file mode 100644 (file)
index 0000000..a95ec21
--- /dev/null
@@ -0,0 +1,64 @@
+/*
+ * jFCPlib - UserObject.java - Copyright © 2009 David Roden
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+package net.pterodactylus.util.thread;
+
+/**
+ * Wrapper around an object that can be set and retrieved. Its primary use is as
+ * a container for return values from anonymous classes.
+ *
+ * <pre>
+ * final ObjectWrapper&lt;Object&gt; objectWrapper = new ObjectWrapper&lt;Object&gt;();
+ * new Runnable() {
+ *     public void run() {
+ *         ...
+ *         objectWrapper.set(someResult);
+ *     }
+ * }.run();
+ * Object result = objectWrapper.get();
+ * </pre>
+ *
+ * @param <T>
+ *            The type of the wrapped object
+ * @author David ‘Bombe’ Roden &lt;bombe@pterodactylus.net&gt;
+ */
+public class ObjectWrapper<T> {
+
+       /** The wrapped object. */
+       private volatile T wrappedObject;
+
+       /**
+        * Returns the wrapped object.
+        *
+        * @return The wrapped object
+        */
+       public T get() {
+               return wrappedObject;
+       }
+
+       /**
+        * Sets the wrapped object.
+        *
+        * @param wrappedObject
+        *            The wrapped object
+        */
+       public void set(T wrappedObject) {
+               this.wrappedObject = wrappedObject;
+       }
+
+}
diff --git a/src/net/pterodactylus/fcp/ARK.java b/src/net/pterodactylus/fcp/ARK.java
deleted file mode 100644 (file)
index 498252d..0000000
+++ /dev/null
@@ -1,99 +0,0 @@
-/*
- * jFCPlib - ARK.java - Copyright © 2008 David Roden
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- */
-
-package net.pterodactylus.fcp;
-
-/**
- * Container for ARKs (address resolution keys).
- *
- * @author David ‘Bombe’ Roden &lt;bombe@freenetproject.org&gt;
- */
-public class ARK {
-
-       /** The public URI of the ARK. */
-       private final String publicURI;
-
-       /** The private URI of the ARK. */
-       private final String privateURI;
-
-       /** The number of the ARK. */
-       private final int number;
-
-       /**
-        * Creates a new ARK with the given URI and number.
-        *
-        * @param publicURI
-        *            The public URI of the ARK
-        * @param number
-        *            The number of the ARK
-        */
-       public ARK(String publicURI, String number) {
-               this(publicURI, null, number);
-       }
-
-       /**
-        * Creates a new ARK with the given URIs and number.
-        *
-        * @param publicURI
-        *            The public URI of the ARK
-        * @param privateURI
-        *            The private URI of the ARK
-        * @param number
-        *            The number of the ARK
-        */
-       public ARK(String publicURI, String privateURI, String number) {
-               if ((publicURI == null) || (number == null)) {
-                       throw new NullPointerException(((publicURI == null) ? "publicURI" : "number") + " must not be null");
-               }
-               this.publicURI = publicURI;
-               this.privateURI = privateURI;
-               try {
-                       this.number = Integer.valueOf(number);
-               } catch (NumberFormatException nfe1) {
-                       throw new IllegalArgumentException("number must be numeric", nfe1);
-               }
-       }
-
-       /**
-        * Returns the public URI of the ARK.
-        *
-        * @return The public URI of the ARK
-        */
-       public String getPublicURI() {
-               return publicURI;
-       }
-
-       /**
-        * Returns the private URI of the ARK.
-        *
-        * @return The private URI of the ARK
-        */
-       public String getPrivateURI() {
-               return privateURI;
-       }
-
-       /**
-        * Returns the number of the ARK.
-        *
-        * @return The number of the ARK
-        */
-       public int getNumber() {
-               return number;
-       }
-
-}
diff --git a/src/net/pterodactylus/fcp/AbstractSendFeedMessage.java b/src/net/pterodactylus/fcp/AbstractSendFeedMessage.java
deleted file mode 100644 (file)
index 86a4078..0000000
+++ /dev/null
@@ -1,44 +0,0 @@
-/*
- * jFCPlib - AbstractSendFeedMessage.java - Copyright © 2009 David Roden
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- */
-
-package net.pterodactylus.fcp;
-
-/**
- * Abstract base implementation for the {@code Send*Feed} commands.
- *
- * @author David ‘Bombe’ Roden &lt;bombe@freenetproject.org&gt;
- */
-public abstract class AbstractSendFeedMessage extends FcpMessage {
-
-       /**
-        * Creates a new “Send*Feed” command.
-        *
-        * @param name
-        *            The name of the command
-        * @param identifier
-        *            The identifier of the request
-        * @param nodeIdentifier
-        *            The identifier of the peer node
-        */
-       protected AbstractSendFeedMessage(String name, String identifier, String nodeIdentifier) {
-               super(name);
-               setField("Identifier", identifier);
-               setField("NodeIdentifier", nodeIdentifier);
-       }
-
-}
diff --git a/src/net/pterodactylus/fcp/AddPeer.java b/src/net/pterodactylus/fcp/AddPeer.java
deleted file mode 100644 (file)
index e9ad80d..0000000
+++ /dev/null
@@ -1,101 +0,0 @@
-/*
- * jFCPlib - AddPeer.java - Copyright © 2008 David Roden
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- */
-
-package net.pterodactylus.fcp;
-
-import java.net.URL;
-
-/**
- * The “AddPeer” request adds a peer to the node.
- *
- * @author David ‘Bombe’ Roden &lt;bombe@freenetproject.org&gt;
- */
-public class AddPeer extends FcpMessage {
-
-       /**
-        * Creates a new “AddPeer” request.
-        */
-       private AddPeer() {
-               super("AddPeer");
-       }
-
-       /**
-        * Creates a new “AddPeer” request that reads the noderef of the peer from
-        * the given file.
-        *
-        * @param file
-        *            The file to read the noderef from
-        */
-       public AddPeer(String file) {
-               this();
-               setField("File", file);
-       }
-
-       /**
-        * Creates a new “AddPeer” request that reads the noderef of the peer from
-        * the given URL.
-        *
-        * @param url
-        *            The URL to read the noderef from
-        */
-       public AddPeer(URL url) {
-               this();
-               setField("URL", String.valueOf(url));
-       }
-
-       /**
-        * Creates a new “AddPeer” request that adds the peer given by the noderef.
-        *
-        * @param nodeRef
-        *            The noderef of the peer
-        */
-       public AddPeer(NodeRef nodeRef) {
-               this();
-               setNodeRef(nodeRef);
-       }
-
-       //
-       // PRIVATE METHODS
-       //
-
-       /**
-        * Sets the noderef of the peer to add.
-        *
-        * @param nodeRef
-        *            The noderef of the peer
-        */
-       private void setNodeRef(NodeRef nodeRef) {
-               setField("lastGoodVersion", nodeRef.getLastGoodVersion().toString());
-               setField("opennet", String.valueOf(nodeRef.isOpennet()));
-               setField("identity", nodeRef.getIdentity());
-               setField("myName", nodeRef.getMyName());
-               setField("location", String.valueOf(nodeRef.getLocation()));
-               setField("testnet", String.valueOf(nodeRef.isTestnet()));
-               setField("version", String.valueOf(nodeRef.getVersion()));
-               setField("physical.udp", nodeRef.getPhysicalUDP());
-               setField("ark.pubURI", nodeRef.getARK().getPublicURI());
-               setField("ark.number", String.valueOf(nodeRef.getARK().getNumber()));
-               setField("dsaPubKey.y", nodeRef.getDSAPublicKey());
-               setField("dsaGroup.g", nodeRef.getDSAGroup().getBase());
-               setField("dsaGroup.p", nodeRef.getDSAGroup().getPrime());
-               setField("dsaGroup.q", nodeRef.getDSAGroup().getSubprime());
-               setField("auth.negTypes", FcpUtils.encodeMultiIntegerField(nodeRef.getNegotiationTypes()));
-               setField("sig", nodeRef.getSignature());
-       }
-
-}
diff --git a/src/net/pterodactylus/fcp/AllData.java b/src/net/pterodactylus/fcp/AllData.java
deleted file mode 100644 (file)
index d1541bf..0000000
+++ /dev/null
@@ -1,102 +0,0 @@
-/*
- * jFCPlib - AllData.java - Copyright © 2008 David Roden
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- */
-
-package net.pterodactylus.fcp;
-
-import java.io.InputStream;
-
-/**
- * The “AllData” message carries the payload of a successful {@link ClientGet}
- * request. You will only received this message if the {@link ClientGet} request
- * was started with a return type of {@link ReturnType#direct}. If you get this
- * message and decide that the data is for you, call
- * {@link #getPayloadInputStream()} to get the data. If an AllData message
- * passes through all registered {@link FcpListener}s without the payload being
- * consumed, the payload is discarded!
- *
- * @author David ‘Bombe’ Roden &lt;bombe@freenetproject.org&gt;
- */
-public class AllData extends BaseMessage {
-
-       /** The payload. */
-       private InputStream payloadInputStream;
-
-       /**
-        * Creates an “AllData” message that wraps the received message.
-        *
-        * @param receivedMessage
-        *            The received message
-        * @param payloadInputStream
-        *            The payload
-        */
-       AllData(FcpMessage receivedMessage, InputStream payloadInputStream) {
-               super(receivedMessage);
-               this.payloadInputStream = payloadInputStream;
-       }
-
-       /**
-        * Returns the identifier of the request.
-        *
-        * @return The identifier of the request
-        */
-       public String getIdentifier() {
-               return getField("Identifier");
-       }
-
-       /**
-        * Returns the length of the data.
-        *
-        * @return The length of the data, or <code>-1</code> if the length could
-        *         not be parsed
-        */
-       public long getDataLength() {
-               return FcpUtils.safeParseLong(getField("DataLength"));
-       }
-
-       /**
-        * Returns the startup time of the request.
-        *
-        * @return The startup time of the request (in milliseconds since Jan 1,
-        *         1970 UTC), or <code>-1</code> if the time could not be parsed
-        */
-       public long getStartupTime() {
-               return FcpUtils.safeParseLong(getField("StartupTime"));
-       }
-
-       /**
-        * Returns the completion time of the request.
-        *
-        * @return The completion time of the request (in milliseconds since Jan 1,
-        *         1970 UTC), or <code>-1</code> if the time could not be parsed
-        */
-       public long getCompletionTime() {
-               return FcpUtils.safeParseLong(getField("CompletionTime"));
-       }
-
-       /**
-        * Returns the payload input stream. You <strong>have</strong> consume the
-        * input stream before returning from the
-        * {@link FcpListener#receivedAllData(FcpConnection, AllData)} method!
-        *
-        * @return The payload
-        */
-       public InputStream getPayloadInputStream() {
-               return payloadInputStream;
-       }
-
-}
diff --git a/src/net/pterodactylus/fcp/BaseMessage.java b/src/net/pterodactylus/fcp/BaseMessage.java
deleted file mode 100644 (file)
index a5ea020..0000000
+++ /dev/null
@@ -1,74 +0,0 @@
-/*
- * jFCPlib - BaseMessage.java - Copyright © 2008 David Roden
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- */
-
-package net.pterodactylus.fcp;
-
-import java.util.Map;
-
-/**
- * A basic message abstraction that wraps a received FCP message.
- *
- * @author David ‘Bombe’ Roden &lt;bombe@freenetproject.org&gt;
- */
-public class BaseMessage {
-
-       /** The received message, wrapped here. */
-       private final FcpMessage receivedMessage;
-
-       /**
-        * Creates a new base message that wraps the given message.
-        *
-        * @param receivedMessage
-        *            The FCP message that was received
-        */
-       BaseMessage(FcpMessage receivedMessage) {
-               this.receivedMessage = receivedMessage;
-       }
-
-       /**
-        * Returns the name of the message.
-        *
-        * @return The name of the message
-        */
-       public String getName() {
-               return receivedMessage.getName();
-       }
-
-       /**
-        * Returns the content of the field.
-        *
-        * @param field
-        *            The name of the field
-        * @return The content of the field, or <code>null</code> if there is no
-        *         such field
-        */
-       protected String getField(String field) {
-               return receivedMessage.getField(field);
-       }
-
-       /**
-        * Returns all fields from the received message.
-        *
-        * @see FcpMessage#getFields()
-        * @return All fields from the message
-        */
-       protected Map<String, String> getFields() {
-               return receivedMessage.getFields();
-       }
-
-}
diff --git a/src/net/pterodactylus/fcp/ClientGet.java b/src/net/pterodactylus/fcp/ClientGet.java
deleted file mode 100644 (file)
index 8b03ee4..0000000
+++ /dev/null
@@ -1,210 +0,0 @@
-/*
- * jFCPlib - ClientGet.java - Copyright © 2008 David Roden
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- */
-
-package net.pterodactylus.fcp;
-
-/**
- * A “ClientGet” request is used for download files from the Freenet node.
- *
- * @author David ‘Bombe’ Roden &lt;bombe@freenetproject.org&gt;
- */
-public class ClientGet extends FcpMessage {
-
-       /**
-        * Creates a new “ClientGet” request.
-        *
-        * @param uri
-        *            The URI to get
-        * @param identifier
-        *            The identifier of the request
-        */
-       public ClientGet(String uri, String identifier) {
-               this(uri, identifier, ReturnType.direct);
-       }
-
-       /**
-        * Creates a new “ClientGet” request.
-        *
-        * @param uri
-        *            The URI to get
-        * @param identifier
-        *            The identifier of the request
-        * @param returnType
-        *            The return type of the request
-        */
-       public ClientGet(String uri, String identifier, ReturnType returnType) {
-               super("ClientGet");
-               setField("URI", uri);
-               setField("Identifier", identifier);
-               setField("ReturnType", String.valueOf(returnType));
-       }
-
-       /**
-        * Sets whether the local data store should be ignored when searching for a
-        * key.
-        *
-        * @param ignoreDataStore
-        *            <code>true</code> to ignore the local data store,
-        *            <code>false</code> to include it
-        */
-       public void setIgnoreDataStore(boolean ignoreDataStore) {
-               setField("IgnoreDS", String.valueOf(ignoreDataStore));
-       }
-
-       /**
-        * Sets whether the search for the key should be restricted to the local
-        * data store only.
-        *
-        * @param dsOnly
-        *            <code>true</code> to restrict the search to the local data
-        *            store, <code>false</code> to search on other nodes, too
-        */
-       public void setDataStoreOnly(boolean dsOnly) {
-               setField("DSonly", String.valueOf(dsOnly));
-       }
-
-       /**
-        * Sets the verbosity of the request.
-        *
-        * @param verbosity
-        *            The verbosity of the request
-        */
-       public void setVerbosity(Verbosity verbosity) {
-               setField("Verbosity", String.valueOf(verbosity));
-       }
-
-       /**
-        * Sets the maximum size of the file to retrieve. If the file is larger than
-        * this size the request will fail!
-        *
-        * @param maxSize
-        *            The maximum size of the file to retrieve
-        */
-       public void setMaxSize(long maxSize) {
-               setField("MaxSize", String.valueOf(maxSize));
-       }
-
-       /**
-        * Sets the maximum size of temporary files created by the node. If a
-        * temporary file is larger than this size the request will fail!
-        *
-        * @param maxTempSize
-        *            The maximum size of temporary files
-        */
-       public void setMaxTempSize(long maxTempSize) {
-               setField("MaxTempSize", String.valueOf(maxTempSize));
-       }
-
-       /**
-        * The maximum number of retries in case a block can not be retrieved.
-        *
-        * @param maxRetries
-        *            The maximum number of retries for failed blocks,
-        *            <code>-1</code> to try forever
-        */
-       public void setMaxRetries(int maxRetries) {
-               setField("MaxRetries", String.valueOf(maxRetries));
-       }
-
-       /**
-        * Sets the priority of the request.
-        *
-        * @param priority
-        *            The priority of the request
-        */
-       public void setPriority(Priority priority) {
-               setField("PriorityClass", String.valueOf(priority));
-       }
-
-       /**
-        * Sets the persistence of the request.
-        *
-        * @param persistence
-        *            The persistence of the request
-        */
-       public void setPersistence(Persistence persistence) {
-               setField("Persistence", String.valueOf(persistence));
-       }
-
-       /**
-        * Sets the client token of the request.
-        *
-        * @param clientToken
-        *            The client token of the request
-        */
-       public void setClientToken(String clientToken) {
-               setField("ClientToken", clientToken);
-       }
-
-       /**
-        * Sets whether the request should be visible on the global queue.
-        *
-        * @param global
-        *            <code>true</code> to make the request visible on the global
-        *            queue, <code>false</code> for client-local queue only
-        */
-       public void setGlobal(boolean global) {
-               setField("Global", String.valueOf(global));
-       }
-
-       /**
-        * Sets whether to request the “binary blob” for a key.
-        *
-        * @param binaryBlob
-        *            <code>true</code> to request the binary blob,
-        *            <code>false</code> to get the “real thing”
-        */
-       public void setBinaryBlob(boolean binaryBlob) {
-               setField("BinaryBlob", String.valueOf(binaryBlob));
-       }
-
-       /**
-        * Sets the allowed MIME types of the requested file. If the MIME type of
-        * the file does not match one of the given MIME types the request will
-        * fail!
-        *
-        * @param allowedMimeTypes
-        *            The allowed MIME types
-        */
-       public void setAllowedMimeTypes(String... allowedMimeTypes) {
-               setField("AllowedMIMETypes", FcpUtils.encodeMultiStringField(allowedMimeTypes));
-       }
-
-       /**
-        * Sets the filename to download the file to. You should only call this
-        * method if your return type is {@link ReturnType#disk}!
-        *
-        * @param filename
-        *            The filename to download the file to
-        */
-       public void setFilename(String filename) {
-               setField("Filename", filename);
-       }
-
-       /**
-        * Sets the name for the temporary file. You should only call this method if
-        * your return type is {@link ReturnType#disk}!
-        *
-        * @param tempFilename
-        *            The name of the temporary file
-        */
-       public void setTempFilename(String tempFilename) {
-               setField("TempFilename", tempFilename);
-       }
-
-}
diff --git a/src/net/pterodactylus/fcp/ClientHello.java b/src/net/pterodactylus/fcp/ClientHello.java
deleted file mode 100644 (file)
index 3079807..0000000
+++ /dev/null
@@ -1,58 +0,0 @@
-/*
- * jFCPlib - ClientHello.java - Copyright © 2008 David Roden
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- */
-
-package net.pterodactylus.fcp;
-
-/**
- * A “ClientHello” message that <i>must</i> be sent to the node first thing
- * after calling {@link FcpConnection#connect()}.
- *
- * @author David ‘Bombe’ Roden &lt;bombe@freenetproject.org&gt;
- */
-public class ClientHello extends FcpMessage {
-
-       /**
-        * Creates a new “ClientHello” message with the given client name. The
-        * client name has to be unique to the node otherwise you will get a
-        * {@link CloseConnectionDuplicateClientName} response from the node!
-        *
-        * @param clientName
-        *            The unique client name
-        */
-       public ClientHello(String clientName) {
-               this(clientName, "2.0");
-       }
-
-       /**
-        * Creates a new “ClientHello” message with the given client name. The
-        * client name has to be unique to the node otherwise you will get a
-        * {@link CloseConnectionDuplicateClientName} response from the node! The
-        * expected FCP version is currently ignored by the node.
-        *
-        * @param clientName
-        *            The unique client name
-        * @param expectedVersion
-        *            The FCP version that the node is expected to talk
-        */
-       public ClientHello(String clientName, String expectedVersion) {
-               super("ClientHello");
-               setField("Name", clientName);
-               setField("ExpectedVersion", expectedVersion);
-       }
-
-}
diff --git a/src/net/pterodactylus/fcp/ClientPut.java b/src/net/pterodactylus/fcp/ClientPut.java
deleted file mode 100644 (file)
index f7dfabc..0000000
+++ /dev/null
@@ -1,231 +0,0 @@
-/*
- * jFCPlib - ClientPut.java - Copyright © 2008 David Roden
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- */
-
-package net.pterodactylus.fcp;
-
-/**
- * A “ClientPut” requests inserts a single file into freenet, either uploading
- * it directly with this messge ({@link UploadFrom#direct}), uploading it from
- * disk ({@link UploadFrom#disk}) or by creating a redirect to another URI (
- * {@link UploadFrom#redirect}).
- *
- * @author David ‘Bombe’ Roden &lt;bombe@freenetproject.org&gt;
- */
-public class ClientPut extends FcpMessage {
-
-       /**
-        * Creates a new “ClientPut” message that inserts a file to the given URI.
-        * The file data <em>has</em> to be supplied to this message using
-        * {@link #setPayloadInputStream(java.io.InputStream)}! Using this
-        * constructor is the same as using
-        * {@link #ClientPut(String, String, UploadFrom)} with
-        * {@link UploadFrom#direct} as third parameter.
-        *
-        * @param uri
-        *            The URI to insert the file to
-        * @param identifier
-        *            The identifier of the request
-        */
-       public ClientPut(String uri, String identifier) {
-               this(uri, identifier, UploadFrom.direct);
-       }
-
-       /**
-        * Creates a new “ClientPut” message that inserts a file to the given URI.
-        * Depending on <code>uploadFrom</code> the file data has to be supplied in
-        * different ways: If <code>uploadFrom</code> is {@link UploadFrom#direct},
-        * use {@link #setPayloadInputStream(java.io.InputStream)} to supply the
-        * input data. If <code>uploadFrom</code> is {@link UploadFrom#disk}, use
-        * {@link #setFilename(String)} to supply the file to upload. You have to
-        * test your direct-disk access (see {@link TestDDARequest},
-        * {@link TestDDAReply}, {@link TestDDAResponse}, {@link TestDDAComplete})
-        * before using this option! If <code>uploadFrom</code> is
-        * {@link UploadFrom#redirect}, use {@link #setTargetURI(String)} to set the
-        * target URI of the redirect.
-        *
-        * @param uri
-        *            The URI to insert to
-        * @param identifier
-        *            The identifier of the insert
-        * @param uploadFrom
-        *            The source of the upload
-        */
-       public ClientPut(String uri, String identifier, UploadFrom uploadFrom) {
-               super("ClientPut");
-               setField("URI", uri);
-               setField("Identifier", identifier);
-               setField("UploadFrom", String.valueOf(uploadFrom));
-       }
-
-       /**
-        * The MIME type of the content.
-        *
-        * @param metadataContentType
-        *            The MIME type of the content
-        */
-       public void setMetadataContentType(String metadataContentType) {
-               setField("Metadata.ContentType", metadataContentType);
-       }
-
-       /**
-        * The verbosity of the request. Depending on this parameter you will
-        * received only the bare minimum of messages for the request (i.e. “it
-        * completed”) or a whole lot more.
-        *
-        * @see Verbosity
-        * @param verbosity
-        *            The verbosity of the request
-        */
-       public void setVerbosity(Verbosity verbosity) {
-               setField("Verbosity", String.valueOf(verbosity));
-       }
-
-       /**
-        * The number of retries for a request if the initial try failed.
-        *
-        * @param maxRetries
-        *            The maximum number of retries after failure, or
-        *            <code>-1</code> to retry forever.
-        */
-       public void setMaxRetries(int maxRetries) {
-               setField("MaxRetries", String.valueOf(maxRetries));
-       }
-
-       /**
-        * Sets the priority of the request.
-        *
-        * @param priority
-        *            The priority of the request
-        */
-       public void setPriority(Priority priority) {
-               setField("PriorityClass", String.valueOf(priority));
-       }
-
-       /**
-        * Determines whether the node should really insert the data or generate the
-        * final CHK only.
-        *
-        * @param getCHKOnly
-        *            <code>true</code> to generate the final CHK only,
-        *            <code>false</code> to really insert the data
-        */
-       public void setGetCHKOnly(boolean getCHKOnly) {
-               setField("GetCHKOnly", String.valueOf(getCHKOnly));
-       }
-
-       /**
-        * Determines whether this request appears on the global queue.
-        *
-        * @param global
-        *            <code>true</code> to put the request on the global queue,
-        *            <code>false</code> for the client-local queue.
-        */
-       public void setGlobal(boolean global) {
-               setField("Global", String.valueOf(global));
-       }
-
-       /**
-        * Determines whether the node should skip compression because the file has
-        * already been compressed.
-        *
-        * @param dontCompress
-        *            <code>true</code> to skip compression of the data in the node,
-        *            <code>false</code> to allow compression
-        */
-       public void setDontCompress(boolean dontCompress) {
-               setField("DontCompress", String.valueOf(dontCompress));
-       }
-
-       /**
-        * Sets an optional client token. This client token is mentioned in progress
-        * and other request-related messages and can be used to identify this
-        * request.
-        *
-        * @param clientToken
-        *            The client token
-        */
-       public void setClientToken(String clientToken) {
-               setField("ClientToken", clientToken);
-       }
-
-       /**
-        * Sets the persistence of this request.
-        *
-        * @param persistence
-        *            The persistence of this request
-        */
-       public void setPersistence(Persistence persistence) {
-               setField("Persistence", String.valueOf(persistence));
-       }
-
-       /**
-        * Sets the target filename of the inserted file. This value is ignored for
-        * all inserts that do not have “CHK@” as a target.
-        *
-        * @param targetFilename
-        *            The filename of the target
-        */
-       public void setTargetFilename(String targetFilename) {
-               setField("TargetFilename", targetFilename);
-       }
-
-       /**
-        * Determines whether to encode the complete file early in the life of the
-        * request.
-        *
-        * @param earlyEncode
-        *            <code>true</code> to generate the final key long before the
-        *            file is completely fetchable
-        */
-       public void setEarlyEncode(boolean earlyEncode) {
-               setField("EarlyEncode", String.valueOf(earlyEncode));
-       }
-
-       /**
-        * Sets the length of the data that will be transferred after this message
-        * if <code>uploadFrom</code> is {@link UploadFrom#direct} is used.
-        *
-        * @param dataLength
-        *            The length of the data
-        */
-       public void setDataLength(long dataLength) {
-               setField("DataLength", String.valueOf(dataLength));
-       }
-
-       /**
-        * Sets the name of the file to upload the data from.
-        *
-        * @param filename
-        *            The filename to upload
-        */
-       public void setFilename(String filename) {
-               setField("Filename", filename);
-       }
-
-       /**
-        * If <code>uploadFrom</code> is {@link UploadFrom#redirect}, use this
-        * method to determine that target of the redirect.
-        *
-        * @param targetURI
-        *            The target URI to redirect to
-        */
-       public void setTargetURI(String targetURI) {
-               setField("TargetURI", targetURI);
-       }
-
-}
diff --git a/src/net/pterodactylus/fcp/ClientPutComplexDir.java b/src/net/pterodactylus/fcp/ClientPutComplexDir.java
deleted file mode 100644 (file)
index 55e5779..0000000
+++ /dev/null
@@ -1,220 +0,0 @@
-/*
- * jFCPlib - ClientPutComplexDir.java - Copyright © 2008 David Roden
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- */
-
-package net.pterodactylus.fcp;
-
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.OutputStream;
-import java.io.SequenceInputStream;
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.List;
-import java.util.Map;
-import java.util.Map.Entry;
-
-import net.pterodactylus.fcp.FileEntry.DirectFileEntry;
-
-/**
- * The “ClientPutComplexDir” lets you upload a directory with different sources
- * for each file.
- *
- * @see FileEntry
- * @author David ‘Bombe’ Roden &lt;bombe@freenetproject.org&gt;
- */
-public class ClientPutComplexDir extends FcpMessage {
-
-       /** The index for added file entries. */
-       private int fileIndex = 0;
-
-       /** The input streams from {@link DirectFileEntry}s. */
-       private final List<InputStream> directFileInputStreams = new ArrayList<InputStream>();
-
-       /**
-        * Creates a new “ClientPutComplexDir” with the given identifier and URI.
-        *
-        * @param identifier
-        *            The identifier of the request
-        * @param uri
-        *            The URI to insert the directory to
-        */
-       public ClientPutComplexDir(String identifier, String uri) {
-               super("ClientPutComplexDir");
-               setField("Identifier", identifier);
-               setField("URI", uri);
-       }
-
-       /**
-        * Sets the verbosity of the request.
-        *
-        * @param verbosity
-        *            The verbosity of the request
-        */
-       public void setVerbosity(Verbosity verbosity) {
-               setField("Verbosity", String.valueOf(verbosity));
-       }
-
-       /**
-        * Sets the maximum number of retries for failed blocks.
-        *
-        * @param maxRetries
-        *            The maximum number of retries for failed blocks, or
-        *            <code>-1</code> to retry endlessly
-        */
-       public void setMaxRetries(int maxRetries) {
-               setField("MaxRetries", String.valueOf(maxRetries));
-       }
-
-       /**
-        * Sets the priority of the request.
-        *
-        * @param priority
-        *            The priority of the request
-        */
-       public void setPriority(Priority priority) {
-               setField("PriorityClass", String.valueOf(priority));
-       }
-
-       /**
-        * Sets whether to generate the final URI only.
-        *
-        * @param getCHKOnly
-        *            <code>true</code> to generate the final CHK only,
-        *            <code>false</code> to complete the insert
-        */
-       public void setGetCHKOnly(boolean getCHKOnly) {
-               setField("GetCHKOnly", String.valueOf(getCHKOnly));
-       }
-
-       /**
-        * Sets whether the request is on the global queue.
-        *
-        * @param global
-        *            <code>true</code> to put the request on the global queue,
-        *            <code>false</code> to put it on the client-local queue
-        */
-       public void setGlobal(boolean global) {
-               setField("Global", String.valueOf(global));
-       }
-
-       /**
-        * Sets whether the node should not try to compress the data.
-        *
-        * @param dontCompress
-        *            <code>true</code> to skip compression of the data,
-        *            <code>false</code> to try and compress the data
-        */
-       public void setDontCompress(boolean dontCompress) {
-               setField("DontCompress", String.valueOf(dontCompress));
-       }
-
-       /**
-        * Sets the client token of the request.
-        *
-        * @param clientToken
-        *            The client token of the request
-        */
-       public void setClientToken(String clientToken) {
-               setField("ClientToken", clientToken);
-       }
-
-       /**
-        * Sets the persistence of the request.
-        *
-        * @param persistence
-        *            The persistence of the request
-        */
-       public void setPersistence(Persistence persistence) {
-               setField("Persistence", String.valueOf(persistence));
-       }
-
-       /**
-        * Sets the target filename of the request. This is useful for inserts that
-        * go to “CHK@” only and creates a manifest with a single file.
-        *
-        * @param targetFilename
-        *            The target filename
-        */
-       public void setTargetFilename(String targetFilename) {
-               setField("TargetFilename", targetFilename);
-       }
-
-       /**
-        * Sets whether to encode the complete data early to generate the
-        * {@link URIGenerated} message early.
-        *
-        * @param earlyEncode
-        *            <code>true</code> to encode the complete data early,
-        *            <code>false</code> otherwise
-        */
-       public void setEarlyEncode(boolean earlyEncode) {
-               setField("EarlyEncode", String.valueOf(earlyEncode));
-       }
-
-       /**
-        * Sets the default name. This is the name of the file that should be shown
-        * if no file was specified.
-        *
-        * @param defaultName
-        *            The default name
-        */
-       public void setDefaultName(String defaultName) {
-               setField("DefaultName", defaultName);
-       }
-
-       /**
-        * Adds an entry for a file.
-        *
-        * @param fileEntry
-        *            The file entry to add
-        */
-       public void addFileEntry(FileEntry fileEntry) {
-               Map<String, String> fields = fileEntry.getFields();
-               for (Entry<String, String> fieldEntry : fields.entrySet()) {
-                       setField("Files." + fileIndex + "." + fieldEntry.getKey(), fieldEntry.getValue());
-               }
-               fileIndex++;
-               if (fileEntry instanceof FileEntry.DirectFileEntry) {
-                       directFileInputStreams.add(((DirectFileEntry) fileEntry).getInputStream());
-               }
-       }
-
-       /**
-        * {@inheritDoc}
-        * <p>
-        * Do not call this method to add input streams! The input streams, if any,
-        * will be taken directly from the {@link FileEntry}s and the stream you set
-        * here will be overridden!
-        */
-       @Override
-       public void setPayloadInputStream(InputStream payloadInputStream) {
-               /* do nothing. */
-       }
-
-       /**
-        * {@inheritDoc}
-        */
-       @Override
-       public void write(OutputStream outputStream) throws IOException {
-               /* create payload stream. */
-               setPayloadInputStream(new SequenceInputStream(Collections.enumeration(directFileInputStreams)));
-               /* write out all the fields. */
-               super.write(outputStream);
-       }
-
-}
diff --git a/src/net/pterodactylus/fcp/ClientPutDiskDir.java b/src/net/pterodactylus/fcp/ClientPutDiskDir.java
deleted file mode 100644 (file)
index d9b3924..0000000
+++ /dev/null
@@ -1,160 +0,0 @@
-/*
- * jFCPlib - ClientPutDiskDir.java - Copyright © 2008 David Roden
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- */
-
-package net.pterodactylus.fcp;
-
-/**
- * The “ClientPutDiskDir” message is used to insert a complete directory from
- * the disk to a single key.
- *
- * @author David ‘Bombe’ Roden &lt;bombe@freenetproject.org&gt;
- */
-public class ClientPutDiskDir extends FcpMessage {
-
-       /**
-        * Creates a new “ClientPutDiskDir” message.
-        *
-        * @param uri
-        *            The URI to insert the file to
-        * @param identifier
-        *            The identifier of the request
-        * @param directory
-        *            The name of the directory to insert
-        */
-       public ClientPutDiskDir(String uri, String identifier, String directory) {
-               super("ClientPutDiskDir");
-               setField("URI", uri);
-               setField("Identifier", identifier);
-               setField("Filename", directory);
-       }
-
-       /**
-        * The verbosity of the request. Depending on this parameter you will
-        * received only the bare minimum of messages for the request (i.e. “it
-        * completed”) or a whole lot more.
-        *
-        * @see Verbosity
-        * @param verbosity
-        *            The verbosity of the request
-        */
-       public void setVerbosity(Verbosity verbosity) {
-               setField("Verbosity", String.valueOf(verbosity));
-       }
-
-       /**
-        * The number of retries for a request if the initial try failed.
-        *
-        * @param maxRetries
-        *            The maximum number of retries after failure, or
-        *            <code>-1</code> to retry forever.
-        */
-       public void setMaxRetries(int maxRetries) {
-               setField("MaxRetries", String.valueOf(maxRetries));
-       }
-
-       /**
-        * Sets the priority of the request.
-        *
-        * @param priority
-        *            The priority of the request
-        */
-       public void setPriority(Priority priority) {
-               setField("PriorityClass", String.valueOf(priority));
-       }
-
-       /**
-        * Determines whether the node should really insert the data or generate the
-        * final CHK only.
-        *
-        * @param getCHKOnly
-        *            <code>true</code> to generate the final CHK only,
-        *            <code>false</code> to really insert the data
-        */
-       public void setGetCHKOnly(boolean getCHKOnly) {
-               setField("GetCHKOnly", String.valueOf(getCHKOnly));
-       }
-
-       /**
-        * Determines whether this request appears on the global queue.
-        *
-        * @param global
-        *            <code>true</code> to put the request on the global queue,
-        *            <code>false</code> for the client-local queue.
-        */
-       public void setGlobal(boolean global) {
-               setField("Global", String.valueOf(global));
-       }
-
-       /**
-        * Determines whether the node should skip compression because the file has
-        * already been compressed.
-        *
-        * @param dontCompress
-        *            <code>true</code> to skip compression of the data in the node,
-        *            <code>false</code> to allow compression
-        */
-       public void setDontCompress(boolean dontCompress) {
-               setField("DontCompress", String.valueOf(dontCompress));
-       }
-
-       /**
-        * Sets an optional client token. This client token is mentioned in progress
-        * and other request-related messages and can be used to identify this
-        * request.
-        *
-        * @param clientToken
-        *            The client token
-        */
-       public void setClientToken(String clientToken) {
-               setField("ClientToken", clientToken);
-       }
-
-       /**
-        * Sets the persistence of this request.
-        *
-        * @param persistence
-        *            The persistence of this request
-        */
-       public void setPersistence(Persistence persistence) {
-               setField("Persistence", String.valueOf(persistence));
-       }
-
-       /**
-        * Sets the name of the default file. The default file is shown when the key
-        * is requested with an additional name.
-        *
-        * @param defaultName
-        *            The name of the default file
-        */
-       public void setDefaultName(String defaultName) {
-               setField("DefaultName", defaultName);
-       }
-
-       /**
-        * Sets whether unreadable files allow the insert to continue.
-        *
-        * @param allowUnreadableFiles
-        *            <code>true</code> to just ignore unreadable files,
-        *            <code>false</code> to let the insert fail when an unreadable
-        *            file is encountered
-        */
-       public void setAllowUnreadableFiles(boolean allowUnreadableFiles) {
-               setField("AllowUnreadableFiles", String.valueOf(allowUnreadableFiles));
-       }
-
-}
diff --git a/src/net/pterodactylus/fcp/CloseConnectionDuplicateClientName.java b/src/net/pterodactylus/fcp/CloseConnectionDuplicateClientName.java
deleted file mode 100644 (file)
index db0ff0d..0000000
+++ /dev/null
@@ -1,39 +0,0 @@
-/*
- * jFCPlib - CloseConnectionDuplicateClientName.java - Copyright © 2008 David Roden
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- */
-
-package net.pterodactylus.fcp;
-
-/**
- * A “CloseConnectionDuplicateClientName” message.
- *
- * @author David ‘Bombe’ Roden &lt;bombe@freenetproject.org&gt;
- */
-public class CloseConnectionDuplicateClientName extends BaseMessage {
-
-       /**
-        * Creates a new CloseConnectionDuplicateClientName message that wraps the
-        * given message.
-        *
-        * @param receivedMessage
-        *            The received message
-        */
-       CloseConnectionDuplicateClientName(FcpMessage receivedMessage) {
-               super(receivedMessage);
-       }
-
-}
diff --git a/src/net/pterodactylus/fcp/ConfigData.java b/src/net/pterodactylus/fcp/ConfigData.java
deleted file mode 100644 (file)
index 4eb7954..0000000
+++ /dev/null
@@ -1,128 +0,0 @@
-/*
- * jFCPlib - ConfigData.java - Copyright © 2008 David Roden
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- */
-
-package net.pterodactylus.fcp;
-
-/**
- * A “ConfigData” message contains various aspects of the node’s configuration.
- *
- * @see GetConfig
- * @author David ‘Bombe’ Roden &lt;bombe@freenetproject.org&gt;
- */
-public class ConfigData extends BaseMessage {
-
-       /**
-        * Creates a new “ConfigData” message that wraps the received message.
-        *
-        * @param receivedMessage
-        *            The received message
-        */
-       ConfigData(FcpMessage receivedMessage) {
-               super(receivedMessage);
-       }
-
-       /**
-        * Returns the current value of the given option.
-        *
-        * @param option
-        *            The name of the option
-        * @return The current value of the option
-        */
-       public String getCurrent(String option) {
-               return getField("current." + option);
-       }
-
-       /**
-        * Returns the short description of the given option.
-        *
-        * @param option
-        *            The name of the option
-        * @return The short description of the option
-        */
-       public String getShortDescription(String option) {
-               return getField("shortDescription." + option);
-       }
-
-       /**
-        * Returns the long description of the given option.
-        *
-        * @param option
-        *            The name of the option
-        * @return The long description of the option
-        */
-       public String getLongDescription(String option) {
-               return getField("longDescription." + option);
-       }
-
-       /**
-        * Returns the data type of the given option.
-        *
-        * @param option
-        *            The name of the option
-        * @return The data type of the option
-        */
-       public String getDataType(String option) {
-               return getField("dataType." + option);
-       }
-
-       /**
-        * Returns the default value of the given option.
-        *
-        * @param option
-        *            The name of the option
-        * @return The default value of the option
-        */
-       public String getDefault(String option) {
-               return getField("default." + option);
-       }
-
-       /**
-        * Returns the sort order of the given option.
-        *
-        * @param option
-        *            The name of the option
-        * @return The sort order of the option, or <code>-1</code> if the sort
-        *         order could not be parsed
-        */
-       public int getSortOrder(String option) {
-               return FcpUtils.safeParseInt(getField("sortOrder." + option));
-       }
-
-       /**
-        * Returns the expert flag of the given option.
-        *
-        * @param option
-        *            The name of the option
-        * @return The expert flag of the option
-        */
-       public boolean getExpertFlag(String option) {
-               return Boolean.valueOf(getField("expertFlag." + option));
-       }
-
-       /**
-        * Returns the force-write flag of the given option
-        *
-        * @param option
-        *            The name of the option
-        * @return The force-write flag of the given option
-        */
-       public boolean getForceWriteFlag(String option) {
-               return Boolean.valueOf(getField("forceWriteFlag." + option));
-       }
-
-}
diff --git a/src/net/pterodactylus/fcp/DSAGroup.java b/src/net/pterodactylus/fcp/DSAGroup.java
deleted file mode 100644 (file)
index 4674e66..0000000
+++ /dev/null
@@ -1,85 +0,0 @@
-/*
- * jFCPlib - DSAGroup.java - Copyright © 2008 David Roden
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- */
-
-package net.pterodactylus.fcp;
-
-import java.security.interfaces.DSAParams;
-
-/**
- * Container for the DSA group of a peer. A DSA group consists of a base (called
- * “g”), a prime (called “p”) and a subprime (called “q”).
- *
- * @see DSAParams
- * @author David ‘Bombe’ Roden &lt;bombe@freenetproject.org&gt;
- */
-public class DSAGroup {
-
-       /** The base of the DSA group. */
-       private final String base;
-
-       /** The prime of the DSA group. */
-       private final String prime;
-
-       /** The subprime of the DSA group. */
-       private final String subprime;
-
-       /**
-        * Creates a new DSA group with the given base (“g”), prime (“p”), and
-        * subprime (“q”).
-        *
-        * @param base
-        *            The base of the DSA group
-        * @param prime
-        *            The prime of the DSA group
-        * @param subprime
-        *            The subprime of the DSA group
-        */
-       public DSAGroup(String base, String prime, String subprime) {
-               this.base = base;
-               this.prime = prime;
-               this.subprime = subprime;
-       }
-
-       /**
-        * Returns the base (“g”) of the DSA group.
-        *
-        * @return The base of the DSA group
-        */
-       public String getBase() {
-               return base;
-       }
-
-       /**
-        * Returns the prime (“p”) of the DSA group.
-        *
-        * @return The prime of the DSA group
-        */
-       public String getPrime() {
-               return prime;
-       }
-
-       /**
-        * Returns the subprime (“q”) of the DSA group.
-        *
-        * @return The subprime of the DSA group
-        */
-       public String getSubprime() {
-               return subprime;
-       }
-
-}
diff --git a/src/net/pterodactylus/fcp/DataFound.java b/src/net/pterodactylus/fcp/DataFound.java
deleted file mode 100644 (file)
index 81318c1..0000000
+++ /dev/null
@@ -1,77 +0,0 @@
-/*
- * jFCPlib - DataFound.java - Copyright © 2008 David Roden
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- */
-
-package net.pterodactylus.fcp;
-
-/**
- * A “DataFound” message signals the client that the data requested by a
- * {@link ClientGet} operation has been found. This message does not include the
- * actual data, though.
- *
- * @author David ‘Bombe’ Roden &lt;bombe@freenetproject.org&gt;
- */
-public class DataFound extends BaseMessage {
-
-       /**
-        * Creates a new “DataFound” message that wraps the received message.
-        *
-        * @param receivedMessage
-        *            The received message
-        */
-       DataFound(FcpMessage receivedMessage) {
-               super(receivedMessage);
-       }
-
-       /**
-        * Returns whether the request is on the global queue.
-        *
-        * @return <code>true</code> if the request is on the global queue,
-        *         <code>false</code> if the request is on the client-local queue
-        */
-       public boolean isGlobal() {
-               return Boolean.valueOf(getField("Global"));
-       }
-
-       /**
-        * Returns the identifier of the request.
-        *
-        * @return The identifier of the request
-        */
-       public String getIdentifier() {
-               return getField("Identifier");
-       }
-
-       /**
-        * Returns the content type of the data.
-        *
-        * @return The content type of the data
-        */
-       public String getMetadataContentType() {
-               return getField("Metadata.ContentType");
-       }
-
-       /**
-        * Returns the length of the data.
-        *
-        * @return The length of the data
-        */
-       public long getDataLength() {
-               return FcpUtils.safeParseLong(getField("DataLength"));
-       }
-
-}
diff --git a/src/net/pterodactylus/fcp/EndListPeerNotes.java b/src/net/pterodactylus/fcp/EndListPeerNotes.java
deleted file mode 100644 (file)
index 5c381f6..0000000
+++ /dev/null
@@ -1,39 +0,0 @@
-/*
- * jFCPlib - EndListPeerNotes.java - Copyright © 2008 David Roden
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- */
-
-package net.pterodactylus.fcp;
-
-/**
- * The “EndListPeerNotes” message signals the end of a list of “PeerNote”
- * messages.
- *
- * @author David ‘Bombe’ Roden &lt;bombe@freenetproject.org&gt;
- */
-public class EndListPeerNotes extends BaseMessage {
-
-       /**
-        * Creates a new “EndListPeerNotes” message that wraps the received message.
-        *
-        * @param fcpMessage
-        *            The received message
-        */
-       EndListPeerNotes(FcpMessage fcpMessage) {
-               super(fcpMessage);
-       }
-
-}
diff --git a/src/net/pterodactylus/fcp/EndListPeers.java b/src/net/pterodactylus/fcp/EndListPeers.java
deleted file mode 100644 (file)
index c0cf82f..0000000
+++ /dev/null
@@ -1,47 +0,0 @@
-/*
- * jFCPlib - EndListPeers.java - Copyright © 2008 David Roden
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- */
-
-package net.pterodactylus.fcp;
-
-/**
- * This message marks the end of a list of “Peer” replies.
- *
- * @author David ‘Bombe’ Roden &lt;bombe@freenetproject.org&gt;
- */
-public class EndListPeers extends BaseMessage {
-
-       /**
-        * Creates a new “EndListPeers” message that wraps the received message.
-        *
-        * @param receivedMessage
-        *            The message that was received
-        */
-       EndListPeers(FcpMessage receivedMessage) {
-               super(receivedMessage);
-       }
-
-       /**
-        * Returns the identifier of the request.
-        *
-        * @return The identifier of the request
-        */
-       public String getIdentifier() {
-               return getField("Identifier");
-       }
-
-}
diff --git a/src/net/pterodactylus/fcp/EndListPersistentRequests.java b/src/net/pterodactylus/fcp/EndListPersistentRequests.java
deleted file mode 100644 (file)
index 893f2f1..0000000
+++ /dev/null
@@ -1,40 +0,0 @@
-/*
- * jFCPlib - EndListPersistentRequests.java - Copyright © 2008 David Roden
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- */
-
-package net.pterodactylus.fcp;
-
-/**
- * The “EndListPersistentRequests” message signals the end of a list of
- * {@link PersistentGet} and {@link PersistentPut} requests.
- *
- * @author David ‘Bombe’ Roden &lt;bombe@freenetproject.org&gt;
- */
-public class EndListPersistentRequests extends BaseMessage {
-
-       /**
-        * Creates a new “EndListPersistentRequests” message that wraps the received
-        * message.
-        *
-        * @param receivedMessage
-        *            The received message
-        */
-       EndListPersistentRequests(FcpMessage receivedMessage) {
-               super(receivedMessage);
-       }
-
-}
diff --git a/src/net/pterodactylus/fcp/FCPPluginMessage.java b/src/net/pterodactylus/fcp/FCPPluginMessage.java
deleted file mode 100644 (file)
index c167411..0000000
+++ /dev/null
@@ -1,76 +0,0 @@
-/*
- * jFCPlib - PluginMessage.java - Copyright © 2008 David Roden
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- */
-
-package net.pterodactylus.fcp;
-
-/**
- * An “CPPluginMessage” sends a message with custom parameters and (optional)
- * payload to a plugin.
- *
- * @author David ‘Bombe’ Roden &lt;bombe@freenetproject.org&gt;
- */
-public class FCPPluginMessage extends FcpMessage {
-
-       /**
-        * Creates a new “FCPPluginMessage” message for the given plugin.
-        *
-        * @param pluginClass
-        *            The name of the plugin class
-        */
-       public FCPPluginMessage(String pluginClass) {
-               super("FCPPluginMessage");
-               setField("PluginName", pluginClass);
-       }
-
-       /**
-        * Sets the identifier of the request. Though this is still optional you are
-        * encouraged to include it because the plugin might reply in random order
-        * to requests.
-        *
-        * @param identifier
-        *            The identifier of the request
-        */
-       public void setIdentifier(String identifier) {
-               setField("Identifier", identifier);
-       }
-
-       /**
-        * Sets a custom parameter for the plugin.
-        *
-        * @param key
-        *            The key of the parameter
-        * @param value
-        *            The value of the parameter
-        */
-       public void setParameter(String key, String value) {
-               setField("Param." + key, value);
-       }
-
-       /**
-        * Sets the length of data of the optional payload. If you call this method
-        * you also have to call {@link #setPayloadInputStream(java.io.InputStream)}
-        * !
-        *
-        * @param dataLength
-        *            The length of data in the payload input stream
-        */
-       public void setDataLength(long dataLength) {
-               setField("DataLength", String.valueOf(dataLength));
-       }
-
-}
diff --git a/src/net/pterodactylus/fcp/FCPPluginReply.java b/src/net/pterodactylus/fcp/FCPPluginReply.java
deleted file mode 100644 (file)
index c3b5281..0000000
+++ /dev/null
@@ -1,117 +0,0 @@
-/*
- * jFCPlib - FCPPluginReply.java - Copyright © 2008 David Roden
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- */
-
-package net.pterodactylus.fcp;
-
-import java.io.InputStream;
-import java.util.HashMap;
-import java.util.Map;
-import java.util.Map.Entry;
-
-/**
- * The “FCPPluginReply” is sent by a plugin as a response to a
- * {@link FCPPluginMessage} message.
- *
- * @author David ‘Bombe’ Roden &lt;bombe@freenetproject.org&gt;
- */
-public class FCPPluginReply extends BaseMessage {
-
-       /** The payload input stream. */
-       private final InputStream payloadInputStream;
-
-       /**
-        * Creates a new “FCPPluginReply” message that wraps the received message.
-        *
-        * @param receivedMessage
-        *            The received message
-        * @param payloadInputStream
-        *            The optional input stream for the payload
-        */
-       FCPPluginReply(FcpMessage receivedMessage, InputStream payloadInputStream) {
-               super(receivedMessage);
-               this.payloadInputStream = payloadInputStream;
-       }
-
-       /**
-        * Returns the name of the plugin.
-        *
-        * @return The name of the plugin
-        */
-       public String getPluginName() {
-               return getField("PluginName");
-       }
-
-       /**
-        * Returns the identifier of the request.
-        *
-        * @return The identifier of the request
-        */
-       public String getIdentifier() {
-               return getField("Identifier");
-       }
-
-       /**
-        * Returns the length of the optional payload.
-        *
-        * @return The length of the payload, or <code>-1</code> if there is no
-        *         payload or the length could not be parsed
-        */
-       public long getDataLength() {
-               return FcpUtils.safeParseLong(getField("DataLength"));
-       }
-
-       /**
-        * Returns a reply from the plugin.
-        *
-        * @param key
-        *            The name of the reply
-        * @return The value of the reply
-        */
-       public String getReply(String key) {
-               return getField("Replies." + key);
-       }
-
-       /**
-        * Returns all replies from the plugin. The plugin sends replies as normal
-        * message fields prefixed by “Replies.”. The keys of the returned map do
-        * not contain this prefix!
-        *
-        * @return All replies from the plugin
-        */
-       public Map<String, String> getReplies() {
-               Map<String, String> fields = getFields();
-               Map<String, String> replies = new HashMap<String, String>();
-               for (Entry<String, String> field : fields.entrySet()) {
-                       if (field.getKey().startsWith("Replies.")) {
-                               replies.put(field.getKey().substring(8), field.getValue());
-                       }
-               }
-               return replies;
-       }
-
-       /**
-        * Returns the optional payload.
-        *
-        * @return The payload of the reply, or <code>null</code> if there is no
-        *         payload
-        */
-       public InputStream getPayloadInputStream() {
-               return payloadInputStream;
-       }
-
-}
diff --git a/src/net/pterodactylus/fcp/FcpAdapter.java b/src/net/pterodactylus/fcp/FcpAdapter.java
deleted file mode 100644 (file)
index a358d4c..0000000
+++ /dev/null
@@ -1,305 +0,0 @@
-/*
- * jFCPlib - FcpAdapter.java - Copyright © 2008 David Roden
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- */
-
-package net.pterodactylus.fcp;
-
-/**
- * Adapter for {@link FcpListener}.
- *
- * @author David ‘Bombe’ Roden &lt;bombe@freenetproject.org&gt;
- */
-public class FcpAdapter implements FcpListener {
-
-       /**
-        * {@inheritDoc}
-        */
-       public void receivedNodeHello(FcpConnection fcpConnection, NodeHello nodeHello) {
-               /* empty. */
-       }
-
-       /**
-        * {@inheritDoc}
-        */
-       public void receivedCloseConnectionDuplicateClientName(FcpConnection fcpConnection, CloseConnectionDuplicateClientName closeConnectionDuplicateClientName) {
-               /* empty. */
-       }
-
-       /**
-        * {@inheritDoc}
-        */
-       public void receivedSSKKeypair(FcpConnection fcpConnection, SSKKeypair sskKeypair) {
-               /* empty. */
-       }
-
-       /**
-        * {@inheritDoc}
-        */
-       public void receivedPeer(FcpConnection fcpConnection, Peer peer) {
-               /* empty. */
-       }
-
-       /**
-        * {@inheritDoc}
-        */
-       public void receivedEndListPeers(FcpConnection fcpConnection, EndListPeers endListPeers) {
-               /* empty. */
-       }
-
-       /**
-        * {@inheritDoc}
-        */
-       public void receivedPeerNote(FcpConnection fcpConnection, PeerNote peerNote) {
-               /* empty. */
-       }
-
-       /**
-        * {@inheritDoc}
-        */
-       public void receivedEndListPeerNotes(FcpConnection fcpConnection, EndListPeerNotes endListPeerNotes) {
-               /* empty. */
-       }
-
-       /**
-        * {@inheritDoc}
-        */
-       public void receivedPeerRemoved(FcpConnection fcpConnection, PeerRemoved peerRemoved) {
-               /* empty. */
-       }
-
-       /**
-        * {@inheritDoc}
-        *
-        * @see FcpListener#receivedNodeData(FcpConnection, NodeData)
-        */
-       public void receivedNodeData(FcpConnection fcpConnection, NodeData nodeData) {
-               /* empty. */
-       }
-
-       /**
-        * {@inheritDoc}
-        *
-        * @see FcpListener#receivedTestDDAReply(FcpConnection, TestDDAReply)
-        */
-       public void receivedTestDDAReply(FcpConnection fcpConnection, TestDDAReply testDDAReply) {
-               /* empty. */
-       }
-
-       /**
-        * {@inheritDoc}
-        */
-       public void receivedTestDDAComplete(FcpConnection fcpConnection, TestDDAComplete testDDAComplete) {
-               /* empty. */
-       }
-
-       /**
-        * {@inheritDoc}
-        */
-       public void receivedPersistentGet(FcpConnection fcpConnection, PersistentGet persistentGet) {
-               /* empty. */
-       }
-
-       /**
-        * {@inheritDoc}
-        */
-       public void receivedPersistentPut(FcpConnection fcpConnection, PersistentPut persistentPut) {
-               /* empty. */
-       }
-
-       /**
-        * {@inheritDoc}
-        */
-       public void receivedEndListPersistentRequests(FcpConnection fcpConnection, EndListPersistentRequests endListPersistentRequests) {
-               /* empty. */
-       }
-
-       /**
-        * {@inheritDoc}
-        */
-       public void receivedURIGenerated(FcpConnection fcpConnection, URIGenerated uriGenerated) {
-               /* empty. */
-       }
-
-       /**
-        * {@inheritDoc}
-        */
-       public void receivedDataFound(FcpConnection fcpConnection, DataFound dataFound) {
-               /* empty. */
-       }
-
-       /**
-        * {@inheritDoc}
-        */
-       public void receivedAllData(FcpConnection fcpConnection, AllData allData) {
-               /* empty. */
-       }
-
-       /**
-        * {@inheritDoc}
-        */
-       public void receivedSimpleProgress(FcpConnection fcpConnection, SimpleProgress simpleProgress) {
-               /* empty. */
-       }
-
-       /**
-        * {@inheritDoc}
-        */
-       public void receivedStartedCompression(FcpConnection fcpConnection, StartedCompression startedCompression) {
-               /* empty. */
-       }
-
-       /**
-        * {@inheritDoc}
-        */
-       public void receivedFinishedCompression(FcpConnection fcpConnection, FinishedCompression finishedCompression) {
-               /* empty. */
-       }
-
-       /**
-        * {@inheritDoc}
-        */
-       public void receivedUnknownPeerNoteType(FcpConnection fcpConnection, UnknownPeerNoteType unknownPeerNoteType) {
-               /* empty. */
-       }
-
-       /**
-        * {@inheritDoc}
-        */
-       public void receivedUnknownNodeIdentifier(FcpConnection fcpConnection, UnknownNodeIdentifier unknownNodeIdentifier) {
-               /* empty. */
-       }
-
-       /**
-        * {@inheritDoc}
-        */
-       public void receivedConfigData(FcpConnection fcpConnection, ConfigData configData) {
-               /* empty. */
-       }
-
-       /**
-        * {@inheritDoc}
-        */
-       public void receivedGetFailed(FcpConnection fcpConnection, GetFailed getFailed) {
-               /* empty. */
-       }
-
-       /**
-        * {@inheritDoc}
-        */
-       public void receivedPutFailed(FcpConnection fcpConnection, PutFailed putFailed) {
-               /* empty. */
-       }
-
-       /**
-        * {@inheritDoc}
-        */
-       public void receivedIdentifierCollision(FcpConnection fcpConnection, IdentifierCollision identifierCollision) {
-               /* empty. */
-       }
-
-       /**
-        * {@inheritDoc}
-        */
-       public void receivedPersistentPutDir(FcpConnection fcpConnection, PersistentPutDir persistentPutDir) {
-               /* empty. */
-       }
-
-       /**
-        * {@inheritDoc}
-        */
-       public void receivedPersistentRequestRemoved(FcpConnection fcpConnection, PersistentRequestRemoved persistentRequestRemoved) {
-               /* empty. */
-       }
-
-       /**
-        * {@inheritDoc}
-        */
-       public void receivedSubscribedUSKUpdate(FcpConnection fcpConnection, SubscribedUSKUpdate subscribedUSKUpdate) {
-               /* empty. */
-       }
-
-       /**
-        * {@inheritDoc}
-        */
-       public void receivedPluginInfo(FcpConnection fcpConnection, PluginInfo pluginInfo) {
-               /* empty. */
-       }
-
-       /**
-        * {@inheritDoc}
-        */
-       public void receivedFCPPluginReply(FcpConnection fcpConnection, FCPPluginReply fcpPluginReply) {
-               /* empty. */
-       }
-
-       /**
-        * {@inheritDoc}
-        */
-       public void receivedPersistentRequestModified(FcpConnection fcpConnection, PersistentRequestModified persistentRequestModified) {
-               /* empty. */
-       }
-
-       /**
-        * {@inheritDoc}
-        */
-       public void receivedPutSuccessful(FcpConnection fcpConnection, PutSuccessful putSuccessful) {
-               /* empty. */
-       }
-
-       /**
-        * {@inheritDoc}
-        */
-       public void receivedPutFetchable(FcpConnection fcpConnection, PutFetchable putFetchable) {
-               /* empty. */
-       }
-
-       /**
-        * {@inheritDoc}
-        */
-       public void receivedProtocolError(FcpConnection fcpConnection, ProtocolError protocolError) {
-               /* empty. */
-       }
-
-       /**
-        * {@inheritDoc}
-        */
-       public void receivedSentFeed(FcpConnection source, SentFeed sentFeed) {
-               /* empty. */
-       }
-
-       /**
-        * {@inheritDoc}
-        */
-       public void receivedBookmarkFeed(FcpConnection fcpConnection, ReceivedBookmarkFeed receivedBookmarkFeed) {
-               /* empty. */
-       }
-
-       /**
-        * {@inheritDoc}
-        */
-       public void receivedMessage(FcpConnection fcpConnection, FcpMessage fcpMessage) {
-               /* empty. */
-       }
-
-       /**
-        * {@inheritDoc}
-        */
-       public void connectionClosed(FcpConnection fcpConnection, Throwable throwable) {
-               /* empty. */
-       }
-
-}
diff --git a/src/net/pterodactylus/fcp/FcpConnection.java b/src/net/pterodactylus/fcp/FcpConnection.java
deleted file mode 100644 (file)
index 2f40785..0000000
+++ /dev/null
@@ -1,496 +0,0 @@
-/*
- * jFCPlib - FpcConnection.java - Copyright © 2008 David Roden
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- */
-
-package net.pterodactylus.fcp;
-
-import java.io.Closeable;
-import java.io.FilterInputStream;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.OutputStream;
-import java.net.InetAddress;
-import java.net.Socket;
-import java.net.UnknownHostException;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.Map;
-import java.util.logging.Logger;
-
-/**
- * An FCP connection to a Freenet node.
- *
- * @author David ‘Bombe’ Roden &lt;bombe@freenetproject.org&gt;
- */
-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;
-
-       /** Listener management. */
-       private final FcpListenerManager fcpListenerManager = new FcpListenerManager(this);
-
-       /** The address of the node. */
-       private final InetAddress address;
-
-       /** The port number of the node’s FCP port. */
-       private final int port;
-
-       /** The remote socket. */
-       private Socket remoteSocket;
-
-       /** The input stream from the node. */
-       private InputStream remoteInputStream;
-
-       /** The output stream to the node. */
-       private OutputStream remoteOutputStream;
-
-       /** The connection handler. */
-       private FcpConnectionHandler connectionHandler;
-
-       /** Incoming message statistics. */
-       private Map<String, Integer> incomingMessageStatistics = Collections.synchronizedMap(new HashMap<String, Integer>());
-
-       /**
-        * Creates a new FCP connection to the freenet node running on localhost,
-        * using the default port.
-        *
-        * @throws UnknownHostException
-        *             if the hostname can not be resolved
-        */
-       public FcpConnection() throws UnknownHostException {
-               this(InetAddress.getLocalHost());
-       }
-
-       /**
-        * Creates a new FCP connection to the Freenet node running on the given
-        * host, listening on the default port.
-        *
-        * @param host
-        *            The hostname of the Freenet node
-        * @throws UnknownHostException
-        *             if <code>host</code> can not be resolved
-        */
-       public FcpConnection(String host) throws UnknownHostException {
-               this(host, DEFAULT_PORT);
-       }
-
-       /**
-        * Creates a new FCP connection to the Freenet node running on the given
-        * host, listening on the given port.
-        *
-        * @param host
-        *            The hostname of the Freenet node
-        * @param port
-        *            The port number of the node’s FCP port
-        * @throws UnknownHostException
-        *             if <code>host</code> can not be resolved
-        */
-       public FcpConnection(String host, int port) throws UnknownHostException {
-               this(InetAddress.getByName(host), port);
-       }
-
-       /**
-        * Creates a new FCP connection to the Freenet node running at the given
-        * address, listening on the default port.
-        *
-        * @param address
-        *            The address of the Freenet node
-        */
-       public FcpConnection(InetAddress address) {
-               this(address, DEFAULT_PORT);
-       }
-
-       /**
-        * Creates a new FCP connection to the Freenet node running at the given
-        * address, listening on the given port.
-        *
-        * @param address
-        *            The address of the Freenet node
-        * @param port
-        *            The port number of the node’s FCP port
-        */
-       public FcpConnection(InetAddress address, int port) {
-               this.address = address;
-               this.port = port;
-       }
-
-       //
-       // LISTENER MANAGEMENT
-       //
-
-       /**
-        * Adds the given listener to the list of listeners.
-        *
-        * @param fcpListener
-        *            The listener to add
-        */
-       public void addFcpListener(FcpListener fcpListener) {
-               fcpListenerManager.addListener(fcpListener);
-       }
-
-       /**
-        * Removes the given listener from the list of listeners.
-        *
-        * @param fcpListener
-        *            The listener to remove
-        */
-       public void removeFcpListener(FcpListener fcpListener) {
-               fcpListenerManager.removeListener(fcpListener);
-       }
-
-       //
-       // ACTIONS
-       //
-
-       /**
-        * Connects to the node.
-        *
-        * @throws IOException
-        *             if an I/O error occurs
-        * @throws IllegalStateException
-        *             if there is already a connection to the node
-        */
-       public synchronized void connect() throws IOException, IllegalStateException {
-               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();
-               new Thread(connectionHandler = new FcpConnectionHandler(this, remoteInputStream)).start();
-       }
-
-       /**
-        * 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() {
-               close();
-       }
-
-       /**
-        * Closes the connection. If there is no connection to the node, this method
-        * does nothing.
-        */
-       public void close() {
-               handleDisconnect(null);
-       }
-
-       /**
-        * Sends the given FCP message.
-        *
-        * @param fcpMessage
-        *            The FCP message to send
-        * @throws IOException
-        *             if an I/O error occurs
-        */
-       public synchronized void sendMessage(FcpMessage fcpMessage) throws IOException {
-               logger.fine("sending message: " + fcpMessage.getName());
-               fcpMessage.write(remoteOutputStream);
-       }
-
-       //
-       // PACKAGE-PRIVATE METHODS
-       //
-
-       /**
-        * Handles the given message, notifying listeners. This message should only
-        * be called by {@link FcpConnectionHandler}.
-        *
-        * @param fcpMessage
-        *            The received message
-        */
-       void handleMessage(FcpMessage fcpMessage) {
-               logger.fine("received message: " + fcpMessage.getName());
-               String messageName = fcpMessage.getName();
-               countMessage(messageName);
-               if ("SimpleProgress".equals(messageName)) {
-                       fcpListenerManager.fireReceivedSimpleProgress(new SimpleProgress(fcpMessage));
-               } else if ("ProtocolError".equals(messageName)) {
-                       fcpListenerManager.fireReceivedProtocolError(new ProtocolError(fcpMessage));
-               } else if ("PersistentGet".equals(messageName)) {
-                       fcpListenerManager.fireReceivedPersistentGet(new PersistentGet(fcpMessage));
-               } else if ("PersistentPut".equals(messageName)) {
-                       fcpListenerManager.fireReceivedPersistentPut(new PersistentPut(fcpMessage));
-               } else if ("PersistentPutDir".equals(messageName)) {
-                       fcpListenerManager.fireReceivedPersistentPutDir(new PersistentPutDir(fcpMessage));
-               } else if ("URIGenerated".equals(messageName)) {
-                       fcpListenerManager.fireReceivedURIGenerated(new URIGenerated(fcpMessage));
-               } else if ("EndListPersistentRequests".equals(messageName)) {
-                       fcpListenerManager.fireReceivedEndListPersistentRequests(new EndListPersistentRequests(fcpMessage));
-               } else if ("Peer".equals(messageName)) {
-                       fcpListenerManager.fireReceivedPeer(new Peer(fcpMessage));
-               } else if ("PeerNote".equals(messageName)) {
-                       fcpListenerManager.fireReceivedPeerNote(new PeerNote(fcpMessage));
-               } else if ("StartedCompression".equals(messageName)) {
-                       fcpListenerManager.fireReceivedStartedCompression(new StartedCompression(fcpMessage));
-               } else if ("FinishedCompression".equals(messageName)) {
-                       fcpListenerManager.fireReceivedFinishedCompression(new FinishedCompression(fcpMessage));
-               } else if ("GetFailed".equals(messageName)) {
-                       fcpListenerManager.fireReceivedGetFailed(new GetFailed(fcpMessage));
-               } else if ("PutFetchable".equals(messageName)) {
-                       fcpListenerManager.fireReceivedPutFetchable(new PutFetchable(fcpMessage));
-               } else if ("PutSuccessful".equals(messageName)) {
-                       fcpListenerManager.fireReceivedPutSuccessful(new PutSuccessful(fcpMessage));
-               } else if ("PutFailed".equals(messageName)) {
-                       fcpListenerManager.fireReceivedPutFailed(new PutFailed(fcpMessage));
-               } else if ("DataFound".equals(messageName)) {
-                       fcpListenerManager.fireReceivedDataFound(new DataFound(fcpMessage));
-               } else if ("SubscribedUSKUpdate".equals(messageName)) {
-                       fcpListenerManager.fireReceivedSubscribedUSKUpdate(new SubscribedUSKUpdate(fcpMessage));
-               } else if ("IdentifierCollision".equals(messageName)) {
-                       fcpListenerManager.fireReceivedIdentifierCollision(new IdentifierCollision(fcpMessage));
-               } else if ("AllData".equals(messageName)) {
-                       LimitedInputStream payloadInputStream = getInputStream(FcpUtils.safeParseLong(fcpMessage.getField("DataLength")));
-                       fcpListenerManager.fireReceivedAllData(new AllData(fcpMessage, payloadInputStream));
-                       try {
-                               payloadInputStream.consume();
-                       } catch (IOException ioe1) {
-                               /* well, ignore. when the connection handler fails, all fails. */
-                       }
-               } else if ("EndListPeerNotes".equals(messageName)) {
-                       fcpListenerManager.fireReceivedEndListPeerNotes(new EndListPeerNotes(fcpMessage));
-               } else if ("EndListPeers".equals(messageName)) {
-                       fcpListenerManager.fireReceivedEndListPeers(new EndListPeers(fcpMessage));
-               } else if ("SSKKeypair".equals(messageName)) {
-                       fcpListenerManager.fireReceivedSSKKeypair(new SSKKeypair(fcpMessage));
-               } else if ("PeerRemoved".equals(messageName)) {
-                       fcpListenerManager.fireReceivedPeerRemoved(new PeerRemoved(fcpMessage));
-               } else if ("PersistentRequestModified".equals(messageName)) {
-                       fcpListenerManager.fireReceivedPersistentRequestModified(new PersistentRequestModified(fcpMessage));
-               } else if ("PersistentRequestRemoved".equals(messageName)) {
-                       fcpListenerManager.fireReceivedPersistentRequestRemoved(new PersistentRequestRemoved(fcpMessage));
-               } else if ("UnknownPeerNoteType".equals(messageName)) {
-                       fcpListenerManager.fireReceivedUnknownPeerNoteType(new UnknownPeerNoteType(fcpMessage));
-               } else if ("UnknownNodeIdentifier".equals(messageName)) {
-                       fcpListenerManager.fireReceivedUnknownNodeIdentifier(new UnknownNodeIdentifier(fcpMessage));
-               } else if ("FCPPluginReply".equals(messageName)) {
-                       LimitedInputStream payloadInputStream = getInputStream(FcpUtils.safeParseLong(fcpMessage.getField("DataLength")));
-                       fcpListenerManager.fireReceivedFCPPluginReply(new FCPPluginReply(fcpMessage, payloadInputStream));
-                       try {
-                               payloadInputStream.consume();
-                       } catch (IOException ioe1) {
-                               /* ignore. */
-                       }
-               } else if ("PluginInfo".equals(messageName)) {
-                       fcpListenerManager.fireReceivedPluginInfo(new PluginInfo(fcpMessage));
-               } else if ("NodeData".equals(messageName)) {
-                       fcpListenerManager.fireReceivedNodeData(new NodeData(fcpMessage));
-               } else if ("TestDDAReply".equals(messageName)) {
-                       fcpListenerManager.fireReceivedTestDDAReply(new TestDDAReply(fcpMessage));
-               } else if ("TestDDAComplete".equals(messageName)) {
-                       fcpListenerManager.fireReceivedTestDDAComplete(new TestDDAComplete(fcpMessage));
-               } else if ("ConfigData".equals(messageName)) {
-                       fcpListenerManager.fireReceivedConfigData(new ConfigData(fcpMessage));
-               } else if ("NodeHello".equals(messageName)) {
-                       fcpListenerManager.fireReceivedNodeHello(new NodeHello(fcpMessage));
-               } else if ("CloseConnectionDuplicateClientName".equals(messageName)) {
-                       fcpListenerManager.fireReceivedCloseConnectionDuplicateClientName(new CloseConnectionDuplicateClientName(fcpMessage));
-               } else if ("SentFeed".equals(messageName)) {
-                       fcpListenerManager.fireSentFeed(new SentFeed(fcpMessage));
-               } else if ("ReceivedBookmarkFeed".equals(messageName)) {
-                       fcpListenerManager.fireReceivedBookmarkFeed(new ReceivedBookmarkFeed(fcpMessage));
-               } else {
-                       fcpListenerManager.fireMessageReceived(fcpMessage);
-               }
-       }
-
-       /**
-        * 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(Throwable throwable) {
-               FcpUtils.close(remoteInputStream);
-               FcpUtils.close(remoteOutputStream);
-               FcpUtils.close(remoteSocket);
-               if (connectionHandler != null) {
-                       connectionHandler.stop();
-                       connectionHandler = null;
-                       fcpListenerManager.fireConnectionClosed(throwable);
-               }
-       }
-
-       //
-       // PRIVATE METHODS
-       //
-
-       /**
-        * Incremets the counter in {@link #incomingMessageStatistics} by
-        * <cod>1</code> for the given message name.
-        *
-        * @param name
-        *            The name of the message to count
-        */
-       private void countMessage(String name) {
-               int oldValue = 0;
-               if (incomingMessageStatistics.containsKey(name)) {
-                       oldValue = incomingMessageStatistics.get(name);
-               }
-               incomingMessageStatistics.put(name, oldValue + 1);
-               logger.finest("count for " + name + ": " + (oldValue + 1));
-       }
-
-       /**
-        * Returns a limited input stream from the node’s input stream.
-        *
-        * @param dataLength
-        *            The length of the stream
-        * @return The limited input stream
-        */
-       private synchronized LimitedInputStream getInputStream(long dataLength) {
-               if (dataLength <= 0) {
-                       return new LimitedInputStream(null, 0);
-               }
-               return new LimitedInputStream(remoteInputStream, dataLength);
-       }
-
-       /**
-        * A wrapper around an {@link InputStream} that only supplies a limit number
-        * of bytes from the underlying input stream.
-        *
-        * @author David ‘Bombe’ Roden &lt;bombe@freenetproject.org&gt;
-        */
-       private static class LimitedInputStream extends FilterInputStream {
-
-               /** The remaining number of bytes that can be read. */
-               private long remaining;
-
-               /**
-                * Creates a new LimitedInputStream that supplies at most
-                * <code>length</code> bytes from the given input stream.
-                *
-                * @param inputStream
-                *            The input stream
-                * @param length
-                *            The number of bytes to read
-                */
-               public LimitedInputStream(InputStream inputStream, long length) {
-                       super(inputStream);
-                       remaining = length;
-               }
-
-               /**
-                * @see java.io.FilterInputStream#available()
-                */
-               @Override
-               public synchronized int available() throws IOException {
-                       if (remaining == 0) {
-                               return 0;
-                       }
-                       return (int) Math.min(super.available(), Math.min(Integer.MAX_VALUE, remaining));
-               }
-
-               /**
-                * @see java.io.FilterInputStream#read()
-                */
-               @Override
-               public synchronized int read() throws IOException {
-                       int read = -1;
-                       if (remaining > 0) {
-                               read = super.read();
-                               remaining--;
-                       }
-                       return read;
-               }
-
-               /**
-                * @see java.io.FilterInputStream#read(byte[], int, int)
-                */
-               @Override
-               public synchronized int read(byte[] b, int off, int len) throws IOException {
-                       if (remaining == 0) {
-                               return -1;
-                       }
-                       int toCopy = (int) Math.min(len, Math.min(remaining, Integer.MAX_VALUE));
-                       int read = super.read(b, off, toCopy);
-                       remaining -= read;
-                       return read;
-               }
-
-               /**
-                * @see java.io.FilterInputStream#skip(long)
-                */
-               @Override
-               public synchronized long skip(long n) throws IOException {
-                       if ((n < 0) || (remaining == 0)) {
-                               return 0;
-                       }
-                       long skipped = super.skip(Math.min(n, remaining));
-                       remaining -= skipped;
-                       return skipped;
-               }
-
-               /**
-                * {@inheritDoc} This method does nothing, as {@link #mark(int)} and
-                * {@link #reset()} are not supported.
-                *
-                * @see java.io.FilterInputStream#mark(int)
-                */
-               @Override
-               public void mark(int readlimit) {
-                       /* do nothing. */
-               }
-
-               /**
-                * {@inheritDoc}
-                *
-                * @see java.io.FilterInputStream#markSupported()
-                * @return <code>false</code>
-                */
-               @Override
-               public boolean markSupported() {
-                       return false;
-               }
-
-               /**
-                * {@inheritDoc} This method does nothing, as {@link #mark(int)} and
-                * {@link #reset()} are not supported.
-                *
-                * @see java.io.FilterInputStream#reset()
-                */
-               @Override
-               public void reset() throws IOException {
-                       /* do nothing. */
-               }
-
-               /**
-                * Consumes the input stream, i.e. read all bytes until the limit is
-                * reached.
-                *
-                * @throws IOException
-                *             if an I/O error occurs
-                */
-               public synchronized void consume() throws IOException {
-                       while (remaining > 0) {
-                               skip(remaining);
-                       }
-               }
-
-       }
-
-}
diff --git a/src/net/pterodactylus/fcp/FcpConnectionHandler.java b/src/net/pterodactylus/fcp/FcpConnectionHandler.java
deleted file mode 100644 (file)
index dbf0969..0000000
+++ /dev/null
@@ -1,160 +0,0 @@
-/*
- * jFCPlib - FcpConnectionHandler.java - Copyright © 2008 David Roden
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- */
-
-package net.pterodactylus.fcp;
-
-import java.io.IOException;
-import java.io.InputStream;
-import java.nio.ByteBuffer;
-import java.nio.charset.Charset;
-
-/**
- * Handles an FCP connection to a node.
- *
- * @author David ‘Bombe’ Roden &lt;bombe@freenetproject.org&gt;
- */
-class FcpConnectionHandler implements Runnable {
-
-       /** The underlying connection. */
-       private final FcpConnection fcpConnection;
-
-       /** The input stream from the node. */
-       private final InputStream remoteInputStream;
-
-       /** Whether to stop the connection handler. */
-       private boolean shouldStop;
-
-       /** Whether the next read line feed should be ignored. */
-       private boolean ignoreNextLinefeed;
-
-       /**
-        * Creates a new connection handler that operates on the given connection
-        * and input stream.
-        *
-        * @param fcpConnection
-        *            The underlying FCP connection
-        * @param remoteInputStream
-        *            The input stream from the node
-        */
-       public FcpConnectionHandler(FcpConnection fcpConnection, InputStream remoteInputStream) {
-               this.fcpConnection = fcpConnection;
-               this.remoteInputStream = remoteInputStream;
-       }
-
-       /**
-        * {@inheritDoc}
-        */
-       public void run() {
-               FcpMessage fcpMessage = null;
-               Throwable throwable = null;
-               while (true) {
-                       synchronized (this) {
-                               if (shouldStop) {
-                                       break;
-                               }
-                       }
-                       try {
-                               String line = readLine();
-                               System.out.println("read line: " + line);
-                               if (line == null) {
-                                       break;
-                               }
-                               if (line.length() == 0) {
-                                       continue;
-                               }
-                               line = line.trim();
-                               if (fcpMessage == null) {
-                                       fcpMessage = new FcpMessage(line);
-                                       continue;
-                               }
-                               if ("EndMessage".equalsIgnoreCase(line) || "Data".equalsIgnoreCase(line)) {
-                                       fcpConnection.handleMessage(fcpMessage);
-                                       fcpMessage = null;
-                               }
-                               int equalSign = line.indexOf('=');
-                               if (equalSign == -1) {
-                                       /* something's fishy! */
-                                       continue;
-                               }
-                               String field = line.substring(0, equalSign);
-                               String value = line.substring(equalSign + 1);
-                               assert fcpMessage != null: "fcp message is null";
-                               fcpMessage.setField(field, value);
-                       } catch (IOException ioe1) {
-                               throwable = ioe1;
-                               break;
-                       }
-               }
-               fcpConnection.handleDisconnect(throwable);
-       }
-
-       /**
-        * Stops the connection handler.
-        */
-       public void stop() {
-               synchronized (this) {
-                       shouldStop = true;
-               }
-       }
-
-       //
-       // PRIVATE METHODS
-       //
-
-       /**
-        * Reads bytes from {@link #remoteInputStream} until ‘\r’ or ‘\n’ are
-        * encountered and decodes the read bytes using UTF-8.
-        *
-        * @return The decoded line
-        * @throws IOException
-        *             if an I/O error occurs
-        */
-       private String readLine() throws IOException {
-               byte[] readBytes = new byte[512];
-               int readIndex = 0;
-               while (true) {
-                       int nextByte = remoteInputStream.read();
-                       if (nextByte == -1) {
-                               if (readIndex == 0) {
-                                       return null;
-                               }
-                               break;
-                       }
-                       if (nextByte == 10) {
-                               if (!ignoreNextLinefeed) {
-                                       break;
-                               }
-                       }
-                       ignoreNextLinefeed = false;
-                       if (nextByte == 13) {
-                               ignoreNextLinefeed = true;
-                               break;
-                       }
-                       if (readIndex == readBytes.length) {
-                               /* recopy & enlarge array */
-                               byte[] newReadBytes = new byte[readBytes.length * 2];
-                               System.arraycopy(readBytes, 0, newReadBytes, 0, readBytes.length);
-                               readBytes = newReadBytes;
-                       }
-                       readBytes[readIndex++] = (byte) nextByte;
-               }
-               ByteBuffer byteBuffer = ByteBuffer.wrap(readBytes, 0, readIndex);
-               return Charset.forName("UTF-8").decode(byteBuffer).toString();
-       }
-
-}
diff --git a/src/net/pterodactylus/fcp/FcpKeyPair.java b/src/net/pterodactylus/fcp/FcpKeyPair.java
deleted file mode 100644 (file)
index 4b9ba05..0000000
+++ /dev/null
@@ -1,65 +0,0 @@
-/*
- * jFCPlib - FcpKeyPair.java - Copyright © 2008 David Roden
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- */
-
-package net.pterodactylus.fcp;
-
-/**
- * Container for an SSK keypair.
- *
- * @author David ‘Bombe’ Roden &lt;bombe@freenetproject.org&gt;
- */
-public class FcpKeyPair {
-
-       /** The public key. */
-       private final String publicKey;
-
-       /** The private key. */
-       private final String privateKey;
-
-       /**
-        * Creates a new keypair from the given keys.
-        *
-        * @param publicKey
-        *            The public key
-        * @param privateKey
-        *            The private key
-        */
-       public FcpKeyPair(String publicKey, String privateKey) {
-               this.publicKey = publicKey;
-               this.privateKey = privateKey;
-       }
-
-       /**
-        * Returns the public key of this keypair.
-        *
-        * @return The public key
-        */
-       public String getPublicKey() {
-               return publicKey;
-       }
-
-       /**
-        * Returns the private key of this keypair.
-        *
-        * @return The private key
-        */
-       public String getPrivateKey() {
-               return privateKey;
-       }
-
-}
diff --git a/src/net/pterodactylus/fcp/FcpListener.java b/src/net/pterodactylus/fcp/FcpListener.java
deleted file mode 100644 (file)
index 4f0c77a..0000000
+++ /dev/null
@@ -1,428 +0,0 @@
-/*
- * jFCPlib - FpcListener.java - Copyright © 2008 David Roden
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- */
-
-package net.pterodactylus.fcp;
-
-import java.util.EventListener;
-
-/**
- * Interface for objects that want to be notified on certain FCP events.
- *
- * @author David ‘Bombe’ Roden &lt;bombe@freenetproject.org&gt;
- */
-public interface FcpListener extends EventListener {
-
-       /**
-        * Notifies a listener that a “NodeHello” message was received.
-        *
-        * @param fcpConnection
-        *            The connection that received the message
-        * @param nodeHello
-        *            The “NodeHello” message
-        */
-       public void receivedNodeHello(FcpConnection fcpConnection, NodeHello nodeHello);
-
-       /**
-        * Notifies a listener that a “CloseConnectionDuplicateClientName” message
-        * was received.
-        *
-        * @param fcpConnection
-        *            The connection that received the message
-        * @param closeConnectionDuplicateClientName
-        *            The “CloseConnectionDuplicateClientName” message
-        */
-       public void receivedCloseConnectionDuplicateClientName(FcpConnection fcpConnection, CloseConnectionDuplicateClientName closeConnectionDuplicateClientName);
-
-       /**
-        * Notifies a listener that a “SSKKeypair” message was received.
-        *
-        * @param fcpConnection
-        *            The connection that received themessage
-        * @param sskKeypair
-        *            The “SSKKeypair” message
-        */
-       public void receivedSSKKeypair(FcpConnection fcpConnection, SSKKeypair sskKeypair);
-
-       /**
-        * Notifies a listener that a “Peer” message was received.
-        *
-        * @param fcpConnection
-        *            The connection that received the message
-        * @param peer
-        *            The “Peer” message
-        */
-       public void receivedPeer(FcpConnection fcpConnection, Peer peer);
-
-       /**
-        * Notifies a listener that an “EndListPeers” message was received.
-        *
-        * @param fcpConnection
-        *            The connection that recevied the message
-        * @param endListPeers
-        *            The “EndListPeers” message
-        */
-       public void receivedEndListPeers(FcpConnection fcpConnection, EndListPeers endListPeers);
-
-       /**
-        * Notifies a listener that a “PeerNote” message was received.
-        *
-        * @param fcpConnection
-        *            The connection that received the message
-        * @param peerNote
-        *            The “PeerNote” message
-        */
-       public void receivedPeerNote(FcpConnection fcpConnection, PeerNote peerNote);
-
-       /**
-        * Notifies a listener that an “EndListPeerNotes” message was received.
-        *
-        * @param fcpConnection
-        *            The connection that received the message
-        * @param endListPeerNotes
-        *            The “EndListPeerNotes” message
-        */
-       public void receivedEndListPeerNotes(FcpConnection fcpConnection, EndListPeerNotes endListPeerNotes);
-
-       /**
-        * Notifies a listener that a “PeerRemoved” message was received.
-        *
-        * @param fcpConnection
-        *            The connection that received the message
-        * @param peerRemoved
-        *            The “PeerRemoved” message
-        */
-       public void receivedPeerRemoved(FcpConnection fcpConnection, PeerRemoved peerRemoved);
-
-       /**
-        * Notifies a listener that a “NodeData” message was received.
-        *
-        * @param fcpConnection
-        *            The connection that received the message
-        * @param nodeData
-        *            The “NodeData” message
-        */
-       public void receivedNodeData(FcpConnection fcpConnection, NodeData nodeData);
-
-       /**
-        * Notifies a listener that a “TestDDAReply” message was received.
-        *
-        * @param fcpConnection
-        *            The connection that received the message
-        * @param testDDAReply
-        *            The “TestDDAReply” message
-        */
-       public void receivedTestDDAReply(FcpConnection fcpConnection, TestDDAReply testDDAReply);
-
-       /**
-        * Notifies a listener that a “TestDDAComplete” was received.
-        *
-        * @param fcpConnection
-        *            The connection that received the message
-        * @param testDDAComplete
-        *            The “TestDDAComplete” message
-        */
-       public void receivedTestDDAComplete(FcpConnection fcpConnection, TestDDAComplete testDDAComplete);
-
-       /**
-        * Notifies a listener that a “PersistentGet” was received.
-        *
-        * @param fcpConnection
-        *            The connection that received the message
-        * @param persistentGet
-        *            The “PersistentGet” message
-        */
-       public void receivedPersistentGet(FcpConnection fcpConnection, PersistentGet persistentGet);
-
-       /**
-        * Notifies a listener that a “PersistentPut” was received.
-        *
-        * @param fcpConnection
-        *            The connection that received the message
-        * @param persistentPut
-        *            The “PersistentPut” message
-        */
-       public void receivedPersistentPut(FcpConnection fcpConnection, PersistentPut persistentPut);
-
-       /**
-        * Notifies a listener that a “EndListPersistentRequests” was received.
-        *
-        * @param fcpConnection
-        *            The connection that received the message
-        * @param endListPersistentRequests
-        *            The “EndListPersistentRequests” message
-        */
-       public void receivedEndListPersistentRequests(FcpConnection fcpConnection, EndListPersistentRequests endListPersistentRequests);
-
-       /**
-        * Notifies a listener that a “URIGenerated” was received.
-        *
-        * @param fcpConnection
-        *            The connection that received the message
-        * @param uriGenerated
-        *            The “URIGenerated” message
-        */
-       public void receivedURIGenerated(FcpConnection fcpConnection, URIGenerated uriGenerated);
-
-       /**
-        * Notifies a listener that a “DataFound” was received.
-        *
-        * @param fcpConnection
-        *            The connection that received the message
-        * @param dataFound
-        *            The “DataFound” message
-        */
-       public void receivedDataFound(FcpConnection fcpConnection, DataFound dataFound);
-
-       /**
-        * Notifies a listener that an “AllData” was received.
-        *
-        * @param fcpConnection
-        *            The connection that received the message
-        * @param allData
-        *            The “AllData” message
-        */
-       public void receivedAllData(FcpConnection fcpConnection, AllData allData);
-
-       /**
-        * Notifies a listener that a “SimpleProgress” was received.
-        *
-        * @param fcpConnection
-        *            The connection that received the message
-        * @param simpleProgress
-        *            The “SimpleProgress” message
-        */
-       public void receivedSimpleProgress(FcpConnection fcpConnection, SimpleProgress simpleProgress);
-
-       /**
-        * Notifies a listener that a “StartedCompression” was received.
-        *
-        * @param fcpConnection
-        *            The connection that received the message
-        * @param startedCompression
-        *            The “StartedCompression” message
-        */
-       public void receivedStartedCompression(FcpConnection fcpConnection, StartedCompression startedCompression);
-
-       /**
-        * Notifies a listener that a “FinishedCompression” was received.
-        *
-        * @param fcpConnection
-        *            The connection that received the message
-        * @param finishedCompression
-        *            The “FinishedCompression” message
-        */
-       public void receivedFinishedCompression(FcpConnection fcpConnection, FinishedCompression finishedCompression);
-
-       /**
-        * Notifies a listener that an “UnknownPeerNoteType” was received.
-        *
-        * @param fcpConnection
-        *            The connection that received the message
-        * @param unknownPeerNoteType
-        *            The “UnknownPeerNoteType” message
-        */
-       public void receivedUnknownPeerNoteType(FcpConnection fcpConnection, UnknownPeerNoteType unknownPeerNoteType);
-
-       /**
-        * Notifies a listener that a “UnknownNodeIdentifier” message was received.
-        *
-        * @param fcpConnection
-        *            The connection that received the message
-        * @param unknownNodeIdentifier
-        *            The “UnknownNodeIdentifier” message
-        */
-       public void receivedUnknownNodeIdentifier(FcpConnection fcpConnection, UnknownNodeIdentifier unknownNodeIdentifier);
-
-       /**
-        * Notifies a listener that a “ConfigData” message was received.
-        *
-        * @param fcpConnection
-        *            The connection that received the message
-        * @param configData
-        *            The “ConfigData” message
-        */
-       public void receivedConfigData(FcpConnection fcpConnection, ConfigData configData);
-
-       /**
-        * Notifies a listener that a “GetFailed” message was recevied.
-        *
-        * @param fcpConnection
-        *            The connection that received the message
-        * @param getFailed
-        *            The “GetFailed” message
-        */
-       public void receivedGetFailed(FcpConnection fcpConnection, GetFailed getFailed);
-
-       /**
-        * Notifies a listener that a “PutFailed” message was received.
-        *
-        * @param fcpConnection
-        *            The connection that received the message
-        * @param putFailed
-        *            The “PutFailed” message
-        */
-       public void receivedPutFailed(FcpConnection fcpConnection, PutFailed putFailed);
-
-       /**
-        * Notifies a listener that an “IdentifierCollision” message was receied.
-        *
-        * @param fcpConnection
-        *            The connection that received the message
-        * @param identifierCollision
-        *            The “IdentifierCollision” message
-        */
-       public void receivedIdentifierCollision(FcpConnection fcpConnection, IdentifierCollision identifierCollision);
-
-       /**
-        * Notifies a listener that a “PersistentPutDir” message was received.
-        *
-        * @param fcpConnection
-        *            The connection that received the message
-        * @param persistentPutDir
-        *            The “PersistentPutDir” message
-        */
-       public void receivedPersistentPutDir(FcpConnection fcpConnection, PersistentPutDir persistentPutDir);
-
-       /**
-        * Notifies a listener that a “PersistentRequestRemoved” message was
-        * received.
-        *
-        * @param fcpConnection
-        *            The connection that received the message
-        * @param persistentRequestRemoved
-        *            The “PersistentRequestRemoved” message
-        */
-       public void receivedPersistentRequestRemoved(FcpConnection fcpConnection, PersistentRequestRemoved persistentRequestRemoved);
-
-       /**
-        * Notifies a listener that a “SubscribedUSKUpdate” message was received.
-        *
-        * @param fcpConnection
-        *            The connection that recevied the message
-        * @param subscribedUSKUpdate
-        *            The “SubscribedUSKUpdate” message
-        */
-       public void receivedSubscribedUSKUpdate(FcpConnection fcpConnection, SubscribedUSKUpdate subscribedUSKUpdate);
-
-       /**
-        * Notifies a listener that a “PluginInfo” message was received.
-        *
-        * @param fcpConnection
-        *            The connection that received the message
-        * @param pluginInfo
-        *            The “PluginInfo” message
-        */
-       public void receivedPluginInfo(FcpConnection fcpConnection, PluginInfo pluginInfo);
-
-       /**
-        * Notifies a listener that an “FCPPluginReply“ message was received.
-        *
-        * @param fcpConnection
-        *            The connection that received the message
-        * @param fcpPluginReply
-        *            The “FCPPluginReply” message
-        */
-       public void receivedFCPPluginReply(FcpConnection fcpConnection, FCPPluginReply fcpPluginReply);
-
-       /**
-        * Notifies a listener that a “PersistentRequestModified” message was
-        * received.
-        *
-        * @param fcpConnection
-        *            The connection that received the message
-        * @param persistentRequestModified
-        *            The “PersistentRequestModified” message
-        */
-       public void receivedPersistentRequestModified(FcpConnection fcpConnection, PersistentRequestModified persistentRequestModified);
-
-       /**
-        * Notifies a listener that a “PutSuccessful” message was received.
-        *
-        * @param fcpConnection
-        *            The connection that received the message
-        * @param putSuccessful
-        *            The “PutSuccessful” message
-        */
-       public void receivedPutSuccessful(FcpConnection fcpConnection, PutSuccessful putSuccessful);
-
-       /**
-        * Notifies a listener that a “PutFetchable” message was received.
-        *
-        * @param fcpConnection
-        *            The connection that received the message
-        * @param putFetchable
-        *            The “PutFetchable” message
-        */
-       public void receivedPutFetchable(FcpConnection fcpConnection, PutFetchable putFetchable);
-
-       /**
-        * Notifies a listener that a feed was sent to a peer.
-        *
-        * @param source
-        *            The connection that received the message
-        * @param sentFeed
-        *            The “SentFeed” message
-        */
-       public void receivedSentFeed(FcpConnection source, SentFeed sentFeed);
-
-       /**
-        * Notifies a listener that a bookmark was updated.
-        *
-        * @param fcpConnection
-        *            The connection that received the message
-        * @param receivedBookmarkFeed
-        *            The “ReceivedBookmarkFeed” message
-        */
-       public void receivedBookmarkFeed(FcpConnection fcpConnection, ReceivedBookmarkFeed receivedBookmarkFeed);
-
-       /**
-        * Notifies a listener that a “ProtocolError” was received.
-        *
-        * @param fcpConnection
-        *            The connection that received the message
-        * @param protocolError
-        *            The “ProtocolError” message
-        */
-       public void receivedProtocolError(FcpConnection fcpConnection, ProtocolError protocolError);
-
-       /**
-        * Notifies a listener that a message has been received. This method is only
-        * called if {@link FcpConnection#handleMessage(FcpMessage)} does not
-        * recognize the message. Should that ever happen, please file a bug report!
-        *
-        * @param fcpConnection
-        *            The connection that received the message
-        * @param fcpMessage
-        *            The message that was received
-        */
-       public void receivedMessage(FcpConnection fcpConnection, FcpMessage fcpMessage);
-
-       /**
-        * Notifies a listener that a connection was closed. A closed connection can
-        * be reestablished by calling {@link FcpConnection#connect()} on the same
-        * object again.
-        *
-        * @param fcpConnection
-        *            The connection that was closed.
-        * @param throwable
-        *            The exception that caused the disconnect, or <code>null</code>
-        *            if there was no exception
-        */
-       public void connectionClosed(FcpConnection fcpConnection, Throwable throwable);
-
-}
diff --git a/src/net/pterodactylus/fcp/FcpListenerManager.java b/src/net/pterodactylus/fcp/FcpListenerManager.java
deleted file mode 100644 (file)
index 4e1cce6..0000000
+++ /dev/null
@@ -1,568 +0,0 @@
-/*
- * jFCPlib - FcpListenerManager.java - Copyright © 2009 David Roden
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- */
-
-package net.pterodactylus.fcp;
-
-import net.pterodactylus.util.event.AbstractListenerManager;
-
-/**
- * Manages FCP listeners and event firing.
- *
- * @author David ‘Bombe’ Roden &lt;bombe@pterodactylus.net&gt;
- */
-public class FcpListenerManager extends AbstractListenerManager<FcpConnection, FcpListener> {
-
-       /**
-        * Creates a new listener manager.
-        *
-        * @param fcpConnection
-        *            The source FCP connection
-        */
-       public FcpListenerManager(FcpConnection fcpConnection) {
-               super(fcpConnection);
-       }
-
-       /**
-        * Notifies listeners that a “NodeHello” message was received.
-        *
-        * @see FcpListener#receivedNodeHello(FcpConnection, NodeHello)
-        * @param nodeHello
-        *            The “NodeHello” message
-        */
-       public void fireReceivedNodeHello(NodeHello nodeHello) {
-               for (FcpListener fcpListener : getListeners()) {
-                       fcpListener.receivedNodeHello(getSource(), nodeHello);
-               }
-       }
-
-       /**
-        * Notifies listeners that a “CloseConnectionDuplicateClientName” message
-        * was received.
-        *
-        * @see FcpListener#receivedCloseConnectionDuplicateClientName(FcpConnection,
-        *      CloseConnectionDuplicateClientName)
-        * @param closeConnectionDuplicateClientName
-        *            The “CloseConnectionDuplicateClientName” message
-        */
-       public void fireReceivedCloseConnectionDuplicateClientName(CloseConnectionDuplicateClientName closeConnectionDuplicateClientName) {
-               for (FcpListener fcpListener : getListeners()) {
-                       fcpListener.receivedCloseConnectionDuplicateClientName(getSource(), closeConnectionDuplicateClientName);
-               }
-       }
-
-       /**
-        * Notifies listeners that a “SSKKeypair” message was received.
-        *
-        * @see FcpListener#receivedSSKKeypair(FcpConnection, SSKKeypair)
-        * @param sskKeypair
-        *            The “SSKKeypair” message
-        */
-       public void fireReceivedSSKKeypair(SSKKeypair sskKeypair) {
-               for (FcpListener fcpListener : getListeners()) {
-                       fcpListener.receivedSSKKeypair(getSource(), sskKeypair);
-               }
-       }
-
-       /**
-        * Notifies listeners that a “Peer” message was received.
-        *
-        * @see FcpListener#receivedPeer(FcpConnection, Peer)
-        * @param peer
-        *            The “Peer” message
-        */
-       public void fireReceivedPeer(Peer peer) {
-               for (FcpListener fcpListener : getListeners()) {
-                       fcpListener.receivedPeer(getSource(), peer);
-               }
-       }
-
-       /**
-        * Notifies all listeners that an “EndListPeers” message was received.
-        *
-        * @see FcpListener#receivedEndListPeers(FcpConnection, EndListPeers)
-        * @param endListPeers
-        *            The “EndListPeers” message
-        */
-       public void fireReceivedEndListPeers(EndListPeers endListPeers) {
-               for (FcpListener fcpListener : getListeners()) {
-                       fcpListener.receivedEndListPeers(getSource(), endListPeers);
-               }
-       }
-
-       /**
-        * Notifies all listeners that a “PeerNote” message was received.
-        *
-        * @see FcpListener#receivedPeerNote(FcpConnection, PeerNote)
-        * @param peerNote
-        */
-       public void fireReceivedPeerNote(PeerNote peerNote) {
-               for (FcpListener fcpListener : getListeners()) {
-                       fcpListener.receivedPeerNote(getSource(), peerNote);
-               }
-       }
-
-       /**
-        * Notifies all listeners that an “EndListPeerNotes” message was received.
-        *
-        * @see FcpListener#receivedEndListPeerNotes(FcpConnection,
-        *      EndListPeerNotes)
-        * @param endListPeerNotes
-        *            The “EndListPeerNotes” message
-        */
-       public void fireReceivedEndListPeerNotes(EndListPeerNotes endListPeerNotes) {
-               for (FcpListener fcpListener : getListeners()) {
-                       fcpListener.receivedEndListPeerNotes(getSource(), endListPeerNotes);
-               }
-       }
-
-       /**
-        * Notifies all listeners that a “PeerRemoved” message was received.
-        *
-        * @see FcpListener#receivedPeerRemoved(FcpConnection, PeerRemoved)
-        * @param peerRemoved
-        *            The “PeerRemoved” message
-        */
-       public void fireReceivedPeerRemoved(PeerRemoved peerRemoved) {
-               for (FcpListener fcpListener : getListeners()) {
-                       fcpListener.receivedPeerRemoved(getSource(), peerRemoved);
-               }
-       }
-
-       /**
-        * Notifies all listeners that a “NodeData” message was received.
-        *
-        * @see FcpListener#receivedNodeData(FcpConnection, NodeData)
-        * @param nodeData
-        *            The “NodeData” message
-        */
-       public void fireReceivedNodeData(NodeData nodeData) {
-               for (FcpListener fcpListener : getListeners()) {
-                       fcpListener.receivedNodeData(getSource(), nodeData);
-               }
-       }
-
-       /**
-        * Notifies all listeners that a “TestDDAReply” message was received.
-        *
-        * @see FcpListener#receivedTestDDAReply(FcpConnection, TestDDAReply)
-        * @param testDDAReply
-        *            The “TestDDAReply” message
-        */
-       public void fireReceivedTestDDAReply(TestDDAReply testDDAReply) {
-               for (FcpListener fcpListener : getListeners()) {
-                       fcpListener.receivedTestDDAReply(getSource(), testDDAReply);
-               }
-       }
-
-       /**
-        * Notifies all listeners that a “TestDDAComplete” message was received.
-        *
-        * @see FcpListener#receivedTestDDAComplete(FcpConnection, TestDDAComplete)
-        * @param testDDAComplete
-        *            The “TestDDAComplete” message
-        */
-       public void fireReceivedTestDDAComplete(TestDDAComplete testDDAComplete) {
-               for (FcpListener fcpListener : getListeners()) {
-                       fcpListener.receivedTestDDAComplete(getSource(), testDDAComplete);
-               }
-       }
-
-       /**
-        * Notifies all listeners that a “PersistentGet” message was received.
-        *
-        * @see FcpListener#receivedPersistentGet(FcpConnection, PersistentGet)
-        * @param persistentGet
-        *            The “PersistentGet” message
-        */
-       public void fireReceivedPersistentGet(PersistentGet persistentGet) {
-               for (FcpListener fcpListener : getListeners()) {
-                       fcpListener.receivedPersistentGet(getSource(), persistentGet);
-               }
-       }
-
-       /**
-        * Notifies all listeners that a “PersistentPut” message was received.
-        *
-        * @see FcpListener#receivedPersistentPut(FcpConnection, PersistentPut)
-        * @param persistentPut
-        *            The “PersistentPut” message
-        */
-       public void fireReceivedPersistentPut(PersistentPut persistentPut) {
-               for (FcpListener fcpListener : getListeners()) {
-                       fcpListener.receivedPersistentPut(getSource(), persistentPut);
-               }
-       }
-
-       /**
-        * Notifies all listeners that a “EndListPersistentRequests” message was
-        * received.
-        *
-        * @see FcpListener#receivedEndListPersistentRequests(FcpConnection,
-        *      EndListPersistentRequests)
-        * @param endListPersistentRequests
-        *            The “EndListPersistentRequests” message
-        */
-       public void fireReceivedEndListPersistentRequests(EndListPersistentRequests endListPersistentRequests) {
-               for (FcpListener fcpListener : getListeners()) {
-                       fcpListener.receivedEndListPersistentRequests(getSource(), endListPersistentRequests);
-               }
-       }
-
-       /**
-        * Notifies all listeners that a “URIGenerated” message was received.
-        *
-        * @see FcpListener#receivedURIGenerated(FcpConnection, URIGenerated)
-        * @param uriGenerated
-        *            The “URIGenerated” message
-        */
-       public void fireReceivedURIGenerated(URIGenerated uriGenerated) {
-               for (FcpListener fcpListener : getListeners()) {
-                       fcpListener.receivedURIGenerated(getSource(), uriGenerated);
-               }
-       }
-
-       /**
-        * Notifies all listeners that a “DataFound” message was received.
-        *
-        * @see FcpListener#receivedDataFound(FcpConnection, DataFound)
-        * @param dataFound
-        *            The “DataFound” message
-        */
-       public void fireReceivedDataFound(DataFound dataFound) {
-               for (FcpListener fcpListener : getListeners()) {
-                       fcpListener.receivedDataFound(getSource(), dataFound);
-               }
-       }
-
-       /**
-        * Notifies all listeners that an “AllData” message was received.
-        *
-        * @see FcpListener#receivedAllData(FcpConnection, AllData)
-        * @param allData
-        *            The “AllData” message
-        */
-       public void fireReceivedAllData(AllData allData) {
-               for (FcpListener fcpListener : getListeners()) {
-                       fcpListener.receivedAllData(getSource(), allData);
-               }
-       }
-
-       /**
-        * Notifies all listeners that a “SimpleProgress” message was received.
-        *
-        * @see FcpListener#receivedSimpleProgress(FcpConnection, SimpleProgress)
-        * @param simpleProgress
-        *            The “SimpleProgress” message
-        */
-       public void fireReceivedSimpleProgress(SimpleProgress simpleProgress) {
-               for (FcpListener fcpListener : getListeners()) {
-                       fcpListener.receivedSimpleProgress(getSource(), simpleProgress);
-               }
-       }
-
-       /**
-        * Notifies all listeners that a “StartedCompression” message was received.
-        *
-        * @see FcpListener#receivedStartedCompression(FcpConnection,
-        *      StartedCompression)
-        * @param startedCompression
-        *            The “StartedCompression” message
-        */
-       public void fireReceivedStartedCompression(StartedCompression startedCompression) {
-               for (FcpListener fcpListener : getListeners()) {
-                       fcpListener.receivedStartedCompression(getSource(), startedCompression);
-               }
-       }
-
-       /**
-        * Notifies all listeners that a “FinishedCompression” message was received.
-        *
-        * @see FcpListener#receivedFinishedCompression(FcpConnection,
-        *      FinishedCompression)
-        * @param finishedCompression
-        *            The “FinishedCompression” message
-        */
-       public void fireReceivedFinishedCompression(FinishedCompression finishedCompression) {
-               for (FcpListener fcpListener : getListeners()) {
-                       fcpListener.receivedFinishedCompression(getSource(), finishedCompression);
-               }
-       }
-
-       /**
-        * Notifies all listeners that an “UnknownPeerNoteType” message was
-        * received.
-        *
-        * @see FcpListener#receivedUnknownPeerNoteType(FcpConnection,
-        *      UnknownPeerNoteType)
-        * @param unknownPeerNoteType
-        *            The “UnknownPeerNoteType” message
-        */
-       public void fireReceivedUnknownPeerNoteType(UnknownPeerNoteType unknownPeerNoteType) {
-               for (FcpListener fcpListener : getListeners()) {
-                       fcpListener.receivedUnknownPeerNoteType(getSource(), unknownPeerNoteType);
-               }
-       }
-
-       /**
-        * Notifies all listeners that an “UnknownNodeIdentifier” message was
-        * received.
-        *
-        * @see FcpListener#receivedUnknownNodeIdentifier(FcpConnection,
-        *      UnknownNodeIdentifier)
-        * @param unknownNodeIdentifier
-        *            The “UnknownNodeIdentifier” message
-        */
-       public void fireReceivedUnknownNodeIdentifier(UnknownNodeIdentifier unknownNodeIdentifier) {
-               for (FcpListener fcpListener : getListeners()) {
-                       fcpListener.receivedUnknownNodeIdentifier(getSource(), unknownNodeIdentifier);
-               }
-       }
-
-       /**
-        * Notifies all listeners that a “ConfigData” message was received.
-        *
-        * @see FcpListener#receivedConfigData(FcpConnection, ConfigData)
-        * @param configData
-        *            The “ConfigData” message
-        */
-       public void fireReceivedConfigData(ConfigData configData) {
-               for (FcpListener fcpListener : getListeners()) {
-                       fcpListener.receivedConfigData(getSource(), configData);
-               }
-       }
-
-       /**
-        * Notifies all listeners that a “GetFailed” message was received.
-        *
-        * @see FcpListener#receivedGetFailed(FcpConnection, GetFailed)
-        * @param getFailed
-        *            The “GetFailed” message
-        */
-       public void fireReceivedGetFailed(GetFailed getFailed) {
-               for (FcpListener fcpListener : getListeners()) {
-                       fcpListener.receivedGetFailed(getSource(), getFailed);
-               }
-       }
-
-       /**
-        * Notifies all listeners that a “PutFailed” message was received.
-        *
-        * @see FcpListener#receivedPutFailed(FcpConnection, PutFailed)
-        * @param putFailed
-        *            The “PutFailed” message
-        */
-       public void fireReceivedPutFailed(PutFailed putFailed) {
-               for (FcpListener fcpListener : getListeners()) {
-                       fcpListener.receivedPutFailed(getSource(), putFailed);
-               }
-       }
-
-       /**
-        * Notifies all listeners that an “IdentifierCollision” message was
-        * received.
-        *
-        * @see FcpListener#receivedIdentifierCollision(FcpConnection,
-        *      IdentifierCollision)
-        * @param identifierCollision
-        *            The “IdentifierCollision” message
-        */
-       public void fireReceivedIdentifierCollision(IdentifierCollision identifierCollision) {
-               for (FcpListener fcpListener : getListeners()) {
-                       fcpListener.receivedIdentifierCollision(getSource(), identifierCollision);
-               }
-       }
-
-       /**
-        * Notifies all listeners that an “PersistentPutDir” message was received.
-        *
-        * @see FcpListener#receivedPersistentPutDir(FcpConnection,
-        *      PersistentPutDir)
-        * @param persistentPutDir
-        *            The “PersistentPutDir” message
-        */
-       public void fireReceivedPersistentPutDir(PersistentPutDir persistentPutDir) {
-               for (FcpListener fcpListener : getListeners()) {
-                       fcpListener.receivedPersistentPutDir(getSource(), persistentPutDir);
-               }
-       }
-
-       /**
-        * Notifies all listeners that a “PersistentRequestRemoved” message was
-        * received.
-        *
-        * @see FcpListener#receivedPersistentRequestRemoved(FcpConnection,
-        *      PersistentRequestRemoved)
-        * @param persistentRequestRemoved
-        *            The “PersistentRequestRemoved” message
-        */
-       public void fireReceivedPersistentRequestRemoved(PersistentRequestRemoved persistentRequestRemoved) {
-               for (FcpListener fcpListener : getListeners()) {
-                       fcpListener.receivedPersistentRequestRemoved(getSource(), persistentRequestRemoved);
-               }
-       }
-
-       /**
-        * Notifies all listeners that a “SubscribedUSKUpdate” message was received.
-        *
-        * @see FcpListener#receivedSubscribedUSKUpdate(FcpConnection,
-        *      SubscribedUSKUpdate)
-        * @param subscribedUSKUpdate
-        *            The “SubscribedUSKUpdate” message
-        */
-       public void fireReceivedSubscribedUSKUpdate(SubscribedUSKUpdate subscribedUSKUpdate) {
-               for (FcpListener fcpListener : getListeners()) {
-                       fcpListener.receivedSubscribedUSKUpdate(getSource(), subscribedUSKUpdate);
-               }
-       }
-
-       /**
-        * Notifies all listeners that a “PluginInfo” message was received.
-        *
-        * @see FcpListener#receivedPluginInfo(FcpConnection, PluginInfo)
-        * @param pluginInfo
-        *            The “PluginInfo” message
-        */
-       public void fireReceivedPluginInfo(PluginInfo pluginInfo) {
-               for (FcpListener fcpListener : getListeners()) {
-                       fcpListener.receivedPluginInfo(getSource(), pluginInfo);
-               }
-       }
-
-       /**
-        * Notifies all listeners that an “FCPPluginReply” message was received.
-        *
-        * @see FcpListener#receivedFCPPluginReply(FcpConnection, FCPPluginReply)
-        * @param fcpPluginReply
-        *            The “FCPPluginReply” message
-        */
-       public void fireReceivedFCPPluginReply(FCPPluginReply fcpPluginReply) {
-               for (FcpListener fcpListener : getListeners()) {
-                       fcpListener.receivedFCPPluginReply(getSource(), fcpPluginReply);
-               }
-       }
-
-       /**
-        * Notifies all listeners that a “PersistentRequestModified” message was
-        * received.
-        *
-        * @see FcpListener#receivedPersistentRequestModified(FcpConnection,
-        *      PersistentRequestModified)
-        * @param persistentRequestModified
-        *            The “PersistentRequestModified” message
-        */
-       public void fireReceivedPersistentRequestModified(PersistentRequestModified persistentRequestModified) {
-               for (FcpListener fcpListener : getListeners()) {
-                       fcpListener.receivedPersistentRequestModified(getSource(), persistentRequestModified);
-               }
-       }
-
-       /**
-        * Notifies all listeners that a “PutSuccessful” message was received.
-        *
-        * @see FcpListener#receivedPutSuccessful(FcpConnection, PutSuccessful)
-        * @param putSuccessful
-        *            The “PutSuccessful” message
-        */
-       public void fireReceivedPutSuccessful(PutSuccessful putSuccessful) {
-               for (FcpListener fcpListener : getListeners()) {
-                       fcpListener.receivedPutSuccessful(getSource(), putSuccessful);
-               }
-       }
-
-       /**
-        * Notifies all listeners that a “PutFetchable” message was received.
-        *
-        * @see FcpListener#receivedPutFetchable(FcpConnection, PutFetchable)
-        * @param putFetchable
-        *            The “PutFetchable” message
-        */
-       public void fireReceivedPutFetchable(PutFetchable putFetchable) {
-               for (FcpListener fcpListener : getListeners()) {
-                       fcpListener.receivedPutFetchable(getSource(), putFetchable);
-               }
-       }
-
-       /**
-        * Notifies all listeners that a “ProtocolError” message was received.
-        *
-        * @see FcpListener#receivedProtocolError(FcpConnection, ProtocolError)
-        * @param protocolError
-        *            The “ProtocolError” message
-        */
-       public void fireReceivedProtocolError(ProtocolError protocolError) {
-               for (FcpListener fcpListener : getListeners()) {
-                       fcpListener.receivedProtocolError(getSource(), protocolError);
-               }
-       }
-
-       /**
-        * Notifies all listeners that a “SentFeed” message was received.
-        *
-        * @see FcpListener#receivedSentFeed(FcpConnection, SentFeed)
-        * @param sentFeed
-        *            The “SentFeed” message.
-        */
-       public void fireSentFeed(SentFeed sentFeed) {
-               for (FcpListener fcpListener : getListeners()) {
-                       fcpListener.receivedSentFeed(getSource(), sentFeed);
-               }
-       }
-
-       /**
-        * Notifies all listeners that a “ReceivedBookmarkFeed” message was
-        * received.
-        *
-        * @see FcpListener#receivedBookmarkFeed(FcpConnection,
-        *      ReceivedBookmarkFeed)
-        * @param receivedBookmarkFeed
-        *            The “ReceivedBookmarkFeed” message
-        */
-       public void fireReceivedBookmarkFeed(ReceivedBookmarkFeed receivedBookmarkFeed) {
-               for (FcpListener fcpListener : getListeners()) {
-                       fcpListener.receivedBookmarkFeed(getSource(), receivedBookmarkFeed);
-               }
-       }
-
-       /**
-        * Notifies all registered listeners that a message has been received.
-        *
-        * @see FcpListener#receivedMessage(FcpConnection, FcpMessage)
-        * @param fcpMessage
-        *            The message that was received
-        */
-       public void fireMessageReceived(FcpMessage fcpMessage) {
-               for (FcpListener fcpListener : getListeners()) {
-                       fcpListener.receivedMessage(getSource(), fcpMessage);
-               }
-       }
-
-       /**
-        * Notifies all listeners that the connection to the node was closed.
-        *
-        * @param throwable
-        *            The exception that caused the disconnect, or <code>null</code>
-        *            if there was no exception
-        * @see FcpListener#connectionClosed(FcpConnection, Throwable)
-        */
-       public void fireConnectionClosed(Throwable throwable) {
-               for (FcpListener fcpListener : getListeners()) {
-                       fcpListener.connectionClosed(getSource(), throwable);
-               }
-       }
-
-}
diff --git a/src/net/pterodactylus/fcp/FcpMessage.java b/src/net/pterodactylus/fcp/FcpMessage.java
deleted file mode 100644 (file)
index b238db3..0000000
+++ /dev/null
@@ -1,195 +0,0 @@
-/*
- * jFCPlib - FcpMessage.java - Copyright © 2008 David Roden
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- */
-
-package net.pterodactylus.fcp;
-
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.OutputStream;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.Iterator;
-import java.util.Map;
-import java.util.Map.Entry;
-
-/**
- * An FCP message. FCP messages consist of a name, an arbitrary amount of
- * “fields” (i.e. key-value pairs), a message end marker, and optional payload
- * data that follows the marker.
- *
- * @author David ‘Bombe’ Roden &lt;bombe@freenetproject.org&gt;
- */
-public class FcpMessage implements Iterable<String> {
-
-       /** Constant for the linefeed. */
-       private static final String LINEFEED = "\r\n";
-
-       /** The name of the message. */
-       private final String name;
-
-       /** The fields of the message. */
-       private final Map<String, String> fields = new HashMap<String, String>();
-
-       /** The optional payload input stream. */
-       private InputStream payloadInputStream;
-
-       /**
-        * Creates a new FCP message with the given name.
-        *
-        * @param name
-        *            The name of the FCP message
-        */
-       public FcpMessage(String name) {
-               this(name, null);
-       }
-
-       /**
-        * Creates a new FCP message with the given name and the given payload input
-        * stream. The payload input stream is not read until the message is sent to
-        * the node using {@link FcpConnection#sendMessage(FcpMessage)}.
-        *
-        * @param name
-        *            The name of the message
-        * @param payloadInputStream
-        *            The payload of the message
-        */
-       public FcpMessage(String name, InputStream payloadInputStream) {
-               this.name = name;
-               this.payloadInputStream = payloadInputStream;
-       }
-
-       /**
-        * Returns the name of the message.
-        *
-        * @return The name of the message
-        */
-       public String getName() {
-               return name;
-       }
-
-       /**
-        * Checks whether this message has a field with the given name.
-        *
-        * @param field
-        *            The name of the field to check for
-        * @return <code>true</code> if the message has a field with the given name,
-        *         <code>false</code> otherwise
-        */
-       public boolean hasField(String field) {
-               return fields.containsKey(field);
-       }
-
-       /**
-        * Sets the field with the given name to the given value. If the field
-        * already exists in this message it is overwritten.
-        *
-        * @param field
-        *            The name of the field
-        * @param value
-        *            The value of the field
-        */
-       public void setField(String field, String value) {
-               if ((field == null) || (value == null)) {
-                       throw new NullPointerException(((field == null) ? "field " : "value ") + "must not be null");
-               }
-               fields.put(field, value);
-       }
-
-       /**
-        * Returns the value of the given field.
-        *
-        * @param field
-        *            The name of the field
-        * @return The value of the field, or <code>null</code> if there is no such
-        *         field
-        */
-       public String getField(String field) {
-               return fields.get(field);
-       }
-
-       /**
-        * Returns all fields of this message.
-        *
-        * @return All fields of this message
-        */
-       public Map<String, String> getFields() {
-               return Collections.unmodifiableMap(fields);
-       }
-
-       /**
-        * {@inheritDoc}
-        */
-       public Iterator<String> iterator() {
-               return fields.keySet().iterator();
-       }
-
-       /**
-        * Sets the payload input stream of the message.
-        *
-        * @param payloadInputStream
-        *            The payload input stream
-        */
-       public void setPayloadInputStream(InputStream payloadInputStream) {
-               this.payloadInputStream = payloadInputStream;
-       }
-
-       /**
-        * Writes this message to the given output stream. If the message has a
-        * payload (i.e. {@link #payloadInputStream} is not <code>null</code>) the
-        * payload is written to the given output stream after the message as well.
-        * That means that this method can only be called once because on the second
-        * invocation the payload input stream could not be read (again).
-        *
-        * @param outputStream
-        *            The output stream to write the message to
-        * @throws IOException
-        *             if an I/O error occurs
-        */
-       public void write(OutputStream outputStream) throws IOException {
-               writeLine(outputStream, name);
-               for (Entry<String, String> fieldEntry : fields.entrySet()) {
-                       writeLine(outputStream, fieldEntry.getKey() + "=" + fieldEntry.getValue());
-               }
-               writeLine(outputStream, "EndMessage");
-               outputStream.flush();
-               if (payloadInputStream != null) {
-                       FcpUtils.copy(payloadInputStream, outputStream);
-                       outputStream.flush();
-               }
-       }
-
-       //
-       // PRIVATE METHODS
-       //
-
-       /**
-        * Writes the given line (followed by {@link #LINEFEED} to the given output
-        * stream, using UTF-8 as encoding.
-        *
-        * @param outputStream
-        *            The output stream to write to
-        * @param line
-        *            The line to write
-        * @throws IOException
-        *             if an I/O error occurs
-        */
-       private void writeLine(OutputStream outputStream, String line) throws IOException {
-               outputStream.write((line + LINEFEED).getBytes("UTF-8"));
-       }
-
-}
diff --git a/src/net/pterodactylus/fcp/FcpTest.java b/src/net/pterodactylus/fcp/FcpTest.java
deleted file mode 100644 (file)
index 6c51848..0000000
+++ /dev/null
@@ -1,92 +0,0 @@
-/*
- * jFCPlib - FcpTest.java - Copyright © 2008 David Roden
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- */
-
-package net.pterodactylus.fcp;
-
-import java.io.IOException;
-
-import junit.framework.TestCase;
-
-/**
- * Tests various commands and the FCP connection.
- *
- * @author David ‘Bombe’ Roden &lt;bombe@freenetproject.org&gt;
- */
-public class FcpTest extends TestCase {
-
-       /** The FCP connection. */
-       private FcpConnection fcpConnection;
-
-       /**
-        * {@inheritDoc}
-        */
-       @Override
-       protected void setUp() throws Exception {
-               fcpConnection = new FcpConnection("wing");
-               fcpConnection.connect();
-               fcpConnection.sendMessage(new ClientHello("FcpTest"));
-       }
-
-       /**
-        * {@inheritDoc}
-        */
-       @Override
-       protected void tearDown() throws Exception {
-               fcpConnection.close();
-       }
-
-       /**
-        * Tests the FCP connection be simply {@link #setUp() setting it up} and
-        * {@link #tearDown() tearing it down} again.
-        */
-       public void testFcpConnection() {
-               /* do nothing. */
-       }
-
-       /**
-        * Generates an SSK key pair.
-        *
-        * @throws IOException
-        *             if an I/O error occurs
-        * @throws InterruptedException
-        *             if {@link Object#wait()} wakes up spuriously
-        */
-       public void testGenerateSSK() throws IOException, InterruptedException {
-               final SSKKeypair[] keypair = new SSKKeypair[1];
-               FcpAdapter fcpAdapter = new FcpAdapter() {
-
-                       /**
-                        * {@inheritDoc}
-                        */
-                       @Override
-                       public void receivedSSKKeypair(FcpConnection fcpConnection, SSKKeypair sskKeypair) {
-                               keypair[0] = sskKeypair;
-                               synchronized (this) {
-                                       notify();
-                               }
-                       }
-               };
-               fcpConnection.addFcpListener(fcpAdapter);
-               synchronized (fcpAdapter) {
-                       fcpConnection.sendMessage(new GenerateSSK());
-                       fcpAdapter.wait();
-               }
-               assertNotNull("ssk keypair", keypair[0]);
-       }
-
-}
diff --git a/src/net/pterodactylus/fcp/FcpUtils.java b/src/net/pterodactylus/fcp/FcpUtils.java
deleted file mode 100644 (file)
index 0957083..0000000
+++ /dev/null
@@ -1,469 +0,0 @@
-/*
- * jFCPlib - FcpUtils.java - Copyright © 2008 David Roden
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- */
-
-package net.pterodactylus.fcp;
-
-import java.io.ByteArrayInputStream;
-import java.io.ByteArrayOutputStream;
-import java.io.Closeable;
-import java.io.EOFException;
-import java.io.File;
-import java.io.FileInputStream;
-import java.io.FileOutputStream;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.OutputStream;
-import java.net.Socket;
-import java.util.StringTokenizer;
-import java.util.concurrent.atomic.AtomicLong;
-
-/**
- * Helper class with utility methods for the FCP protocol.
- *
- * @author David ‘Bombe’ Roden &lt;bombe@freenetproject.org&gt;
- */
-public class FcpUtils {
-
-       /** Counter for unique identifiers. */
-       private static AtomicLong counter = new AtomicLong();
-
-       /**
-        * Returns a unique identifier.
-        *
-        * @return A unique identifier
-        */
-       public static String getUniqueIdentifier() {
-               return new StringBuilder().append(System.currentTimeMillis()).append('-').append(counter.getAndIncrement()).toString();
-       }
-
-       /**
-        * Parses an integer field, separated by ‘;’ and returns the parsed values.
-        *
-        * @param field
-        *            The field to parse
-        * @return An array with the parsed values
-        * @throws NumberFormatException
-        *             if a value can not be converted to a number
-        */
-       public static int[] decodeMultiIntegerField(String field) throws NumberFormatException {
-               StringTokenizer fieldTokens = new StringTokenizer(field, ";");
-               int[] result = new int[fieldTokens.countTokens()];
-               int counter = 0;
-               while (fieldTokens.hasMoreTokens()) {
-                       String fieldToken = fieldTokens.nextToken();
-                       result[counter++] = Integer.valueOf(fieldToken);
-               }
-               return result;
-       }
-
-       /**
-        * Encodes the given integer array into a string, separating the values by
-        * ‘;’.
-        *
-        * @param values
-        *            The values to encode
-        * @return The encoded values
-        */
-       public static String encodeMultiIntegerField(int[] values) {
-               StringBuilder encodedField = new StringBuilder();
-               for (int value : values) {
-                       if (encodedField.length() > 0) {
-                               encodedField.append(';');
-                       }
-                       encodedField.append(value);
-               }
-               return encodedField.toString();
-       }
-
-       /**
-        * Encodes the given string array into a string, separating the values by
-        * ‘;’.
-        *
-        * @param values
-        *            The values to encode
-        * @return The encoded values
-        */
-       public static String encodeMultiStringField(String[] values) {
-               StringBuilder encodedField = new StringBuilder();
-               for (String value : values) {
-                       if (encodedField.length() > 0) {
-                               encodedField.append(';');
-                       }
-                       encodedField.append(value);
-               }
-               return encodedField.toString();
-       }
-
-       /**
-        * Tries to parse the given string into an int, returning <code>-1</code> if
-        * the string can not be parsed.
-        *
-        * @param value
-        *            The string to parse
-        * @return The parsed int, or <code>-1</code>
-        */
-       public static int safeParseInt(String value) {
-               return safeParseInt(value, -1);
-       }
-
-       /**
-        * Tries to parse the given string into an int, returning
-        * <code>defaultValue</code> if the string can not be parsed.
-        *
-        * @param value
-        *            The string to parse
-        * @param defaultValue
-        *            The value to return if the string can not be parsed.
-        * @return The parsed int, or <code>defaultValue</code>
-        */
-       public static int safeParseInt(String value, int defaultValue) {
-               try {
-                       return Integer.valueOf(value);
-               } catch (NumberFormatException nfe1) {
-                       return defaultValue;
-               }
-       }
-
-       /**
-        * Tries to parse the given string into an long, returning <code>-1</code>
-        * if the string can not be parsed.
-        *
-        * @param value
-        *            The string to parse
-        * @return The parsed long, or <code>-1</code>
-        */
-       public static long safeParseLong(String value) {
-               return safeParseLong(value, -1);
-       }
-
-       /**
-        * Tries to parse the given string into an long, returning
-        * <code>defaultValue</code> if the string can not be parsed.
-        *
-        * @param value
-        *            The string to parse
-        * @param defaultValue
-        *            The value to return if the string can not be parsed.
-        * @return The parsed long, or <code>defaultValue</code>
-        */
-       public static long safeParseLong(String value, long defaultValue) {
-               try {
-                       return Integer.valueOf(value);
-               } catch (NumberFormatException nfe1) {
-                       return defaultValue;
-               }
-       }
-
-       /**
-        * Closes the given socket.
-        *
-        * @param socket
-        *            The socket to close
-        */
-       public static void close(Socket socket) {
-               if (socket != null) {
-                       try {
-                               socket.close();
-                       } catch (IOException ioe1) {
-                               /* ignore. */
-                       }
-               }
-       }
-
-       /**
-        * Closes the given Closeable.
-        *
-        * @param closeable
-        *            The Closeable to close
-        */
-       public static void close(Closeable closeable) {
-               if (closeable != null) {
-                       try {
-                               closeable.close();
-                       } catch (IOException ioe1) {
-                               /* ignore. */
-                       }
-               }
-       }
-
-       /**
-        * Copies as many bytes as possible (i.e. until {@link InputStream#read()}
-        * returns <code>-1</code>) from the source input stream to the destination
-        * output stream.
-        *
-        * @param source
-        *            The input stream to read from
-        * @param destination
-        *            The output stream to write to
-        * @throws IOException
-        *             if an I/O error occurs
-        */
-       public static void copy(InputStream source, OutputStream destination) throws IOException {
-               copy(source, destination, -1);
-       }
-
-       /**
-        * Copies <code>length</code> bytes from the source input stream to the
-        * destination output stream. If <code>length</code> is <code>-1</code> as
-        * much bytes as possible will be copied (i.e. until
-        * {@link InputStream#read()} returns <code>-1</code> to signal the end of
-        * the stream).
-        *
-        * @param source
-        *            The input stream to read from
-        * @param destination
-        *            The output stream to write to
-        * @param length
-        *            The number of bytes to copy
-        * @throws IOException
-        *             if an I/O error occurs
-        */
-       public static void copy(InputStream source, OutputStream destination, long length) throws IOException {
-               copy(source, destination, length, 1 << 16);
-       }
-
-       /**
-        * Copies <code>length</code> bytes from the source input stream to the
-        * destination output stream. If <code>length</code> is <code>-1</code> as
-        * much bytes as possible will be copied (i.e. until
-        * {@link InputStream#read()} returns <code>-1</code> to signal the end of
-        * the stream).
-        *
-        * @param source
-        *            The input stream to read from
-        * @param destination
-        *            The output stream to write to
-        * @param length
-        *            The number of bytes to copy
-        * @param bufferSize
-        *            The buffer size
-        * @throws IOException
-        *             if an I/O error occurs
-        */
-       public static void copy(InputStream source, OutputStream destination, long length, int bufferSize) throws IOException {
-               long remaining = length;
-               byte[] buffer = new byte[bufferSize];
-               int read = 0;
-               while ((remaining == -1) || (remaining > 0)) {
-                       read = source.read(buffer, 0, ((remaining > bufferSize) || (remaining == -1)) ? bufferSize : (int) remaining);
-                       if (read == -1) {
-                               if (length == -1) {
-                                       return;
-                               }
-                               throw new EOFException("stream reached eof");
-                       }
-                       destination.write(buffer, 0, read);
-                       remaining -= read;
-               }
-       }
-
-       /**
-        * This input stream stores the content of another input stream either in a
-        * file or in memory, depending on the length of the input stream.
-        *
-        * @author David ‘Bombe’ Roden &lt;bombe@freenetproject.org&gt;
-        */
-       public static class TempInputStream extends InputStream {
-
-               /** The default maximum lenght for in-memory storage. */
-               public static final long MAX_LENGTH_MEMORY = 65536;
-
-               /** The temporary file to read from. */
-               private final File tempFile;
-
-               /** The input stream that reads from the file. */
-               private final InputStream fileInputStream;
-
-               /** The input stream that reads from memory. */
-               private final InputStream memoryInputStream;
-
-               /**
-                * Creates a new temporary input stream that stores the given input
-                * stream in a temporary file.
-                *
-                * @param originalInputStream
-                *            The original input stream
-                * @throws IOException
-                *             if an I/O error occurs
-                */
-               public TempInputStream(InputStream originalInputStream) throws IOException {
-                       this(originalInputStream, -1);
-               }
-
-               /**
-                * Creates a new temporary input stream that stores the given input
-                * stream in memory if it is shorter than {@link #MAX_LENGTH_MEMORY},
-                * otherwise it is stored in a file.
-                *
-                * @param originalInputStream
-                *            The original input stream
-                * @param length
-                *            The length of the input stream
-                * @throws IOException
-                *             if an I/O error occurs
-                */
-               public TempInputStream(InputStream originalInputStream, long length) throws IOException {
-                       this(originalInputStream, length, MAX_LENGTH_MEMORY);
-               }
-
-               /**
-                * Creates a new temporary input stream that stores the given input
-                * stream in memory if it is shorter than <code>maxMemoryLength</code>,
-                * otherwise it is stored in a file.
-                *
-                * @param originalInputStream
-                *            The original input stream
-                * @param length
-                *            The length of the input stream
-                * @param maxMemoryLength
-                *            The maximum length to store in memory
-                * @throws IOException
-                *             if an I/O error occurs
-                */
-               public TempInputStream(InputStream originalInputStream, long length, long maxMemoryLength) throws IOException {
-                       if ((length > -1) && (length <= maxMemoryLength)) {
-                               ByteArrayOutputStream memoryOutputStream = new ByteArrayOutputStream((int) length);
-                               try {
-                                       FcpUtils.copy(originalInputStream, memoryOutputStream, length, (int) length);
-                               } finally {
-                                       memoryOutputStream.close();
-                               }
-                               tempFile = null;
-                               fileInputStream = null;
-                               memoryInputStream = new ByteArrayInputStream(memoryOutputStream.toByteArray());
-                       } else {
-                               tempFile = File.createTempFile("temp-", ".bin");
-                               tempFile.deleteOnExit();
-                               FileOutputStream fileOutputStream = null;
-                               try {
-                                       fileOutputStream = new FileOutputStream(tempFile);
-                                       FcpUtils.copy(originalInputStream, fileOutputStream);
-                                       fileInputStream = new FileInputStream(tempFile);
-                               } finally {
-                                       FcpUtils.close(fileOutputStream);
-                               }
-                               memoryInputStream = null;
-                       }
-               }
-
-               /**
-                * {@inheritDoc}
-                */
-               @Override
-               public int available() throws IOException {
-                       if (memoryInputStream != null) {
-                               return memoryInputStream.available();
-                       }
-                       return fileInputStream.available();
-               }
-
-               /**
-                * {@inheritDoc}
-                */
-               @Override
-               public void close() throws IOException {
-                       if (memoryInputStream != null) {
-                               memoryInputStream.close();
-                               return;
-                       }
-                       tempFile.delete();
-                       fileInputStream.close();
-               }
-
-               /**
-                * {@inheritDoc}
-                */
-               @Override
-               public synchronized void mark(int readlimit) {
-                       if (memoryInputStream != null) {
-                               memoryInputStream.mark(readlimit);
-                               return;
-                       }
-                       fileInputStream.mark(readlimit);
-               }
-
-               /**
-                * {@inheritDoc}
-                */
-               @Override
-               public boolean markSupported() {
-                       if (memoryInputStream != null) {
-                               return memoryInputStream.markSupported();
-                       }
-                       return fileInputStream.markSupported();
-               }
-
-               /**
-                * {@inheritDoc}
-                */
-               @Override
-               public int read() throws IOException {
-                       if (memoryInputStream != null) {
-                               return memoryInputStream.read();
-                       }
-                       return fileInputStream.read();
-               }
-
-               /**
-                * {@inheritDoc}
-                */
-               @Override
-               public int read(byte[] b) throws IOException {
-                       if (memoryInputStream != null) {
-                               return memoryInputStream.read(b);
-                       }
-                       return fileInputStream.read(b);
-               }
-
-               /**
-                * {@inheritDoc}
-                */
-               @Override
-               public int read(byte[] b, int off, int len) throws IOException {
-                       if (memoryInputStream != null) {
-                               return memoryInputStream.read(b, off, len);
-                       }
-                       return fileInputStream.read(b, off, len);
-               }
-
-               /**
-                * {@inheritDoc}
-                */
-               @Override
-               public synchronized void reset() throws IOException {
-                       if (memoryInputStream != null) {
-                               memoryInputStream.reset();
-                               return;
-                       }
-                       fileInputStream.reset();
-               }
-
-               /**
-                * {@inheritDoc}
-                */
-               @Override
-               public long skip(long n) throws IOException {
-                       if (memoryInputStream != null) {
-                               return memoryInputStream.skip(n);
-                       }
-                       return fileInputStream.skip(n);
-               }
-
-       }
-
-}
diff --git a/src/net/pterodactylus/fcp/FileEntry.java b/src/net/pterodactylus/fcp/FileEntry.java
deleted file mode 100644 (file)
index f939d78..0000000
+++ /dev/null
@@ -1,294 +0,0 @@
-/*
- * jFCPlib - FileEntry.java - Copyright © 2008 David Roden
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- */
-
-package net.pterodactylus.fcp;
-
-import java.io.InputStream;
-import java.util.HashMap;
-import java.util.Map;
-
-/**
- * Container class for file entry data.
- *
- * @see ClientPutComplexDir#addFileEntry(FileEntry)
- * @author David ‘Bombe’ Roden &lt;bombe@freenetproject.org&gt;
- */
-public abstract class FileEntry {
-
-       /** The name of the file. */
-       protected final String name;
-
-       /** The upload source of the file. */
-       protected final UploadFrom uploadFrom;
-
-       /**
-        * Creates a new file entry with the given name and upload source.
-        *
-        * @param name
-        *            The name of the file
-        * @param uploadFrom
-        *            The upload source of the file
-        */
-       protected FileEntry(String name, UploadFrom uploadFrom) {
-               this.name = name;
-               this.uploadFrom = uploadFrom;
-       }
-
-       /**
-        * Creates a new file entry for a file that should be transmitted to the
-        * node in the payload of the message.
-        *
-        * @param name
-        *            The name of the file
-        * @param contentType
-        *            The content type of the file, or <code>null</code> to let the
-        *            node auto-detect it
-        * @param length
-        *            The length of the file
-        * @param dataInputStream
-        *            The input stream of the file
-        * @return A file entry
-        */
-       public static FileEntry createDirectFileEntry(String name, String contentType, long length, InputStream dataInputStream) {
-               return new DirectFileEntry(name, contentType, length, dataInputStream);
-       }
-
-       /**
-        * Creates a new file entry for a file that should be uploaded from disk.
-        *
-        * @param name
-        *            The name of the file
-        * @param filename
-        *            The name of the file on disk
-        * @param contentType
-        *            The content type of the file, or <code>null</code> to let the
-        *            node auto-detect it
-        * @param length
-        *            The length of the file, or <code>-1</code> to not specify a
-        *            size
-        * @return A file entry
-        */
-       public static FileEntry createDiskFileEntry(String name, String filename, String contentType, long length) {
-               return new DiskFileEntry(name, filename, contentType, length);
-       }
-
-       /**
-        * Creates a new file entry for a file that redirects to another URI.
-        *
-        * @param name
-        *            The name of the file
-        * @param targetURI
-        *            The target URI of the redirect
-        * @return A file entry
-        */
-       public static FileEntry createRedirectFileEntry(String name, String targetURI) {
-               return new RedirectFileEntry(name, targetURI);
-       }
-
-       /**
-        * Returns the fields for this file entry.
-        *
-        * @return The fields for this file entry
-        */
-       abstract Map<String, String> getFields();
-
-       /**
-        * A file entry for a file that should be transmitted in the payload of the
-        * {@link ClientPutComplexDir} message.
-        *
-        * @author David ‘Bombe’ Roden &lt;bombe@freenetproject.org&gt;
-        */
-       static class DirectFileEntry extends FileEntry {
-
-               /** The content type of the data. */
-               private final String contentType;
-
-               /** The length of the data. */
-               private final long length;
-
-               /** The input stream of the data. */
-               private final InputStream inputStream;
-
-               /**
-                * Creates a new direct file entry with content type auto-detection.
-                *
-                * @param name
-                *            The name of the file
-                * @param length
-                *            The length of the file
-                * @param inputStream
-                *            The input stream of the file
-                */
-               public DirectFileEntry(String name, long length, InputStream inputStream) {
-                       this(name, null, length, inputStream);
-               }
-
-               /**
-                * Creates a new direct file entry.
-                *
-                * @param name
-                *            The name of the file
-                * @param contentType
-                *            The content type of the file, or <code>null</code> to let
-                *            the node auto-detect it
-                * @param length
-                *            The length of the file
-                * @param inputStream
-                *            The input stream of the file
-                */
-               public DirectFileEntry(String name, String contentType, long length, InputStream inputStream) {
-                       super(name, UploadFrom.direct);
-                       this.contentType = contentType;
-                       this.length = length;
-                       this.inputStream = inputStream;
-               }
-
-               /**
-                * {@inheritDoc}
-                */
-               @Override
-               Map<String, String> getFields() {
-                       Map<String, String> fields = new HashMap<String, String>();
-                       fields.put("Name", name);
-                       fields.put("UploadFrom", String.valueOf(uploadFrom));
-                       fields.put("DataLength", String.valueOf(length));
-                       if (contentType != null) {
-                               fields.put("Metadata.ContentType", contentType);
-                       }
-                       return fields;
-               }
-
-               /**
-                * Returns the input stream of the file.
-                *
-                * @return The input stream of the file
-                */
-               InputStream getInputStream() {
-                       return inputStream;
-               }
-
-       }
-
-       /**
-        * A file entry for a file that should be uploaded from the disk.
-        *
-        * @author David ‘Bombe’ Roden &lt;bombe@freenetproject.org&gt;
-        */
-       static class DiskFileEntry extends FileEntry {
-
-               /** The name of the on-disk file. */
-               private final String filename;
-
-               /** The content type of the file. */
-               private final String contentType;
-
-               /** The length of the file. */
-               private final long length;
-
-               /**
-                * Creates a new disk file entry.
-                *
-                * @param name
-                *            The name of the file
-                * @param filename
-                *            The name of the on-disk file
-                * @param length
-                *            The length of the file
-                */
-               public DiskFileEntry(String name, String filename, long length) {
-                       this(name, filename, null, length);
-               }
-
-               /**
-                * Creates a new disk file entry.
-                *
-                * @param name
-                *            The name of the file
-                * @param filename
-                *            The name of the on-disk file
-                * @param contentType
-                *            The content type of the file, or <code>null</code> to let
-                *            the node auto-detect it
-                * @param length
-                *            The length of the file
-                */
-               public DiskFileEntry(String name, String filename, String contentType, long length) {
-                       super(name, UploadFrom.disk);
-                       this.filename = filename;
-                       this.contentType = contentType;
-                       this.length = length;
-               }
-
-               /**
-                * {@inheritDoc}
-                */
-               @Override
-               Map<String, String> getFields() {
-                       Map<String, String> fields = new HashMap<String, String>();
-                       fields.put("Name", name);
-                       fields.put("UploadFrom", String.valueOf(uploadFrom));
-                       fields.put("Filename", filename);
-                       if (length > -1) {
-                               fields.put("DataSize", String.valueOf(length));
-                       }
-                       if (contentType != null) {
-                               fields.put("Metadata.ContentType", contentType);
-                       }
-                       return fields;
-               }
-
-       }
-
-       /**
-        * A file entry for a file that redirects to another URI.
-        *
-        * @author David ‘Bombe’ Roden &lt;bombe@freenetproject.org&gt;
-        */
-       static class RedirectFileEntry extends FileEntry {
-
-               /** The target URI of the redirect. */
-               private String targetURI;
-
-               /**
-                * Creates a new redirect file entry.
-                *
-                * @param name
-                *            The name of the file
-                * @param targetURI
-                *            The target URI of the redirect
-                */
-               public RedirectFileEntry(String name, String targetURI) {
-                       super(name, UploadFrom.redirect);
-                       this.targetURI = targetURI;
-               }
-
-               /**
-                * {@inheritDoc}
-                */
-               @Override
-               Map<String, String> getFields() {
-                       Map<String, String> fields = new HashMap<String, String>();
-                       fields.put("Name", name);
-                       fields.put("UploadFrom", String.valueOf(uploadFrom));
-                       fields.put("TargetURI", targetURI);
-                       return fields;
-               }
-
-       }
-
-}
diff --git a/src/net/pterodactylus/fcp/FinishedCompression.java b/src/net/pterodactylus/fcp/FinishedCompression.java
deleted file mode 100644 (file)
index 9d09d62..0000000
+++ /dev/null
@@ -1,76 +0,0 @@
-/*
- * jFCPlib - FinishedCompression.java - Copyright © 2008 David Roden
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- */
-
-package net.pterodactylus.fcp;
-
-/**
- * A “FinishedCompression” message signals the client that the compression of
- * the request data has been finished.
- *
- * @author David ‘Bombe’ Roden &lt;bombe@freenetproject.org&gt;
- */
-public class FinishedCompression extends BaseMessage {
-
-       /**
-        * Creates a new “FinishedCompression” message that wraps the received
-        * message.
-        *
-        * @param receivedMessage
-        *            The message that was recevied
-        */
-       FinishedCompression(FcpMessage receivedMessage) {
-               super(receivedMessage);
-       }
-
-       /**
-        * Returns the identifier of the request.
-        *
-        * @return The identifier of the request
-        */
-       public String getIdentifier() {
-               return getField("Identifier");
-       }
-
-       /**
-        * Returns the ID of the codec that was used for compression.
-        *
-        * @return The ID of the codec that was used for compression
-        */
-       public int getCodec() {
-               return FcpUtils.safeParseInt(getField("Codec"));
-       }
-
-       /**
-        * Returns the original size of the data (i.e. before compression).
-        *
-        * @return The original size of the data
-        */
-       public long getOriginalSize() {
-               return FcpUtils.safeParseLong(getField("OriginalSize"));
-       }
-
-       /**
-        * Returns the compressed size of the data (i.e. after compression).
-        *
-        * @return The compressed size of the data
-        */
-       public long getCompressedSize() {
-               return FcpUtils.safeParseLong(getField("CompressedSize"));
-       }
-
-}
diff --git a/src/net/pterodactylus/fcp/GenerateSSK.java b/src/net/pterodactylus/fcp/GenerateSSK.java
deleted file mode 100644 (file)
index 5e33c6c..0000000
+++ /dev/null
@@ -1,47 +0,0 @@
-/*
- * jFCPlib - GenerateSSK.java - Copyright © 2008 David Roden
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- */
-
-package net.pterodactylus.fcp;
-
-/**
- * A “GenerateSSK” message. This message tells the node to generate a new SSK
- * key pair.
- *
- * @author David ‘Bombe’ Roden &lt;bombe@freenetproject.org&gt;
- */
-public class GenerateSSK extends FcpMessage {
-
-       /**
-        * Creates a new “GenerateSSK” message.
-        */
-       public GenerateSSK() {
-               this(FcpUtils.getUniqueIdentifier());
-       }
-
-       /**
-        * Creates a new “GenerateSSK” message with the given client identifier.
-        *
-        * @param clientIdentifier
-        *            The client identifier
-        */
-       public GenerateSSK(String clientIdentifier) {
-               super("GenerateSSK");
-               setField("Identifier", clientIdentifier);
-       }
-
-}
diff --git a/src/net/pterodactylus/fcp/GetConfig.java b/src/net/pterodactylus/fcp/GetConfig.java
deleted file mode 100644 (file)
index 11e4cc6..0000000
+++ /dev/null
@@ -1,132 +0,0 @@
-/*
- * jFCPlib - GetConfig.java - Copyright © 2008 David Roden
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- */
-
-package net.pterodactylus.fcp;
-
-/**
- * The “GetConfig” command tells the node to send its configuration to the
- * client.
- *
- * @author David ‘Bombe’ Roden &lt;bombe@freenetproject.org&gt;
- */
-public class GetConfig extends FcpMessage {
-
-       /**
-        * Creates a new “GetConfig” command.
-        */
-       public GetConfig() {
-               super("GetConfig");
-       }
-
-       /**
-        * Sets whether the {@link ConfigData} result message shall include the
-        * current values.
-        *
-        * @param withCurrent
-        *            <code>true</code> to include current values in the result,
-        *            <code>false</code> otherwise
-        */
-       public void setWithCurrent(boolean withCurrent) {
-               setField("WithCurrent", String.valueOf(withCurrent));
-       }
-
-       /**
-        * Sets whether the {@link ConfigData} result message shall include the
-        * short descriptions.
-        *
-        * @param withShortDescription
-        *            <code>true</code> to include the short descriptions in the
-        *            result, <code>false</code> otherwise
-        */
-       public void setWithShortDescription(boolean withShortDescription) {
-               setField("WithShortDescription", String.valueOf(withShortDescription));
-       }
-
-       /**
-        * Sets whether the {@link ConfigData} result message shall include the long
-        * descriptions.
-        *
-        * @param withLongDescription
-        *            <code>true</code> to include the long descriptions in the
-        *            result, <code>false</code> otherwise
-        */
-       public void setWithLongDescription(boolean withLongDescription) {
-               setField("WithLongDescription", String.valueOf(withLongDescription));
-       }
-
-       /**
-        * Sets whether the {@link ConfigData} result message shall include the data
-        * types.
-        *
-        * @param withDataTypes
-        *            <code>true</code> to include the data types in the result,
-        *            <code>false</code> otherwise
-        */
-       public void setWithDataTypes(boolean withDataTypes) {
-               setField("WithDataTypes", String.valueOf(withDataTypes));
-       }
-
-       /**
-        * Sets whether the {@link ConfigData} result message shall include the
-        * defaults.
-        *
-        * @param setWithDefaults
-        *            <code>true</code> to include the defaults in the result,
-        *            <code>false</code> otherwise
-        */
-       public void setWithDefaults(boolean setWithDefaults) {
-               setField("WithDefaults", String.valueOf(setWithDefaults));
-       }
-
-       /**
-        * Sets whether the {@link ConfigData} result message shall include the sort
-        * order.
-        *
-        * @param withSortOrder
-        *            <code>true</code> to include the sort order in the result,
-        *            <code>false</code> otherwise
-        */
-       public void setWithSortOrder(boolean withSortOrder) {
-               setField("WithSortOrder", String.valueOf(withSortOrder));
-       }
-
-       /**
-        * Sets whether the {@link ConfigData} result message shall include the
-        * expert flag.
-        *
-        * @param withExpertFlag
-        *            <code>true</code> to include the expert flag in the result,
-        *            <code>false</code> otherwise
-        */
-       public void setWithExpertFlag(boolean withExpertFlag) {
-               setField("WithExpertFlag", String.valueOf(withExpertFlag));
-       }
-
-       /**
-        * Sets whether the {@link ConfigData} result message shall include the
-        * force-write flag.
-        *
-        * @param withForceWriteFlag
-        *            <code>true</code> to include the force-write flag in the
-        *            result, <code>false</code> otherwise
-        */
-       public void setWithForceWriteFlag(boolean withForceWriteFlag) {
-               setField("WithForceWriteFlag", String.valueOf(withForceWriteFlag));
-       }
-
-}
diff --git a/src/net/pterodactylus/fcp/GetFailed.java b/src/net/pterodactylus/fcp/GetFailed.java
deleted file mode 100644 (file)
index c01bf2b..0000000
+++ /dev/null
@@ -1,210 +0,0 @@
-/*
- * jFCPlib - GetFailed.java - Copyright © 2008 David Roden
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- */
-
-package net.pterodactylus.fcp;
-
-import java.util.ArrayList;
-import java.util.List;
-import java.util.Map;
-import java.util.Map.Entry;
-
-/**
- * The “GetFailed” message signals the client that a {@link ClientGet} request
- * has failed. This also means that no further progress messages for that
- * request will be sent.
- *
- * @author David ‘Bombe’ Roden &lt;bombe@freenetproject.org&gt;
- */
-public class GetFailed extends BaseMessage {
-
-       /**
-        * Creates a new “GetFailed” message that wraps the received message.
-        *
-        * @param receivedMessage
-        *            The received message
-        */
-       GetFailed(FcpMessage receivedMessage) {
-               super(receivedMessage);
-       }
-
-       /**
-        * Returns the code of the error.
-        *
-        * @return The code of the error, or <code>-1</code> if the error code could
-        *         not be parsed
-        */
-       public int getCode() {
-               return FcpUtils.safeParseInt(getField("Code"));
-       }
-
-       /**
-        * Returns the identifier of the request.
-        *
-        * @return The identifier of the request
-        */
-       public String getIdentifier() {
-               return getField("Identifier");
-       }
-
-       /**
-        * Returns whether the request is on the global queue.
-        *
-        * @return <code>true</code> if the request is on the global queue,
-        *         <code>false</code> if it is on the client-local queue
-        */
-       public boolean isGlobal() {
-               return Boolean.valueOf(getField("Global"));
-       }
-
-       /**
-        * Returns the description of the error code.
-        *
-        * @return The description of the error code
-        */
-       public String getCodeDescription() {
-               return getField("CodeDescription");
-       }
-
-       /**
-        * Returns the extra description of the error.
-        *
-        * @return The extra description of the error
-        */
-       public String getExtraDescription() {
-               return getField("ExtraDescription");
-       }
-
-       /**
-        * Returns the short description of the error.
-        *
-        * @return The short description of the error
-        */
-       public String getShortCodeDescription() {
-               return getField("ShortCodeDescription");
-       }
-
-       /**
-        * Returns the expected data length, if already knows.
-        *
-        * @return The expected data length, or <code>-1</code> if the length could
-        *         not be parsed
-        */
-       public long getExpectedDataLength() {
-               return FcpUtils.safeParseLong(getField("ExpectedDataLength"));
-       }
-
-       /**
-        * Returns the expected content type of the request.
-        *
-        * @return The expected content type
-        */
-       public String getExpectedMetadataContentType() {
-               return getField("ExpectedMetadata.ContentType");
-       }
-
-       /**
-        * Returns whether the expected values (see {@link #getExpectedDataLength()}
-        * and {@link #getExpectedMetadataContentType()}) have already been
-        * finalized and can be trusted. If the values have not been finalized that
-        * can change over time.
-        *
-        * @return <code>true</code> if the expected values have already been
-        *         finalized, <code>false</code> otherwise
-        */
-       public boolean isFinalizedExpected() {
-               return Boolean.valueOf(getField("FinalizedExpected"));
-       }
-
-       /**
-        * Returns the URI the request is redirected to (in case of a request for a
-        * USK). This is returned so that client applications know that the URI of
-        * the key has updated.
-        *
-        * @return The URI the request was redirected to
-        */
-       public String getRedirectURI() {
-               return getField("RedirectURI");
-       }
-
-       /**
-        * Returns whether the request failed fatally. If a request fails fatally it
-        * can never complete, even with inifinite retries.
-        *
-        * @return <code>true</code> if the request failed fatally,
-        *         <code>false</code> otherwise
-        */
-       public boolean isFatal() {
-               return Boolean.valueOf(getField("Fatal"));
-       }
-
-       /**
-        * Returns a list of complex error codes with the message. Use
-        * {@link #getComplexErrorDescription(int)} and
-        * {@link #getComplexErrorCount(int)} to get details.
-        *
-        * @return A list of complex error codes
-        */
-       public int[] getComplexErrorCodes() {
-               Map<String, String> allFields = getFields();
-               List<Integer> errorCodeList = new ArrayList<Integer>();
-               for (Entry<String, String> field : allFields.entrySet()) {
-                       String fieldKey = field.getKey();
-                       if (fieldKey.startsWith("Errors.")) {
-                               int nextDot = fieldKey.indexOf('.', 7);
-                               if (nextDot > -1) {
-                                       int errorCode = FcpUtils.safeParseInt(fieldKey.substring(7, nextDot));
-                                       if (errorCode != -1) {
-                                               errorCodeList.add(errorCode);
-                                       }
-                               }
-                       }
-               }
-               int[] errorCodes = new int[errorCodeList.size()];
-               int errorIndex = 0;
-               for (int errorCode : errorCodeList) {
-                       errorCodes[errorIndex++] = errorCode;
-               }
-               return errorCodes;
-       }
-
-       /**
-        * Returns the description of the complex error. You should only hand it
-        * error codes you got from {@link #getComplexErrorCodes()}!
-        *
-        * @param errorCode
-        *            The error code
-        * @return The description of the complex error
-        */
-       public String getComplexErrorDescription(int errorCode) {
-               return getField("Errors." + errorCode + ".Description");
-       }
-
-       /**
-        * Returns the count of the complex error. You should only hand it error
-        * codes you got from {@link #getComplexErrorCodes()}!
-        *
-        * @param errorCode
-        *            The error code
-        * @return The count of the complex error, or <code>-1</code> if the count
-        *         could not be parsed
-        */
-       public int getComplexErrorCount(int errorCode) {
-               return FcpUtils.safeParseInt(getField("Errors." + errorCode + ".Count"));
-       }
-
-}
diff --git a/src/net/pterodactylus/fcp/GetNode.java b/src/net/pterodactylus/fcp/GetNode.java
deleted file mode 100644 (file)
index 799b44b..0000000
+++ /dev/null
@@ -1,63 +0,0 @@
-/*
- * jFCPlib - GetNode.java - Copyright © 2008 David Roden
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- */
-
-package net.pterodactylus.fcp;
-
-/**
- * The “GetNode” command returns the darknet or opennet noderef of the node,
- * optionally including private and volatile data.
- *
- * @author David ‘Bombe’ Roden &lt;bombe@freenetproject.org&gt;
- */
-public class GetNode extends FcpMessage {
-
-       /**
-        * Creates a “GetNode” command that returns the darknet noderef of the node.
-        */
-       public GetNode() {
-               this(null, null, null);
-       }
-
-       /**
-        * Creates a “GetNode” command that returns the request noderef of the node,
-        * including private and volatile data, if requested. If any of the Boolean
-        * parameters are <code>null</code> the parameter is ignored and the node’s
-        * default value is used.
-        *
-        * @param giveOpennetRef
-        *            <code>true</code> to request the opennet noderef,
-        *            <code>false</code> for darknet
-        * @param withPrivate
-        *            <code>true</code> to include private data in the noderef
-        * @param withVolatile
-        *            <code>true</code> to include volatile data in the noderef
-        */
-       public GetNode(Boolean giveOpennetRef, Boolean withPrivate, Boolean withVolatile) {
-               super("GetNode");
-               if (giveOpennetRef != null) {
-                       setField("GiveOpennetRef", String.valueOf(giveOpennetRef));
-               }
-               if (withPrivate != null) {
-                       setField("WithPrivate", String.valueOf(withPrivate));
-               }
-               if (withVolatile != null) {
-                       setField("WithVolatile", String.valueOf(withVolatile));
-               }
-       }
-
-}
diff --git a/src/net/pterodactylus/fcp/GetPluginInfo.java b/src/net/pterodactylus/fcp/GetPluginInfo.java
deleted file mode 100644 (file)
index 8ad5392..0000000
+++ /dev/null
@@ -1,54 +0,0 @@
-/*
- * jFCPlib - GetPluginInfo.java - Copyright © 2008 David Roden
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- */
-
-package net.pterodactylus.fcp;
-
-/**
- * The “GetPluginInfo” message requests information about a plugin from the
- * node, which will response with a {@link PluginInfo} message.
- *
- * @author David ‘Bombe’ Roden &lt;bombe@freenetproject.org&gt;
- */
-public class GetPluginInfo extends FcpMessage {
-
-       /**
-        * Creates a new “GetPluginInfo” message.
-        *
-        * @param pluginName
-        *            The name of the plugin
-        * @param identifier
-        *            The identifier of the request
-        */
-       public GetPluginInfo(String pluginName, String identifier) {
-               super("GetPluginInfo");
-               setField("PluginName", pluginName);
-               setField("Identifier", identifier);
-       }
-
-       /**
-        * Sets whether detailed information about the plugin is wanted.
-        *
-        * @param detailed
-        *            <code>true</code> to request detailed information about the
-        *            plugin, <code>false</code> otherwise
-        */
-       public void setDetailed(boolean detailed) {
-               setField("Detailed", String.valueOf(detailed));
-       }
-
-}
diff --git a/src/net/pterodactylus/fcp/GetRequestStatus.java b/src/net/pterodactylus/fcp/GetRequestStatus.java
deleted file mode 100644 (file)
index 5e2d63b..0000000
+++ /dev/null
@@ -1,64 +0,0 @@
-/*
- * jFCPlib - GetRequestStatus.java - Copyright © 2008 David Roden
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- */
-
-package net.pterodactylus.fcp;
-
-/**
- * The “GetRequestStatus” message is used request status information about a
- * running request. It is also the only way to trigger a download of a persisted
- * completed {@link ClientGet} with a return type of {@link ReturnType#direct}.
- *
- * @author David ‘Bombe’ Roden &lt;bombe@freenetproject.org&gt;
- */
-public class GetRequestStatus extends FcpMessage {
-
-       /**
-        * Creates a new “GetRequestStatus” message.
-        *
-        * @param identifier
-        *            The identifier of the request
-        */
-       public GetRequestStatus(String identifier) {
-               super("GetRequestStatus");
-               setField("Identifier", identifier);
-       }
-
-       /**
-        * Sets whether the request is on the global queue.
-        *
-        * @param global
-        *            <code>true</code> if the request is on the global queue,
-        *            <code>false</code> if it is on the client-local queue
-        */
-       public void setGlobal(boolean global) {
-               setField("Global", String.valueOf(global));
-       }
-
-       /**
-        * Sets whether the omit the transmission of the request data in a
-        * {@link AllData} message.
-        *
-        * @param onlyData
-        *            <code>true</code> to skip transmission of data,
-        *            <code>false</code> to download data
-        */
-       public void setOnlyData(boolean onlyData) {
-               setField("OnlyData", String.valueOf(onlyData));
-       }
-
-}
diff --git a/src/net/pterodactylus/fcp/IdentifierCollision.java b/src/net/pterodactylus/fcp/IdentifierCollision.java
deleted file mode 100644 (file)
index bc96a70..0000000
+++ /dev/null
@@ -1,59 +0,0 @@
-/*
- * jFCPlib - IdentifierCollision.java - Copyright © 2008 David Roden
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- */
-
-package net.pterodactylus.fcp;
-
-/**
- * The “IdentifierCollision” message signals the client that the identifier
- * chosen for a request is already existing.
- *
- * @author David ‘Bombe’ Roden &lt;bombe@freenetproject.org&gt;
- */
-public class IdentifierCollision extends BaseMessage {
-
-       /**
-        * Creates a new “IdentifierCollision” message that wraps the received
-        * message.
-        *
-        * @param receivedMessage
-        *            The received message
-        */
-       IdentifierCollision(FcpMessage receivedMessage) {
-               super(receivedMessage);
-       }
-
-       /**
-        * Returns the identifier of the request.
-        *
-        * @return The identifier of the request
-        */
-       public String getIdentifier() {
-               return getField("Identifier");
-       }
-
-       /**
-        * Returns whether the request is on the global queue.
-        *
-        * @return <code>true</code> if the request is on the global queue,
-        *         <code>false</code> if it is on the client-local queue
-        */
-       public boolean isGlobal() {
-               return Boolean.valueOf(getField("Global"));
-       }
-
-}
diff --git a/src/net/pterodactylus/fcp/ListPeer.java b/src/net/pterodactylus/fcp/ListPeer.java
deleted file mode 100644 (file)
index f16f385..0000000
+++ /dev/null
@@ -1,42 +0,0 @@
-/*
- * jFCPlib - ListPeer.java - Copyright © 2008 David Roden
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- */
-
-package net.pterodactylus.fcp;
-
-/**
- * The “ListPeer” request asks the node about the details of a given peer.
- *
- * @author David ‘Bombe’ Roden &lt;bombe@freenetproject.org&gt;
- */
-public class ListPeer extends FcpMessage {
-
-       /**
-        * Creates a new “ListPeer” request that returns information about the node
-        * specified by <code>nodeIdentifier</code>. <code>nodeIdentifier</code> can
-        * be of several formats: The node’s name, its identity, or its IP address
-        * and port (connection with a ‘:’).
-        *
-        * @param nodeIdentifier
-        *            The identifier of the node to get details about
-        */
-       public ListPeer(String nodeIdentifier) {
-               super("ListPeer");
-               setField("NodeIdentifier", nodeIdentifier);
-       }
-
-}
diff --git a/src/net/pterodactylus/fcp/ListPeerNotes.java b/src/net/pterodactylus/fcp/ListPeerNotes.java
deleted file mode 100644 (file)
index 82e3399..0000000
+++ /dev/null
@@ -1,41 +0,0 @@
-/*
- * jFCPlib - ListPeerNotes.java - Copyright © 2008 David Roden
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- */
-
-package net.pterodactylus.fcp;
-
-/**
- * A “ListPeerNodes” request tells the node to list all notes that have been
- * entered for a node. Note that notes are only supported for darknet nodes.
- *
- * @author David ‘Bombe’ Roden &lt;bombe@freenetproject.org&gt;
- */
-public class ListPeerNotes extends FcpMessage {
-
-       /**
-        * Creates a new “ListPeerNotes” request that lists all notes of the
-        * specified node.
-        *
-        * @param nodeIdentifier
-        *            The identifier of the node
-        */
-       public ListPeerNotes(String nodeIdentifier) {
-               super("ListPeerNotes");
-               setField("NodeIdentifier", nodeIdentifier);
-       }
-
-}
diff --git a/src/net/pterodactylus/fcp/ListPeers.java b/src/net/pterodactylus/fcp/ListPeers.java
deleted file mode 100644 (file)
index b0cbd1b..0000000
+++ /dev/null
@@ -1,58 +0,0 @@
-/*
- * jFCPlib - ListPeers.java - Copyright © 2008 David Roden
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- */
-
-package net.pterodactylus.fcp;
-
-/**
- * The “ListPeer” requests asks the node for a list of all peers it has.
- *
- * @author David ‘Bombe’ Roden &lt;bombe@freenetproject.org&gt;
- */
-public class ListPeers extends FcpMessage {
-
-       /**
-        * Creates a new “ListPeers” request that only includes basic data of the
-        * peers.
-        *
-        * @param identifier
-        *            The identifier of the request
-        */
-       public ListPeers(String identifier) {
-               this(identifier, false, false);
-       }
-
-       /**
-        * Creates a new “ListPeers” request that includes wanted data of the peers.
-        *
-        * @param identifier
-        *            The identifier of the request
-        * @param withMetadata
-        *            If <code>true</code> metadata of the peers is included in the
-        *            reply
-        * @param withVolatile
-        *            if <code>true</code> volatile data of the peers is included in
-        *            the reply
-        */
-       public ListPeers(String identifier, boolean withMetadata, boolean withVolatile) {
-               super("ListPeers");
-               setField("Identifier", identifier);
-               setField("WithMetadata", String.valueOf(withMetadata));
-               setField("WithVolatile", String.valueOf(withVolatile));
-       }
-
-}
diff --git a/src/net/pterodactylus/fcp/ListPersistentRequests.java b/src/net/pterodactylus/fcp/ListPersistentRequests.java
deleted file mode 100644 (file)
index 645205c..0000000
+++ /dev/null
@@ -1,38 +0,0 @@
-/*
- * jFCPlib - ListPersistentRequests.java - Copyright © 2008 David Roden
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- */
-
-package net.pterodactylus.fcp;
-
-/**
- * Command to tell the node to list all persistent requests from the current
- * queue, which is either the global queue or the client-local queue, depending
- * on your {@link WatchGlobal} status.
- *
- * @author David ‘Bombe’ Roden &lt;bombe@freenetproject.org&gt;
- */
-public class ListPersistentRequests extends FcpMessage {
-
-       /**
-        * Creates a new “ListPersistentRequests” command that lists all persistent
-        * requests in the current queue.
-        */
-       public ListPersistentRequests() {
-               super("ListPersistentRequests");
-       }
-
-}
diff --git a/src/net/pterodactylus/fcp/ModifyConfig.java b/src/net/pterodactylus/fcp/ModifyConfig.java
deleted file mode 100644 (file)
index 412b818..0000000
+++ /dev/null
@@ -1,50 +0,0 @@
-/*
- * jFCPlib - ModifyConfig.java - Copyright © 2008 David Roden
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- */
-
-package net.pterodactylus.fcp;
-
-/**
- * The “ModifyConfig” message is used to change the node’s configuration.
- *
- * @author David ‘Bombe’ Roden &lt;bombe@freenetproject.org&gt;
- */
-public class ModifyConfig extends FcpMessage {
-
-       /**
-        * Creates a new “ModifyConfig” message.
-        */
-       public ModifyConfig() {
-               super("ModifyConfig");
-       }
-
-       /**
-        * Sets the option with the given name to the given value.
-        *
-        * @param option
-        *            The name of the option
-        * @param value
-        *            The value of the option
-        */
-       public void setOption(String option, String value) {
-               if (option.indexOf('.') == -1) {
-                       throw new IllegalArgumentException("invalid option name");
-               }
-               setField(option, value);
-       }
-
-}
diff --git a/src/net/pterodactylus/fcp/ModifyPeer.java b/src/net/pterodactylus/fcp/ModifyPeer.java
deleted file mode 100644 (file)
index dc9af6b..0000000
+++ /dev/null
@@ -1,56 +0,0 @@
-/*
- * jFCPlib - ModifyPeer.java - Copyright © 2008 David Roden
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- */
-
-package net.pterodactylus.fcp;
-
-/**
- * The “ModifyPeer” request lets you modify certain properties of a peer.
- *
- * @author David ‘Bombe’ Roden &lt;bombe@freenetproject.org&gt;
- */
-public class ModifyPeer extends FcpMessage {
-
-       /**
-        * Creates a new “ModifyPeer” request. All Boolean parameters may be null to
-        * not influence the current setting.
-        *
-        * @param nodeIdentifier
-        *            The identifier of the node, i.e. name, identity, or IP address
-        *            and port
-        * @param allowLocalAddresses
-        *            Whether to allow local addresses from this node
-        * @param disabled
-        *            Whether the node is disabled
-        * @param listenOnly
-        *            Whether your node should not try to connect the node
-        */
-       public ModifyPeer(String nodeIdentifier, Boolean allowLocalAddresses, Boolean disabled, Boolean listenOnly) {
-               super("ModifyPeer");
-               setField("NodeIdentifier", nodeIdentifier);
-               if (allowLocalAddresses != null) {
-                       setField("AllowLocalAddresses", String.valueOf(allowLocalAddresses));
-               }
-               if (disabled != null) {
-                       setField("IsDisabled", String.valueOf(disabled));
-               }
-               if (listenOnly != null) {
-                       setField("IsListenOnly", String.valueOf(listenOnly));
-               }
-       }
-
-}
diff --git a/src/net/pterodactylus/fcp/ModifyPeerNote.java b/src/net/pterodactylus/fcp/ModifyPeerNote.java
deleted file mode 100644 (file)
index dbb2ea7..0000000
+++ /dev/null
@@ -1,49 +0,0 @@
-/*
- * jFCPlib - ModifyPeerNote.java - Copyright © 2008 David Roden
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- */
-
-package net.pterodactylus.fcp;
-
-/**
- * The “ModifyPeerNote” command modifies a peer note.
- *
- * @author David ‘Bombe’ Roden &lt;bombe@freenetproject.org&gt;
- */
-public class ModifyPeerNote extends FcpMessage {
-
-       /**
-        * Creates a new “ModifyPeerNote” request that changes peer note of the
-        * given type and node to the given text.
-        *
-        * @see PeerNote
-        * @param nodeIdentifier
-        *            The identifier of the node, i.e. name, identity, or IP address
-        *            and port
-        * @param noteText
-        *            The base64-encoded text
-        * @param peerNoteType
-        *            The type of the note to change, possible values are only
-        *            {@link PeerNote#TYPE_PRIVATE_PEER_NOTE} at the moment
-        */
-       public ModifyPeerNote(String nodeIdentifier, String noteText, int peerNoteType) {
-               super("ModifyPeer");
-               setField("NodeIdentifier", nodeIdentifier);
-               setField("NoteText", noteText);
-               setField("PeerNoteType", String.valueOf(peerNoteType));
-       }
-
-}
diff --git a/src/net/pterodactylus/fcp/ModifyPersistentRequest.java b/src/net/pterodactylus/fcp/ModifyPersistentRequest.java
deleted file mode 100644 (file)
index cc71829..0000000
+++ /dev/null
@@ -1,65 +0,0 @@
-/*
- * jFCPlib - ModifyPersistentRequest.java - Copyright © 2008 David Roden
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- */
-
-package net.pterodactylus.fcp;
-
-/**
- * A “ModifyPersistentRequest” is used to modify certain properties of a
- * persistent request while it is running.
- *
- * @author David ‘Bombe’ Roden &lt;bombe@freenetproject.org&gt;
- */
-public class ModifyPersistentRequest extends FcpMessage {
-
-       /**
-        * Creates a new “ModifyPersistentRequest” that changes the specified
-        * request.
-        *
-        * @param requestIdentifier
-        *            The identifier of the request
-        * @param global
-        *            <code>true</code> if the request is on the global queue,
-        *            <code>false</code> if it is on the client-local queue
-        */
-       public ModifyPersistentRequest(String requestIdentifier, boolean global) {
-               super("ModifyPersistentRequest");
-               setField("Identifier", requestIdentifier);
-               setField("Global", String.valueOf(global));
-       }
-
-       /**
-        * Sets the new client token of the request.
-        *
-        * @param newClientToken
-        *            The new client token of the request
-        */
-       public void setClientToken(String newClientToken) {
-               setField("ClientToken", newClientToken);
-       }
-
-       /**
-        * Sets the new priority of the request.
-        *
-        * @param newPriority
-        *            The new priority of the request
-        */
-       public void setPriority(Priority newPriority) {
-               setField("PriorityClass", String.valueOf(newPriority));
-       }
-
-}
diff --git a/src/net/pterodactylus/fcp/NodeData.java b/src/net/pterodactylus/fcp/NodeData.java
deleted file mode 100644 (file)
index 5425833..0000000
+++ /dev/null
@@ -1,176 +0,0 @@
-/*
- * jFCPlib - NodeData.java - Copyright © 2008 David Roden
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- */
-
-package net.pterodactylus.fcp;
-
-/**
- * The “NodeData” contains the noderef of the node, along with additional data.
- *
- * @author David ‘Bombe’ Roden &lt;bombe@freenetproject.org&gt;
- */
-public class NodeData extends BaseMessage {
-
-       /** The noderef of the node. */
-       private final NodeRef nodeRef;
-
-       /**
-        * Creates a new “NodeData” message that wraps the received message.
-        *
-        * @param receivedMessage
-        *            The received message
-        */
-       NodeData(FcpMessage receivedMessage) {
-               super(receivedMessage);
-               nodeRef = new NodeRef(receivedMessage);
-       }
-
-       /**
-        * Returns the noderef of the node.
-        *
-        * @return The noderef of the node
-        */
-       public NodeRef getNodeRef() {
-               return nodeRef;
-       }
-
-       /**
-        * Returns the last good version, i.e. the oldest version the node will
-        * connect to.
-        *
-        * @return The last good version
-        */
-       public Version getLastGoodVersion() {
-               return nodeRef.getLastGoodVersion();
-       }
-
-       /**
-        * Returns the signature of the noderef.
-        *
-        * @return The signature of the noderef
-        */
-       public String getSignature() {
-               return nodeRef.getSignature();
-       }
-
-       /**
-        * Returns whether the noderef is the opennet noderef of the node
-        *
-        * @return <code>true</code> if the noderef is the opennet noderef of the
-        *         node, <code>false</code> otherwise
-        */
-       public boolean isOpennet() {
-               return nodeRef.isOpennet();
-       }
-
-       /**
-        * Returns the identity of the node
-        *
-        * @return The identity of the node
-        */
-       public String getIdentity() {
-               return nodeRef.getIdentity();
-       }
-
-       /**
-        * Returns the name of the node.
-        *
-        * @return The name of the node
-        */
-       public String getMyName() {
-               return nodeRef.getMyName();
-       }
-
-       /**
-        * Returns the version of the node.
-        *
-        * @return The version of the node
-        */
-       public Version getVersion() {
-               return nodeRef.getVersion();
-       }
-
-       /**
-        * Returns IP addresses and port number of the node.
-        *
-        * @return The IP addresses and port numbers of the node
-        */
-       public String getPhysicalUDP() {
-               return nodeRef.getPhysicalUDP();
-       }
-
-       /**
-        * Returns the ARK of the node.
-        *
-        * @return The ARK of the node
-        */
-       public ARK getARK() {
-               return nodeRef.getARK();
-       }
-
-       /**
-        * Returns the public key of the node.
-        *
-        * @return The public key of the node
-        */
-       public String getDSAPublicKey() {
-               return nodeRef.getDSAPublicKey();
-       }
-
-       /**
-        * Returns the private key of the node.
-        *
-        * @return The private key of the node
-        */
-       public String getDSKPrivateKey() {
-               return getField("dsaPrivKey.x");
-       }
-
-       /**
-        * Returns the DSA group of the node.
-        *
-        * @return The DSA group of the node
-        */
-       public DSAGroup getDSAGroup() {
-               return nodeRef.getDSAGroup();
-       }
-
-       /**
-        * Returns the negotiation types supported by the node.
-        *
-        * @return The node’s supported negotiation types
-        */
-       public int[] getNegotiationTypes() {
-               return nodeRef.getNegotiationTypes();
-       }
-
-       /**
-        * Returns one of the volatile fields from the message. The given field name
-        * is prepended with “volatile.” so if you want to get the value of the
-        * field with the name “volatile.freeJavaMemory” you only need to specify
-        * “freeJavaMemory”.
-        *
-        * @param field
-        *            The name of the field
-        * @return The value of the field, or <code>null</code> if there is no such
-        *         field
-        */
-       public String getVolatile(String field) {
-               return getField("volatile." + field);
-       }
-
-}
diff --git a/src/net/pterodactylus/fcp/NodeHello.java b/src/net/pterodactylus/fcp/NodeHello.java
deleted file mode 100644 (file)
index 01b0515..0000000
+++ /dev/null
@@ -1,191 +0,0 @@
-/*
- * jFCPlib - NodeHello.java - Copyright © 2008 David Roden
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- */
-
-package net.pterodactylus.fcp;
-
-/**
- * Some convenience methods for parsing a “NodeHello” message from the node.
- *
- * @author David ‘Bombe’ Roden &lt;bombe@freenetproject.org&gt;
- */
-public class NodeHello extends BaseMessage {
-
-       /**
-        * Createa a new “NodeHello” message that wraps the received message.
-        *
-        * @param receivedMessage
-        *            The received FCP message
-        */
-       NodeHello(FcpMessage receivedMessage) {
-               super(receivedMessage);
-       }
-
-       /**
-        * Returns the build of the node. This may not be a number but also a string
-        * like “@custom@” in case you built the node yourself.
-        *
-        * @return The build of the node
-        */
-       public String getBuild() {
-               return getField("Build");
-       }
-
-       /**
-        * Returns the build number of the node. This may not be a number but also a
-        * string like “@custom@” in case you built the node yourself.
-        *
-        * @return The build number of the node, or <code>-1</code> if the build
-        *         number could not be determined
-        */
-       public int getBuildNumber() {
-               return FcpUtils.safeParseInt(getBuild());
-       }
-
-       /**
-        * Returns the number of compression codecs.
-        *
-        * @return The number of compression codecs
-        */
-       public String getCompressionCodecs() {
-               return getField("CompressionCodecs");
-       }
-
-       /**
-        * Returns the number of compression codecs.
-        *
-        * @return The number of compression codecs, or <code>-1</code> if the
-        *         number of compression codecs could not be determined
-        */
-       public int getCompressionCodecsNumber() {
-               return FcpUtils.safeParseInt(getCompressionCodecs());
-       }
-
-       /**
-        * Returns the unique connection identifier.
-        *
-        * @return The connection identifier
-        */
-       public String getConnectionIdentifier() {
-               return getField("ConnectionIdentifier");
-       }
-
-       /**
-        * Returns the build of the external library file.
-        *
-        * @return The build of the external library file
-        */
-       public String getExtBuild() {
-               return getField("ExtBuild");
-       }
-
-       /**
-        * Returns the build number of the external library file.
-        *
-        * @return The build number of the external library file, or <code>-1</code>
-        *         if the build number could not be determined
-        */
-       public int getExtBuildNumber() {
-               return FcpUtils.safeParseInt(getExtBuild());
-       }
-
-       /**
-        * Returns the revision of the external library file.
-        *
-        * @return The revision of the external library file
-        */
-       public String getExtRevision() {
-               return getField("ExtRevision");
-       }
-
-       /**
-        * Returns the revision number of the external library file.
-        *
-        * @return The revision number of the external library file, or
-        *         <code>-1</code> if the revision number could not be determined
-        */
-       public int getExtRevisionNumber() {
-               return FcpUtils.safeParseInt(getExtRevision());
-       }
-
-       /**
-        * Returns the FCP version the node speaks.
-        *
-        * @return The FCP version the node speaks
-        */
-       public String getFCPVersion() {
-               return getField("FCPVersion");
-       }
-
-       /**
-        * Returns the make of the node, e.g. “Fred” (freenet reference
-        * implementation).
-        *
-        * @return The make of the node
-        */
-       public String getNode() {
-               return getField("Node");
-       }
-
-       /**
-        * Returns the language of the node as 2-letter code, e.g. “en” or “de”.
-        *
-        * @return The language of the node
-        */
-       public String getNodeLanguage() {
-               return getField("NodeLanguage");
-       }
-
-       /**
-        * Returns the revision of the node.
-        *
-        * @return The revision of the node
-        */
-       public String getRevision() {
-               return getField("Revision");
-       }
-
-       /**
-        * Returns the revision number of the node.
-        *
-        * @return The revision number of the node, or <code>-1</code> if the
-        *         revision number coult not be determined
-        */
-       public int getRevisionNumber() {
-               return FcpUtils.safeParseInt(getRevision());
-       }
-
-       /**
-        * Returns whether the node is currently is testnet mode.
-        *
-        * @return <code>true</code> if the node is currently in testnet mode,
-        *         <code>false</code> otherwise
-        */
-       public boolean getTestnet() {
-               return Boolean.valueOf(getField("Testnet"));
-       }
-
-       /**
-        * Returns the version of the node.
-        *
-        * @return The version of the node
-        */
-       public String getVersion() {
-               return getField("Version");
-       }
-
-}
diff --git a/src/net/pterodactylus/fcp/NodeRef.java b/src/net/pterodactylus/fcp/NodeRef.java
deleted file mode 100644 (file)
index 64ca56c..0000000
+++ /dev/null
@@ -1,353 +0,0 @@
-/*
- * jFCPlib - NodeRef.java - Copyright © 2008 David Roden
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- */
-
-package net.pterodactylus.fcp;
-
-/**
- * A reference for a node. The noderef contains all data that is necessary to
- * establish a trusted and secure connection to the node.
- *
- * @author David ‘Bombe’ Roden &lt;bombe@freenetproject.org&gt;
- */
-public class NodeRef {
-
-       /** The identity of the node. */
-       private String identity;
-
-       /** Whether the node is an opennet peer. */
-       private boolean opennet;
-
-       /** The name of the node. */
-       private String name;
-
-       /** The location of the node. */
-       private double location;
-
-       /** The IP addresses and ports of the node. */
-       private String physicalUDP;
-
-       /** The ARK of the node. */
-       private ARK ark;
-
-       /** The public DSA key of the node. */
-       private String dsaPublicKey;
-
-       /** The DSA group of the node. */
-       private DSAGroup dsaGroup;
-
-       /** The node’s supported negotiation types. */
-       private int[] negotiationTypes;
-
-       /** The version of the node. */
-       private Version version;
-
-       /** The oldest version the node will connect to. */
-       private Version lastGoodVersion;
-
-       /** Whether the node is a testnet node. */
-       private boolean testnet;
-
-       /** The signature of the reference. */
-       private String signature;
-
-       /**
-        * Creates a new, empty noderef.
-        */
-       public NodeRef() {
-               /* intentionally left blank. */
-       }
-
-       /**
-        * Creates a new noderef that is initialized with fields from the given
-        * message.
-        *
-        * @param fromMessage
-        *            The message to get initial values for the noderef from
-        */
-       public NodeRef(FcpMessage fromMessage) {
-               identity = fromMessage.getField("identity");
-               opennet = Boolean.valueOf(fromMessage.getField("opennet"));
-               name = fromMessage.getField("myName");
-               if (fromMessage.hasField("location")) {
-                       location = Double.valueOf(fromMessage.getField("location"));
-               }
-               physicalUDP = fromMessage.getField("physical.udp");
-               ark = new ARK(fromMessage.getField("ark.pubURI"), fromMessage.getField("ark.privURI"), fromMessage.getField("ark.number"));
-               dsaPublicKey = fromMessage.getField("dsaPubKey.y");
-               dsaGroup = new DSAGroup(fromMessage.getField("dsaGroup.b"), fromMessage.getField("dsaGroup.p"), fromMessage.getField("dsaGroup.q"));
-               negotiationTypes = FcpUtils.decodeMultiIntegerField(fromMessage.getField("auth.negTypes"));
-               version = new Version(fromMessage.getField("version"));
-               lastGoodVersion = new Version(fromMessage.getField("lastGoodVersion"));
-               testnet = Boolean.valueOf(fromMessage.getField("testnet"));
-               signature = fromMessage.getField("sig");
-       }
-
-       /**
-        * Returns the identity of the node.
-        *
-        * @return The identity of the node
-        */
-       public String getIdentity() {
-               return identity;
-       }
-
-       /**
-        * Sets the identity of the node.
-        *
-        * @param identity
-        *            The identity of the node
-        */
-       public void setIdentity(String identity) {
-               this.identity = identity;
-       }
-
-       /**
-        * Returns whether the node is an opennet peer.
-        *
-        * @return <code>true</code> if the node is an opennet peer,
-        *         <code>false</code> otherwise
-        */
-       public boolean isOpennet() {
-               return opennet;
-       }
-
-       /**
-        * Sets whether the node is an opennet peer.
-        *
-        * @param opennet
-        *            <code>true</code> if the node is an opennet peer,
-        *            <code>false</code> otherwise
-        */
-       public void setOpennet(boolean opennet) {
-               this.opennet = opennet;
-       }
-
-       /**
-        * Returns the name of the node. If the node is an opennet peer, it will not
-        * have a name!
-        *
-        * @return The name of the node, or <code>null</code> if the node is an
-        *         opennet peer
-        */
-       public String getMyName() {
-               return name;
-       }
-
-       /**
-        * Sets the name of the peer.
-        *
-        * @param name
-        *            The name of the peer
-        */
-       public void setName(String name) {
-               this.name = name;
-       }
-
-       /**
-        * Returns the location of the node.
-        *
-        * @return The location of the node
-        */
-       public double getLocation() {
-               return location;
-       }
-
-       /**
-        * Sets the location of the node
-        *
-        * @param location
-        *            The location of the node
-        */
-       public void setLocation(double location) {
-               this.location = location;
-       }
-
-       /**
-        * Returns the IP addresses and port numbers of the node.
-        *
-        * @return The IP addresses and port numbers of the node
-        */
-       public String getPhysicalUDP() {
-               return physicalUDP;
-       }
-
-       /**
-        * Sets the IP addresses and port numbers of the node.
-        *
-        * @param physicalUDP
-        *            The IP addresses and port numbers of the node
-        */
-       public void setPhysicalUDP(String physicalUDP) {
-               this.physicalUDP = physicalUDP;
-       }
-
-       /**
-        * Returns the ARK of the node.
-        *
-        * @return The ARK of the node
-        */
-       public ARK getARK() {
-               return ark;
-       }
-
-       /**
-        * Sets the ARK of the node.
-        *
-        * @param ark
-        *            The ARK of the node
-        */
-       public void setARK(ARK ark) {
-               this.ark = ark;
-       }
-
-       /**
-        * Returns the public DSA key of the node.
-        *
-        * @return The public DSA key of the node
-        */
-       public String getDSAPublicKey() {
-               return dsaPublicKey;
-       }
-
-       /**
-        * Sets the public DSA key of the node.
-        *
-        * @param dsaPublicKey
-        *            The public DSA key of the node
-        */
-       public void setDSAPublicKey(String dsaPublicKey) {
-               this.dsaPublicKey = dsaPublicKey;
-       }
-
-       /**
-        * Returns the DSA group of the node.
-        *
-        * @return The DSA group of the node
-        */
-       public DSAGroup getDSAGroup() {
-               return dsaGroup;
-       }
-
-       /**
-        * Sets the DSA group of the node.
-        *
-        * @param dsaGroup
-        *            The DSA group of the node
-        */
-       public void setDSAGroup(DSAGroup dsaGroup) {
-               this.dsaGroup = dsaGroup;
-       }
-
-       /**
-        * Returns the negotiation types supported by the node.
-        *
-        * @return The node’s supported negotiation types
-        */
-       public int[] getNegotiationTypes() {
-               return negotiationTypes;
-       }
-
-       /**
-        * Sets the negotiation types supported by the node.
-        *
-        * @param negotiationTypes
-        *            The node’s supported negotiation types
-        */
-       public void setNegotiationTypes(int[] negotiationTypes) {
-               this.negotiationTypes = negotiationTypes;
-       }
-
-       /**
-        * Returns the version of the node.
-        *
-        * @return The version of the node
-        */
-       public Version getVersion() {
-               return version;
-       }
-
-       /**
-        * Sets the version of the node.
-        *
-        * @param version
-        *            The version of the node
-        */
-       public void setVersion(Version version) {
-               this.version = version;
-       }
-
-       /**
-        * Returns the last good version of the node.
-        *
-        * @return The oldest version the node will connect to
-        */
-       public Version getLastGoodVersion() {
-               return lastGoodVersion;
-       }
-
-       /**
-        * Sets the last good version of the node.
-        *
-        * @param lastGoodVersion
-        *            The oldest version the node will connect to
-        */
-       public void setLastGoodVersion(Version lastGoodVersion) {
-               this.lastGoodVersion = lastGoodVersion;
-       }
-
-       /**
-        * Returns whether the node is a testnet node.
-        *
-        * @return <code>true</code> if the node is a testnet node,
-        *         <code>false</code> otherwise
-        */
-       public boolean isTestnet() {
-               return testnet;
-       }
-
-       /**
-        * Sets whether this node is a testnet node.
-        *
-        * @param testnet
-        *            <code>true</code> if the node is a testnet node,
-        *            <code>false</code> otherwise
-        */
-       public void setTestnet(boolean testnet) {
-               this.testnet = testnet;
-       }
-
-       /**
-        * Returns the signature of the noderef.
-        *
-        * @return The signature of the noderef
-        */
-       public String getSignature() {
-               return signature;
-       }
-
-       /**
-        * Sets the signature of the noderef.
-        *
-        * @param signature
-        *            The signature of the noderef
-        */
-       public void setSignature(String signature) {
-               this.signature = signature;
-       }
-
-}
diff --git a/src/net/pterodactylus/fcp/Peer.java b/src/net/pterodactylus/fcp/Peer.java
deleted file mode 100644 (file)
index 3cfa856..0000000
+++ /dev/null
@@ -1,258 +0,0 @@
-/*
- * jFCPlib - Peer.java - Copyright © 2008 David Roden
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- */
-
-package net.pterodactylus.fcp;
-
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.Map;
-import java.util.Map.Entry;
-
-/**
- * The “Peer” reply by the node contains information about a peer.
- *
- * @author David ‘Bombe’ Roden &lt;bombe@freenetproject.org&gt;
- */
-public class Peer extends BaseMessage {
-
-       /**
-        * Creates a new “Peer” reply from the received message.
-        *
-        * @param receivedMessage
-        *            The received message
-        */
-       Peer(FcpMessage receivedMessage) {
-               super(receivedMessage);
-       }
-
-       /**
-        * Returns a collection of fields as a node reference.
-        *
-        * @return The node reference contained within this message
-        */
-       public NodeRef getNodeRef() {
-               NodeRef nodeRef = new NodeRef();
-               nodeRef.setARK(getARK());
-               nodeRef.setDSAGroup(getDSAGroup());
-               nodeRef.setDSAPublicKey(getDSAPublicKey());
-               nodeRef.setIdentity(getIdentity());
-               nodeRef.setLastGoodVersion(getLastGoodVersion());
-               nodeRef.setLocation(getLocation());
-               nodeRef.setName(getMyName());
-               nodeRef.setNegotiationTypes(getNegotiationTypes());
-               nodeRef.setOpennet(isOpennet());
-               nodeRef.setPhysicalUDP(getPhysicalUDP());
-               nodeRef.setVersion(getVersion());
-               return nodeRef;
-       }
-
-       /**
-        * Returns the identifier of the request.
-        *
-        * @return The identifier of the request
-        */
-       public String getIdentifier() {
-               return getField("Identifier");
-       }
-
-       /**
-        * Returns the “physical.udp” line from the message. It contains all IP
-        * addresses and port numbers of the peer.
-        *
-        * @return The IP addresses and port numbers of the peer
-        */
-       public String getPhysicalUDP() {
-               return getField("physical.udp");
-       }
-
-       /**
-        * Returns whether the listed peer is an opennet peer.
-        *
-        * @return <code>true</code> if the peer is an opennet peer,
-        *         <code>false</code> if the peer is a darknet peer
-        */
-       public boolean isOpennet() {
-               return Boolean.valueOf(getField("opennet"));
-       }
-
-       /**
-        * Returns whether this peer is a seed.
-        *
-        * @return <code>true</code> if the peer is a seed, <code>false</code>
-        *         otherwise
-        */
-       public boolean isSeed() {
-               return Boolean.valueOf(getField("seed"));
-       }
-
-       /**
-        * Returns the “y” part of the peer’s public DSA key.
-        *
-        * @return The public DSA key
-        */
-       public String getDSAPublicKey() {
-               return getField("dsaPubKey.y");
-       }
-
-       /**
-        * Returns the DSA group of the peer.
-        *
-        * @return The DSA group of the peer
-        */
-       public DSAGroup getDSAGroup() {
-               return new DSAGroup(getField("dsaGroup.g"), getField("dsaGroup.p"), getField("dsaGroup.q"));
-       }
-
-       /**
-        * Returns the last good version of the peer, i.e. the oldest version the
-        * peer will connect to.
-        *
-        * @return The last good version of the peer
-        */
-       public Version getLastGoodVersion() {
-               return new Version(getField("lastGoodVersion"));
-       }
-
-       /**
-        * Returns the ARK of the peer.
-        *
-        * @return The ARK of the peer
-        */
-       public ARK getARK() {
-               return new ARK(getField("ark.pubURI"), getField("ark.number"));
-       }
-
-       /**
-        * Returns the identity of the peer.
-        *
-        * @return The identity of the peer
-        */
-       public String getIdentity() {
-               return getField("identity");
-       }
-
-       /**
-        * Returns the name of the peer. If the peer is not a darknet peer it will
-        * have no name.
-        *
-        * @return The name of the peer, or <code>null</code> if the peer is an
-        *         opennet peer
-        */
-       public String getMyName() {
-               return getField("myName");
-       }
-
-       /**
-        * Returns the location of the peer.
-        *
-        * @return The location of the peer
-        * @throws NumberFormatException
-        *             if the field can not be parsed
-        */
-       public double getLocation() throws NumberFormatException {
-               return Double.valueOf(getField("location"));
-       }
-
-       /**
-        * Returns whether the peer is a testnet node.
-        *
-        * @return <code>true</code> if the peer is a testnet node,
-        *         <code>false</code> otherwise
-        */
-       public boolean isTestnet() {
-               return Boolean.valueOf("testnet");
-       }
-
-       /**
-        * Returns the version of the peer.
-        *
-        * @return The version of the peer
-        */
-       public Version getVersion() {
-               return new Version(getField("version"));
-       }
-
-       /**
-        * Returns the negotiation types the peer supports.
-        *
-        * @return The supported negotiation types
-        */
-       public int[] getNegotiationTypes() {
-               return FcpUtils.decodeMultiIntegerField(getField("auth.negTypes"));
-       }
-
-       /**
-        * Returns all volatile fields from the message.
-        *
-        * @return All volatile files
-        */
-       public Map<String, String> getVolatileFields() {
-               Map<String, String> volatileFields = new HashMap<String, String>();
-               for (Entry<String, String> field : getFields().entrySet()) {
-                       if (field.getKey().startsWith("volatile.")) {
-                               volatileFields.put(field.getKey(), field.getValue());
-                       }
-               }
-               return Collections.unmodifiableMap(volatileFields);
-       }
-
-       /**
-        * Returns one of the volatile fields from the message. The given field name
-        * is prepended with “volatile.” so if you want to get the value of the
-        * field with the name “volatile.status” you only need to specify “status”.
-        *
-        * @param field
-        *            The name of the field
-        * @return The value of the field, or <code>null</code> if there is no such
-        *         field
-        */
-       public String getVolatile(String field) {
-               return getField("volatile." + field);
-       }
-
-       /**
-        * Returns all metadata fields from the message.
-        *
-        * @return All volatile files
-        */
-       public Map<String, String> getMetadataFields() {
-               Map<String, String> metadataFields = new HashMap<String, String>();
-               for (Entry<String, String> field : getFields().entrySet()) {
-                       if (field.getKey().startsWith("metadata.")) {
-                               metadataFields.put(field.getKey(), field.getValue());
-                       }
-               }
-               return Collections.unmodifiableMap(metadataFields);
-       }
-
-       /**
-        * Returns one of the metadata fields from the message. The given field name
-        * is prepended with “metadata.” so if you want to get the value of the
-        * field with the name “metadata.timeLastRoutable” you only need to specify
-        * “timeLastRoutable”.
-        *
-        * @param field
-        *            The name of the field
-        * @return The value of the field, or <code>null</code> if there is no such
-        *         field
-        */
-       public String getMetadata(String field) {
-               return getField("metadata." + field);
-       }
-
-}
diff --git a/src/net/pterodactylus/fcp/PeerNote.java b/src/net/pterodactylus/fcp/PeerNote.java
deleted file mode 100644 (file)
index 7b32207..0000000
+++ /dev/null
@@ -1,70 +0,0 @@
-/*
- * jFCPlib - PeerNote.java - Copyright © 2008 David Roden
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- */
-
-package net.pterodactylus.fcp;
-
-/**
- * The “PeerNote” message contains a private note that has been entered for a
- * darknet peer.
- *
- * @author David ‘Bombe’ Roden &lt;bombe@freenetproject.org&gt;
- */
-public class PeerNote extends BaseMessage {
-
-       /** The type for base64 encoded peer notes. */
-       public static final int TYPE_PRIVATE_PEER_NOTE = 1;
-
-       /**
-        * Creates a “PeerNote” message that wraps the recevied message.
-        *
-        * @param receivedMessage
-        *            The received message
-        */
-       PeerNote(FcpMessage receivedMessage) {
-               super(receivedMessage);
-       }
-
-       /**
-        * Returns the identifier of the node this note belongs to.
-        *
-        * @return The note’s node’s identifier
-        */
-       public String getNodeIdentifier() {
-               return getField("NodeIdentifier");
-       }
-
-       /**
-        * Returns the base64-encoded note text.
-        *
-        * @return The note text
-        */
-       public String getNoteText() {
-               return getField("NoteText");
-       }
-
-       /**
-        * Returns the type of the peer note.
-        *
-        * @return The type of the peer note, or <code>-1</code> if the type can not
-        *         be parsed
-        */
-       public int getPeerNoteType() {
-               return FcpUtils.safeParseInt(getField("PeerNoteType"));
-       }
-
-}
diff --git a/src/net/pterodactylus/fcp/PeerRemoved.java b/src/net/pterodactylus/fcp/PeerRemoved.java
deleted file mode 100644 (file)
index 61aa08d..0000000
+++ /dev/null
@@ -1,56 +0,0 @@
-/*
- * jFCPlib - PeerRemoved.java - Copyright © 2008 David Roden
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- */
-
-package net.pterodactylus.fcp;
-
-/**
- * A “PeerRemoved” message is sent by the node when a peer has been removed.
- *
- * @author David ‘Bombe’ Roden &lt;bombe@freenetproject.org&gt;
- */
-public class PeerRemoved extends BaseMessage {
-
-       /**
-        * Creates a new “PeerRemoved” message that wraps the received message.
-        *
-        * @param receivedMessage
-        *            The received message
-        */
-       PeerRemoved(FcpMessage receivedMessage) {
-               super(receivedMessage);
-       }
-
-       /**
-        * Returns the identity of the removed peer.
-        *
-        * @return The identity of the removed peer
-        */
-       public String getIdentity() {
-               return getField("Identity");
-       }
-
-       /**
-        * Returns the node identifier of the removed peer.
-        *
-        * @return The node identifier of the removed peer
-        */
-       public String getNodeIdentifier() {
-               return getField("NodeIdentifier");
-       }
-
-}
diff --git a/src/net/pterodactylus/fcp/Persistence.java b/src/net/pterodactylus/fcp/Persistence.java
deleted file mode 100644 (file)
index 44c5e62..0000000
+++ /dev/null
@@ -1,46 +0,0 @@
-/*
- * jFCPlib - Persistence.java - Copyright © 2008 David Roden
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- */
-
-package net.pterodactylus.fcp;
-
-/**
- * Convenience class for persistence values.
- *
- * @author David ‘Bombe’ Roden &lt;bombe@freenetproject.org&gt;
- */
-public enum Persistence {
-
-       /**
-        * Connection persistence. A request with this persistence will die as soon
-        * as the connection goes down.
-        */
-       connection,
-
-       /**
-        * Reboot persistence. A request with this persistence will live until the
-        * node is restarted.
-        */
-       reboot,
-
-       /** Forever persistence. A request with this persistence will live forever. */
-       forever,
-
-       /** Unknown persistence. */
-       unknown;
-
-}
diff --git a/src/net/pterodactylus/fcp/PersistentGet.java b/src/net/pterodactylus/fcp/PersistentGet.java
deleted file mode 100644 (file)
index 7489801..0000000
+++ /dev/null
@@ -1,153 +0,0 @@
-/*
- * jFCPlib - PersistentGet.java - Copyright © 2008 David Roden
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- */
-
-package net.pterodactylus.fcp;
-
-/**
- * The “PersistentGet” message is sent to the client to inform it about a
- * persistent download, either in the client-local queue or in the global queue.
- *
- * @author David ‘Bombe’ Roden &lt;bombe@freenetproject.org&gt;
- */
-public class PersistentGet extends BaseMessage {
-
-       /**
-        * Creates a new “PersistentGet” message that wraps the received message.
-        *
-        * @param receivedMessage
-        *            The received message
-        */
-       PersistentGet(FcpMessage receivedMessage) {
-               super(receivedMessage);
-       }
-
-       /**
-        * Returns the identifier of the request.
-        *
-        * @return The identifier of the request
-        */
-       public String getIdentifier() {
-               return getField("Identifier");
-       }
-
-       /**
-        * Returns the URI of the request.
-        *
-        * @return The URI of the request
-        */
-       public String getURI() {
-               return getField("URI");
-       }
-
-       /**
-        * Returns the verbosity of the request.
-        *
-        * @return The verbosity of the request
-        */
-       public Verbosity getVerbosity() {
-               return Verbosity.valueOf(getField("Verbosity"));
-       }
-
-       /**
-        * Returns the return type of the request.
-        *
-        * @return The return type of the request
-        */
-       public ReturnType getReturnType() {
-               try {
-                       return ReturnType.valueOf(getField("ReturnType"));
-               } catch (IllegalArgumentException iae1) {
-                       return ReturnType.unknown;
-               }
-       }
-
-       /**
-        * Returns the name of the file the data is downloaded to. This field will
-        * only be set if {@link #getReturnType()} is {@link ReturnType#disk}.
-        *
-        * @return The name of the file the data is downloaded to
-        */
-       public String getFilename() {
-               return getField("Filename");
-       }
-
-       /**
-        * Returns the name of the temporary file. This field will only be set if
-        * {@link #getReturnType()} is {@link ReturnType#disk}.
-        *
-        * @return The name of the temporary file
-        */
-       public String getTempFilename() {
-               return getField("TempFilename");
-       }
-
-       /**
-        * Returns the client token of the request.
-        *
-        * @return The client token of the request
-        */
-       public String getClientToken() {
-               return getField("ClientToken");
-       }
-
-       /**
-        * Returns the priority of the request.
-        *
-        * @return The priority of the request
-        */
-       public Priority getPriority() {
-               return Priority.values()[FcpUtils.safeParseInt(getField("PriorityClass"), Priority.unknown.ordinal())];
-       }
-
-       /**
-        * Returns the persistence of the request.
-        *
-        * @return The persistence of the request, or {@link Persistence#unknown} if
-        *         the persistence could not be parsed
-        */
-       public Persistence getPersistence() {
-               try {
-                       return Persistence.valueOf(getField("Persistence"));
-               } catch (IllegalArgumentException iae1) {
-                       return Persistence.unknown;
-               }
-       }
-
-       /**
-        * Returns whether this request is on the global queue or on the
-        * client-local queue.
-        *
-        * @return <code>true</code> if the request is on the global queue,
-        *         <code>false</code> if the request is on the client-local queue
-        */
-       public boolean isGlobal() {
-               return Boolean.valueOf(getField("Global"));
-       }
-
-       /**
-        * Returns the maximum number of retries for a failed block.
-        *
-        * @return The maximum number of retries for a failed block, <code>-1</code>
-        *         for endless retries, <code>-2</code> if the number could not be
-        *         parsed
-        */
-       public int getMaxRetries() {
-               return FcpUtils.safeParseInt(getField("MaxRetries"), -2);
-       }
-
-}
diff --git a/src/net/pterodactylus/fcp/PersistentPut.java b/src/net/pterodactylus/fcp/PersistentPut.java
deleted file mode 100644 (file)
index 383ea93..0000000
+++ /dev/null
@@ -1,163 +0,0 @@
-/*
- * jFCPlib - PersistentPut.java - Copyright © 2008 David Roden
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- */
-
-package net.pterodactylus.fcp;
-
-/**
- * A “PersistentPut” message notifies a client about a persistent
- * {@link ClientPut} request.
- *
- * @author David ‘Bombe’ Roden &lt;bombe@freenetproject.org&gt;
- */
-public class PersistentPut extends BaseMessage {
-
-       /**
-        * Creates a new “PersistentPut” message that wraps the received message.
-        *
-        * @param receivedMessage
-        *            The received message
-        */
-       PersistentPut(FcpMessage receivedMessage) {
-               super(receivedMessage);
-       }
-
-       /**
-        * Returns the client token of the request.
-        *
-        * @return The client token of the request
-        */
-       public String getClientToken() {
-               return getField("ClientToken");
-       }
-
-       /**
-        * Returns the data length of the request.
-        *
-        * @return The data length of the request, or <code>-1</code> if the length
-        *         could not be parsed
-        */
-       public long getDataLength() {
-               return FcpUtils.safeParseLong(getField("DataLength"));
-       }
-
-       /**
-        * Returns whether the request is on the global queue.
-        *
-        * @return <code>true</code> if the request is on the global queue,
-        *         <code>false</code> otherwise
-        */
-       public boolean isGlobal() {
-               return Boolean.valueOf(getField("Global"));
-       }
-
-       /**
-        * Returns the identifier of the request.
-        *
-        * @return The identifier of the request
-        */
-       public String getIdentifier() {
-               return getField("Identifier");
-       }
-
-       /**
-        * Returns the maximum number of retries for failed blocks. When
-        * <code>-1</code> is returned each block is tried forever.
-        *
-        * @return The maximum number of retries for failed blocks, or
-        *         <code>-1</code> for unlimited retries, or <code>-2</code> if the
-        *         number of retries could not be parsed
-        */
-       public int getMaxRetries() {
-               return FcpUtils.safeParseInt(getField("MaxRetries"));
-       }
-
-       /**
-        * Returns the content type of the data.
-        *
-        * @return The content type
-        */
-       public String getMetadataContentType() {
-               return getField("Metadata.ContentType");
-       }
-
-       /**
-        * Returns the persistence of the request.
-        *
-        * @return The persistence of the request
-        */
-       public Persistence getPersistence() {
-               return Persistence.valueOf(getField("Persistence"));
-       }
-
-       /**
-        * Returns the priority of the request.
-        *
-        * @return The priority of the request, or {@link Priority#unknown} if the
-        *         priority could not be parsed
-        */
-       public Priority getPriority() {
-               return Priority.values()[FcpUtils.safeParseInt(getField("PriorityClass"), Priority.unknown.ordinal())];
-       }
-
-       /**
-        * Returns whether this request has started.
-        *
-        * @return <code>true</code> if the request has started, <code>false</code>
-        *         otherwise
-        */
-       public boolean isStarted() {
-               return Boolean.valueOf(getField("Started"));
-       }
-
-       /**
-        * Returns the target filename of the request.
-        *
-        * @return The target filename of the request
-        */
-       public String getTargetFilename() {
-               return getField("TargetFilename");
-       }
-
-       /**
-        * Returns the upload source of the request.
-        *
-        * @return The upload source of the request
-        */
-       public UploadFrom getUploadFrom() {
-               return UploadFrom.valueOf(getField("UploadFrom"));
-       }
-
-       /**
-        * Returns the target URI of the request.
-        *
-        * @return The target URI of the request
-        */
-       public String getURI() {
-               return getField("URI");
-       }
-
-       /**
-        * Returns the verbosity of the request.
-        *
-        * @return The verbosity of the request
-        */
-       public Verbosity getVerbosity() {
-               return Verbosity.valueOf(getField("Verbosity"));
-       }
-
-}
diff --git a/src/net/pterodactylus/fcp/PersistentPutDir.java b/src/net/pterodactylus/fcp/PersistentPutDir.java
deleted file mode 100644 (file)
index 47c3d8d..0000000
+++ /dev/null
@@ -1,170 +0,0 @@
-/*
- * jFCPlib - PersistentPutDir.java - Copyright © 2008 David Roden
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- */
-
-package net.pterodactylus.fcp;
-
-/**
- * A “PersistentPutDir” is the response to a {@link ClientPutDiskDir} message.
- * It is also sent as a possible response to a {@link ListPersistentRequests}
- * message.
- *
- * @author David ‘Bombe’ Roden &lt;bombe@freenetproject.org&gt;
- */
-public class PersistentPutDir extends BaseMessage {
-
-       /**
-        * Creates a new “PersistentPutDir” message that wraps the received message.
-        *
-        * @param receivedMessage
-        *            The received message
-        */
-       PersistentPutDir(FcpMessage receivedMessage) {
-               super(receivedMessage);
-       }
-
-       /**
-        * Returns the identifier of the request.
-        *
-        * @return The identifier of the request
-        */
-       public String getIdentifier() {
-               return getField("Identifier");
-       }
-
-       /**
-        * Returns the URI of the request.
-        *
-        * @return The URI of the request
-        */
-       public String getURI() {
-               return getField("URI");
-       }
-
-       /**
-        * Returns the verbosity of the request.
-        *
-        * @return The verbosity of the request
-        */
-       public Verbosity getVerbosity() {
-               return Verbosity.valueOf(getField("Verbosity"));
-       }
-
-       /**
-        * Returns the priority of the request.
-        *
-        * @return The priority of the request
-        */
-       public Priority getPriority() {
-               return Priority.values()[FcpUtils.safeParseInt(getField("PriorityClass"), Priority.unknown.ordinal())];
-       }
-
-       /**
-        * Returns whether the request is on the global queue.
-        *
-        * @return <code>true</code> if the request is on the global queue,
-        *         <code>false</code> if it is on the client-local queue
-        */
-       public boolean isGlobal() {
-               return Boolean.valueOf(getField("Global"));
-       }
-
-       /**
-        * Returns the maximum number of retries for failed blocks.
-        *
-        * @return The maximum number of retries, or <code>-1</code> for endless
-        *         retries, or <code>-2</code> if the number could not be parsed
-        */
-       public int getMaxRetries() {
-               return FcpUtils.safeParseInt(getField("MaxRetries"), -2);
-       }
-
-       /**
-        * Returns the number of files in the request.
-        *
-        * @return The number of files in the request
-        */
-       public int getFileCount() {
-               int fileCount = -1;
-               while (getField("Files." + ++fileCount + ".UploadFrom") != null) {
-                       /* do nothing. */
-               }
-               return fileCount;
-       }
-
-       /**
-        * Returns the name of the file at the given index. The index is counted
-        * from <code>0</code>.
-        *
-        * @param fileIndex
-        *            The index of the file
-        * @return The name of the file at the given index
-        */
-       public String getFileName(int fileIndex) {
-               return getField("Files." + fileIndex + ".Name");
-       }
-
-       /**
-        * Returns the length of the file at the given index. The index is counted
-        * from <code>0</code>.
-        *
-        * @param fileIndex
-        *            The index of the file
-        * @return The length of the file at the given index
-        */
-       public long getFileDataLength(int fileIndex) {
-               return FcpUtils.safeParseLong(getField("Files." + fileIndex + ".DataLength"));
-       }
-
-       /**
-        * Returns the upload source of the file at the given index. The index is
-        * counted from <code>0</code>.
-        *
-        * @param fileIndex
-        *            The index of the file
-        * @return The upload source of the file at the given index
-        */
-       public UploadFrom getFileUploadFrom(int fileIndex) {
-               return UploadFrom.valueOf(getField("Files." + fileIndex + ".UploadFrom"));
-       }
-
-       /**
-        * Returns the content type of the file at the given index. The index is
-        * counted from <code>0</code>.
-        *
-        * @param fileIndex
-        *            The index of the file
-        * @return The content type of the file at the given index
-        */
-       public String getFileMetadataContentType(int fileIndex) {
-               return getField("Files." + fileIndex + ".Metadata.ContentType");
-       }
-
-       /**
-        * Returns the filename of the file at the given index. This value is only
-        * returned if {@link #getFileUploadFrom(int)} is returning
-        * {@link UploadFrom#disk}. The index is counted from <code>0</code>.
-        *
-        * @param fileIndex
-        *            The index of the file
-        * @return The filename of the file at the given index
-        */
-       public String getFileFilename(int fileIndex) {
-               return getField("Files." + fileIndex + ".Filename");
-       }
-
-}
diff --git a/src/net/pterodactylus/fcp/PersistentRequestModified.java b/src/net/pterodactylus/fcp/PersistentRequestModified.java
deleted file mode 100644 (file)
index ea8d1ac..0000000
+++ /dev/null
@@ -1,79 +0,0 @@
-/*
- * jFCPlib - PersistentRequestModified.java - Copyright © 2008 David Roden
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- */
-
-package net.pterodactylus.fcp;
-
-/**
- * The “PersistentRequestModified” message is a reply to
- * {@link ModifyPersistentRequest}.
- *
- * @author David ‘Bombe’ Roden &lt;bombe@freenetproject.org&gt;
- */
-public class PersistentRequestModified extends BaseMessage {
-
-       /**
-        * Creates a new “PersistentRequestModified” message that wraps the received
-        * message.
-        *
-        * @param receivedMessage
-        *            The received message
-        */
-       PersistentRequestModified(FcpMessage receivedMessage) {
-               super(receivedMessage);
-       }
-
-       /**
-        * Returns the identifier of the changed request.
-        *
-        * @return The identifier of the request
-        */
-       public String getIdentifier() {
-               return getField("Identifier");
-       }
-
-       /**
-        * Returns whether the request is on the global queue.
-        *
-        * @return <code>true</code> if the request is on the global queue,
-        *         <code>false</code> if it is on a client-local queue
-        */
-       public boolean isGlobal() {
-               return Boolean.valueOf(getField("Global"));
-       }
-
-       /**
-        * Returns the client token, if it was changed.
-        *
-        * @return The new client token, or <code>null</code> if the client token
-        *         was not changed
-        */
-       public String getClientToken() {
-               return getField("ClientToken");
-       }
-
-       /**
-        * Returns the priority of the request, if it was changed.
-        *
-        * @return The new priority of the request, or {@link Priority#unknown} if
-        *         the priority was not changed
-        */
-       public Priority getPriority() {
-               return Priority.values()[FcpUtils.safeParseInt(getField("PriorityClass"), Priority.unknown.ordinal())];
-       }
-
-}
diff --git a/src/net/pterodactylus/fcp/PersistentRequestRemoved.java b/src/net/pterodactylus/fcp/PersistentRequestRemoved.java
deleted file mode 100644 (file)
index 154c88c..0000000
+++ /dev/null
@@ -1,60 +0,0 @@
-/*
- * jFCPlib - PersistentRequestRemoved.java - Copyright © 2008 David Roden
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- */
-
-package net.pterodactylus.fcp;
-
-/**
- * A “PersistentRequestRemoved” message signals that a persistent request was
- * removed from either the global or the client-local queue.
- *
- * @author David ‘Bombe’ Roden &lt;bombe@freenetproject.org&gt;
- */
-public class PersistentRequestRemoved extends BaseMessage {
-
-       /**
-        * Creates a new “PersistentRequestRemoved” message that wraps the received
-        * message.
-        *
-        * @param receivedMessage
-        *            The received message
-        */
-       PersistentRequestRemoved(FcpMessage receivedMessage) {
-               super(receivedMessage);
-       }
-
-       /**
-        * Returns the identifier of the request.
-        *
-        * @return The identifier of the request
-        */
-       public String getIdentifier() {
-               return getField("Identifier");
-       }
-
-       /**
-        * Returns whether the request was removed from the global queue.
-        *
-        * @return <code>true</code> if the request was removed from the global
-        *         queue, <code>false</code> if it was removed from the client-local
-        *         queue
-        */
-       public boolean isGlobal() {
-               return Boolean.valueOf(getField("Global"));
-       }
-
-}
diff --git a/src/net/pterodactylus/fcp/PluginInfo.java b/src/net/pterodactylus/fcp/PluginInfo.java
deleted file mode 100644 (file)
index 84ddaea..0000000
+++ /dev/null
@@ -1,75 +0,0 @@
-/*
- * jFCPlib - PluginInfo.java - Copyright © 2008 David Roden
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- */
-
-package net.pterodactylus.fcp;
-
-/**
- * The “PluginInfo” message is a reply to the {@link GetPluginInfo} request.
- *
- * @author David ‘Bombe’ Roden &lt;bombe@freenetproject.org&gt;
- */
-public class PluginInfo extends BaseMessage {
-
-       /**
-        * Creates a new “PluginInfo” message that wraps the received message.
-        *
-        * @param receivedMessage
-        *            The received message
-        */
-       PluginInfo(FcpMessage receivedMessage) {
-               super(receivedMessage);
-       }
-
-       /**
-        * Returns the name of the plugin.
-        *
-        * @return The name of the plugin
-        */
-       public String getPluginName() {
-               return getField("PluginName");
-       }
-
-       /**
-        * Returns the identifier of the request.
-        *
-        * @return The identifier of the request
-        */
-       public String getIdentifier() {
-               return getField("Identifier");
-       }
-
-       /**
-        * Returns the original URI of the plugin.
-        *
-        * @return The original URI of the plugin
-        */
-       public String getOriginalURI() {
-               return getField("OriginalUri");
-       }
-
-       /**
-        * Returns whether the plugin is started.
-        *
-        * @return <code>true</code> if the plugin is started, <code>false</code>
-        *         otherwise
-        */
-       public boolean isStarted() {
-               return Boolean.valueOf("Started");
-       }
-
-}
diff --git a/src/net/pterodactylus/fcp/Priority.java b/src/net/pterodactylus/fcp/Priority.java
deleted file mode 100644 (file)
index 45560db..0000000
+++ /dev/null
@@ -1,60 +0,0 @@
-/*
- * jFCPlib - Priority.java - Copyright © 2008 David Roden
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- */
-
-package net.pterodactylus.fcp;
-
-/**
- * The priority classes used by the Freenet node.
- *
- * @author David ‘Bombe’ Roden &lt;bombe@freenetproject.org&gt;
- */
-public enum Priority {
-
-       /** Maximum priority. */
-       maximum,
-
-       /** Priority for interactive request, i.e. FProxy. */
-       interactive,
-
-       /** Priority for splitfile manifests. */
-       immediateSplitfile,
-
-       /** Priority for USK searches. */
-       update,
-
-       /** Priority for splitfile blocks. */
-       bulkSplitfile,
-
-       /** Priority for prefetching blocks. */
-       prefetch,
-
-       /** Minimum priority. */
-       minimum,
-
-       /** Unknown priority. */
-       unknown;
-
-       /**
-        * @see java.lang.Enum#toString()
-        */
-       @Override
-       public String toString() {
-               return String.valueOf(ordinal());
-       }
-
-}
diff --git a/src/net/pterodactylus/fcp/ProtocolError.java b/src/net/pterodactylus/fcp/ProtocolError.java
deleted file mode 100644 (file)
index f59d1fe..0000000
+++ /dev/null
@@ -1,96 +0,0 @@
-/*
- * jFCPlib - ProtocolError.java - Copyright © 2008 David Roden
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- */
-
-package net.pterodactylus.fcp;
-
-/**
- * The “ProtocolError” message signals that something has gone really wrong.
- *
- * @author David ‘Bombe’ Roden &lt;bombe@freenetproject.org&gt;
- */
-public class ProtocolError extends BaseMessage {
-
-       /**
-        * Creates a new “ProtocolError” message that wraps the received message.
-        *
-        * @param receivedMessage
-        *            The received message
-        */
-       ProtocolError(FcpMessage receivedMessage) {
-               super(receivedMessage);
-       }
-
-       /**
-        * Returns whether the causing message had the “Global” flag set.
-        *
-        * @return <code>true</code> if the causing message had the “Global” flag
-        *         set
-        */
-       public boolean isGlobal() {
-               return Boolean.valueOf(getField("Global"));
-       }
-
-       /**
-        * Returns the error code.
-        *
-        * @return The error code, or <code>-1</code> if the error code could not be
-        *         parsed
-        */
-       public int getCode() {
-               return FcpUtils.safeParseInt(getField("Code"));
-       }
-
-       /**
-        * Returns the description of the error.
-        *
-        * @return The description of the error
-        */
-       public String getCodeDescription() {
-               return getField("CodeDescription");
-       }
-
-       /**
-        * Returns some extra description of the error.
-        *
-        * @return Extra description of the error, or <code>null</code> if there is
-        *         none
-        */
-       public String getExtraDescription() {
-               return getField("ExtraDescription");
-       }
-
-       /**
-        * Returns whether the connection to the node can stay open.
-        *
-        * @return <code>true</code> when the connection has to be closed,
-        *         <code>false</code> otherwise
-        */
-       public boolean isFatal() {
-               return Boolean.valueOf(getField("Fatal"));
-       }
-
-       /**
-        * The identifier of the causing request, if any.
-        *
-        * @return The identifier of the causing request
-        */
-       public String getIdentifier() {
-               return getField("Identifier");
-       }
-
-}
diff --git a/src/net/pterodactylus/fcp/PutFailed.java b/src/net/pterodactylus/fcp/PutFailed.java
deleted file mode 100644 (file)
index b6916f4..0000000
+++ /dev/null
@@ -1,176 +0,0 @@
-/*
- * jFCPlib - GetFailed.java - Copyright © 2008 David Roden
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- */
-
-package net.pterodactylus.fcp;
-
-import java.util.ArrayList;
-import java.util.List;
-import java.util.Map;
-import java.util.Map.Entry;
-
-/**
- * The “PutFailed” message signals the client that a {@link ClientPut} request
- * has failed. This also means that no further progress messages for that
- * request will be sent.
- *
- * @author David ‘Bombe’ Roden &lt;bombe@freenetproject.org&gt;
- */
-public class PutFailed extends BaseMessage {
-
-       /**
-        * Creates a new “PutFailed” message that wraps the received message.
-        *
-        * @param receivedMessage
-        *            The received message
-        */
-       PutFailed(FcpMessage receivedMessage) {
-               super(receivedMessage);
-       }
-
-       /**
-        * Returns the code of the error.
-        *
-        * @return The code of the error, or <code>-1</code> if the error code could
-        *         not be parsed
-        */
-       public int getCode() {
-               return FcpUtils.safeParseInt(getField("Code"));
-       }
-
-       /**
-        * Returns the identifier of the request.
-        *
-        * @return The identifier of the request
-        */
-       public String getIdentifier() {
-               return getField("Identifier");
-       }
-
-       /**
-        * Returns whether the request is on the global queue.
-        *
-        * @return <code>true</code> if the request is on the global queue,
-        *         <code>false</code> if it is on the client-local queue
-        */
-       public boolean isGlobal() {
-               return Boolean.valueOf(getField("Global"));
-       }
-
-       /**
-        * Returns the description of the error code.
-        *
-        * @return The description of the error code
-        */
-       public String getCodeDescription() {
-               return getField("CodeDescription");
-       }
-
-       /**
-        * Returns the extra description of the error.
-        *
-        * @return The extra description of the error
-        */
-       public String getExtraDescription() {
-               return getField("ExtraDescription");
-       }
-
-       /**
-        * Returns the short description of the error.
-        *
-        * @return The short description of the error
-        */
-       public String getShortCodeDescription() {
-               return getField("ShortCodeDescription");
-       }
-
-       /**
-        * Returns the expected URI of the request.
-        *
-        * @return The expected URI
-        */
-       public String getExpectedURI() {
-               return getField("ExpectedURI");
-       }
-
-       /**
-        * Returns whether the request failed fatally. If a request fails fatally it
-        * can never complete, even with inifinite retries.
-        *
-        * @return <code>true</code> if the request failed fatally,
-        *         <code>false</code> otherwise
-        */
-       public boolean isFatal() {
-               return Boolean.valueOf(getField("Fatal"));
-       }
-
-       /**
-        * Returns a list of complex error codes with the message. Use
-        * {@link #getComplexErrorDescription(int)} and
-        * {@link #getComplexErrorCount(int)} to get details.
-        *
-        * @return A list of complex error codes
-        */
-       public int[] getComplexErrorCodes() {
-               Map<String, String> allFields = getFields();
-               List<Integer> errorCodeList = new ArrayList<Integer>();
-               for (Entry<String, String> field : allFields.entrySet()) {
-                       String fieldKey = field.getKey();
-                       if (fieldKey.startsWith("Errors.")) {
-                               int nextDot = fieldKey.indexOf('.', 7);
-                               if (nextDot > -1) {
-                                       int errorCode = FcpUtils.safeParseInt(fieldKey.substring(7, nextDot));
-                                       if (errorCode != -1) {
-                                               errorCodeList.add(errorCode);
-                                       }
-                               }
-                       }
-               }
-               int[] errorCodes = new int[errorCodeList.size()];
-               int errorIndex = 0;
-               for (int errorCode : errorCodeList) {
-                       errorCodes[errorIndex++] = errorCode;
-               }
-               return errorCodes;
-       }
-
-       /**
-        * Returns the description of the complex error. You should only hand it
-        * error codes you got from {@link #getComplexErrorCodes()}!
-        *
-        * @param errorCode
-        *            The error code
-        * @return The description of the complex error
-        */
-       public String getComplexErrorDescription(int errorCode) {
-               return getField("Errors." + errorCode + ".Description");
-       }
-
-       /**
-        * Returns the count of the complex error. You should only hand it error
-        * codes you got from {@link #getComplexErrorCodes()}!
-        *
-        * @param errorCode
-        *            The error code
-        * @return The count of the complex error, or <code>-1</code> if the count
-        *         could not be parsed
-        */
-       public int getComplexErrorCount(int errorCode) {
-               return FcpUtils.safeParseInt(getField("Errors." + errorCode + ".Count"));
-       }
-
-}
diff --git a/src/net/pterodactylus/fcp/PutFetchable.java b/src/net/pterodactylus/fcp/PutFetchable.java
deleted file mode 100644 (file)
index 0c4e941..0000000
+++ /dev/null
@@ -1,68 +0,0 @@
-/*
- * jFCPlib - PutFetchable.java - Copyright © 2008 David Roden
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- */
-
-package net.pterodactylus.fcp;
-
-/**
- * The “PutFetchable” message informs a client that a {@link ClientPut} request
- * has progressed far enough that the resulting final URI might already be
- * fetchable.
- *
- * @author David ‘Bombe’ Roden &lt;bombe@freenetproject.org&gt;
- */
-public class PutFetchable extends BaseMessage {
-
-       /**
-        * Creates a new “PutFetchable” message that wraps the received message.
-        *
-        * @param receivedMessage
-        *            The received message
-        */
-       PutFetchable(FcpMessage receivedMessage) {
-               super(receivedMessage);
-       }
-
-       /**
-        * Returns the identifier of the request.
-        *
-        * @return The identifier of the request
-        */
-       public String getIdentifier() {
-               return getField("Identifier");
-       }
-
-       /**
-        * Returns whether the request is on the global queue.
-        *
-        * @return <code>true</code> if the request is on the global queue,
-        *         <code>false</code> if it is on the client-local queue
-        */
-       public boolean isGlobal() {
-               return Boolean.valueOf(getField("Global"));
-       }
-
-       /**
-        * Returns the URI of the request.
-        *
-        * @return The URI of the request
-        */
-       public String getURI() {
-               return getField("URI");
-       }
-
-}
diff --git a/src/net/pterodactylus/fcp/PutSuccessful.java b/src/net/pterodactylus/fcp/PutSuccessful.java
deleted file mode 100644 (file)
index cea36ee..0000000
+++ /dev/null
@@ -1,87 +0,0 @@
-/*
- * jFCPlib - PutSuccessful.java - Copyright © 2008 David Roden
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- */
-
-package net.pterodactylus.fcp;
-
-/**
- * The “PutSuccessful” message informs a client about a successfully finished
- * {@link ClientPut} (or similar) request.
- *
- * @author David ‘Bombe’ Roden &lt;bombe@freenetproject.org&gt;
- */
-public class PutSuccessful extends BaseMessage {
-
-       /**
-        * Creates a new “PutSuccessful” message that wraps the received message.
-        *
-        * @param receivedMessage
-        *            The received message
-        */
-       PutSuccessful(FcpMessage receivedMessage) {
-               super(receivedMessage);
-       }
-
-       /**
-        * Returns the identifier of the request.
-        *
-        * @return The identifier of the request
-        */
-       public String getIdentifier() {
-               return getField("Identifier");
-       }
-
-       /**
-        * Returns whether the request is on the global queue.
-        *
-        * @return <code>true</code> if the request is on the global queue,
-        *         <code>false</code> if it is on the client-local queue
-        */
-       public boolean isGlobal() {
-               return Boolean.valueOf(getField("Global"));
-       }
-
-       /**
-        * Returns the final URI of the {@link ClientPut} request.
-        *
-        * @return The final URI of the request
-        */
-       public String getURI() {
-               return getField("URI");
-       }
-
-       /**
-        * Returns the time the insert started.
-        *
-        * @return The time the insert started (in milliseconds since Jan 1, 1970
-        *         UTC), or <code>-1</code> if the time could not be parsed
-        */
-       public long getStartupTime() {
-               return FcpUtils.safeParseLong(getField("StartupTime"));
-       }
-
-       /**
-        * Returns the time the insert completed.
-        *
-        * @return The time the insert completed (in milliseconds since Jan 1, 1970
-        *         UTC), or <code>-1</code> if the time could not be parsed
-        */
-       public long getCompletionTime() {
-               return FcpUtils.safeParseLong(getField("CompletionTime"));
-       }
-
-}
diff --git a/src/net/pterodactylus/fcp/ReceivedBookmarkFeed.java b/src/net/pterodactylus/fcp/ReceivedBookmarkFeed.java
deleted file mode 100644 (file)
index 02369f0..0000000
+++ /dev/null
@@ -1,78 +0,0 @@
-/*
- * jFCPlib - ReceivedBookmarkFeed.java - Copyright © 2009 David Roden
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- */
-
-package net.pterodactylus.fcp;
-
-/**
- * Implementation of the “ReceivedBookmarkFeed” FCP message. This message
- * notifies an FCP client that an update for a bookmark has been found.
- *
- * @author David ‘Bombe’ Roden &lt;bombe@freenetproject.org&gt;
- */
-public class ReceivedBookmarkFeed extends BaseMessage {
-
-       /**
-        * Creates a new “ReceivedBookmarkFeed” message.
-        *
-        * @param fcpMessage
-        *            The FCP message to get the fields from
-        */
-       public ReceivedBookmarkFeed(FcpMessage fcpMessage) {
-               super(fcpMessage);
-       }
-
-       /**
-        * Returns the name of the bookmark.
-        *
-        * @return The bookmark’s name
-        */
-       public String getBookmarkName() {
-               return getField("Name");
-       }
-
-       /**
-        * Returns the URI of the updated bookmark.
-        *
-        * @return The bookmark’s URI
-        */
-       public String getURI() {
-               return getField("URI");
-       }
-
-       /**
-        * Returns whether the bookmark has an active link image.
-        *
-        * @return {@code true} if the bookmark has an active link image, {@code
-        *         false} otherwise
-        */
-       public boolean hasActiveLink() {
-               return Boolean.parseBoolean(getField("HasAnActiveLink"));
-       }
-
-       /**
-        * Returns the description of the bookmark. Note that the description may be
-        * {@code null} and if it is not, it is base64-encoded!
-        *
-        * @return The bookmark’s description, or {@code null} if the bookmark has
-        *         no description
-        */
-       public String getDescription() {
-               return getField("Description");
-       }
-
-}
diff --git a/src/net/pterodactylus/fcp/RemovePeer.java b/src/net/pterodactylus/fcp/RemovePeer.java
deleted file mode 100644 (file)
index 5eae728..0000000
+++ /dev/null
@@ -1,40 +0,0 @@
-/*
- * jFCPlib - RemovePeer.java - Copyright © 2008 David Roden
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- */
-
-package net.pterodactylus.fcp;
-
-/**
- * The “RemovePeer” command removes a peer.
- *
- * @author David ‘Bombe’ Roden &lt;bombe@freenetproject.org&gt;
- */
-public class RemovePeer extends FcpMessage {
-
-       /**
-        * Creates a new “RemovePeer” command that removes the given peer.
-        *
-        * @param nodeIdentifier
-        *            The identifier of the node, i.e. its name, identity, or IP
-        *            address and port pair
-        */
-       public RemovePeer(String nodeIdentifier) {
-               super("RemovePeer");
-               setField("NodeIdentifier", nodeIdentifier);
-       }
-
-}
diff --git a/src/net/pterodactylus/fcp/RemovePersistentRequest.java b/src/net/pterodactylus/fcp/RemovePersistentRequest.java
deleted file mode 100644 (file)
index e5686b9..0000000
+++ /dev/null
@@ -1,52 +0,0 @@
-/*
- * jFCPlib - RemovePersistentRequest.java - Copyright © 2008 David Roden
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- */
-
-package net.pterodactylus.fcp;
-
-/**
- * The “RemovePersistentRequest” message tells the node to remove a persistent
- * request, cancelling it first (resulting in a {@link GetFailed} or
- * {@link PutFailed} message), if necessary.
- *
- * @author David ‘Bombe’ Roden &lt;bombe@freenetproject.org&gt;
- */
-public class RemovePersistentRequest extends FcpMessage {
-
-       /**
-        * Creates a new “RemovePersistentRequest” message.
-        *
-        * @param identifier
-        *            The identifier of the request
-        */
-       public RemovePersistentRequest(String identifier) {
-               super("RemovePersistentRequest");
-               setField("Identifier", identifier);
-       }
-
-       /**
-        * Sets whether the request is on the global queue.
-        *
-        * @param global
-        *            <code>true</code> if the request is on the global queue,
-        *            <code>false</code> if it is on the client-local queue
-        */
-       public void setGlobal(boolean global) {
-               setField("Global", String.valueOf(global));
-       }
-
-}
diff --git a/src/net/pterodactylus/fcp/ReturnType.java b/src/net/pterodactylus/fcp/ReturnType.java
deleted file mode 100644 (file)
index a3ffbcd..0000000
+++ /dev/null
@@ -1,40 +0,0 @@
-/*
- * jFCPlib - ReturnType.java - Copyright © 2008 David Roden
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- */
-
-package net.pterodactylus.fcp;
-
-/**
- * The different return types for {@link ClientGet} requests.
- *
- * @author David ‘Bombe’ Roden &lt;bombe@freenetproject.org&gt;
- */
-public enum ReturnType {
-
-       /** Don't transfer the data at all. */
-       none,
-
-       /** Transfer the data directly after the message. */
-       direct,
-
-       /** Copy the data to disk. */
-       disk,
-
-       /** Unknown return type. */
-       unknown;
-
-}
diff --git a/src/net/pterodactylus/fcp/SSKKeypair.java b/src/net/pterodactylus/fcp/SSKKeypair.java
deleted file mode 100644 (file)
index fd0b40a..0000000
+++ /dev/null
@@ -1,66 +0,0 @@
-/*
- * jFCPlib - SSKKeypair.java - Copyright © 2008 David Roden
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- */
-
-package net.pterodactylus.fcp;
-
-/**
- * An “SSKKeypair” message that is sent as a response to a {@link GenerateSSK}
- * message.
- *
- * @author David ‘Bombe’ Roden &lt;bombe@freenetproject.org&gt;
- */
-public class SSKKeypair extends BaseMessage {
-
-       /**
-        * Creates a new “SSKKeypair” message that wraps the received message.
-        *
-        * @param receivedMessage
-        *            The received message
-        */
-       SSKKeypair(FcpMessage receivedMessage) {
-               super(receivedMessage);
-       }
-
-       /**
-        * Returns the identifier of the request.
-        *
-        * @return The identifier of the request
-        */
-       public String getIdentifier() {
-               return getField("Identifier");
-       }
-
-       /**
-        * Returns the URI that must be used to insert data.
-        *
-        * @return The insert URI
-        */
-       public String getInsertURI() {
-               return getField("InsertURI");
-       }
-
-       /**
-        * Returns the URI that must be used to request data.
-        *
-        * @return The request URI
-        */
-       public String getRequestURI() {
-               return getField("RequestURI");
-       }
-
-}
diff --git a/src/net/pterodactylus/fcp/SendBookmarkFeed.java b/src/net/pterodactylus/fcp/SendBookmarkFeed.java
deleted file mode 100644 (file)
index 522e830..0000000
+++ /dev/null
@@ -1,53 +0,0 @@
-/*
- * jFCPlib - SendBookmarkFeed.java - Copyright © 2009 David Roden
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- */
-
-package net.pterodactylus.fcp;
-
-/**
- * The “SendBookmarkFeed” command sends a bookmark to a peer.
- *
- * @author David ‘Bombe’ Roden &lt;bombe@freenetproject.org&gt;
- */
-public class SendBookmarkFeed extends AbstractSendFeedMessage {
-
-       /**
-        * Creates a new “SendBookmarkFeed” command.
-        *
-        * @param identifier
-        *            The identifier of the request
-        * @param nodeIdentifier
-        *            The identifier of the peer node
-        * @param name
-        *            The name of the bookmark
-        * @param uri
-        *            The URI of the bookmark
-        * @param description
-        *            The description of the bookmark (may be {@code null})
-        * @param hasActiveLink
-        *            {@code true} if the bookmark has an activelink image, {@code
-        *            false} otherwise
-        */
-       public SendBookmarkFeed(String identifier, String nodeIdentifier, String name, String uri, String description, boolean hasActiveLink) {
-               super("SendBookmarkFeed", identifier, nodeIdentifier);
-               setField("Name", name);
-               setField("URI", uri);
-               setField("Description", description);
-               setField("HasActiveLink", String.valueOf(hasActiveLink));
-       }
-
-}
diff --git a/src/net/pterodactylus/fcp/SendDownloadFeed.java b/src/net/pterodactylus/fcp/SendDownloadFeed.java
deleted file mode 100644 (file)
index ccaa000..0000000
+++ /dev/null
@@ -1,47 +0,0 @@
-/*
- * jFCPlib - SendDownloadFeed.java - Copyright © 2009 David Roden
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- */
-
-package net.pterodactylus.fcp;
-
-/**
- * The “SendDownloadFeed” command sends information about a download to a peer
- * node.
- *
- * @author David ‘Bombe’ Roden &lt;bombe@freenetproject.org&gt;
- */
-public class SendDownloadFeed extends AbstractSendFeedMessage {
-
-       /**
-        * Creates a new “SendDownloadFeed” to a peer node.
-        *
-        * @param identifier
-        *            The identifier of the request
-        * @param nodeIdentifier
-        *            The identifier of the peer node
-        * @param uri
-        *            The URI of the download to send
-        * @param description
-        *            The description of the download (may be {@code null})
-        */
-       public SendDownloadFeed(String identifier, String nodeIdentifier, String uri, String description) {
-               super("SendDownloadFeed", identifier, nodeIdentifier);
-               setField("URI", uri);
-               setField("Description", description);
-       }
-
-}
diff --git a/src/net/pterodactylus/fcp/SendTextFeed.java b/src/net/pterodactylus/fcp/SendTextFeed.java
deleted file mode 100644 (file)
index 339324d..0000000
+++ /dev/null
@@ -1,43 +0,0 @@
-/*
- * jFCPlib - SendTextFeed.java - Copyright © 2009 David Roden
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- */
-
-package net.pterodactylus.fcp;
-
-/**
- * The “SendTextFeed” command sends an arbitrary text to a peer node.
- *
- * @author David ‘Bombe’ Roden &lt;bombe@freenetproject.org&gt;
- */
-public class SendTextFeed extends AbstractSendFeedMessage {
-
-       /**
-        * Creates a new “SendTextFeed” command.
-        *
-        * @param identifier
-        *            The identifier of the request
-        * @param nodeIdentifier
-        *            The identifier of the peer node
-        * @param text
-        *            The text to send
-        */
-       public SendTextFeed(String identifier, String nodeIdentifier, String text) {
-               super("SendTextFeed", identifier, nodeIdentifier);
-               setField("Text", text);
-       }
-
-}
diff --git a/src/net/pterodactylus/fcp/SentFeed.java b/src/net/pterodactylus/fcp/SentFeed.java
deleted file mode 100644 (file)
index eb7ca0a..0000000
+++ /dev/null
@@ -1,76 +0,0 @@
-/*
- * jFCPlib - SentFeed.java - Copyright © 2009 David Roden
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- */
-
-package net.pterodactylus.fcp;
-
-/**
- * The “SentFeed” message signals that a feed was successfully sent to a peer.
- *
- * @author David ‘Bombe’ Roden &lt;bombe@freenetproject.org&gt;
- */
-public class SentFeed extends BaseMessage {
-
-       /**
-        * Creates a new “SentFeed” message from the given FCP message.
-        *
-        * @param fcpMessage
-        *            The FCP message containing the “SentFeed” message
-        */
-       public SentFeed(FcpMessage fcpMessage) {
-               super(fcpMessage);
-       }
-
-       /**
-        * Returns the identifier of the sent feed. The identifier of this message
-        * matches the identifier that was given when a {@link SendBookmarkFeed},
-        * {@link SendDownloadFeed}, or {@link SendTextFeed} command was created.
-        *
-        * @return The send feed’s identifier
-        */
-       public String getIdentifier() {
-               return getField("Identifier");
-       }
-
-       /**
-        * Returns the node status of the peer. The node status is definied in
-        * {@code freenet.node.PeerManager}.
-        * <p>
-        * <ol start="1">
-        * <li>Connected</li>
-        * <li>Backed off</li>
-        * <li>Version too new</li>
-        * <li>Version too old</li>
-        * <li>Disconnected</li>
-        * <li>Never connected</li>
-        * <li>Disabled</li>
-        * <li>Bursting</li>
-        * <li>Listening</li>
-        * <li>Listening only</li>
-        * <li>Clock problem</li>
-        * <li>Connection error</li>
-        * <li>Disconnecting</li>
-        * <li>Routing disabled</li>
-        * </ol>
-        *
-        * @return The node’s status
-        */
-       public int getNodeStatus() {
-               return FcpUtils.safeParseInt(getField("NodeStatus"));
-       }
-
-}
diff --git a/src/net/pterodactylus/fcp/Shutdown.java b/src/net/pterodactylus/fcp/Shutdown.java
deleted file mode 100644 (file)
index 3841c4d..0000000
+++ /dev/null
@@ -1,35 +0,0 @@
-/*
- * jFCPlib - Shutdown.java - Copyright © 2008 David Roden
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- */
-
-package net.pterodactylus.fcp;
-
-/**
- * Command that shuts down the node.
- *
- * @author David ‘Bombe’ Roden &lt;bombe@freenetproject.org&gt;
- */
-public class Shutdown extends FcpMessage {
-
-       /**
-        * Creates a new “Shutdown” message.
-        */
-       public Shutdown() {
-               super("Shutdown");
-       }
-
-}
diff --git a/src/net/pterodactylus/fcp/SimpleProgress.java b/src/net/pterodactylus/fcp/SimpleProgress.java
deleted file mode 100644 (file)
index 4d93512..0000000
+++ /dev/null
@@ -1,111 +0,0 @@
-/*
- * jFCPlib - SimpleProgress.java - Copyright © 2008 David Roden
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- */
-
-package net.pterodactylus.fcp;
-
-/**
- * A “SimpleProgress” message tells the client about the progress of a
- * {@link ClientGet} or {@link ClientPut} operation.
- *
- * @author David ‘Bombe’ Roden &lt;bombe@freenetproject.org&gt;
- */
-public class SimpleProgress extends BaseMessage {
-
-       /**
-        * Creates a new “SimpleProgress” message that wraps the received message.
-        *
-        * @param receivedMessage
-        *            The received message
-        */
-       SimpleProgress(FcpMessage receivedMessage) {
-               super(receivedMessage);
-       }
-
-       /**
-        * Returns the total number of blocks. This number may increase as long as
-        * {@link #isFinalizedTotal()} returns <code>false</code>.
-        *
-        * @return The total number of blocks
-        */
-       public int getTotal() {
-               return FcpUtils.safeParseInt(getField("Total"));
-       }
-
-       /**
-        * Returns the number of blocks that are required to completet the request.
-        * This number might actually be lower than {@link #getTotal} because of
-        * redundancy information. This number may also increase as long as
-        * {@link #isFinalizedTotal()} returns <code>false</code>.
-        *
-        * @return The number of required blocks
-        */
-       public int getRequired() {
-               return FcpUtils.safeParseInt(getField("Required"));
-       }
-
-       /**
-        * Returns the number of blocks that have failed and run out of retries.
-        *
-        * @return The number of failed blocks
-        */
-       public int getFailed() {
-               return FcpUtils.safeParseInt(getField("Failed"));
-       }
-
-       /**
-        * Returns the number of fatally failed blocks. A block that failed fatally
-        * can never be completed, even with infinite retries.
-        *
-        * @return The number of fatally failed blocks
-        */
-       public int getFatallyFailed() {
-               return FcpUtils.safeParseInt(getField("FatallyFailed"));
-       }
-
-       /**
-        * Returns the number of blocks that have been successfully processed.
-        *
-        * @return The number of succeeded blocks
-        */
-       public int getSucceeded() {
-               return FcpUtils.safeParseInt(getField("Succeeded"));
-       }
-
-       /**
-        * Returns whether the total number of blocks (see {@link #getTotal()} has
-        * been finalized. Once the total number of blocks has been finalized for a
-        * request it will not change any more, and this method of every further
-        * SimpleProgress message will always return <code>true</code>.
-        *
-        * @return <code>true</code> if the number of total blocks has been
-        *         finalized, <code>false</code> otherwise
-        */
-       public boolean isFinalizedTotal() {
-               return Boolean.valueOf(getField("FinalizedTotal"));
-       }
-
-       /**
-        * Returns the identifier of the request.
-        *
-        * @return The identifier of the request
-        */
-       public String getIdentifier() {
-               return getField("Identifier");
-       }
-
-}
diff --git a/src/net/pterodactylus/fcp/StartedCompression.java b/src/net/pterodactylus/fcp/StartedCompression.java
deleted file mode 100644 (file)
index a7c4fa2..0000000
+++ /dev/null
@@ -1,59 +0,0 @@
-/*
- * jFCPlib - StartedCompression.java - Copyright © 2008 David Roden
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- */
-
-package net.pterodactylus.fcp;
-
-/**
- * The “StartedCompression” message signals the client the compressing for a
- * request has started.
- *
- * @author David ‘Bombe’ Roden &lt;bombe@freenetproject.org&gt;
- */
-public class StartedCompression extends BaseMessage {
-
-       /**
-        * Creates a new “StartedCompression” message that wraps the received
-        * message.
-        *
-        * @param receivedMessage
-        *            The received message
-        */
-       StartedCompression(FcpMessage receivedMessage) {
-               super(receivedMessage);
-       }
-
-       /**
-        * Returns the identifier of the request.
-        *
-        * @return The identifier of the request
-        */
-       public String getIdentifier() {
-               return getField("Identifier");
-       }
-
-       /**
-        * Returns the number of the codec that is used for compression.
-        *
-        * @return The codec used for the compression, or <code>-1</code> if the
-        *         codec could not be parsed
-        */
-       public int getCodec() {
-               return FcpUtils.safeParseInt(getField("Codec"));
-       }
-
-}
diff --git a/src/net/pterodactylus/fcp/SubscribeFeeds.java b/src/net/pterodactylus/fcp/SubscribeFeeds.java
deleted file mode 100644 (file)
index 1f18620..0000000
+++ /dev/null
@@ -1,40 +0,0 @@
-/*
- * jFCPlib - SubscribeFeeds.java - Copyright © 2009 David Roden
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- */
-
-package net.pterodactylus.fcp;
-
-/**
- * The “SubscribeFeeds” command tells the node that the client is interested in
- * receiving the feeds sent by peer nodes.
- *
- * @author David ‘Bombe’ Roden &lt;bombe@freenetproject.org&gt;
- */
-public class SubscribeFeeds extends FcpMessage {
-
-       /**
-        * Creates a new “SubscribeFeeds” command.
-        *
-        * @param identifier
-        *            The identifier of the request
-        */
-       public SubscribeFeeds(String identifier) {
-               super("SubscribeFeeds");
-               setField("Identifier", identifier);
-       }
-
-}
diff --git a/src/net/pterodactylus/fcp/SubscribeUSK.java b/src/net/pterodactylus/fcp/SubscribeUSK.java
deleted file mode 100644 (file)
index 6a18333..0000000
+++ /dev/null
@@ -1,55 +0,0 @@
-/*
- * jFCPlib - SubscribeUSK.java - Copyright © 2008 David Roden
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- */
-
-package net.pterodactylus.fcp;
-
-/**
- * With a “SubscribeUSK” a client requests to be notified if the edition number
- * of a USK changes.
- *
- * @author David ‘Bombe’ Roden &lt;bombe@freenetproject.org&gt;
- */
-public class SubscribeUSK extends FcpMessage {
-
-       /**
-        * Creates a new “SubscribeUSK” message.
-        *
-        * @param uri
-        *            The URI to watch for changes
-        * @param identifier
-        *            The identifier of the request
-        */
-       public SubscribeUSK(String uri, String identifier) {
-               super("SubscribeUSK");
-               setField("URI", uri);
-               setField("Identifier", identifier);
-       }
-
-       /**
-        * Sets whether updates for the USK are actively searched.
-        *
-        * @param active
-        *            <code>true</code> to actively search for newer editions,
-        *            <code>false</code> to only watch for newer editions that are
-        *            found from other requests
-        */
-       public void setActive(boolean active) {
-               setField("DontPoll", String.valueOf(!active));
-       }
-
-}
diff --git a/src/net/pterodactylus/fcp/SubscribedUSKUpdate.java b/src/net/pterodactylus/fcp/SubscribedUSKUpdate.java
deleted file mode 100644 (file)
index e616b5d..0000000
+++ /dev/null
@@ -1,70 +0,0 @@
-/*
- * jFCPlib - SubscribedUSKUpdate.java - Copyright © 2008 David Roden
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- */
-
-package net.pterodactylus.fcp;
-
-/**
- * A “SubscribedUSKUpdate” message is sent each time a new edition of a USK that
- * was previously subscribed to with {@link SubscribeUSK} was found. Note that
- * if the new edition that was found is several editions ahead of the currently
- * last known edition, you will received a SubscribedUSKUpdate for each edition
- * inbetween as welL!
- *
- * @author David ‘Bombe’ Roden &lt;bombe@freenetproject.org&gt;
- */
-public class SubscribedUSKUpdate extends BaseMessage {
-
-       /**
-        * Creates a new “SubscribedUSKUpdate” message that wraps the received
-        * message.
-        *
-        * @param receivedMessage
-        *            The received message
-        */
-       SubscribedUSKUpdate(FcpMessage receivedMessage) {
-               super(receivedMessage);
-       }
-
-       /**
-        * Returns the identifier of the subscription.
-        *
-        * @return The identifier of the subscription
-        */
-       public String getIdentifier() {
-               return getField("Identifier");
-       }
-
-       /**
-        * Returns the new edition that was found.
-        *
-        * @return The new edition
-        */
-       public int getEdition() {
-               return FcpUtils.safeParseInt(getField("Edition"));
-       }
-
-       /**
-        * Returns the complete URI, including the new edition.
-        *
-        * @return The complete URI
-        */
-       public String getURI() {
-               return getField("URI");
-       }
-
-}
diff --git a/src/net/pterodactylus/fcp/TestDDAComplete.java b/src/net/pterodactylus/fcp/TestDDAComplete.java
deleted file mode 100644 (file)
index bea91d9..0000000
+++ /dev/null
@@ -1,68 +0,0 @@
-/*
- * jFCPlib - TestDDAComplete.java - Copyright © 2008 David Roden
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- */
-
-package net.pterodactylus.fcp;
-
-/**
- * The “TestDDAComplete” message signals that the node has finished checking
- * your read and write access to a certain directory.
- *
- * @author David ‘Bombe’ Roden &lt;bombe@freenetproject.org&gt;
- */
-public class TestDDAComplete extends BaseMessage {
-
-       /**
-        * Creates a new “TestDDAComplete” message that wraps the received message.
-        *
-        * @param receivedMessage
-        *            The received message
-        */
-       TestDDAComplete(FcpMessage receivedMessage) {
-               super(receivedMessage);
-       }
-
-       /**
-        * Returns the directory the authorization is given for.
-        *
-        * @return The directory that was tested for read and/or write access
-        */
-       public String getDirectory() {
-               return getField("Directory");
-       }
-
-       /**
-        * Returns whether read access to the directory is allowed.
-        *
-        * @return <code>true</code> if the client is allowed to read from that
-        *         directory, <code>false</code> otherwise
-        */
-       public boolean isReadDirectoryAllowed() {
-               return Boolean.valueOf(getField("ReadDirectoryAllowed"));
-       }
-
-       /**
-        * Returns whether write access to the directory is allowed.
-        *
-        * @return <code>true</code> if the client is allowed to write into that
-        *         directory, <code>false</code> otherwise
-        */
-       public boolean isWriteDirectoryAllowed() {
-               return Boolean.valueOf(getField("WriteDirectoryAllowed"));
-       }
-
-}
diff --git a/src/net/pterodactylus/fcp/TestDDAReply.java b/src/net/pterodactylus/fcp/TestDDAReply.java
deleted file mode 100644 (file)
index bf102d6..0000000
+++ /dev/null
@@ -1,82 +0,0 @@
-/*
- * jFCPlib - TestDDAReply.java - Copyright © 2008 David Roden
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- */
-
-package net.pterodactylus.fcp;
-
-/**
- * The “TestDDAReply” is sent as a response to {@link TestDDARequest}. If you
- * specified that you wanted to read files from that directory
- * {@link #getReadFilename()} will give you a filename. Similarly, if you
- * specified that you want to write in the directory {@link #getWriteFilename()}
- * will give you a filename to write {@link #getContentToWrite()} to.
- *
- * @author David ‘Bombe’ Roden &lt;bombe@freenetproject.org&gt;
- */
-public class TestDDAReply extends BaseMessage {
-
-       /**
-        * Creates a “TestDDAReply” message that wraps the received message.
-        *
-        * @param receivedMessage
-        *            The received message
-        */
-       TestDDAReply(FcpMessage receivedMessage) {
-               super(receivedMessage);
-       }
-
-       /**
-        * Returns the directory the TestDDRequest was made for.
-        *
-        * @return The directory to test
-        */
-       public String getDirectory() {
-               return getField("Directory");
-       }
-
-       /**
-        * Returns the filename you have to read to proof your ability to read that
-        * specific directory.
-        *
-        * @return The name of the file to read
-        */
-       public String getReadFilename() {
-               return getField("ReadFilename");
-       }
-
-       /**
-        * Returns the filename you have to write to to proof your ability to write
-        * to that specific directory.
-        *
-        * @return The name of the file write to
-        */
-       public String getWriteFilename() {
-               return getField("WriteFilename");
-       }
-
-       /**
-        * If you requested a test for writing permissions you have to write the
-        * return value of this method to the file given by
-        * {@link #getWriteFilename()}.
-        *
-        * @return The content to write to the file
-        */
-       public String getContentToWrite() {
-               return getField("ContentToWrite");
-       }
-
-}
diff --git a/src/net/pterodactylus/fcp/TestDDARequest.java b/src/net/pterodactylus/fcp/TestDDARequest.java
deleted file mode 100644 (file)
index 89a0202..0000000
+++ /dev/null
@@ -1,45 +0,0 @@
-/*
- * jFCPlib - TestDDARequest.java - Copyright © 2008 David Roden
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- */
-
-package net.pterodactylus.fcp;
-
-/**
- * The “TestDDARequest” initiates a DDA test sequence.
- *
- * @author David ‘Bombe’ Roden &lt;bombe@freenetproject.org&gt;
- */
-public class TestDDARequest extends FcpMessage {
-
-       /**
-        * Creates a new “TestDDARequest” command that initiates a DDA test.
-        *
-        * @param directory
-        *            The directory you want to access files in
-        * @param wantReadDirectory
-        *            <code>true</code> if you want to read files from the directory
-        * @param wantWriteDirectory
-        *            <code>true</code> if you want to write files to the directory
-        */
-       public TestDDARequest(String directory, boolean wantReadDirectory, boolean wantWriteDirectory) {
-               super("TestDDARequest");
-               setField("Directory", directory);
-               setField("WantReadDirectory", String.valueOf(wantReadDirectory));
-               setField("WantWriteDirectory", String.valueOf(wantWriteDirectory));
-       }
-
-}
diff --git a/src/net/pterodactylus/fcp/TestDDAResponse.java b/src/net/pterodactylus/fcp/TestDDAResponse.java
deleted file mode 100644 (file)
index 76660c5..0000000
+++ /dev/null
@@ -1,63 +0,0 @@
-/*
- * jFCPlib - TestDDAResponse.java - Copyright © 2008 David Roden
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- */
-
-package net.pterodactylus.fcp;
-
-/**
- * A “TestDDAResponse” is sent to let the node know that either created a file
- * with the content from {@link TestDDAReply#getContentToWrite()} or that you
- * read the content of the file given by {@link TestDDAReply#getReadFilename()}.
- *
- * @author David ‘Bombe’ Roden &lt;bombe@freenetproject.org&gt;
- */
-public class TestDDAResponse extends FcpMessage {
-
-       /**
-        * Creates a new “TestDDAResponse” message that signals that you created the
-        * file given by {@link TestDDAReply#getWriteFilename()} and wrote the
-        * contents given by {@link TestDDAReply#getContentToWrite()} to it.
-        *
-        * @param directory
-        *            The directory from the {@link TestDDARequest} command
-        */
-       public TestDDAResponse(String directory) {
-               this(directory, null);
-       }
-
-       /**
-        * Creates a new “TestDDAResponse” message that signals that you created the
-        * file given by {@link TestDDAReply#getWriteFilename()} with the contents
-        * given by {@link TestDDAReply#getContentToWrite()} to it (when you
-        * specified that you want to write to the directory) and/or that you read
-        * the file given by {@link TestDDAReply#getReadFilename()} (when you
-        * specified you wanted to read the directory).
-        *
-        * @param directory
-        *            The directory from the {@link TestDDARequest} command
-        * @param readContent
-        *            The read content, or <code>null</code> if you did not request
-        *            read access
-        */
-       public TestDDAResponse(String directory, String readContent) {
-               super("TestDDAResponse");
-               if (readContent != null) {
-                       setField("ReadContent", readContent);
-               }
-       }
-
-}
diff --git a/src/net/pterodactylus/fcp/URIGenerated.java b/src/net/pterodactylus/fcp/URIGenerated.java
deleted file mode 100644 (file)
index 06d3888..0000000
+++ /dev/null
@@ -1,69 +0,0 @@
-/*
- * jFCPlib - URIGenerated.java - Copyright © 2008 David Roden
- *
- * This program is free software; you can redistribute it and/or modify it under
- * the terms of the GNU General Public License as published by the Free Software
- * Foundation; either version 2 of the License, or (at your option) any later
- * version.
- *
- * This program is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
- * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
- * details.
- *
- * You should have received a copy of the GNU General Public License along with
- * this program; if not, write to the Free Software Foundation, Inc., 59 Temple
- * Place - Suite 330, Boston, MA 02111-1307, USA.
- */
-
-package net.pterodactylus.fcp;
-
-/**
- * The “URIGenerated” message signals the client that an URI was generated for a
- * {@link ClientPut} (or {@link ClientPutDiskDir} or {@link ClientPutComplexDir}
- * ) request.
- *
- * @author David ‘Bombe’ Roden &lt;bombe@freenetproject.org&gt;
- */
-public class URIGenerated extends BaseMessage {
-
-       /**
-        * Creates a new “URIGenerated” message that wraps the received message.
-        *
-        * @param receivedMessage
-        *            The received message
-        */
-       URIGenerated(FcpMessage receivedMessage) {
-               super(receivedMessage);
-       }
-
-       /**
-        * Returns the identifier of the request that generated an URI.
-        *
-        * @return The identifier of the request
-        */
-       public String getIdentifier() {
-               return getField("Identifier");
-       }
-
-       /**
-        * Returns the URI that was generated by the request.
-        *
-        * @return The URI that was generated by the request
-        */
-       public String getURI() {
-               return getField("URI");
-       }
-
-       /**
-        * Returns whether the request that generated the URI is on the global queue
-        * or on the client-local queue.
-        *
-        * @return <code>true</code> if the request is on the global queue,
-        *         <code>false</code> if it is on the client-local queue
-        */
-       public boolean isGlobal() {
-               return Boolean.parseBoolean(getField("Global"));
-       }
-
-}
diff --git a/src/net/pterodactylus/fcp/UnknownNodeIdentifier.java b/src/net/pterodactylus/fcp/UnknownNodeIdentifier.java
deleted file mode 100644 (file)
index af7b2f5..0000000
+++ /dev/null
@@ -1,49 +0,0 @@
-/*
- * jFCPlib - UnknownNodeIdentifier.java - Copyright © 2008 David Roden
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- */
-
-package net.pterodactylus.fcp;
-
-/**
- * The “UnknownNodeIdentifier” message signals the client that the node
- * identifier given in a command like {@link ListPeer} is unknown.
- *
- * @author David ‘Bombe’ Roden &lt;bombe@freenetproject.org&gt;
- */
-public class UnknownNodeIdentifier extends BaseMessage {
-
-       /**
-        * Creates a new “UnknownNodeIdentifier” message that wraps the received
-        * message.
-        *
-        * @param receivedMessage
-        *            The received message
-        */
-       UnknownNodeIdentifier(FcpMessage receivedMessage) {
-               super(receivedMessage);
-       }
-
-       /**
-        * Returns the unknown node identifier.
-        *
-        * @return The unknown node identifier
-        */
-       public String getNodeIdentifier() {
-               return getField("NodeIdentifier");
-       }
-
-}
diff --git a/src/net/pterodactylus/fcp/UnknownPeerNoteType.java b/src/net/pterodactylus/fcp/UnknownPeerNoteType.java
deleted file mode 100644 (file)
index b36c4ee..0000000
+++ /dev/null
@@ -1,49 +0,0 @@
-/*
- * jFCPlib - UnknownPeerNoteType.java - Copyright © 2008 David Roden
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- */
-
-package net.pterodactylus.fcp;
-
-/**
- * The ”UnknownPeerNoteType” message signals the client that the type of peer
- * note used in a previous {@link ModifyPeerNote} is unknown.
- *
- * @author David ‘Bombe’ Roden &lt;bombe@freenetproject.org&gt;
- */
-public class UnknownPeerNoteType extends BaseMessage {
-
-       /**
-        * Creates a new ”UnknownPeerNoteType” message that wraps the received
-        * message.
-        *
-        * @param receivedMessage
-        *            The received message
-        */
-       public UnknownPeerNoteType(FcpMessage receivedMessage) {
-               super(receivedMessage);
-       }
-
-       /**
-        * Returns the type of peer note that is unkown.
-        *
-        * @return The unknown peer note type
-        */
-       public int getPeerNoteType() {
-               return FcpUtils.safeParseInt(getField("PeerNoteType"));
-       }
-
-}
diff --git a/src/net/pterodactylus/fcp/UploadFrom.java b/src/net/pterodactylus/fcp/UploadFrom.java
deleted file mode 100644 (file)
index fff6d19..0000000
+++ /dev/null
@@ -1,38 +0,0 @@
-/*
- * jFCPlib - UploadFrom.java - Copyright © 2008 David Roden
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- */
-
-package net.pterodactylus.fcp;
-
-/**
- * Enumeration for the different values for the “UploadFrom” field in
- * {@link ClientPut} and {@link ClientGet} requests.
- *
- * @author David ‘Bombe’ Roden &lt;bombe@freenetproject.org&gt;
- */
-public enum UploadFrom {
-
-       /** Request data follows the request. */
-       direct,
-
-       /** Request data is written to or read from disk. */
-       disk,
-
-       /** Request data is just a redirect. */
-       redirect;
-
-}
diff --git a/src/net/pterodactylus/fcp/Verbosity.java b/src/net/pterodactylus/fcp/Verbosity.java
deleted file mode 100644 (file)
index 62a2da8..0000000
+++ /dev/null
@@ -1,105 +0,0 @@
-/*
- * jFCPlib - Verbosity.java - Copyright © 2008 David Roden
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- */
-
-package net.pterodactylus.fcp;
-
-/**
- * Convenicence class for verbosity handling. This might come in handy with the
- * {@link ClientPut} and {@link ClientGet} requests. The verbosity is a bit-mask
- * that can be composed of several bits. {@link #PROGRESS} and
- * {@link #COMPRESSION} are single bits in that mask and can be combined into a
- * new verbosity using {@link #add(Verbosity)}.
- *
- * @author David ‘Bombe’ Roden &lt;bombe@freenetproject.org&gt;
- */
-public class Verbosity {
-
-       /** Constant for no verbosity at all. */
-       public static final Verbosity NONE = new Verbosity(0);
-
-       /** Constant for progress message verbosity. */
-       public static final Verbosity PROGRESS = new Verbosity(1);
-
-       /** Constant for compression message verbosity. */
-       public static final Verbosity COMPRESSION = new Verbosity(512);
-
-       /** Constant for all events. */
-       public static final Verbosity ALL = new Verbosity(-1);
-
-       /** The verbosity level. */
-       private final int level;
-
-       /**
-        * Creates a new verbosity with the given level.
-        *
-        * @param level
-        *            The verbosity level
-        */
-       private Verbosity(int level) {
-               this.level = level;
-       }
-
-       /**
-        * Adds the given verbosity to this verbosity and returns a verbosity with
-        * the new value. The value of this verbosity is not changed.
-        *
-        * @param verbosity
-        *            The verbosity to add to this verbosity
-        * @return The verbosity with the new level.
-        */
-       public Verbosity add(Verbosity verbosity) {
-               return new Verbosity(level | verbosity.level);
-       }
-
-       /**
-        * Checks whether this Verbosity contains all bits of the given Verbosity.
-        *
-        * @param verbosity
-        *            The verbosity to check for in this Verbosity
-        * @return <code>true</code> if and only if all set bits in the given
-        *         Verbosity are also set in this Verbosity
-        */
-       public boolean contains(Verbosity verbosity) {
-               return (level & verbosity.level) == verbosity.level;
-       }
-
-       /**
-        * @see java.lang.Object#toString()
-        */
-       @Override
-       public String toString() {
-               return String.valueOf(level);
-       }
-
-       /**
-        * Parses the given string and creates a Verbosity with the given level.
-        *
-        * @param s
-        *            The string to parse
-        * @return The parsed verbosity, or {@link #NONE} if the string could not be
-        *         parsed
-        */
-       public static Verbosity valueOf(String s) {
-               try {
-                       return new Verbosity(Integer.valueOf(s));
-               } catch (NumberFormatException nfe1) {
-                       return NONE;
-               }
-       }
-
-}
diff --git a/src/net/pterodactylus/fcp/Version.java b/src/net/pterodactylus/fcp/Version.java
deleted file mode 100644 (file)
index 0f1d5cb..0000000
+++ /dev/null
@@ -1,135 +0,0 @@
-/*
- * jFCPlib - Version.java - Copyright © 2008 David Roden
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- */
-
-package net.pterodactylus.fcp;
-
-import java.util.StringTokenizer;
-
-/**
- * Container for the “lastGoodVersion” field.
- *
- * @author David ‘Bombe’ Roden &lt;bombe@freenetproject.org&gt;
- */
-public class Version {
-
-       /** The name of the node implementation. */
-       private final String nodeName;
-
-       /** The tree version of the node. */
-       private final String treeVersion;
-
-       /** The protocol version of the node. */
-       private final String protocolVersion;
-
-       /** The build number of the node. */
-       private final int buildNumber;
-
-       /**
-        * Creates a new Version from the given string. The string consists of the
-        * four required fields node name, tree version, protocol version, and build
-        * number, separated by a comma.
-        *
-        * @param version
-        *            The version string
-        * @throws NullPointerException
-        *             if <code>version</code> is <code>null</code>
-        * @throws IllegalArgumentException
-        *             if <code>version</code> is not in the right format
-        */
-       public Version(String version) {
-               if (version == null) {
-                       throw new NullPointerException("version must not be null");
-               }
-               StringTokenizer versionTokens = new StringTokenizer(version, ",");
-               if (versionTokens.countTokens() != 4) {
-                       throw new IllegalArgumentException("version must consist of four fields");
-               }
-               this.nodeName = versionTokens.nextToken();
-               this.treeVersion = versionTokens.nextToken();
-               this.protocolVersion = versionTokens.nextToken();
-               try {
-                       this.buildNumber = Integer.valueOf(versionTokens.nextToken());
-               } catch (NumberFormatException nfe1) {
-                       throw new IllegalArgumentException("last part of version must be numeric", nfe1);
-               }
-       }
-
-       /**
-        * Creates a new Version from the given parts.
-        *
-        * @param nodeName
-        *            The name of the node implementation
-        * @param treeVersion
-        *            The tree version
-        * @param protocolVersion
-        *            The protocol version
-        * @param buildNumber
-        *            The build number of the node
-        */
-       public Version(String nodeName, String treeVersion, String protocolVersion, int buildNumber) {
-               this.nodeName = nodeName;
-               this.treeVersion = treeVersion;
-               this.protocolVersion = protocolVersion;
-               this.buildNumber = buildNumber;
-       }
-
-       /**
-        * Returns the name of the node implementation.
-        *
-        * @return The node name
-        */
-       public String getNodeName() {
-               return nodeName;
-       }
-
-       /**
-        * The tree version of the node.
-        *
-        * @return The tree version of the node
-        */
-       public String getTreeVersion() {
-               return treeVersion;
-       }
-
-       /**
-        * The protocol version of the node
-        *
-        * @return The protocol version of the node
-        */
-       public String getProtocolVersion() {
-               return protocolVersion;
-       }
-
-       /**
-        * The build number of the node.
-        *
-        * @return The build number of the node
-        */
-       public int getBuildNumber() {
-               return buildNumber;
-       }
-
-       /**
-        * @see java.lang.Object#toString()
-        */
-       @Override
-       public String toString() {
-               return nodeName + "," + treeVersion + "," + protocolVersion + "," + buildNumber;
-       }
-
-}
diff --git a/src/net/pterodactylus/fcp/WatchGlobal.java b/src/net/pterodactylus/fcp/WatchGlobal.java
deleted file mode 100644 (file)
index b973679..0000000
+++ /dev/null
@@ -1,58 +0,0 @@
-/*
- * jFCPlib - WatchGlobal.java - Copyright © 2008 David Roden
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- */
-
-package net.pterodactylus.fcp;
-
-/**
- * The “WatchGlobal” messages enables clients to watch the global queue in
- * addition to the client-local queue.
- *
- * @author David ‘Bombe’ Roden &lt;bombe@freenetproject.org&gt;
- */
-public class WatchGlobal extends FcpMessage {
-
-       /**
-        * Enables or disables watching the global queue.
-        *
-        * @param enabled
-        *            <code>true</code> to watch the global queue and the
-        *            client-local queue, <code>false</code> to watch only the
-        *            client-local queue
-        */
-       public WatchGlobal(boolean enabled) {
-               this(enabled, Verbosity.ALL);
-       }
-
-       /**
-        * Enables or disables watching the global queue, optionally masking out
-        * certain events.
-        *
-        * @param enabled
-        *            <code>true</code> to watch the global queue and the
-        *            client-local queue, <code>false</code> to watch only the
-        *            client-local queue
-        * @param verbosityMask
-        *            A verbosity mask that determines which events are received
-        */
-       public WatchGlobal(boolean enabled, Verbosity verbosityMask) {
-               super("WatchGlobal");
-               setField("Enabled", String.valueOf(enabled));
-               setField("VerbosityMask", String.valueOf(verbosityMask));
-       }
-
-}
diff --git a/src/net/pterodactylus/fcp/highlevel/FcpClient.java b/src/net/pterodactylus/fcp/highlevel/FcpClient.java
deleted file mode 100644 (file)
index 3012e00..0000000
+++ /dev/null
@@ -1,1120 +0,0 @@
-/*
- * jFCPlib - FcpClient.java - Copyright © 2009 David Roden
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- */
-
-package net.pterodactylus.fcp.highlevel;
-
-import java.io.IOException;
-import java.io.InputStream;
-import java.net.InetAddress;
-import java.net.URL;
-import java.net.UnknownHostException;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.Map;
-import java.util.Set;
-import java.util.Map.Entry;
-import java.util.concurrent.CountDownLatch;
-
-import net.pterodactylus.fcp.AddPeer;
-import net.pterodactylus.fcp.ClientHello;
-import net.pterodactylus.fcp.CloseConnectionDuplicateClientName;
-import net.pterodactylus.fcp.DataFound;
-import net.pterodactylus.fcp.EndListPeerNotes;
-import net.pterodactylus.fcp.EndListPeers;
-import net.pterodactylus.fcp.EndListPersistentRequests;
-import net.pterodactylus.fcp.FCPPluginMessage;
-import net.pterodactylus.fcp.FCPPluginReply;
-import net.pterodactylus.fcp.FcpAdapter;
-import net.pterodactylus.fcp.FcpConnection;
-import net.pterodactylus.fcp.FcpListener;
-import net.pterodactylus.fcp.GenerateSSK;
-import net.pterodactylus.fcp.GetFailed;
-import net.pterodactylus.fcp.GetNode;
-import net.pterodactylus.fcp.ListPeerNotes;
-import net.pterodactylus.fcp.ListPeers;
-import net.pterodactylus.fcp.ListPersistentRequests;
-import net.pterodactylus.fcp.ModifyPeer;
-import net.pterodactylus.fcp.ModifyPeerNote;
-import net.pterodactylus.fcp.NodeData;
-import net.pterodactylus.fcp.NodeHello;
-import net.pterodactylus.fcp.NodeRef;
-import net.pterodactylus.fcp.Peer;
-import net.pterodactylus.fcp.PeerNote;
-import net.pterodactylus.fcp.PeerRemoved;
-import net.pterodactylus.fcp.PersistentGet;
-import net.pterodactylus.fcp.PersistentPut;
-import net.pterodactylus.fcp.ProtocolError;
-import net.pterodactylus.fcp.RemovePeer;
-import net.pterodactylus.fcp.SSKKeypair;
-import net.pterodactylus.fcp.SimpleProgress;
-import net.pterodactylus.fcp.WatchGlobal;
-import net.pterodactylus.util.filter.Filter;
-import net.pterodactylus.util.filter.Filters;
-import net.pterodactylus.util.thread.ObjectWrapper;
-
-/**
- * High-level FCP client that hides the details of the underlying FCP
- * implementation.
- *
- * @author David ‘Bombe’ Roden &lt;bombe@freenetproject.org&gt;
- */
-public class FcpClient {
-
-       /** Object used for synchronization. */
-       private final Object syncObject = new Object();
-
-       /** Listener management. */
-       private final FcpClientListenerManager fcpClientListenerManager = new FcpClientListenerManager(this);
-
-       /** The name of this client. */
-       private final String name;
-
-       /** The underlying FCP connection. */
-       private final FcpConnection fcpConnection;
-
-       /** Whether the client is currently connected. */
-       private volatile boolean connected;
-
-       /**
-        * Creates an FCP client with the given name.
-        *
-        * @param name
-        *            The name of the FCP client
-        * @throws UnknownHostException
-        *             if the hostname “localhost” is unknown
-        */
-       public FcpClient(String name) throws UnknownHostException {
-               this(name, "localhost");
-       }
-
-       /**
-        * Creates an FCP client.
-        *
-        * @param name
-        *            The name of the FCP client
-        * @param hostname
-        *            The hostname of the Freenet node
-        * @throws UnknownHostException
-        *             if the given hostname can not be resolved
-        */
-       public FcpClient(String name, String hostname) throws UnknownHostException {
-               this(name, hostname, FcpConnection.DEFAULT_PORT);
-       }
-
-       /**
-        * Creates an FCP client.
-        *
-        * @param name
-        *            The name of the FCP client
-        * @param hostname
-        *            The hostname of the Freenet node
-        * @param port
-        *            The Freenet node’s FCP port
-        * @throws UnknownHostException
-        *             if the given hostname can not be resolved
-        */
-       public FcpClient(String name, String hostname, int port) throws UnknownHostException {
-               this(name, InetAddress.getByName(hostname), port);
-       }
-
-       /**
-        * Creates an FCP client.
-        *
-        * @param name
-        *            The name of the FCP client
-        * @param host
-        *            The host address of the Freenet node
-        */
-       public FcpClient(String name, InetAddress host) {
-               this(name, host, FcpConnection.DEFAULT_PORT);
-       }
-
-       /**
-        * Creates an FCP client.
-        *
-        * @param name
-        *            The name of the FCP client
-        * @param host
-        *            The host address of the Freenet node
-        * @param port
-        *            The Freenet node’s FCP port
-        */
-       public FcpClient(String name, InetAddress host, int port) {
-               this.name = name;
-               fcpConnection = new FcpConnection(host, port);
-               fcpConnection.addFcpListener(new FcpAdapter() {
-
-                       /**
-                        * {@inheritDoc}
-                        */
-                       @Override
-                       @SuppressWarnings("synthetic-access")
-                       public void connectionClosed(FcpConnection fcpConnection, Throwable throwable) {
-                               connected = false;
-                               fcpClientListenerManager.fireFcpClientDisconnected();
-                       }
-               });
-       }
-
-       //
-       // LISTENER MANAGEMENT
-       //
-
-       /**
-        * Adds an FCP listener to the underlying connection.
-        *
-        * @param fcpListener
-        *            The FCP listener to add
-        */
-       public void addFcpListener(FcpListener fcpListener) {
-               fcpConnection.addFcpListener(fcpListener);
-       }
-
-       /**
-        * Removes an FCP listener from the underlying connection.
-        *
-        * @param fcpListener
-        *            The FCP listener to remove
-        */
-       public void removeFcpListener(FcpListener fcpListener) {
-               fcpConnection.removeFcpListener(fcpListener);
-       }
-
-       /**
-        * Adds an FCP client listener to the list of registered listeners.
-        *
-        * @param fcpClientListener
-        *            The FCP client listener to add
-        */
-       public void addFcpClientListener(FcpClientListener fcpClientListener) {
-               fcpClientListenerManager.addListener(fcpClientListener);
-       }
-
-       /**
-        * Removes an FCP client listener from the list of registered listeners.
-        *
-        * @param fcpClientListener
-        *            The FCP client listener to remove
-        */
-       public void removeFcpClientListener(FcpClientListener fcpClientListener) {
-               fcpClientListenerManager.removeListener(fcpClientListener);
-       }
-
-       //
-       // ACTIONS
-       //
-
-       /**
-        * Connects the FCP client.
-        *
-        * @throws IOException
-        *             if an I/O error occurs
-        * @throws FcpException
-        *             if an FCP error occurs
-        */
-       public void connect() throws IOException, FcpException {
-               checkConnected(false);
-               connected = true;
-               new ExtendedFcpAdapter() {
-
-                       /**
-                        * {@inheritDoc}
-                        */
-                       @Override
-                       @SuppressWarnings("synthetic-access")
-                       public void run() throws IOException {
-                               fcpConnection.connect();
-                               ClientHello clientHello = new ClientHello(name);
-                               fcpConnection.sendMessage(clientHello);
-                               WatchGlobal watchGlobal = new WatchGlobal(true);
-                               fcpConnection.sendMessage(watchGlobal);
-                       }
-
-                       /**
-                        * {@inheritDoc}
-                        */
-                       @Override
-                       public void receivedNodeHello(FcpConnection fcpConnection, NodeHello nodeHello) {
-                               completionLatch.countDown();
-                       }
-               }.execute();
-       }
-
-       /**
-        * Disconnects the FCP client.
-        */
-       public void disconnect() {
-               synchronized (syncObject) {
-                       fcpConnection.close();
-                       syncObject.notifyAll();
-               }
-       }
-
-       /**
-        * Returns whether this client is currently connected.
-        *
-        * @return {@code true} if the client is currently connected, {@code false}
-        *         otherwise
-        */
-       public boolean isConnected() {
-               return connected;
-       }
-
-       //
-       // PEER MANAGEMENT
-       //
-
-       /**
-        * Returns all peers that the node has.
-        *
-        * @param withMetadata
-        *            <code>true</code> to include peer metadata
-        * @param withVolatile
-        *            <code>true</code> to include volatile peer data
-        * @return A set containing the node’s peers
-        * @throws IOException
-        *             if an I/O error occurs
-        * @throws FcpException
-        *             if an FCP error occurs
-        */
-       public Collection<Peer> getPeers(final boolean withMetadata, final boolean withVolatile) throws IOException, FcpException {
-               final Set<Peer> peers = Collections.synchronizedSet(new HashSet<Peer>());
-               new ExtendedFcpAdapter() {
-
-                       /** The ID of the “ListPeers” request. */
-                       @SuppressWarnings("synthetic-access")
-                       private String identifier = createIdentifier("list-peers");
-
-                       /**
-                        * {@inheritDoc}
-                        */
-                       @Override
-                       @SuppressWarnings("synthetic-access")
-                       public void run() throws IOException {
-                               fcpConnection.sendMessage(new ListPeers(identifier, withMetadata, withVolatile));
-                       }
-
-                       /**
-                        * {@inheritDoc}
-                        */
-                       @Override
-                       public void receivedPeer(FcpConnection fcpConnection, Peer peer) {
-                               if (peer.getIdentifier().equals(identifier)) {
-                                       peers.add(peer);
-                               }
-                       }
-
-                       /**
-                        * {@inheritDoc}
-                        */
-                       @Override
-                       public void receivedEndListPeers(FcpConnection fcpConnection, EndListPeers endListPeers) {
-                               if (endListPeers.getIdentifier().equals(identifier)) {
-                                       completionLatch.countDown();
-                               }
-                       }
-               }.execute();
-               return peers;
-       }
-
-       /**
-        * Returns all darknet peers.
-        *
-        * @param withMetadata
-        *            <code>true</code> to include peer metadata
-        * @param withVolatile
-        *            <code>true</code> to include volatile peer data
-        * @return A set containing the node’s darknet peers
-        * @throws IOException
-        *             if an I/O error occurs
-        * @throws FcpException
-        *             if an FCP error occurs
-        */
-       public Collection<Peer> getDarknetPeers(boolean withMetadata, boolean withVolatile) throws IOException, FcpException {
-               Collection<Peer> allPeers = getPeers(withMetadata, withVolatile);
-               Collection<Peer> darknetPeers = new HashSet<Peer>();
-               for (Peer peer : allPeers) {
-                       if (!peer.isOpennet() && !peer.isSeed()) {
-                               darknetPeers.add(peer);
-                       }
-               }
-               return darknetPeers;
-       }
-
-       /**
-        * Returns all opennet peers.
-        *
-        * @param withMetadata
-        *            <code>true</code> to include peer metadata
-        * @param withVolatile
-        *            <code>true</code> to include volatile peer data
-        * @return A set containing the node’s opennet peers
-        * @throws IOException
-        *             if an I/O error occurs
-        * @throws FcpException
-        *             if an FCP error occurs
-        */
-       public Collection<Peer> getOpennetPeers(boolean withMetadata, boolean withVolatile) throws IOException, FcpException {
-               Collection<Peer> allPeers = getPeers(withMetadata, withVolatile);
-               Collection<Peer> opennetPeers = new HashSet<Peer>();
-               for (Peer peer : allPeers) {
-                       if (peer.isOpennet() && !peer.isSeed()) {
-                               opennetPeers.add(peer);
-                       }
-               }
-               return opennetPeers;
-       }
-
-       /**
-        * Returns all seed peers.
-        *
-        * @param withMetadata
-        *            <code>true</code> to include peer metadata
-        * @param withVolatile
-        *            <code>true</code> to include volatile peer data
-        * @return A set containing the node’s seed peers
-        * @throws IOException
-        *             if an I/O error occurs
-        * @throws FcpException
-        *             if an FCP error occurs
-        */
-       public Collection<Peer> getSeedPeers(boolean withMetadata, boolean withVolatile) throws IOException, FcpException {
-               Collection<Peer> allPeers = getPeers(withMetadata, withVolatile);
-               Collection<Peer> seedPeers = new HashSet<Peer>();
-               for (Peer peer : allPeers) {
-                       if (peer.isSeed()) {
-                               seedPeers.add(peer);
-                       }
-               }
-               return seedPeers;
-       }
-
-       /**
-        * Adds the given peer to the node.
-        *
-        * @param peer
-        *            The peer to add
-        * @throws IOException
-        *             if an I/O error occurs
-        * @throws FcpException
-        *             if an FCP error occurs
-        */
-       public void addPeer(Peer peer) throws IOException, FcpException {
-               addPeer(peer.getNodeRef());
-       }
-
-       /**
-        * Adds the peer defined by the noderef to the node.
-        *
-        * @param nodeRef
-        *            The noderef that defines the new peer
-        * @throws IOException
-        *             if an I/O error occurs
-        * @throws FcpException
-        *             if an FCP error occurs
-        */
-       public void addPeer(NodeRef nodeRef) throws IOException, FcpException {
-               addPeer(new AddPeer(nodeRef));
-       }
-
-       /**
-        * Adds a peer, reading the noderef from the given URL.
-        *
-        * @param url
-        *            The URL to read the noderef from
-        * @throws IOException
-        *             if an I/O error occurs
-        * @throws FcpException
-        *             if an FCP error occurs
-        */
-       public void addPeer(URL url) throws IOException, FcpException {
-               addPeer(new AddPeer(url));
-       }
-
-       /**
-        * Adds a peer, reading the noderef of the peer from the given file.
-        * <strong>Note:</strong> the file to read the noderef from has to reside on
-        * the same machine as the node!
-        *
-        * @param file
-        *            The name of the file containing the peer’s noderef
-        * @throws IOException
-        *             if an I/O error occurs
-        * @throws FcpException
-        *             if an FCP error occurs
-        */
-       public void addPeer(String file) throws IOException, FcpException {
-               addPeer(new AddPeer(file));
-       }
-
-       /**
-        * Sends the given {@link AddPeer} message to the node. This method should
-        * not be called directly. Use one of {@link #addPeer(Peer)},
-        * {@link #addPeer(NodeRef)}, {@link #addPeer(URL)}, or
-        * {@link #addPeer(String)} instead.
-        *
-        * @param addPeer
-        *            The “AddPeer” message
-        * @throws IOException
-        *             if an I/O error occurs
-        * @throws FcpException
-        *             if an FCP error occurs
-        */
-       private void addPeer(final AddPeer addPeer) throws IOException, FcpException {
-               new ExtendedFcpAdapter() {
-
-                       /**
-                        * {@inheritDoc}
-                        */
-                       @Override
-                       @SuppressWarnings("synthetic-access")
-                       public void run() throws IOException {
-                               fcpConnection.sendMessage(addPeer);
-                       }
-
-                       /**
-                        * {@inheritDoc}
-                        */
-                       @Override
-                       public void receivedPeer(FcpConnection fcpConnection, Peer peer) {
-                               completionLatch.countDown();
-                       }
-               }.execute();
-       }
-
-       /**
-        * Modifies the given peer.
-        *
-        * @param peer
-        *            The peer to modify
-        * @param allowLocalAddresses
-        *            <code>true</code> to allow local address, <code>false</code>
-        *            to not allow local address, <code>null</code> to not change
-        *            the setting
-        * @param disabled
-        *            <code>true</code> to disable the peer, <code>false</code> to
-        *            enable the peer, <code>null</code> to not change the setting
-        * @param listenOnly
-        *            <code>true</code> to enable “listen only” for the peer,
-        *            <code>false</code> to disable it, <code>null</code> to not
-        *            change it
-        * @throws IOException
-        *             if an I/O error occurs
-        * @throws FcpException
-        *             if an FCP error occurs
-        */
-       public void modifyPeer(final Peer peer, final Boolean allowLocalAddresses, final Boolean disabled, final Boolean listenOnly) throws IOException, FcpException {
-               new ExtendedFcpAdapter() {
-
-                       /**
-                        * {@inheritDoc}
-                        */
-                       @Override
-                       @SuppressWarnings("synthetic-access")
-                       public void run() throws IOException {
-                               fcpConnection.sendMessage(new ModifyPeer(peer.getIdentity(), allowLocalAddresses, disabled, listenOnly));
-                       }
-
-                       /**
-                        * {@inheritDoc}
-                        */
-                       @Override
-                       public void receivedPeer(FcpConnection fcpConnection, Peer peer) {
-                               completionLatch.countDown();
-                       }
-               }.execute();
-       }
-
-       /**
-        * Removes the given peer.
-        *
-        * @param peer
-        *            The peer to remove
-        * @throws IOException
-        *             if an I/O error occurs
-        * @throws FcpException
-        *             if an FCP error occurs
-        */
-       public void removePeer(final Peer peer) throws IOException, FcpException {
-               new ExtendedFcpAdapter() {
-
-                       /**
-                        * {@inheritDoc}
-                        */
-                       @Override
-                       @SuppressWarnings("synthetic-access")
-                       public void run() throws IOException {
-                               fcpConnection.sendMessage(new RemovePeer(peer.getIdentity()));
-                       }
-
-                       /**
-                        * {@inheritDoc}
-                        */
-                       @Override
-                       public void receivedPeerRemoved(FcpConnection fcpConnection, PeerRemoved peerRemoved) {
-                               completionLatch.countDown();
-                       }
-               }.execute();
-       }
-
-       //
-       // PEER NOTES MANAGEMENT
-       //
-
-       /**
-        * Returns the peer note of the given peer.
-        *
-        * @param peer
-        *            The peer to get the note for
-        * @return The peer’s note
-        * @throws IOException
-        *             if an I/O error occurs
-        * @throws FcpException
-        *             if an FCP error occurs
-        */
-       public PeerNote getPeerNote(final Peer peer) throws IOException, FcpException {
-               final ObjectWrapper<PeerNote> objectWrapper = new ObjectWrapper<PeerNote>();
-               new ExtendedFcpAdapter() {
-
-                       /**
-                        * {@inheritDoc}
-                        */
-                       @Override
-                       @SuppressWarnings("synthetic-access")
-                       public void run() throws IOException {
-                               fcpConnection.sendMessage(new ListPeerNotes(peer.getIdentity()));
-                       }
-
-                       /**
-                        * {@inheritDoc}
-                        */
-                       @Override
-                       public void receivedPeerNote(FcpConnection fcpConnection, PeerNote peerNote) {
-                               if (peerNote.getNodeIdentifier().equals(peer.getIdentity())) {
-                                       objectWrapper.set(peerNote);
-                               }
-                       }
-
-                       /**
-                        * {@inheritDoc}
-                        */
-                       @Override
-                       public void receivedEndListPeerNotes(FcpConnection fcpConnection, EndListPeerNotes endListPeerNotes) {
-                               completionLatch.countDown();
-                       }
-               }.execute();
-               return objectWrapper.get();
-       }
-
-       /**
-        * Replaces the peer note for the given peer.
-        *
-        * @param peer
-        *            The peer
-        * @param noteText
-        *            The new base64-encoded note text
-        * @param noteType
-        *            The type of the note (currently only <code>1</code> is
-        *            allowed)
-        * @throws IOException
-        *             if an I/O error occurs
-        * @throws FcpException
-        *             if an FCP error occurs
-        */
-       public void modifyPeerNote(final Peer peer, final String noteText, final int noteType) throws IOException, FcpException {
-               new ExtendedFcpAdapter() {
-
-                       /**
-                        * {@inheritDoc}
-                        */
-                       @Override
-                       @SuppressWarnings("synthetic-access")
-                       public void run() throws IOException {
-                               fcpConnection.sendMessage(new ModifyPeerNote(peer.getIdentity(), noteText, noteType));
-                       }
-
-                       /**
-                        * {@inheritDoc}
-                        */
-                       @Override
-                       public void receivedPeer(FcpConnection fcpConnection, Peer receivedPeer) {
-                               if (receivedPeer.getIdentity().equals(peer.getIdentity())) {
-                                       completionLatch.countDown();
-                               }
-                       }
-               }.execute();
-       }
-
-       //
-       // KEY GENERATION
-       //
-
-       /**
-        * Generates a new SSK key pair.
-        *
-        * @return The generated key pair
-        * @throws IOException
-        *             if an I/O error occurs
-        * @throws FcpException
-        *             if an FCP error occurs
-        */
-       public SSKKeypair generateKeyPair() throws IOException, FcpException {
-               final ObjectWrapper<SSKKeypair> sskKeypairWrapper = new ObjectWrapper<SSKKeypair>();
-               new ExtendedFcpAdapter() {
-
-                       /**
-                        * {@inheritDoc}
-                        */
-                       @Override
-                       @SuppressWarnings("synthetic-access")
-                       public void run() throws IOException {
-                               fcpConnection.sendMessage(new GenerateSSK());
-                       }
-
-                       /**
-                        * {@inheritDoc}
-                        */
-                       @Override
-                       public void receivedSSKKeypair(FcpConnection fcpConnection, SSKKeypair sskKeypair) {
-                               sskKeypairWrapper.set(sskKeypair);
-                               completionLatch.countDown();
-                       }
-               }.execute();
-               return sskKeypairWrapper.get();
-       }
-
-       //
-       // REQUEST MANAGEMENT
-       //
-
-       /**
-        * Returns all currently visible persistent get requests.
-        *
-        * @param global
-        *            <code>true</code> to return get requests from the global
-        *            queue, <code>false</code> to only show requests from the
-        *            client-local queue
-        * @return All get requests
-        * @throws IOException
-        *             if an I/O error occurs
-        * @throws FcpException
-        *             if an FCP error occurs
-        */
-       public Collection<Request> getGetRequests(final boolean global) throws IOException, FcpException {
-               return Filters.filteredCollection(getRequests(global), new Filter<Request>() {
-
-                       /**
-                        * {@inheritDoc}
-                        */
-                       public boolean filterObject(Request request) {
-                               return request instanceof GetRequest;
-                       }
-               });
-       }
-
-       /**
-        * Returns all currently visible persistent put requests.
-        *
-        * @param global
-        *            <code>true</code> to return put requests from the global
-        *            queue, <code>false</code> to only show requests from the
-        *            client-local queue
-        * @return All put requests
-        * @throws IOException
-        *             if an I/O error occurs
-        * @throws FcpException
-        *             if an FCP error occurs
-        */
-       public Collection<Request> getPutRequests(final boolean global) throws IOException, FcpException {
-               return Filters.filteredCollection(getRequests(global), new Filter<Request>() {
-
-                       /**
-                        * {@inheritDoc}
-                        */
-                       public boolean filterObject(Request request) {
-                               return request instanceof PutRequest;
-                       }
-               });
-       }
-
-       /**
-        * Returns all currently visible persistent requests.
-        *
-        * @param global
-        *            <code>true</code> to return requests from the global queue,
-        *            <code>false</code> to only show requests from the client-local
-        *            queue
-        * @return All requests
-        * @throws IOException
-        *             if an I/O error occurs
-        * @throws FcpException
-        *             if an FCP error occurs
-        */
-       public Collection<Request> getRequests(final boolean global) throws IOException, FcpException {
-               final Map<String, Request> requests = Collections.synchronizedMap(new HashMap<String, Request>());
-               new ExtendedFcpAdapter() {
-
-                       /**
-                        * {@inheritDoc}
-                        */
-                       @Override
-                       @SuppressWarnings("synthetic-access")
-                       public void run() throws IOException {
-                               fcpConnection.sendMessage(new ListPersistentRequests());
-                       }
-
-                       /**
-                        * {@inheritDoc}
-                        */
-                       @Override
-                       public void receivedPersistentGet(FcpConnection fcpConnection, PersistentGet persistentGet) {
-                               if (!persistentGet.isGlobal() || global) {
-                                       GetRequest getRequest = new GetRequest(persistentGet);
-                                       requests.put(persistentGet.getIdentifier(), getRequest);
-                               }
-                       }
-
-                       /**
-                        * {@inheritDoc}
-                        *
-                        * @see net.pterodactylus.fcp.FcpAdapter#receivedDataFound(net.pterodactylus.fcp.FcpConnection,
-                        *      net.pterodactylus.fcp.DataFound)
-                        */
-                       @Override
-                       public void receivedDataFound(FcpConnection fcpConnection, DataFound dataFound) {
-                               Request getRequest = requests.get(dataFound.getIdentifier());
-                               if (getRequest == null) {
-                                       return;
-                               }
-                               getRequest.setComplete(true);
-                               getRequest.setLength(dataFound.getDataLength());
-                               getRequest.setContentType(dataFound.getMetadataContentType());
-                       }
-
-                       /**
-                        * {@inheritDoc}
-                        *
-                        * @see net.pterodactylus.fcp.FcpAdapter#receivedGetFailed(net.pterodactylus.fcp.FcpConnection,
-                        *      net.pterodactylus.fcp.GetFailed)
-                        */
-                       @Override
-                       public void receivedGetFailed(FcpConnection fcpConnection, GetFailed getFailed) {
-                               Request getRequest = requests.get(getFailed.getIdentifier());
-                               if (getRequest == null) {
-                                       return;
-                               }
-                               getRequest.setComplete(true);
-                               getRequest.setFailed(true);
-                               getRequest.setFatal(getFailed.isFatal());
-                               getRequest.setErrorCode(getFailed.getCode());
-                       }
-
-                       /**
-                        * {@inheritDoc}
-                        *
-                        * @see net.pterodactylus.fcp.FcpAdapter#receivedPersistentPut(net.pterodactylus.fcp.FcpConnection,
-                        *      net.pterodactylus.fcp.PersistentPut)
-                        */
-                       @Override
-                       public void receivedPersistentPut(FcpConnection fcpConnection, PersistentPut persistentPut) {
-                               if (!persistentPut.isGlobal() || global) {
-                                       PutRequest putRequest = new PutRequest(persistentPut);
-                                       requests.put(persistentPut.getIdentifier(), putRequest);
-                               }
-                       }
-
-                       /**
-                        * {@inheritDoc}
-                        *
-                        * @see net.pterodactylus.fcp.FcpAdapter#receivedSimpleProgress(net.pterodactylus.fcp.FcpConnection,
-                        *      net.pterodactylus.fcp.SimpleProgress)
-                        */
-                       @Override
-                       public void receivedSimpleProgress(FcpConnection fcpConnection, SimpleProgress simpleProgress) {
-                               Request request = requests.get(simpleProgress.getIdentifier());
-                               if (request == null) {
-                                       return;
-                               }
-                               request.setTotalBlocks(simpleProgress.getTotal());
-                               request.setRequiredBlocks(simpleProgress.getRequired());
-                               request.setFailedBlocks(simpleProgress.getFailed());
-                               request.setFatallyFailedBlocks(simpleProgress.getFatallyFailed());
-                               request.setSucceededBlocks(simpleProgress.getSucceeded());
-                               request.setFinalizedTotal(simpleProgress.isFinalizedTotal());
-                       }
-
-                       /**
-                        * {@inheritDoc}
-                        */
-                       @Override
-                       public void receivedEndListPersistentRequests(FcpConnection fcpConnection, EndListPersistentRequests endListPersistentRequests) {
-                               completionLatch.countDown();
-                       }
-               }.execute();
-               return requests.values();
-       }
-
-       /**
-        * Sends a message to a plugin and waits for the response.
-        *
-        * @param pluginClass
-        *            The name of the plugin class
-        * @param parameters
-        *            The parameters for the plugin
-        * @return The responses from the plugin
-        * @throws FcpException
-        *             if an FCP error occurs
-        * @throws IOException
-        *             if an I/O error occurs
-        */
-       public Map<String, String> sendPluginMessage(String pluginClass, Map<String, String> parameters) throws IOException, FcpException {
-               return sendPluginMessage(pluginClass, parameters, 0, null);
-       }
-
-       /**
-        * Sends a message to a plugin and waits for the response.
-        *
-        * @param pluginClass
-        *            The name of the plugin class
-        * @param parameters
-        *            The parameters for the plugin
-        * @param dataLength
-        *            The length of the optional data stream, or {@code 0} if there
-        *            is no optional data stream
-        * @param dataInputStream
-        *            The input stream for the payload, or {@code null} if there is
-        *            no payload
-        * @return The responses from the plugin
-        * @throws FcpException
-        *             if an FCP error occurs
-        * @throws IOException
-        *             if an I/O error occurs
-        */
-       public Map<String, String> sendPluginMessage(final String pluginClass, final Map<String, String> parameters, final long dataLength, final InputStream dataInputStream) throws IOException, FcpException {
-               final Map<String, String> pluginReplies = Collections.synchronizedMap(new HashMap<String, String>());
-               new ExtendedFcpAdapter() {
-
-                       @SuppressWarnings("synthetic-access")
-                       private final String identifier = createIdentifier("FCPPluginMessage");
-
-                       @Override
-                       @SuppressWarnings("synthetic-access")
-                       public void run() throws IOException {
-                               FCPPluginMessage fcpPluginMessage = new FCPPluginMessage(pluginClass);
-                               for (Entry<String, String> parameter : parameters.entrySet()) {
-                                       fcpPluginMessage.setParameter(parameter.getKey(), parameter.getValue());
-                               }
-                               fcpPluginMessage.setIdentifier(identifier);
-                               if ((dataLength > 0) && (dataInputStream != null)) {
-                                       fcpPluginMessage.setDataLength(dataLength);
-                                       fcpPluginMessage.setPayloadInputStream(dataInputStream);
-                               }
-                               fcpConnection.sendMessage(fcpPluginMessage);
-                       }
-
-                       /**
-                        * {@inheritDoc}
-                        */
-                       @Override
-                       public void receivedFCPPluginReply(FcpConnection fcpConnection, FCPPluginReply fcpPluginReply) {
-                               if (!fcpPluginReply.getIdentifier().equals(identifier)) {
-                                       return;
-                               }
-                               pluginReplies.putAll(fcpPluginReply.getReplies());
-                               completionLatch.countDown();
-                       }
-
-               }.execute();
-               return pluginReplies;
-       }
-
-       //
-       // NODE INFORMATION
-       //
-
-       /**
-        * Returns information about the node.
-        *
-        * @param giveOpennetRef
-        *            Whether to return the OpenNet reference
-        * @param withPrivate
-        *            Whether to return private node data
-        * @param withVolatile
-        *            Whether to return volatile node data
-        * @return Node information
-        * @throws FcpException
-        *             if an FCP error occurs
-        * @throws IOException
-        *             if an I/O error occurs
-        */
-       public NodeData getNodeInformation(final Boolean giveOpennetRef, final Boolean withPrivate, final Boolean withVolatile) throws IOException, FcpException {
-               final ObjectWrapper<NodeData> nodeDataWrapper = new ObjectWrapper<NodeData>();
-               new ExtendedFcpAdapter() {
-
-                       @Override
-                       @SuppressWarnings("synthetic-access")
-                       public void run() throws IOException {
-                               GetNode getNodeMessage = new GetNode(giveOpennetRef, withPrivate, withVolatile);
-                               fcpConnection.sendMessage(getNodeMessage);
-                       }
-
-                       /**
-                        * {@inheritDoc}
-                        */
-                       @Override
-                       public void receivedNodeData(FcpConnection fcpConnection, NodeData nodeData) {
-                               nodeDataWrapper.set(nodeData);
-                               completionLatch.countDown();
-                       }
-               }.execute();
-               return nodeDataWrapper.get();
-       }
-
-       //
-       // PRIVATE METHODS
-       //
-
-       /**
-        * Creates a unique request identifier.
-        *
-        * @param basename
-        *            The basename of the request
-        * @return The created request identifier
-        */
-       private String createIdentifier(String basename) {
-               return basename + "-" + System.currentTimeMillis() + "-" + (int) (Math.random() * Integer.MAX_VALUE);
-       }
-
-       /**
-        * Checks whether the connection is in the required state.
-        *
-        * @param connected
-        *            The required connection state
-        * @throws FcpException
-        *             if the connection is not in the required state
-        */
-       private void checkConnected(boolean connected) throws FcpException {
-               if (this.connected != connected) {
-                       throw new FcpException("Client is " + (connected ? "not" : "already") + " connected.");
-               }
-       }
-
-       /**
-        * Tells the client that it is now disconnected. This method is called by
-        * {@link ExtendedFcpAdapter} only.
-        */
-       private void setDisconnected() {
-               connected = false;
-       }
-
-       /**
-        * Implementation of an {@link FcpListener} that can store an
-        * {@link FcpException} and wait for the arrival of a certain command.
-        *
-        * @author David ‘Bombe’ Roden &lt;bombe@freenetproject.org&gt;
-        */
-       private abstract class ExtendedFcpAdapter extends FcpAdapter {
-
-               /** The count down latch used to wait for completion. */
-               protected final CountDownLatch completionLatch = new CountDownLatch(1);
-
-               /** The FCP exception, if any. */
-               protected FcpException fcpException;
-
-               /**
-                * Creates a new extended FCP adapter.
-                */
-               public ExtendedFcpAdapter() {
-                       /* do nothing. */
-               }
-
-               /**
-                * Executes the FCP commands in {@link #run()}, wrapping the execution
-                * and catching exceptions.
-                *
-                * @throws IOException
-                *             if an I/O error occurs
-                * @throws FcpException
-                *             if an FCP error occurs
-                */
-               @SuppressWarnings("synthetic-access")
-               public void execute() throws IOException, FcpException {
-                       checkConnected(true);
-                       fcpConnection.addFcpListener(this);
-                       try {
-                               run();
-                               while (true) {
-                                       try {
-                                               completionLatch.await();
-                                               break;
-                                       } catch (InterruptedException ie1) {
-                                               /* ignore, we’ll loop. */
-                                       }
-                               }
-                       } catch (IOException ioe1) {
-                               setDisconnected();
-                               throw ioe1;
-                       } finally {
-                               fcpConnection.removeFcpListener(this);
-                       }
-                       if (fcpException != null) {
-                               setDisconnected();
-                               throw fcpException;
-                       }
-               }
-
-               /**
-                * The FCP commands that actually get executed.
-                *
-                * @throws IOException
-                *             if an I/O error occurs
-                */
-               public abstract void run() throws IOException;
-
-               /**
-                * {@inheritDoc}
-                */
-               @Override
-               public void connectionClosed(FcpConnection fcpConnection, Throwable throwable) {
-                       fcpException = new FcpException("Connection closed", throwable);
-                       completionLatch.countDown();
-               }
-
-               /**
-                * {@inheritDoc}
-                */
-               @Override
-               public void receivedCloseConnectionDuplicateClientName(FcpConnection fcpConnection, CloseConnectionDuplicateClientName closeConnectionDuplicateClientName) {
-                       fcpException = new FcpException("Connection closed, duplicate client name");
-                       completionLatch.countDown();
-               }
-
-               /**
-                * {@inheritDoc}
-                */
-               @Override
-               public void receivedProtocolError(FcpConnection fcpConnection, ProtocolError protocolError) {
-                       fcpException = new FcpException("Protocol error (" + protocolError.getCode() + ", " + protocolError.getCodeDescription());
-                       completionLatch.countDown();
-               }
-
-       }
-
-}
diff --git a/src/net/pterodactylus/fcp/highlevel/FcpClientListener.java b/src/net/pterodactylus/fcp/highlevel/FcpClientListener.java
deleted file mode 100644 (file)
index 2d06094..0000000
+++ /dev/null
@@ -1,38 +0,0 @@
-/*
- * jFCPlib - FcpClientListener.java - Copyright © 2009 David Roden
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- */
-
-package net.pterodactylus.fcp.highlevel;
-
-import java.util.EventListener;
-
-/**
- * Listener for {@link FcpClient} events.
- *
- * @author David ‘Bombe’ Roden &lt;bombe@freenetproject.org&gt;
- */
-public interface FcpClientListener extends EventListener {
-
-       /**
-        * Notifies a listener that the given FCP client was disconnected.
-        *
-        * @param fcpClient
-        *            The FCP client that was disconnected
-        */
-       public void fcpClientDisconnected(FcpClient fcpClient);
-
-}
diff --git a/src/net/pterodactylus/fcp/highlevel/FcpClientListenerManager.java b/src/net/pterodactylus/fcp/highlevel/FcpClientListenerManager.java
deleted file mode 100644 (file)
index aa797e4..0000000
+++ /dev/null
@@ -1,51 +0,0 @@
-/*
- * jFCPlib - FcpClientListenerManager.java - Copyright © 2009 David Roden
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- */
-
-package net.pterodactylus.fcp.highlevel;
-
-import net.pterodactylus.util.event.AbstractListenerManager;
-
-/**
- * Manages {@link FcpClientListener}s and fires events.
- *
- * @author David ‘Bombe’ Roden &lt;bombe@freenetproject.org&gt;
- */
-public class FcpClientListenerManager extends AbstractListenerManager<FcpClient, FcpClientListener> {
-
-       /**
-        * Creates a new FCP client listener manager.
-        *
-        * @param fcpClient
-        *            The source FCP client
-        */
-       public FcpClientListenerManager(FcpClient fcpClient) {
-               super(fcpClient);
-       }
-
-       /**
-        * Notifies all listeners that the FCP client was disconnected.
-        *
-        * @see FcpClientListener#fcpClientDisconnected(FcpClient)
-        */
-       public void fireFcpClientDisconnected() {
-               for (FcpClientListener fcpClientListener : getListeners()) {
-                       fcpClientListener.fcpClientDisconnected(getSource());
-               }
-       }
-
-}
diff --git a/src/net/pterodactylus/fcp/highlevel/FcpException.java b/src/net/pterodactylus/fcp/highlevel/FcpException.java
deleted file mode 100644 (file)
index dffc1f4..0000000
+++ /dev/null
@@ -1,67 +0,0 @@
-/*
- * jFCPlib - FcpException.java - Copyright © 2009 David Roden
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- */
-
-package net.pterodactylus.fcp.highlevel;
-
-/**
- * Exception that signals an error in the FCP protocol.
- *
- * @author David ‘Bombe’ Roden &lt;bombe@freenetproject.org&gt;
- */
-public class FcpException extends Exception {
-
-       /**
-        * Creates a new FCP exception.
-        */
-       public FcpException() {
-               super();
-       }
-
-       /**
-        * Creates a new FCP exception.
-        *
-        * @param message
-        *            The message of the exception
-        */
-       public FcpException(String message) {
-               super(message);
-       }
-
-       /**
-        * Creates a new FCP exception.
-        *
-        * @param cause
-        *            The cause of the exception
-        */
-       public FcpException(Throwable cause) {
-               super(cause);
-       }
-
-       /**
-        * Creates a new FCP exception.
-        *
-        * @param message
-        *            The message of the exception
-        * @param cause
-        *            The cause of the exception
-        */
-       public FcpException(String message, Throwable cause) {
-               super(message, cause);
-       }
-
-}
diff --git a/src/net/pterodactylus/fcp/highlevel/GetRequest.java b/src/net/pterodactylus/fcp/highlevel/GetRequest.java
deleted file mode 100644 (file)
index 7204335..0000000
+++ /dev/null
@@ -1,40 +0,0 @@
-/*
- * jFCPlib - GetRequest.java - Copyright © 2009 David Roden
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- */
-
-package net.pterodactylus.fcp.highlevel;
-
-import net.pterodactylus.fcp.PersistentGet;
-
-/**
- * High-level wrapper around {@link PersistentGet}.
- *
- * @author David ‘Bombe’ Roden &lt;bombe@freenetproject.org&gt;
- */
-public class GetRequest extends Request {
-
-       /**
-        * Creates a new get request.
-        *
-        * @param persistentGet
-        *            The persistent Get request to wrap
-        */
-       GetRequest(PersistentGet persistentGet) {
-               super(persistentGet.getIdentifier(), persistentGet.getClientToken(), persistentGet.isGlobal());
-       }
-
-}
diff --git a/src/net/pterodactylus/fcp/highlevel/PutRequest.java b/src/net/pterodactylus/fcp/highlevel/PutRequest.java
deleted file mode 100644 (file)
index cba84a6..0000000
+++ /dev/null
@@ -1,34 +0,0 @@
-/*
- * jFCPlib - PutRequest.java - Copyright © 2009 David Roden
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- */
-
-package net.pterodactylus.fcp.highlevel;
-
-import net.pterodactylus.fcp.PersistentPut;
-
-/**
- * TODO
- *
- * @author David ‘Bombe’ Roden &lt;bombe@freenetproject.org&gt;
- */
-public class PutRequest extends Request {
-
-       PutRequest(PersistentPut persistentPut) {
-               super(persistentPut.getIdentifier(), persistentPut.getClientToken(), persistentPut.isGlobal());
-       }
-
-}
diff --git a/src/net/pterodactylus/fcp/highlevel/Request.java b/src/net/pterodactylus/fcp/highlevel/Request.java
deleted file mode 100644 (file)
index 0b0f46e..0000000
+++ /dev/null
@@ -1,346 +0,0 @@
-/*
- * jFCPlib - Request.java - Copyright © 2009 David Roden
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- */
-
-package net.pterodactylus.fcp.highlevel;
-
-import net.pterodactylus.fcp.PersistentGet;
-import net.pterodactylus.fcp.PersistentPut;
-
-/**
- * Wrapper class around request responses from the node, such as
- * {@link PersistentGet} or {@link PersistentPut}.
- *
- * @author David ‘Bombe’ Roden &lt;bombe@freenetproject.org&gt;
- */
-public abstract class Request {
-
-       /** The identifier of the request. */
-       private final String identifier;
-
-       /** The client token of the request. */
-       private final String clientToken;
-
-       /** Whether the request is on the global queue. */
-       private final boolean global;
-
-       /** Whether the get request is complete. */
-       private boolean complete;
-
-       /** Whether the get request has failed. */
-       private boolean failed;
-
-       /** The data length. */
-       private long length;
-
-       /** The mime type. */
-       private String contentType;
-
-       /** The error code in case of failure. */
-       private int errorCode;
-
-       /** Whether the failure is fatal. */
-       private boolean fatal;
-
-       /** The total number of blocks. */
-       private int totalBlocks;
-
-       /** The required number of blocks. */
-       private int requiredBlocks;
-
-       /** The successfully processed number of blocks. */
-       private int succeededBlocks;
-
-       /** The number of failed blocks. */
-       private int failedBlocks;
-
-       /** The number of fatally failed blocks. */
-       private int fatallyFailedBlocks;
-
-       /** Whether the total number of blocks is finalized. */
-       private boolean finalizedTotal;
-
-       /**
-        * Creates a new request with the given identifier and client token.
-        *
-        * @param identifier
-        *            The identifier of the request
-        * @param clientToken
-        *            The client token of the request
-        * @param global
-        *            <code>true</code> if the request is on the global queue,
-        *            <code>false</code> otherwise
-        */
-       protected Request(String identifier, String clientToken, boolean global) {
-               this.identifier = identifier;
-               this.clientToken = clientToken;
-               this.global = global;
-       }
-
-       /**
-        * Returns the identifier of the request.
-        *
-        * @return The request’s identifier
-        */
-       public String getIdentifier() {
-               return identifier;
-       }
-
-       /**
-        * Returns the client token of the request.
-        *
-        * @return The request’s client token
-        */
-       public String getClientToken() {
-               return clientToken;
-       }
-
-       /**
-        * Returns whether this request is on the global queue.
-        *
-        * @return <code>true</code> if the request is on the global queue,
-        *         <code>false</code> otherwise
-        */
-       public boolean isGlobal() {
-               return global;
-       }
-
-       /**
-        * Returns whether this request is complete.
-        *
-        * @return <code>true</code> if this request is complete, false otherwise
-        */
-       public boolean isComplete() {
-               return complete;
-       }
-
-       /**
-        * Sets whether this request is complete.
-        *
-        * @param complete
-        *            <code>true</code> if this request is complete, false otherwise
-        */
-       void setComplete(boolean complete) {
-               this.complete = complete;
-       }
-
-       /**
-        * Returns whether this request has failed. This method should only be
-        * called if {@link #isComplete()} returns <code>true</code>.
-        *
-        * @return <code>true</code> if this request failed, <code>false</code>
-        *         otherwise
-        */
-       public boolean hasFailed() {
-               return failed;
-       }
-
-       /**
-        * Sets whether this request has failed.
-        *
-        * @param failed
-        *            <code>true</code> if this request failed, <code>false</code>
-        *            otherwise
-        */
-       void setFailed(boolean failed) {
-               this.failed = failed;
-       }
-
-       /**
-        * Returns the length of the data.
-        *
-        * @return The length of the data
-        */
-       public long getLength() {
-               return length;
-       }
-
-       /**
-        * Sets the length of the data.
-        *
-        * @param length
-        *            The length of the data
-        */
-       void setLength(long length) {
-               this.length = length;
-       }
-
-       /**
-        * Returns the content type of the data.
-        *
-        * @return The content type of the data
-        */
-       public String getContentType() {
-               return contentType;
-       }
-
-       /**
-        * Sets the content type of the data.
-        *
-        * @param contentType
-        *            The content type of the data
-        */
-       void setContentType(String contentType) {
-               this.contentType = contentType;
-       }
-
-       /**
-        * Returns the error code. This method should only be called if
-        * {@link #hasFailed()} returns <code>true</code>.
-        *
-        * @return The error code
-        */
-       public int getErrorCode() {
-               return errorCode;
-       }
-
-       /**
-        * Sets the error code.
-        *
-        * @param errorCode
-        *            The error code
-        */
-       void setErrorCode(int errorCode) {
-               this.errorCode = errorCode;
-       }
-
-       /**
-        * Returns whether this request has fatally failed, i.e. repitition will not
-        * cause the request to succeed.
-        *
-        * @return <code>true</code> if this request can not be made succeed by
-        *         repeating, <code>false</code> otherwise
-        */
-       public boolean isFatal() {
-               return fatal;
-       }
-
-       /**
-        * Sets whether this request has fatally failed.
-        *
-        * @param fatal
-        *            <code>true</code> if this request failed fatally,
-        *            <code>false</code> otherwise
-        */
-       void setFatal(boolean fatal) {
-               this.fatal = fatal;
-       }
-
-       /**
-        * Returns the total number of blocks of this request.
-        *
-        * @return This request’s total number of blocks
-        */
-       public int getTotalBlocks() {
-               return totalBlocks;
-       }
-
-       /**
-        * Sets the total number of blocks of this request.
-        *
-        * @param totalBlocks
-        *            This request’s total number of blocks
-        */
-       public void setTotalBlocks(int totalBlocks) {
-               this.totalBlocks = totalBlocks;
-       }
-
-       /**
-        * TODO
-        *
-        * @return the requiredBlocks
-        */
-       public int getRequiredBlocks() {
-               return requiredBlocks;
-       }
-
-       /**
-        * TODO
-        *
-        * @param requiredBlocks
-        *            the requiredBlocks to set
-        */
-       public void setRequiredBlocks(int requiredBlocks) {
-               this.requiredBlocks = requiredBlocks;
-       }
-
-       /**
-        * TODO
-        *
-        * @return the succeededBlocks
-        */
-       public int getSucceededBlocks() {
-               return succeededBlocks;
-       }
-
-       /**
-        * TODO
-        *
-        * @param succeededBlocks
-        *            the succeededBlocks to set
-        */
-       public void setSucceededBlocks(int succeededBlocks) {
-               this.succeededBlocks = succeededBlocks;
-       }
-
-       /**
-        * TODO
-        *
-        * @return the failedBlocks
-        */
-       public int getFailedBlocks() {
-               return failedBlocks;
-       }
-
-       /**
-        * TODO
-        *
-        * @param failedBlocks
-        *            the failedBlocks to set
-        */
-       public void setFailedBlocks(int failedBlocks) {
-               this.failedBlocks = failedBlocks;
-       }
-
-       /**
-        * TODO
-        *
-        * @return the fatallyFailedBlocks
-        */
-       public int getFatallyFailedBlocks() {
-               return fatallyFailedBlocks;
-       }
-
-       /**
-        * TODO
-        *
-        * @param fatallyFailedBlocks
-        *            the fatallyFailedBlocks to set
-        */
-       public void setFatallyFailedBlocks(int fatallyFailedBlocks) {
-               this.fatallyFailedBlocks = fatallyFailedBlocks;
-       }
-
-       public boolean isFinalizedTotal() {
-               return finalizedTotal;
-       }
-
-       void setFinalizedTotal(boolean finalizedTotal) {
-               this.finalizedTotal = finalizedTotal;
-       }
-
-}
diff --git a/src/net/pterodactylus/fcp/package-info.java b/src/net/pterodactylus/fcp/package-info.java
deleted file mode 100644 (file)
index dbda870..0000000
+++ /dev/null
@@ -1,36 +0,0 @@
-/**
- * Package that holds all the message types that are used in the communication
- * with a Freenet Node.
- * 
- * <h2>Usage</h2>
- * 
- * This library was designed to implement the full range of the Freenet Client
- * Protocol, Version 2.0. At the moment the library provides a rather low-level
- * approach, wrapping each FCP message into its own object but some kind of
- * high-level client that does not require any interfaces to be implemented
- * will probably provided as well.
- * 
- * First, create a connection to the node:
- * 
- * <pre>
- * FcpConnection fcpConnection = new FcpConnection();
- * </pre>
- * 
- * Now implement the {@link net.pterodactylus.fcp.FcpListener} interface
- * and handle all incoming events.
- * 
- * <pre>
- * public class MyClass implements FcpListener {
- * 
- *     public void receivedProtocolError(FcpConnection fcpConnection, ProtocolError protocolError) {
- *             …
- *     }
- * 
- *     // implement all further methods here
- * 
- * }
- * </pre>
- */
-
-package net.pterodactylus.fcp;
-
diff --git a/src/net/pterodactylus/fcp/plugin/WebOfTrustPlugin.java b/src/net/pterodactylus/fcp/plugin/WebOfTrustPlugin.java
deleted file mode 100644 (file)
index 3e99b1e..0000000
+++ /dev/null
@@ -1,661 +0,0 @@
-/*
- * jFCPlib - WebOfTrustPlugin.java - Copyright © 2009 David Roden
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- */
-
-package net.pterodactylus.fcp.plugin;
-
-import java.io.IOException;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.Map;
-import java.util.Set;
-
-import net.pterodactylus.fcp.highlevel.FcpClient;
-import net.pterodactylus.fcp.highlevel.FcpException;
-
-/**
- * Simplifies handling of the web-of-trust plugin.
- *
- * @author David ‘Bombe’ Roden &lt;bombe@freenetproject.org&gt;
- */
-public class WebOfTrustPlugin {
-
-       /** The FCP client to use. */
-       private final FcpClient fcpClient;
-
-       /**
-        * Creates a new web-of-trust plugin wrapper around the given FCP client.
-        *
-        * @param fcpClient
-        *            The FCP client to use for communication with the web-of-trust
-        *            plugin
-        */
-       public WebOfTrustPlugin(FcpClient fcpClient) {
-               this.fcpClient = fcpClient;
-       }
-
-       /**
-        * Creates a new identity.
-        *
-        * @param nickname
-        *            The nickname of the new identity
-        * @param context
-        *            The context for the new identity
-        * @param publishTrustList
-        *            {@code true} if the new identity should publish its trust list
-        * @return The new identity
-        * @throws IOException
-        *             if an I/O error occurs
-        * @throws FcpException
-        *             if an FCP error occurs
-        */
-       public OwnIdentity createIdentity(String nickname, String context, boolean publishTrustList) throws IOException, FcpException {
-               return createIdentity(nickname, context, publishTrustList, null, null);
-       }
-
-       /**
-        * Creates a new identity from the given request and insert URI.
-        *
-        * @param nickname
-        *            The nickname of the new identity
-        * @param context
-        *            The context for the new identity
-        * @param publishTrustList
-        *            {@code true} if the new identity should publish its trust list
-        * @param requestUri
-        *            The request URI of the identity
-        * @param insertUri
-        *            The insert URI of the identity
-        * @return The new identity
-        * @throws IOException
-        *             if an I/O error occurs
-        * @throws FcpException
-        *             if an FCP error occurs
-        */
-       public OwnIdentity createIdentity(String nickname, String context, boolean publishTrustList, String requestUri, String insertUri) throws IOException, FcpException {
-               Map<String, String> parameters = new HashMap<String, String>();
-               parameters.put("Message", "CreateIdentity");
-               parameters.put("Nickname", nickname);
-               parameters.put("Context", context);
-               parameters.put("PublishTrustList", String.valueOf(publishTrustList));
-               if ((requestUri != null) && (insertUri != null)) {
-                       parameters.put("RequestURI", requestUri);
-                       parameters.put("InsertURI", insertUri);
-               }
-               Map<String, String> replies = fcpClient.sendPluginMessage("plugins.WoT.WoT", parameters);
-               if (!replies.get("Message").equals("IdentityCreated")) {
-                       throw new FcpException("WebOfTrust Plugin did not reply with “IdentityCreated” message!");
-               }
-               String identifier = replies.get("ID");
-               String newRequestUri = replies.get("RequestURI");
-               String newInsertUri = replies.get("InsertURI");
-               return new OwnIdentity(identifier, nickname, newRequestUri, newInsertUri);
-       }
-
-       /**
-        * Returns all own identities of the web-of-trust plugins. Almost all other
-        * commands require an {@link OwnIdentity} to return meaningful values.
-        *
-        * @return All own identities of the web-of-trust plugin
-        * @throws IOException
-        *             if an I/O error occurs
-        * @throws FcpException
-        *             if an FCP error occurs
-        */
-       public Set<OwnIdentity> getOwnIdentites() throws IOException, FcpException {
-               Map<String, String> replies = fcpClient.sendPluginMessage("plugins.WoT.WoT", createParameters("Message", "GetOwnIdentities"));
-               if (!replies.get("Message").equals("OwnIdentities")) {
-                       throw new FcpException("WebOfTrust Plugin did not reply with “OwnIdentities” message!");
-               }
-               Set<OwnIdentity> ownIdentities = new HashSet<OwnIdentity>();
-               for (int identityIndex = 1; replies.containsKey("Identity" + identityIndex); identityIndex++) {
-                       String identity = replies.get("Identity" + identityIndex);
-                       String nickname = replies.get("Nickname" + identityIndex);
-                       String requestUri = replies.get("RequestURI" + identityIndex);
-                       String insertUri = replies.get("InsertURI" + identityIndex);
-                       ownIdentities.add(new OwnIdentity(identity, nickname, requestUri, insertUri));
-               }
-               return ownIdentities;
-       }
-
-       /**
-        * Returns the trust given to the identity with the given identifier by the
-        * given own identity.
-        *
-        * @param ownIdentity
-        *            The own identity that is used to calculate trust values
-        * @param identifier
-        *            The identifier of the identity whose trust to get
-        * @return The request identity trust
-        * @throws IOException
-        *             if an I/O error occurs
-        * @throws FcpException
-        *             if an FCP error occurs
-        */
-       public CalculatedTrust getIdentityTrust(OwnIdentity ownIdentity, String identifier) throws IOException, FcpException {
-               Map<String, String> replies = fcpClient.sendPluginMessage("plugins.WoT.WoT", createParameters("Message", "GetIdentity", "TreeOwner", ownIdentity.getIdentifier(), "Identity", identifier));
-               if (!replies.get("Message").equals("Identity")) {
-                       throw new FcpException("WebOfTrust Plugin did not reply with “Identity” message!");
-               }
-               Byte trust = null;
-               try {
-                       trust = Byte.valueOf(replies.get("Trust"));
-               } catch (NumberFormatException nfe1) {
-                       /* ignore. */
-               }
-               Integer score = null;
-               try {
-                       score = Integer.valueOf(replies.get("Score"));
-               } catch (NumberFormatException nfe1) {
-                       /* ignore. */
-               }
-               Integer rank = null;
-               try {
-                       rank = Integer.valueOf(replies.get("Rank"));
-               } catch (NumberFormatException nfe1) {
-                       /* ignore. */
-               }
-               return new CalculatedTrust(trust, score, rank);
-       }
-
-       /**
-        * Adds a new identity by its request URI.
-        *
-        * @param requestUri
-        *            The request URI of the identity to add
-        * @return The added identity
-        * @throws IOException
-        *             if an I/O error occurs
-        * @throws FcpException
-        *             if an FCP error occurs
-        */
-       public Identity addIdentity(String requestUri) throws IOException, FcpException {
-               Map<String, String> replies = fcpClient.sendPluginMessage("plugins.WoT.WoT", createParameters("Message", "AddIdentity", "RequestURI", requestUri));
-               if (!replies.get("Message").equals("IdentityAdded")) {
-                       throw new FcpException("WebOfTrust Plugin did not reply with “IdentityAdded” message!");
-               }
-               String identifier = replies.get("ID");
-               String nickname = replies.get("Nickname");
-               return new Identity(identifier, nickname, requestUri);
-       }
-
-       /**
-        * Returns identities by the given score.
-        *
-        * @param ownIdentity
-        *            The own identity
-        * @param context
-        *            The context to get the identities for
-        * @param positive
-        *            {@code null} to return neutrally trusted identities, {@code
-        *            true} to return positively trusted identities, {@code false}
-        *            for negatively trusted identities
-        * @return The trusted identites
-        * @throws IOException
-        *             if an I/O error occurs
-        * @throws FcpException
-        *             if an FCP error occurs
-        */
-       public Set<Identity> getIdentitesByScore(OwnIdentity ownIdentity, String context, Boolean positive) throws IOException, FcpException {
-               Map<String, String> replies = fcpClient.sendPluginMessage("plugins.WoT.WoT", createParameters("Message", "GetIdentitiesByScore", "TreeOwner", ownIdentity.getIdentifier(), "Context", context, "Selection", ((positive == null) ? "0" : (positive ? "+" : "-"))));
-               if (!replies.get("Message").equals("Identities")) {
-                       throw new FcpException("WebOfTrust Plugin did not reply with “Identities” message!");
-               }
-               Set<Identity> identities = new HashSet<Identity>();
-               for (int identityIndex = 1; replies.containsKey("Identity" + identityIndex); identityIndex++) {
-                       String identifier = replies.get("Identity" + identityIndex);
-                       String nickname = replies.get("Nickname" + identityIndex);
-                       String requestUri = replies.get("RequestURI" + identityIndex);
-                       identities.add(new Identity(identifier, nickname, requestUri));
-               }
-               return identities;
-       }
-
-       /**
-        * Returns the identities that trust the given identity.
-        *
-        * @param identity
-        *            The identity to get the trusters for
-        * @param context
-        *            The context to get the trusters for
-        * @return The identities and their trust values
-        * @throws IOException
-        *             if an I/O error occurs
-        * @throws FcpException
-        *             if an FCP error occurs
-        */
-       public Map<Identity, IdentityTrust> getTrusters(Identity identity, String context) throws IOException, FcpException {
-               Map<String, String> replies = fcpClient.sendPluginMessage("plugins.WoT.WoT", createParameters("Message", "GetTrusters", "Identity", identity.getIdentifier(), "Context", context));
-               if (!replies.get("Message").equals("Identities")) {
-                       throw new FcpException("WebOfTrust Plugin did not reply with “Identities” message!");
-               }
-               Map<Identity, IdentityTrust> identityTrusts = new HashMap<Identity, IdentityTrust>();
-               for (int identityIndex = 1; replies.containsKey("Identity" + identityIndex); identityIndex++) {
-                       String identifier = replies.get("Identity" + identityIndex);
-                       String nickname = replies.get("Nickname" + identityIndex);
-                       String requestUri = replies.get("RequestURI" + identityIndex);
-                       byte trust = Byte.parseByte(replies.get("Value" + identityIndex));
-                       String comment = replies.get("Comment" + identityIndex);
-                       identityTrusts.put(new Identity(identifier, nickname, requestUri), new IdentityTrust(trust, comment));
-               }
-               return identityTrusts;
-       }
-
-       /**
-        * Returns the identities that given identity trusts.
-        *
-        * @param identity
-        *            The identity to get the trustees for
-        * @param context
-        *            The context to get the trustees for
-        * @return The identities and their trust values
-        * @throws IOException
-        *             if an I/O error occurs
-        * @throws FcpException
-        *             if an FCP error occurs
-        */
-       public Map<Identity, IdentityTrust> getTrustees(Identity identity, String context) throws IOException, FcpException {
-               Map<String, String> replies = fcpClient.sendPluginMessage("plugins.WoT.WoT", createParameters("Message", "GetTrustees", "Identity", identity.getIdentifier(), "Context", context));
-               if (!replies.get("Message").equals("Identities")) {
-                       throw new FcpException("WebOfTrust Plugin did not reply with “Identities” message!");
-               }
-               Map<Identity, IdentityTrust> identityTrusts = new HashMap<Identity, IdentityTrust>();
-               for (int identityIndex = 1; replies.containsKey("Identity" + identityIndex); identityIndex++) {
-                       String identifier = replies.get("Identity" + identityIndex);
-                       String nickname = replies.get("Nickname" + identityIndex);
-                       String requestUri = replies.get("RequestURI" + identityIndex);
-                       byte trust = Byte.parseByte(replies.get("Value" + identityIndex));
-                       String comment = replies.get("Comment" + identityIndex);
-                       identityTrusts.put(new Identity(identifier, nickname, requestUri), new IdentityTrust(trust, comment));
-               }
-               return identityTrusts;
-       }
-
-       /**
-        * Sets the trust given to the given identify by the given own identity.
-        *
-        * @param ownIdentity
-        *            The identity that gives the trust
-        * @param identity
-        *            The identity that receives the trust
-        * @param trust
-        *            The trust value (ranging from {@code -100} to {@code 100}
-        * @param comment
-        *            The comment for setting the trust
-        * @throws IOException
-        *             if an I/O error occurs
-        * @throws FcpException
-        *             if an FCP error occurs
-        */
-       public void setTrust(OwnIdentity ownIdentity, Identity identity, byte trust, String comment) throws IOException, FcpException {
-               Map<String, String> replies = fcpClient.sendPluginMessage("plugins.WoT.WoT", createParameters("Message", "SetTrust", "Truster", ownIdentity.getIdentifier(), "Trustee", identity.getIdentifier(), "Value", String.valueOf(trust), "Comment", comment));
-               if (!replies.get("Message").equals("TrustSet")) {
-                       throw new FcpException("WebOfTrust Plugin did not reply with “TrustSet” message!");
-               }
-       }
-
-       /**
-        * Adds the given context to the given identity.
-        *
-        * @param ownIdentity
-        *            The identity to add the context to
-        * @param context
-        *            The context to add
-        * @throws IOException
-        *             if an I/O error occurs
-        * @throws FcpException
-        *             if an FCP error occurs
-        */
-       public void addContext(OwnIdentity ownIdentity, String context) throws IOException, FcpException {
-               Map<String, String> replies = fcpClient.sendPluginMessage("plugins.WoT.WoT", createParameters("Message", "AddContext", "Identity", ownIdentity.getIdentifier(), "Context", context));
-               if (!replies.get("Message").equals("ContextAdded")) {
-                       throw new FcpException("WebOfTrust Plugin did not reply with “ContextAdded” message!");
-               }
-       }
-
-       /**
-        * Removes the given context from the given identity.
-        *
-        * @param ownIdentity
-        *            The identity to remove the context from
-        * @param context
-        *            The context to remove
-        * @throws IOException
-        *             if an I/O error occurs
-        * @throws FcpException
-        *             if an FCP error occurs
-        */
-       public void removeContext(OwnIdentity ownIdentity, String context) throws IOException, FcpException {
-               Map<String, String> replies = fcpClient.sendPluginMessage("plugins.WoT.WoT", createParameters("Message", "RemoveContext", "Identity", ownIdentity.getIdentifier(), "Context", context));
-               if (!replies.get("Message").equals("ContextRemoved")) {
-                       throw new FcpException("WebOfTrust Plugin did not reply with “ContextRemoved” message!");
-               }
-       }
-
-       /**
-        * Sets the given property for the given identity.
-        *
-        * @param ownIdentity
-        *            The identity to set a property for
-        * @param property
-        *            The name of the property to set
-        * @param value
-        *            The value of the property to set
-        * @throws IOException
-        *             if an I/O error occurs
-        * @throws FcpException
-        *             if an FCP error occurs
-        */
-       public void setProperty(OwnIdentity ownIdentity, String property, String value) throws IOException, FcpException {
-               Map<String, String> replies = fcpClient.sendPluginMessage("plugins.WoT.WoT", createParameters("Message", "SetProperty", "Identity", ownIdentity.getIdentifier(), "Property", property, "Value", value));
-               if (!replies.get("Message").equals("PropertyAdded")) {
-                       throw new FcpException("WebOfTrust Plugin did not reply with “PropertyAdded” message!");
-               }
-       }
-
-       /**
-        * Returns the value of the given property for the given identity.
-        *
-        * @param ownIdentity
-        *            The identity to get a property for
-        * @param property
-        *            The name of the property to get
-        * @return The value of the property
-        * @throws IOException
-        *             if an I/O error occurs
-        * @throws FcpException
-        *             if an FCP error occurs
-        */
-       public String getProperty(OwnIdentity ownIdentity, String property) throws IOException, FcpException {
-               Map<String, String> replies = fcpClient.sendPluginMessage("plugins.WoT.WoT", createParameters("Message", "GetProperty", "Identity", ownIdentity.getIdentifier(), "Property", property));
-               if (!replies.get("Message").equals("PropertyValue")) {
-                       throw new FcpException("WebOfTrust Plugin did not reply with “PropertyValue” message!");
-               }
-               return replies.get("Property");
-       }
-
-       /**
-        * Removes the given property from the given identity.
-        *
-        * @param ownIdentity
-        *            The identity to remove a property from
-        * @param property
-        *            The name of the property to remove
-        * @throws IOException
-        *             if an I/O error occurs
-        * @throws FcpException
-        *             if an FCP error occurs
-        */
-       public void removeProperty(OwnIdentity ownIdentity, String property) throws IOException, FcpException {
-               Map<String, String> replies = fcpClient.sendPluginMessage("plugins.WoT.WoT", createParameters("Message", "RemoveProperty", "Identity", ownIdentity.getIdentifier(), "Property", property));
-               if (!replies.get("Message").equals("PropertyRemoved")) {
-                       throw new FcpException("WebOfTrust Plugin did not reply with “PropertyRemoved” message!");
-               }
-       }
-
-       //
-       // PRIVATE METHODS
-       //
-
-       /**
-        * Creates a map from each pair of parameters in the given array.
-        *
-        * @param parameters
-        *            The array of parameters
-        * @return The map created from the array
-        * @throws ArrayIndexOutOfBoundsException
-        *             if the given parameter array does not contains an even number
-        *             of elements
-        */
-       private Map<String, String> createParameters(String... parameters) throws ArrayIndexOutOfBoundsException {
-               Map<String, String> parameterMap = new HashMap<String, String>();
-               for (int index = 0; index < parameters.length; index += 2) {
-                       parameterMap.put(parameters[index], parameters[index + 1]);
-               }
-               return parameterMap;
-       }
-
-       /**
-        * Wrapper around a web-of-trust identity.
-        *
-        * @author David ‘Bombe’ Roden &lt;bombe@freenetproject.org&gt;
-        */
-       public static class Identity {
-
-               /** The identity’s identifier. */
-               private final String identifier;
-
-               /** The identity’s nickname. */
-               private final String nickname;
-
-               /** The identity’s request URI. */
-               private final String requestUri;
-
-               /**
-                * Creates a new identity.
-                *
-                * @param identifier
-                *            The identifies of the identity
-                * @param nickname
-                *            The nickname of the identity
-                * @param requestUri
-                *            The request URI of the identity
-                */
-               public Identity(String identifier, String nickname, String requestUri) {
-                       this.identifier = identifier;
-                       this.nickname = nickname;
-                       this.requestUri = requestUri;
-               }
-
-               /**
-                * Returns the identifier of this identity.
-                *
-                * @return This identity’s identifier
-                */
-               public String getIdentifier() {
-                       return identifier;
-               }
-
-               /**
-                * Returns the nickname of this identity.
-                *
-                * @return This identity’s nickname
-                */
-               public String getNickname() {
-                       return nickname;
-               }
-
-               /**
-                * Returns the request URI of this identity.
-                *
-                * @return This identity’s request URI
-                */
-               public String getRequestUri() {
-                       return requestUri;
-               }
-
-               /**
-                * {@inheritDoc}
-                */
-               @Override
-               public boolean equals(Object obj) {
-                       if ((obj == null) || (obj.getClass() != this.getClass())) {
-                               return false;
-                       }
-                       Identity identity = (Identity) obj;
-                       return identifier.equals(identity.identifier);
-               }
-
-               /**
-                * {@inheritDoc}
-                */
-               @Override
-               public int hashCode() {
-                       return identifier.hashCode();
-               }
-
-       }
-
-       /**
-        * Container for the trust given from one identity to another.
-        *
-        * @author David ‘Bombe’ Roden &lt;bombe@freenetproject.org&gt;
-        */
-       public static class IdentityTrust {
-
-               /** The trust given to the identity. */
-               private final byte trust;
-
-               /** The command for the trust value. */
-               private final String comment;
-
-               /**
-                * Creates a new identity trust container.
-                *
-                * @param trust
-                *            The trust given to the identity
-                * @param comment
-                *            The comment for the trust value
-                */
-               public IdentityTrust(byte trust, String comment) {
-                       this.trust = trust;
-                       this.comment = comment;
-               }
-
-               /**
-                * Returns the trust value given to the identity.
-                *
-                * @return The trust value
-                */
-               public byte getTrust() {
-                       return trust;
-               }
-
-               /**
-                * Returns the comment for the trust value.
-                *
-                * @return The comment for the trust value
-                */
-               public String getComment() {
-                       return comment;
-               }
-
-       }
-
-       /**
-        * Container that stores the trust that is calculated by taking all trustees
-        * and their trust lists into account.
-        *
-        * @author David ‘Bombe’ Roden &lt;bombe@freenetproject.org&gt;
-        */
-       public static class CalculatedTrust {
-
-               /** The calculated trust value. */
-               private final Byte trust;
-
-               /** The calculated score value. */
-               private final Integer score;
-
-               /** The calculated rank. */
-               private final Integer rank;
-
-               /**
-                * Creates a new calculated trust container.
-                *
-                * @param trust
-                *            The calculated trust value
-                * @param score
-                *            The calculated score value
-                * @param rank
-                *            The calculated rank of the
-                */
-               public CalculatedTrust(Byte trust, Integer score, Integer rank) {
-                       this.trust = trust;
-                       this.score = score;
-                       this.rank = rank;
-               }
-
-               /**
-                * Returns the calculated trust value.
-                *
-                * @return The calculated trust value, or {@code null} if the trust
-                *         value is not known
-                */
-               public Byte getTrust() {
-                       return trust;
-               }
-
-               /**
-                * Returns the calculated score value.
-                *
-                * @return The calculated score value, or {@code null} if the score
-                *         value is not known
-                */
-               public Integer getScore() {
-                       return score;
-               }
-
-               /**
-                * Returns the calculated rank.
-                *
-                * @return The calculated rank, or {@code null} if the rank is not known
-                */
-               public Integer getRank() {
-                       return rank;
-               }
-
-       }
-
-       /**
-        * Wrapper around a web-of-trust own identity.
-        *
-        * @author David ‘Bombe’ Roden &lt;bombe@freenetproject.org&gt;
-        */
-       public static class OwnIdentity extends Identity {
-
-               /** The identity’s insert URI. */
-               private final String insertUri;
-
-               /**
-                * Creates a new web-of-trust own identity.
-                *
-                * @param identifier
-                *            The identifier of the identity
-                * @param nickname
-                *            The nickname of the identity
-                * @param requestUri
-                *            The request URI of the identity
-                * @param insertUri
-                *            The insert URI of the identity
-                */
-               public OwnIdentity(String identifier, String nickname, String requestUri, String insertUri) {
-                       super(identifier, nickname, requestUri);
-                       this.insertUri = insertUri;
-               }
-
-               /**
-                * Returns the insert URI of this identity.
-                *
-                * @return This identity’s insert URI
-                */
-               public String getInsertUri() {
-                       return insertUri;
-               }
-
-       }
-
-}
diff --git a/src/net/pterodactylus/util/event/AbstractListenerManager.java b/src/net/pterodactylus/util/event/AbstractListenerManager.java
deleted file mode 100644 (file)
index fb2d43c..0000000
+++ /dev/null
@@ -1,129 +0,0 @@
-/*
- * jFCPlib - AbstractListenerManager.java - Copyright © 2009 David Roden
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-package net.pterodactylus.util.event;
-
-import java.util.EventListener;
-import java.util.List;
-import java.util.concurrent.CopyOnWriteArrayList;
-import java.util.concurrent.Executor;
-
-import net.pterodactylus.util.thread.CurrentThreadExecutor;
-
-/**
- * Abstract implementation of a listener support class. The listener support
- * takes care of adding and removing {@link EventListener} implementations, and
- * subclasses are responsible for firing appropriate events.
- *
- * @param <S>
- *            The type of the source
- *@param <L>
- *            The type of the event listeners
- * @author <a href="mailto:bombe@pterodactylus.net">David ‘Bombe’ Roden</a>
- */
-public abstract class AbstractListenerManager<S, L extends EventListener> {
-
-       /** The source that emits the events. */
-       private final S source;
-
-       /** The list of listeners. */
-       private final List<L> listeners = new CopyOnWriteArrayList<L>();
-
-       /** Service that executes event threads. */
-       private final Executor executor;
-
-       /**
-        * Creates a new listener support that emits events from the given source.
-        *
-        * @param source
-        *            The source of the events
-        */
-       public AbstractListenerManager(S source) {
-               this(source, new CurrentThreadExecutor());
-       }
-
-       /**
-        * Creates a new listener support that emits events from the given source.
-        *
-        * @param source
-        *            The source of the events
-        * @param executor
-        *            The executor used to fire events
-        */
-       public AbstractListenerManager(S source, Executor executor) {
-               this.source = source;
-               this.executor = executor;
-       }
-
-       /**
-        * Adds the given listener to the list of reigstered listeners.
-        *
-        * @param listener
-        *            The listener to add
-        */
-       public void addListener(L listener) {
-               synchronized (listeners) {
-                       listeners.add(listener);
-               }
-       }
-
-       /**
-        * Removes the given listener from the list of registered listeners.
-        *
-        * @param listener
-        *            The listener to remove
-        */
-       public void removeListener(L listener) {
-               synchronized (listeners) {
-                       listeners.remove(listener);
-               }
-       }
-
-       //
-       // PROTECTED METHODS
-       //
-
-       /**
-        * Returns the source for the events.
-        *
-        * @return The event source
-        */
-       protected S getSource() {
-               return source;
-       }
-
-       /**
-        * Returns the executor for the event firing.
-        *
-        * @return The executor
-        */
-       protected Executor getExecutor() {
-               return executor;
-       }
-
-       /**
-        * Returns a list of all registered listeners. The returned list is a copy
-        * of the original list so structural modifications will never occur when
-        * using the returned list.
-        *
-        * @return The list of all registered listeners
-        */
-       protected List<L> getListeners() {
-               return listeners;
-       }
-
-}
diff --git a/src/net/pterodactylus/util/filter/Filter.java b/src/net/pterodactylus/util/filter/Filter.java
deleted file mode 100644 (file)
index 90d7699..0000000
+++ /dev/null
@@ -1,41 +0,0 @@
-/*
- * jFCPlib - Filter.java - Copyright © 2009 David Roden
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- */
-package net.pterodactylus.util.filter;
-
-/**
- * Interface for a filter that determines whether a certain action can be
- * performed on an object based on its properties.
- *
- * @param <T>
- *            The type of the filtered object
- * @author David ‘Bombe’ Roden &lt;bombe@freenetproject.org&gt;
- */
-public interface Filter<T> {
-
-       /**
-        * Runs the given object through this filter and return whether the object
-        * matches this filter or not.
-        *
-        * @param object
-        *            The object to analyse
-        * @return <code>true</code> if the object matched this filter,
-        *         <code>false</code> otherwise
-        */
-       public boolean filterObject(T object);
-
-}
diff --git a/src/net/pterodactylus/util/filter/Filters.java b/src/net/pterodactylus/util/filter/Filters.java
deleted file mode 100644 (file)
index d2bbb49..0000000
+++ /dev/null
@@ -1,190 +0,0 @@
-/*
- * jFCPlib - Filters.java - Copyright © 2009 David Roden
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- */
-package net.pterodactylus.util.filter;
-
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Map;
-import java.util.NoSuchElementException;
-import java.util.Set;
-import java.util.Map.Entry;
-
-/**
- * Defines various methods to filter {@link Collection}s.
- *
- * @author David ‘Bombe’ Roden &lt;bombe@freenetproject.org&gt;
- */
-public class Filters {
-
-       /**
-        * Returns a list that contains only the elements from the given list that
-        * match the given filter.
-        *
-        * @param <E>
-        *            The type of the list elements
-        * @param list
-        *            The list to filter
-        * @param listFilter
-        *            The list filter
-        * @return The filtered list
-        */
-       public static <E> List<E> filteredList(List<E> list, Filter<E> listFilter) {
-               List<E> filteredList = new ArrayList<E>();
-               for (E element : list) {
-                       if (listFilter.filterObject(element)) {
-                               filteredList.add(element);
-                       }
-               }
-               return filteredList;
-       }
-
-       /**
-        * Returns a set that contains only the elements from the given set that
-        * match the given filter.
-        *
-        * @param <E>
-        *            The type of the set elements
-        * @param set
-        *            The set to filter
-        * @param setFilter
-        *            The set filter
-        * @return The filtered set
-        */
-       public static <E> Set<E> filteredSet(Set<E> set, Filter<E> setFilter) {
-               Set<E> filteredSet = new HashSet<E>();
-               for (E element : set) {
-                       if (setFilter.filterObject(element)) {
-                               filteredSet.add(element);
-                       }
-               }
-               return filteredSet;
-       }
-
-       /**
-        * Returns a map that contains only the elements from the given map that
-        * match the given filter.
-        *
-        * @param <K>
-        *            The type of the map keys
-        * @param <V>
-        *            The type of the map values
-        * @param map
-        *            The map to filter
-        * @param mapFilter
-        *            The map filter
-        * @return The filtered map
-        */
-       public static <K, V> Map<K, V> filteredMap(Map<K, V> map, Filter<Entry<K, V>> mapFilter) {
-               Map<K, V> filteredMap = new HashMap<K, V>();
-               for (Entry<K, V> element : map.entrySet()) {
-                       if (mapFilter.filterObject(element)) {
-                               filteredMap.put(element.getKey(), element.getValue());
-                       }
-               }
-               return filteredMap;
-       }
-
-       /**
-        * Returns a collection that contains only the elements from the given
-        * collection that match the given filter.
-        *
-        * @param <K>
-        *            The type of the collection values
-        * @param collection
-        *            The collection to filter
-        * @param collectionFilter
-        *            The collection filter
-        * @return The filtered collection
-        */
-       public static <K> Collection<K> filteredCollection(Collection<K> collection, Filter<K> collectionFilter) {
-               return filteredList(new ArrayList<K>(collection), collectionFilter);
-       }
-
-       /**
-        * Returns an iterator that contains only the elements from the given
-        * iterator that match the given filter.
-        *
-        * @param <E>
-        *            The type of the iterator elements
-        * @param iterator
-        *            The iterator to filter
-        * @param iteratorFilter
-        *            The iterator filter
-        * @return The filtered iterator
-        */
-       public static <E> Iterator<E> filteredIterator(final Iterator<E> iterator, final Filter<E> iteratorFilter) {
-               return new Iterator<E>() {
-
-                       private boolean gotNextElement = false;
-
-                       private E nextElement;
-
-                       private void getNextElement() {
-                               if (gotNextElement) {
-                                       return;
-                               }
-                               while (iterator.hasNext()) {
-                                       nextElement = iterator.next();
-                                       if (iteratorFilter.filterObject(nextElement)) {
-                                               gotNextElement = true;
-                                               break;
-                                       }
-                               }
-                       }
-
-                       /**
-                        * {@inheritDoc}
-                        *
-                        * @see java.util.Iterator#hasNext()
-                        */
-                       public boolean hasNext() {
-                               getNextElement();
-                               return gotNextElement;
-                       }
-
-                       /**
-                        * {@inheritDoc}
-                        *
-                        * @see java.util.Iterator#next()
-                        */
-                       public E next() {
-                               getNextElement();
-                               if (!gotNextElement) {
-                                       throw new NoSuchElementException("no more elements in iteration");
-                               }
-                               gotNextElement = false;
-                               return nextElement;
-                       }
-
-                       /**
-                        * {@inheritDoc}
-                        *
-                        * @see java.util.Iterator#remove()
-                        */
-                       public void remove() {
-                               throw new UnsupportedOperationException("remove() not supported on this iteration");
-                       }
-
-               };
-       }
-
-}
diff --git a/src/net/pterodactylus/util/thread/CurrentThreadExecutor.java b/src/net/pterodactylus/util/thread/CurrentThreadExecutor.java
deleted file mode 100644 (file)
index 71d236d..0000000
+++ /dev/null
@@ -1,38 +0,0 @@
-/*
- * jFCPlib - CurrentThreadExecutor.java - Copyright © 2009 David Roden
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-package net.pterodactylus.util.thread;
-
-import java.util.concurrent.Executor;
-
-/**
- * An {@link Executor} that executes {@link Runnable}s in the current thread.
- *
- * @author <a href="mailto:bombe@pterodactylus.net">David ‘Bombe’ Roden</a>
- */
-public class CurrentThreadExecutor implements Executor {
-
-       /**
-        * {@inheritDoc}
-        *
-        * @see java.util.concurrent.Executor#execute(java.lang.Runnable)
-        */
-       public void execute(Runnable command) {
-               command.run();
-       }
-
-}
diff --git a/src/net/pterodactylus/util/thread/ObjectWrapper.java b/src/net/pterodactylus/util/thread/ObjectWrapper.java
deleted file mode 100644 (file)
index a95ec21..0000000
+++ /dev/null
@@ -1,64 +0,0 @@
-/*
- * jFCPlib - UserObject.java - Copyright © 2009 David Roden
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- */
-
-package net.pterodactylus.util.thread;
-
-/**
- * Wrapper around an object that can be set and retrieved. Its primary use is as
- * a container for return values from anonymous classes.
- *
- * <pre>
- * final ObjectWrapper&lt;Object&gt; objectWrapper = new ObjectWrapper&lt;Object&gt;();
- * new Runnable() {
- *     public void run() {
- *         ...
- *         objectWrapper.set(someResult);
- *     }
- * }.run();
- * Object result = objectWrapper.get();
- * </pre>
- *
- * @param <T>
- *            The type of the wrapped object
- * @author David ‘Bombe’ Roden &lt;bombe@pterodactylus.net&gt;
- */
-public class ObjectWrapper<T> {
-
-       /** The wrapped object. */
-       private volatile T wrappedObject;
-
-       /**
-        * Returns the wrapped object.
-        *
-        * @return The wrapped object
-        */
-       public T get() {
-               return wrappedObject;
-       }
-
-       /**
-        * Sets the wrapped object.
-        *
-        * @param wrappedObject
-        *            The wrapped object
-        */
-       public void set(T wrappedObject) {
-               this.wrappedObject = wrappedObject;
-       }
-
-}
diff --git a/test/main/java/net/pterodactylus/fcp/FcpConnectionTest.java b/test/main/java/net/pterodactylus/fcp/FcpConnectionTest.java
new file mode 100644 (file)
index 0000000..b8b5bdf
--- /dev/null
@@ -0,0 +1,66 @@
+/*
+ * jFCPlib - FcpConnectionTest.java -
+ * Copyright © 2008 David Roden
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+package net.pterodactylus.fcp;
+
+import java.io.IOException;
+import java.io.InputStream;
+
+
+/**
+ * TODO
+ * @author David ‘Bombe’ Roden &lt;bombe@freenetproject.org&gt;
+ */
+public class FcpConnectionTest extends FcpAdapter {
+
+       public static void main(String[] commandLine) throws IllegalStateException, IOException {
+               new FcpConnectionTest();
+       }
+
+       private FcpConnectionTest() throws IllegalStateException, IOException {
+               FcpConnection fcpConnection = new FcpConnection("wing");
+               fcpConnection.addFcpListener(this);
+               fcpConnection.connect();
+               ClientHello clientHello = new ClientHello("bug-test");
+               fcpConnection.sendMessage(clientHello);
+               ClientGet clientGet = new ClientGet("KSK@gpl.txt", "test");
+               fcpConnection.sendMessage(clientGet);
+       }
+
+       /**
+        * {@inheritDoc}
+        */
+       public void receivedAllData(FcpConnection fcpConnection, AllData allData) {
+               System.out.println("AllData");
+               InputStream payloadInputStream = allData.getPayloadInputStream();
+               int r = 0;
+               byte[] buffer = new byte[1024];
+               try {
+                       while ((r = payloadInputStream.read(buffer)) != -1) {
+                               for (int i = 0; i < r; i++) {
+                                       System.out.print((char) buffer[i]);
+                               }
+                       }
+               } catch (IOException e) {
+                       // TODO Auto-generated catch block
+               }
+               fcpConnection.close();
+       }
+
+}
diff --git a/test/net/pterodactylus/fcp/FcpConnectionTest.java b/test/net/pterodactylus/fcp/FcpConnectionTest.java
deleted file mode 100644 (file)
index b8b5bdf..0000000
+++ /dev/null
@@ -1,66 +0,0 @@
-/*
- * jFCPlib - FcpConnectionTest.java -
- * Copyright © 2008 David Roden
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- */
-
-package net.pterodactylus.fcp;
-
-import java.io.IOException;
-import java.io.InputStream;
-
-
-/**
- * TODO
- * @author David ‘Bombe’ Roden &lt;bombe@freenetproject.org&gt;
- */
-public class FcpConnectionTest extends FcpAdapter {
-
-       public static void main(String[] commandLine) throws IllegalStateException, IOException {
-               new FcpConnectionTest();
-       }
-
-       private FcpConnectionTest() throws IllegalStateException, IOException {
-               FcpConnection fcpConnection = new FcpConnection("wing");
-               fcpConnection.addFcpListener(this);
-               fcpConnection.connect();
-               ClientHello clientHello = new ClientHello("bug-test");
-               fcpConnection.sendMessage(clientHello);
-               ClientGet clientGet = new ClientGet("KSK@gpl.txt", "test");
-               fcpConnection.sendMessage(clientGet);
-       }
-
-       /**
-        * {@inheritDoc}
-        */
-       public void receivedAllData(FcpConnection fcpConnection, AllData allData) {
-               System.out.println("AllData");
-               InputStream payloadInputStream = allData.getPayloadInputStream();
-               int r = 0;
-               byte[] buffer = new byte[1024];
-               try {
-                       while ((r = payloadInputStream.read(buffer)) != -1) {
-                               for (int i = 0; i < r; i++) {
-                                       System.out.print((char) buffer[i]);
-                               }
-                       }
-               } catch (IOException e) {
-                       // TODO Auto-generated catch block
-               }
-               fcpConnection.close();
-       }
-
-}