[freenet-cvs] r19264 - in branches/jFCPlib-1.4: . src src/net src/net/pterodactylus src/net/pterodactylus/fcp

bombe at freenetproject.org bombe at freenetproject.org
Sun Apr 13 14:24:08 UTC 2008


Author: bombe
Date: 2008-04-13 14:24:08 +0000 (Sun, 13 Apr 2008)
New Revision: 19264

Added:
   branches/jFCPlib-1.4/javadoc.xml
   branches/jFCPlib-1.4/src/
   branches/jFCPlib-1.4/src/net/
   branches/jFCPlib-1.4/src/net/pterodactylus/
   branches/jFCPlib-1.4/src/net/pterodactylus/fcp/
   branches/jFCPlib-1.4/src/net/pterodactylus/fcp/ARK.java
   branches/jFCPlib-1.4/src/net/pterodactylus/fcp/AddPeer.java
   branches/jFCPlib-1.4/src/net/pterodactylus/fcp/AllData.java
   branches/jFCPlib-1.4/src/net/pterodactylus/fcp/BaseMessage.java
   branches/jFCPlib-1.4/src/net/pterodactylus/fcp/ClientGet.java
   branches/jFCPlib-1.4/src/net/pterodactylus/fcp/ClientHello.java
   branches/jFCPlib-1.4/src/net/pterodactylus/fcp/ClientPut.java
   branches/jFCPlib-1.4/src/net/pterodactylus/fcp/ClientPutComplexDir.java
   branches/jFCPlib-1.4/src/net/pterodactylus/fcp/ClientPutDiskDir.java
   branches/jFCPlib-1.4/src/net/pterodactylus/fcp/CloseConnectionDuplicateClientName.java
   branches/jFCPlib-1.4/src/net/pterodactylus/fcp/ConfigData.java
   branches/jFCPlib-1.4/src/net/pterodactylus/fcp/DSAGroup.java
   branches/jFCPlib-1.4/src/net/pterodactylus/fcp/DataFound.java
   branches/jFCPlib-1.4/src/net/pterodactylus/fcp/EndListPeerNotes.java
   branches/jFCPlib-1.4/src/net/pterodactylus/fcp/EndListPeers.java
   branches/jFCPlib-1.4/src/net/pterodactylus/fcp/EndListPersistentRequests.java
   branches/jFCPlib-1.4/src/net/pterodactylus/fcp/FCPPluginMessage.java
   branches/jFCPlib-1.4/src/net/pterodactylus/fcp/FCPPluginReply.java
   branches/jFCPlib-1.4/src/net/pterodactylus/fcp/FcpAdapter.java
   branches/jFCPlib-1.4/src/net/pterodactylus/fcp/FcpConnection.java
   branches/jFCPlib-1.4/src/net/pterodactylus/fcp/FcpConnectionHandler.java
   branches/jFCPlib-1.4/src/net/pterodactylus/fcp/FcpKeyPair.java
   branches/jFCPlib-1.4/src/net/pterodactylus/fcp/FcpListener.java
   branches/jFCPlib-1.4/src/net/pterodactylus/fcp/FcpMessage.java
   branches/jFCPlib-1.4/src/net/pterodactylus/fcp/FcpTest.java
   branches/jFCPlib-1.4/src/net/pterodactylus/fcp/FcpUtils.java
   branches/jFCPlib-1.4/src/net/pterodactylus/fcp/FileEntry.java
   branches/jFCPlib-1.4/src/net/pterodactylus/fcp/FinishedCompression.java
   branches/jFCPlib-1.4/src/net/pterodactylus/fcp/GenerateSSK.java
   branches/jFCPlib-1.4/src/net/pterodactylus/fcp/GetConfig.java
   branches/jFCPlib-1.4/src/net/pterodactylus/fcp/GetFailed.java
   branches/jFCPlib-1.4/src/net/pterodactylus/fcp/GetNode.java
   branches/jFCPlib-1.4/src/net/pterodactylus/fcp/GetPluginInfo.java
   branches/jFCPlib-1.4/src/net/pterodactylus/fcp/GetRequestStatus.java
   branches/jFCPlib-1.4/src/net/pterodactylus/fcp/IdentifierCollision.java
   branches/jFCPlib-1.4/src/net/pterodactylus/fcp/ListPeer.java
   branches/jFCPlib-1.4/src/net/pterodactylus/fcp/ListPeerNotes.java
   branches/jFCPlib-1.4/src/net/pterodactylus/fcp/ListPeers.java
   branches/jFCPlib-1.4/src/net/pterodactylus/fcp/ListPersistentRequests.java
   branches/jFCPlib-1.4/src/net/pterodactylus/fcp/ModifyConfig.java
   branches/jFCPlib-1.4/src/net/pterodactylus/fcp/ModifyPeer.java
   branches/jFCPlib-1.4/src/net/pterodactylus/fcp/ModifyPeerNote.java
   branches/jFCPlib-1.4/src/net/pterodactylus/fcp/ModifyPersistentRequest.java
   branches/jFCPlib-1.4/src/net/pterodactylus/fcp/NodeData.java
   branches/jFCPlib-1.4/src/net/pterodactylus/fcp/NodeHello.java
   branches/jFCPlib-1.4/src/net/pterodactylus/fcp/NodeRef.java
   branches/jFCPlib-1.4/src/net/pterodactylus/fcp/Peer.java
   branches/jFCPlib-1.4/src/net/pterodactylus/fcp/PeerNote.java
   branches/jFCPlib-1.4/src/net/pterodactylus/fcp/PeerRemoved.java
   branches/jFCPlib-1.4/src/net/pterodactylus/fcp/Persistence.java
   branches/jFCPlib-1.4/src/net/pterodactylus/fcp/PersistentGet.java
   branches/jFCPlib-1.4/src/net/pterodactylus/fcp/PersistentPut.java
   branches/jFCPlib-1.4/src/net/pterodactylus/fcp/PersistentPutDir.java
   branches/jFCPlib-1.4/src/net/pterodactylus/fcp/PersistentRequestModified.java
   branches/jFCPlib-1.4/src/net/pterodactylus/fcp/PersistentRequestRemoved.java
   branches/jFCPlib-1.4/src/net/pterodactylus/fcp/PluginInfo.java
   branches/jFCPlib-1.4/src/net/pterodactylus/fcp/Priority.java
   branches/jFCPlib-1.4/src/net/pterodactylus/fcp/ProtocolError.java
   branches/jFCPlib-1.4/src/net/pterodactylus/fcp/PutFailed.java
   branches/jFCPlib-1.4/src/net/pterodactylus/fcp/PutFetchable.java
   branches/jFCPlib-1.4/src/net/pterodactylus/fcp/PutSuccessful.java
   branches/jFCPlib-1.4/src/net/pterodactylus/fcp/RemovePeer.java
   branches/jFCPlib-1.4/src/net/pterodactylus/fcp/RemovePersistentRequest.java
   branches/jFCPlib-1.4/src/net/pterodactylus/fcp/ReturnType.java
   branches/jFCPlib-1.4/src/net/pterodactylus/fcp/SSKKeypair.java
   branches/jFCPlib-1.4/src/net/pterodactylus/fcp/Shutdown.java
   branches/jFCPlib-1.4/src/net/pterodactylus/fcp/SimpleProgress.java
   branches/jFCPlib-1.4/src/net/pterodactylus/fcp/StartedCompression.java
   branches/jFCPlib-1.4/src/net/pterodactylus/fcp/SubscribeUSK.java
   branches/jFCPlib-1.4/src/net/pterodactylus/fcp/SubscribedUSKUpdate.java
   branches/jFCPlib-1.4/src/net/pterodactylus/fcp/TestDDAComplete.java
   branches/jFCPlib-1.4/src/net/pterodactylus/fcp/TestDDAReply.java
   branches/jFCPlib-1.4/src/net/pterodactylus/fcp/TestDDARequest.java
   branches/jFCPlib-1.4/src/net/pterodactylus/fcp/TestDDAResponse.java
   branches/jFCPlib-1.4/src/net/pterodactylus/fcp/URIGenerated.java
   branches/jFCPlib-1.4/src/net/pterodactylus/fcp/UnknownNodeIdentifier.java
   branches/jFCPlib-1.4/src/net/pterodactylus/fcp/UnknownPeerNoteType.java
   branches/jFCPlib-1.4/src/net/pterodactylus/fcp/UploadFrom.java
   branches/jFCPlib-1.4/src/net/pterodactylus/fcp/Verbosity.java
   branches/jFCPlib-1.4/src/net/pterodactylus/fcp/Version.java
   branches/jFCPlib-1.4/src/net/pterodactylus/fcp/WatchGlobal.java
   branches/jFCPlib-1.4/src/net/pterodactylus/fcp/package-info.java
Modified:
   branches/jFCPlib-1.4/
Log:
add sources


Property changes on: branches/jFCPlib-1.4
___________________________________________________________________
Name: svn:ignore
   + doc


Added: branches/jFCPlib-1.4/javadoc.xml
===================================================================
--- branches/jFCPlib-1.4/javadoc.xml	                        (rev 0)
+++ branches/jFCPlib-1.4/javadoc.xml	2008-04-13 14:24:08 UTC (rev 19264)
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project default="javadoc">
+	<target name="javadoc">
+		<javadoc access="public" author="true" destdir="doc/api" nodeprecated="false" nodeprecatedlist="false" noindex="false" nonavbar="false" notree="false" packagenames="net.pterodactylus.fcp" source="1.4" sourcepath="src" splitindex="true" use="true" version="true" encoding="utf-8" docencoding="utf-8" charset="utf-8" Windowtitle="pterodactylus.net FCP library" Footer="© 2008 by &lt;a href=&quot;mailto:bombe at freenetproject.org&quot;&gt;David ‘Bombe’ Roden&lt;/a&gt;">
+			<link href="http://java.sun.com/j2se/1.4.2/docs/api/" />
+		</javadoc>
+	</target>
+</project>

Added: branches/jFCPlib-1.4/src/net/pterodactylus/fcp/ARK.java
===================================================================
--- branches/jFCPlib-1.4/src/net/pterodactylus/fcp/ARK.java	                        (rev 0)
+++ branches/jFCPlib-1.4/src/net/pterodactylus/fcp/ARK.java	2008-04-13 14:24:08 UTC (rev 19264)
@@ -0,0 +1,101 @@
+/*
+ * jSite2 - 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 at freenetproject.org&gt;
+ * @version $Id$
+ */
+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).intValue();
+		} catch (NumberFormatException nfe1) {
+			throw new IllegalArgumentException("number must be numeric");
+		}
+	}
+
+	/**
+	 * 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;
+	}
+
+}
\ No newline at end of file


Property changes on: branches/jFCPlib-1.4/src/net/pterodactylus/fcp/ARK.java
___________________________________________________________________
Name: svn:keywords
   + Id

Added: branches/jFCPlib-1.4/src/net/pterodactylus/fcp/AddPeer.java
===================================================================
--- branches/jFCPlib-1.4/src/net/pterodactylus/fcp/AddPeer.java	                        (rev 0)
+++ branches/jFCPlib-1.4/src/net/pterodactylus/fcp/AddPeer.java	2008-04-13 14:24:08 UTC (rev 19264)
@@ -0,0 +1,103 @@
+/*
+ * jSite2 - 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 at freenetproject.org&gt;
+ * @version $Id$
+ */
+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());
+	}
+
+}


Property changes on: branches/jFCPlib-1.4/src/net/pterodactylus/fcp/AddPeer.java
___________________________________________________________________
Name: svn:keywords
   + Id

Added: branches/jFCPlib-1.4/src/net/pterodactylus/fcp/AllData.java
===================================================================
--- branches/jFCPlib-1.4/src/net/pterodactylus/fcp/AllData.java	                        (rev 0)
+++ branches/jFCPlib-1.4/src/net/pterodactylus/fcp/AllData.java	2008-04-13 14:24:08 UTC (rev 19264)
@@ -0,0 +1,102 @@
+/*
+ * jSite2 - 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 <a href="mailto:dr at ina-germany.de">David Roden</a>
+ * @version $Id$
+ */
+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.
+	 * 
+	 * @return The payload
+	 */
+	public InputStream getPayloadInputStream() {
+		return payloadInputStream;
+	}
+
+}


Property changes on: branches/jFCPlib-1.4/src/net/pterodactylus/fcp/AllData.java
___________________________________________________________________
Name: svn:keywords
   + Id

Added: branches/jFCPlib-1.4/src/net/pterodactylus/fcp/BaseMessage.java
===================================================================
--- branches/jFCPlib-1.4/src/net/pterodactylus/fcp/BaseMessage.java	                        (rev 0)
+++ branches/jFCPlib-1.4/src/net/pterodactylus/fcp/BaseMessage.java	2008-04-13 14:24:08 UTC (rev 19264)
@@ -0,0 +1,76 @@
+/*
+ * jSite2 - 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 at freenetproject.org&gt;
+ * @version $Id$
+ */
+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 getFields() {
+		return receivedMessage.getFields();
+	}
+
+}


Property changes on: branches/jFCPlib-1.4/src/net/pterodactylus/fcp/BaseMessage.java
___________________________________________________________________
Name: svn:keywords
   + Id

Added: branches/jFCPlib-1.4/src/net/pterodactylus/fcp/ClientGet.java
===================================================================
--- branches/jFCPlib-1.4/src/net/pterodactylus/fcp/ClientGet.java	                        (rev 0)
+++ branches/jFCPlib-1.4/src/net/pterodactylus/fcp/ClientGet.java	2008-04-13 14:24:08 UTC (rev 19264)
@@ -0,0 +1,212 @@
+/*
+ * jSite2 - 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 at freenetproject.org&gt;
+ * @version $Id$
+ */
+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);
+	}
+
+}


Property changes on: branches/jFCPlib-1.4/src/net/pterodactylus/fcp/ClientGet.java
___________________________________________________________________
Name: svn:keywords
   + Id

Added: branches/jFCPlib-1.4/src/net/pterodactylus/fcp/ClientHello.java
===================================================================
--- branches/jFCPlib-1.4/src/net/pterodactylus/fcp/ClientHello.java	                        (rev 0)
+++ branches/jFCPlib-1.4/src/net/pterodactylus/fcp/ClientHello.java	2008-04-13 14:24:08 UTC (rev 19264)
@@ -0,0 +1,60 @@
+/*
+ * jSite2 - 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 at freenetproject.org&gt;
+ * @version $Id$
+ */
+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);
+	}
+
+}


Property changes on: branches/jFCPlib-1.4/src/net/pterodactylus/fcp/ClientHello.java
___________________________________________________________________
Name: svn:keywords
   + Id

Added: branches/jFCPlib-1.4/src/net/pterodactylus/fcp/ClientPut.java
===================================================================
--- branches/jFCPlib-1.4/src/net/pterodactylus/fcp/ClientPut.java	                        (rev 0)
+++ branches/jFCPlib-1.4/src/net/pterodactylus/fcp/ClientPut.java	2008-04-13 14:24:08 UTC (rev 19264)
@@ -0,0 +1,233 @@
+/*
+ * jSite2 - 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 at freenetproject.org&gt;
+ * @version $Id$
+ */
+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);
+	}
+
+}


Property changes on: branches/jFCPlib-1.4/src/net/pterodactylus/fcp/ClientPut.java
___________________________________________________________________
Name: svn:keywords
   + Id

Added: branches/jFCPlib-1.4/src/net/pterodactylus/fcp/ClientPutComplexDir.java
===================================================================
--- branches/jFCPlib-1.4/src/net/pterodactylus/fcp/ClientPutComplexDir.java	                        (rev 0)
+++ branches/jFCPlib-1.4/src/net/pterodactylus/fcp/ClientPutComplexDir.java	2008-04-13 14:24:08 UTC (rev 19264)
@@ -0,0 +1,223 @@
+/*
+ * jSite2 - 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.Iterator;
+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 at freenetproject.org&gt;
+ * @version $Id$
+ */
+public class ClientPutComplexDir extends FcpMessage {
+
+	/** The index for added file entries. */
+	private int fileIndex = 0;
+
+	/** The input streams from {@link FileEntry.DirectFileEntry}s. */
+	private final List directFileInputStreams = new ArrayList();
+
+	/**
+	 * 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 fields = fileEntry.getFields();
+		Iterator entrySetIterator = fields.entrySet().iterator();
+		while (entrySetIterator.hasNext()) {
+			Entry fieldEntry = (Entry) entrySetIterator.next();
+			setField("Files." + fileIndex + "." + fieldEntry.getKey(), (String) 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!
+	 */
+	public void setPayloadInputStream(InputStream payloadInputStream) {
+		/* do nothing. */
+	}
+
+	/**
+	 * {@inheritDoc}
+	 */
+	public void write(OutputStream outputStream) throws IOException {
+		/* create payload stream. */
+		setPayloadInputStream(new SequenceInputStream(Collections.enumeration(directFileInputStreams)));
+		/* write out all the fields. */
+		super.write(outputStream);
+	}
+
+}


Property changes on: branches/jFCPlib-1.4/src/net/pterodactylus/fcp/ClientPutComplexDir.java
___________________________________________________________________
Name: svn:keywords
   + Id

Added: branches/jFCPlib-1.4/src/net/pterodactylus/fcp/ClientPutDiskDir.java
===================================================================
--- branches/jFCPlib-1.4/src/net/pterodactylus/fcp/ClientPutDiskDir.java	                        (rev 0)
+++ branches/jFCPlib-1.4/src/net/pterodactylus/fcp/ClientPutDiskDir.java	2008-04-13 14:24:08 UTC (rev 19264)
@@ -0,0 +1,162 @@
+/*
+ * jSite2 - 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 at freenetproject.org&gt;
+ * @version $Id$
+ */
+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));
+	}
+
+}


Property changes on: branches/jFCPlib-1.4/src/net/pterodactylus/fcp/ClientPutDiskDir.java
___________________________________________________________________
Name: svn:keywords
   + Id

Added: branches/jFCPlib-1.4/src/net/pterodactylus/fcp/CloseConnectionDuplicateClientName.java
===================================================================
--- branches/jFCPlib-1.4/src/net/pterodactylus/fcp/CloseConnectionDuplicateClientName.java	                        (rev 0)
+++ branches/jFCPlib-1.4/src/net/pterodactylus/fcp/CloseConnectionDuplicateClientName.java	2008-04-13 14:24:08 UTC (rev 19264)
@@ -0,0 +1,42 @@
+/*
+ * jSite2 - 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 at freenetproject.org&gt;
+ * @version $Id: CloseConnectionDuplicateClientName.java 712 2008-04-11
+ *          09:50:44Z bombe $
+ */
+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);
+	}
+
+}


Property changes on: branches/jFCPlib-1.4/src/net/pterodactylus/fcp/CloseConnectionDuplicateClientName.java
___________________________________________________________________
Name: svn:keywords
   + Id

Added: branches/jFCPlib-1.4/src/net/pterodactylus/fcp/ConfigData.java
===================================================================
--- branches/jFCPlib-1.4/src/net/pterodactylus/fcp/ConfigData.java	                        (rev 0)
+++ branches/jFCPlib-1.4/src/net/pterodactylus/fcp/ConfigData.java	2008-04-13 14:24:08 UTC (rev 19264)
@@ -0,0 +1,130 @@
+/*
+ * jSite2 - 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 at freenetproject.org&gt;
+ * @version $Id$
+ */
+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)).booleanValue();
+	}
+
+	/**
+	 * 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)).booleanValue();
+	}
+
+}


Property changes on: branches/jFCPlib-1.4/src/net/pterodactylus/fcp/ConfigData.java
___________________________________________________________________
Name: svn:keywords
   + Id

Added: branches/jFCPlib-1.4/src/net/pterodactylus/fcp/DSAGroup.java
===================================================================
--- branches/jFCPlib-1.4/src/net/pterodactylus/fcp/DSAGroup.java	                        (rev 0)
+++ branches/jFCPlib-1.4/src/net/pterodactylus/fcp/DSAGroup.java	2008-04-13 14:24:08 UTC (rev 19264)
@@ -0,0 +1,87 @@
+/*
+ * jSite2 - 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 at freenetproject.org&gt;
+ * @version $Id$
+ */
+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;
+	}
+
+}
\ No newline at end of file


Property changes on: branches/jFCPlib-1.4/src/net/pterodactylus/fcp/DSAGroup.java
___________________________________________________________________
Name: svn:keywords
   + Id

Added: branches/jFCPlib-1.4/src/net/pterodactylus/fcp/DataFound.java
===================================================================
--- branches/jFCPlib-1.4/src/net/pterodactylus/fcp/DataFound.java	                        (rev 0)
+++ branches/jFCPlib-1.4/src/net/pterodactylus/fcp/DataFound.java	2008-04-13 14:24:08 UTC (rev 19264)
@@ -0,0 +1,79 @@
+/*
+ * jSite2 - 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 at freenetproject.org&gt;
+ * @version $Id$
+ */
+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")).booleanValue();
+	}
+
+	/**
+	 * 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"));
+	}
+
+}


Property changes on: branches/jFCPlib-1.4/src/net/pterodactylus/fcp/DataFound.java
___________________________________________________________________
Name: svn:keywords
   + Id

Added: branches/jFCPlib-1.4/src/net/pterodactylus/fcp/EndListPeerNotes.java
===================================================================
--- branches/jFCPlib-1.4/src/net/pterodactylus/fcp/EndListPeerNotes.java	                        (rev 0)
+++ branches/jFCPlib-1.4/src/net/pterodactylus/fcp/EndListPeerNotes.java	2008-04-13 14:24:08 UTC (rev 19264)
@@ -0,0 +1,41 @@
+/*
+ * jSite2 - 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 at freenetproject.org&gt;
+ * @version $Id$
+ */
+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);
+	}
+
+}


Property changes on: branches/jFCPlib-1.4/src/net/pterodactylus/fcp/EndListPeerNotes.java
___________________________________________________________________
Name: svn:keywords
   + Id

Added: branches/jFCPlib-1.4/src/net/pterodactylus/fcp/EndListPeers.java
===================================================================
--- branches/jFCPlib-1.4/src/net/pterodactylus/fcp/EndListPeers.java	                        (rev 0)
+++ branches/jFCPlib-1.4/src/net/pterodactylus/fcp/EndListPeers.java	2008-04-13 14:24:08 UTC (rev 19264)
@@ -0,0 +1,40 @@
+/*
+ * jSite2 - 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 at freenetproject.org&gt;
+ * @version $Id$
+ */
+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);
+	}
+
+}


Property changes on: branches/jFCPlib-1.4/src/net/pterodactylus/fcp/EndListPeers.java
___________________________________________________________________
Name: svn:keywords
   + Id

Added: branches/jFCPlib-1.4/src/net/pterodactylus/fcp/EndListPersistentRequests.java
===================================================================
--- branches/jFCPlib-1.4/src/net/pterodactylus/fcp/EndListPersistentRequests.java	                        (rev 0)
+++ branches/jFCPlib-1.4/src/net/pterodactylus/fcp/EndListPersistentRequests.java	2008-04-13 14:24:08 UTC (rev 19264)
@@ -0,0 +1,42 @@
+/*
+ * jSite2 - 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 at freenetproject.org&gt;
+ * @version $Id$
+ */
+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);
+	}
+
+}


Property changes on: branches/jFCPlib-1.4/src/net/pterodactylus/fcp/EndListPersistentRequests.java
___________________________________________________________________
Name: svn:keywords
   + Id

Added: branches/jFCPlib-1.4/src/net/pterodactylus/fcp/FCPPluginMessage.java
===================================================================
--- branches/jFCPlib-1.4/src/net/pterodactylus/fcp/FCPPluginMessage.java	                        (rev 0)
+++ branches/jFCPlib-1.4/src/net/pterodactylus/fcp/FCPPluginMessage.java	2008-04-13 14:24:08 UTC (rev 19264)
@@ -0,0 +1,77 @@
+/*
+ * jSite2 - 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 at freenetproject.org&gt;
+ * @version $Id$
+ */
+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));
+	}
+
+}


Property changes on: branches/jFCPlib-1.4/src/net/pterodactylus/fcp/FCPPluginMessage.java
___________________________________________________________________
Name: svn:keywords
   + Id

Added: branches/jFCPlib-1.4/src/net/pterodactylus/fcp/FCPPluginReply.java
===================================================================
--- branches/jFCPlib-1.4/src/net/pterodactylus/fcp/FCPPluginReply.java	                        (rev 0)
+++ branches/jFCPlib-1.4/src/net/pterodactylus/fcp/FCPPluginReply.java	2008-04-13 14:24:08 UTC (rev 19264)
@@ -0,0 +1,98 @@
+/*
+ * jSite2 - 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;
+
+/**
+ * The “FCPPluginReply” is sent by a plugin as a response to a
+ * {@link FCPPluginMessage} message.
+ * 
+ * @author David ‘Bombe’ Roden &lt;bombe at freenetproject.org&gt;
+ * @version $Id$
+ */
+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 the optional payload.
+	 * 
+	 * @return The payload of the reply, or <code>null</code> if there is no
+	 *         payload
+	 */
+	public InputStream getPayloadInputStream() {
+		return payloadInputStream;
+	}
+
+}


Property changes on: branches/jFCPlib-1.4/src/net/pterodactylus/fcp/FCPPluginReply.java
___________________________________________________________________
Name: svn:keywords
   + Id

Added: branches/jFCPlib-1.4/src/net/pterodactylus/fcp/FcpAdapter.java
===================================================================
--- branches/jFCPlib-1.4/src/net/pterodactylus/fcp/FcpAdapter.java	                        (rev 0)
+++ branches/jFCPlib-1.4/src/net/pterodactylus/fcp/FcpAdapter.java	2008-04-13 14:24:08 UTC (rev 19264)
@@ -0,0 +1,293 @@
+/*
+ * jSite2 - 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 at freenetproject.org&gt;
+ * @version $Id$
+ */
+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 receviedFinishedCompression(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 receivedMessage(FcpConnection fcpConnection, FcpMessage fcpMessage) {
+		/* empty. */
+	}
+
+	/**
+	 * {@inheritDoc}
+	 */
+	public void connectionClosed(FcpConnection fcpConnection) {
+		/* empty. */
+	}
+
+}


Property changes on: branches/jFCPlib-1.4/src/net/pterodactylus/fcp/FcpAdapter.java
___________________________________________________________________
Name: svn:keywords
   + Id

Added: branches/jFCPlib-1.4/src/net/pterodactylus/fcp/FcpConnection.java
===================================================================
--- branches/jFCPlib-1.4/src/net/pterodactylus/fcp/FcpConnection.java	                        (rev 0)
+++ branches/jFCPlib-1.4/src/net/pterodactylus/fcp/FcpConnection.java	2008-04-13 14:24:08 UTC (rev 19264)
@@ -0,0 +1,966 @@
+/*
+ * jSite2 - 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.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.ArrayList;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * An FCP connection to a Freenet node.
+ * 
+ * @author David ‘Bombe’ Roden &lt;bombe at freenetproject.org&gt;
+ * @version $Id$
+ */
+public class FcpConnection {
+
+	/** The default port for FCP v2. */
+	public static final int DEFAULT_PORT = 9481;
+
+	/** The list of FCP listeners. */
+	private final List fcpListeners = new ArrayList();
+
+	/** 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 incomingMessageStatistics = Collections.synchronizedMap(new HashMap());
+
+	/**
+	 * 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) {
+		fcpListeners.add(fcpListener);
+	}
+
+	/**
+	 * Removes the given listener from the list of listeners.
+	 * 
+	 * @param fcpListener
+	 *            The listener to remove
+	 */
+	public void removeFcpListener(FcpListener fcpListener) {
+		fcpListeners.remove(fcpListener);
+	}
+
+	/**
+	 * Notifies listeners that a “NodeHello” message was received.
+	 * 
+	 * @see FcpListener#receivedNodeHello(FcpConnection, NodeHello)
+	 * @param nodeHello
+	 *            The “NodeHello” message
+	 */
+	private void fireReceivedNodeHello(NodeHello nodeHello) {
+		for (int fcpListenerIndex = 0, fcpListenerCount = fcpListeners.size(); fcpListenerIndex < fcpListenerCount; fcpListenerIndex++) {
+			((FcpListener) fcpListeners.get(fcpListenerIndex)).receivedNodeHello(this, nodeHello);
+		}
+	}
+
+	/**
+	 * Notifies listeners that a “CloseConnectionDuplicateClientName” message
+	 * was received.
+	 * 
+	 * @see FcpListener#receivedCloseConnectionDuplicateClientName(FcpConnection,
+	 *      CloseConnectionDuplicateClientName)
+	 * @param closeConnectionDuplicateClientName
+	 *            The “CloseConnectionDuplicateClientName” message
+	 */
+	private void fireReceivedCloseConnectionDuplicateClientName(CloseConnectionDuplicateClientName closeConnectionDuplicateClientName) {
+		for (int fcpListenerIndex = 0, fcpListenerCount = fcpListeners.size(); fcpListenerIndex < fcpListenerCount; fcpListenerIndex++) {
+			((FcpListener) fcpListeners.get(fcpListenerIndex)).receivedCloseConnectionDuplicateClientName(this, closeConnectionDuplicateClientName);
+		}
+	}
+
+	/**
+	 * Notifies listeners that a “SSKKeypair” message was received.
+	 * 
+	 * @see FcpListener#receivedSSKKeypair(FcpConnection, SSKKeypair)
+	 * @param sskKeypair
+	 *            The “SSKKeypair” message
+	 */
+	private void fireReceivedSSKKeypair(SSKKeypair sskKeypair) {
+		for (int fcpListenerIndex = 0, fcpListenerCount = fcpListeners.size(); fcpListenerIndex < fcpListenerCount; fcpListenerIndex++) {
+			((FcpListener) fcpListeners.get(fcpListenerIndex)).receivedSSKKeypair(this, sskKeypair);
+		}
+	}
+
+	/**
+	 * Notifies listeners that a “Peer” message was received.
+	 * 
+	 * @see FcpListener#receivedPeer(FcpConnection, Peer)
+	 * @param peer
+	 *            The “Peer” message
+	 */
+	private void fireReceivedPeer(Peer peer) {
+		for (int fcpListenerIndex = 0, fcpListenerCount = fcpListeners.size(); fcpListenerIndex < fcpListenerCount; fcpListenerIndex++) {
+			((FcpListener) fcpListeners.get(fcpListenerIndex)).receivedPeer(this, peer);
+		}
+	}
+
+	/**
+	 * Notifies all listeners that an “EndListPeers” message was received.
+	 * 
+	 * @see FcpListener#receivedEndListPeers(FcpConnection, EndListPeers)
+	 * @param endListPeers
+	 *            The “EndListPeers” message
+	 */
+	private void fireReceivedEndListPeers(EndListPeers endListPeers) {
+		for (int fcpListenerIndex = 0, fcpListenerCount = fcpListeners.size(); fcpListenerIndex < fcpListenerCount; fcpListenerIndex++) {
+			((FcpListener) fcpListeners.get(fcpListenerIndex)).receivedEndListPeers(this, endListPeers);
+		}
+	}
+
+	/**
+	 * Notifies all listeners that a “PeerNote” message was received.
+	 * 
+	 * @see FcpListener#receivedPeerNote(FcpConnection, PeerNote)
+	 * @param peerNote
+	 */
+	private void fireReceivedPeerNote(PeerNote peerNote) {
+		for (int fcpListenerIndex = 0, fcpListenerCount = fcpListeners.size(); fcpListenerIndex < fcpListenerCount; fcpListenerIndex++) {
+			((FcpListener) fcpListeners.get(fcpListenerIndex)).receivedPeerNote(this, peerNote);
+		}
+	}
+
+	/**
+	 * Notifies all listeners that an “EndListPeerNotes” message was received.
+	 * 
+	 * @see FcpListener#receivedEndListPeerNotes(FcpConnection,
+	 *      EndListPeerNotes)
+	 * @param endListPeerNotes
+	 *            The “EndListPeerNotes” message
+	 */
+	private void fireReceivedEndListPeerNotes(EndListPeerNotes endListPeerNotes) {
+		for (int fcpListenerIndex = 0, fcpListenerCount = fcpListeners.size(); fcpListenerIndex < fcpListenerCount; fcpListenerIndex++) {
+			((FcpListener) fcpListeners.get(fcpListenerIndex)).receivedEndListPeerNotes(this, endListPeerNotes);
+		}
+	}
+
+	/**
+	 * Notifies all listeners that a “PeerRemoved” message was received.
+	 * 
+	 * @see FcpListener#receivedPeerRemoved(FcpConnection, PeerRemoved)
+	 * @param peerRemoved
+	 *            The “PeerRemoved” message
+	 */
+	private void fireReceivedPeerRemoved(PeerRemoved peerRemoved) {
+		for (int fcpListenerIndex = 0, fcpListenerCount = fcpListeners.size(); fcpListenerIndex < fcpListenerCount; fcpListenerIndex++) {
+			((FcpListener) fcpListeners.get(fcpListenerIndex)).receivedPeerRemoved(this, peerRemoved);
+		}
+	}
+
+	/**
+	 * Notifies all listeners that a “NodeData” message was received.
+	 * 
+	 * @see FcpListener#receivedNodeData(FcpConnection, NodeData)
+	 * @param nodeData
+	 *            The “NodeData” message
+	 */
+	private void fireReceivedNodeData(NodeData nodeData) {
+		for (int fcpListenerIndex = 0, fcpListenerCount = fcpListeners.size(); fcpListenerIndex < fcpListenerCount; fcpListenerIndex++) {
+			((FcpListener) fcpListeners.get(fcpListenerIndex)).receivedNodeData(this, nodeData);
+		}
+	}
+
+	/**
+	 * Notifies all listeners that a “TestDDAReply” message was received.
+	 * 
+	 * @see FcpListener#receivedTestDDAReply(FcpConnection, TestDDAReply)
+	 * @param testDDAReply
+	 *            The “TestDDAReply” message
+	 */
+	private void fireReceivedTestDDAReply(TestDDAReply testDDAReply) {
+		for (int fcpListenerIndex = 0, fcpListenerCount = fcpListeners.size(); fcpListenerIndex < fcpListenerCount; fcpListenerIndex++) {
+			((FcpListener) fcpListeners.get(fcpListenerIndex)).receivedTestDDAReply(this, testDDAReply);
+		}
+	}
+
+	/**
+	 * Notifies all listeners that a “TestDDAComplete” message was received.
+	 * 
+	 * @see FcpListener#receivedTestDDAComplete(FcpConnection, TestDDAComplete)
+	 * @param testDDAComplete
+	 *            The “TestDDAComplete” message
+	 */
+	private void fireReceivedTestDDAComplete(TestDDAComplete testDDAComplete) {
+		for (int fcpListenerIndex = 0, fcpListenerCount = fcpListeners.size(); fcpListenerIndex < fcpListenerCount; fcpListenerIndex++) {
+			((FcpListener) fcpListeners.get(fcpListenerIndex)).receivedTestDDAComplete(this, testDDAComplete);
+		}
+	}
+
+	/**
+	 * Notifies all listeners that a “PersistentGet” message was received.
+	 * 
+	 * @see FcpListener#receivedPersistentGet(FcpConnection, PersistentGet)
+	 * @param persistentGet
+	 *            The “PersistentGet” message
+	 */
+	private void fireReceivedPersistentGet(PersistentGet persistentGet) {
+		for (int fcpListenerIndex = 0, fcpListenerCount = fcpListeners.size(); fcpListenerIndex < fcpListenerCount; fcpListenerIndex++) {
+			((FcpListener) fcpListeners.get(fcpListenerIndex)).receivedPersistentGet(this, persistentGet);
+		}
+	}
+
+	/**
+	 * Notifies all listeners that a “PersistentPut” message was received.
+	 * 
+	 * @see FcpListener#receivedPersistentPut(FcpConnection, PersistentPut)
+	 * @param persistentPut
+	 *            The “PersistentPut” message
+	 */
+	private void fireReceivedPersistentPut(PersistentPut persistentPut) {
+		for (int fcpListenerIndex = 0, fcpListenerCount = fcpListeners.size(); fcpListenerIndex < fcpListenerCount; fcpListenerIndex++) {
+			((FcpListener) fcpListeners.get(fcpListenerIndex)).receivedPersistentPut(this, persistentPut);
+		}
+	}
+
+	/**
+	 * Notifies all listeners that a “EndListPersistentRequests” message was
+	 * received.
+	 * 
+	 * @see FcpListener#receivedEndListPersistentRequests(FcpConnection,
+	 *      EndListPersistentRequests)
+	 * @param endListPersistentRequests
+	 *            The “EndListPersistentRequests” message
+	 */
+	private void fireReceivedEndListPersistentRequests(EndListPersistentRequests endListPersistentRequests) {
+		for (int fcpListenerIndex = 0, fcpListenerCount = fcpListeners.size(); fcpListenerIndex < fcpListenerCount; fcpListenerIndex++) {
+			((FcpListener) fcpListeners.get(fcpListenerIndex)).receivedEndListPersistentRequests(this, endListPersistentRequests);
+		}
+	}
+
+	/**
+	 * Notifies all listeners that a “URIGenerated” message was received.
+	 * 
+	 * @see FcpListener#receivedURIGenerated(FcpConnection, URIGenerated)
+	 * @param uriGenerated
+	 *            The “URIGenerated” message
+	 */
+	private void fireReceivedURIGenerated(URIGenerated uriGenerated) {
+		for (int fcpListenerIndex = 0, fcpListenerCount = fcpListeners.size(); fcpListenerIndex < fcpListenerCount; fcpListenerIndex++) {
+			((FcpListener) fcpListeners.get(fcpListenerIndex)).receivedURIGenerated(this, uriGenerated);
+		}
+	}
+
+	/**
+	 * Notifies all listeners that a “DataFound” message was received.
+	 * 
+	 * @see FcpListener#receivedDataFound(FcpConnection, DataFound)
+	 * @param dataFound
+	 *            The “DataFound” message
+	 */
+	private void fireReceivedDataFound(DataFound dataFound) {
+		for (int fcpListenerIndex = 0, fcpListenerCount = fcpListeners.size(); fcpListenerIndex < fcpListenerCount; fcpListenerIndex++) {
+			((FcpListener) fcpListeners.get(fcpListenerIndex)).receivedDataFound(this, dataFound);
+		}
+	}
+
+	/**
+	 * Notifies all listeners that an “AllData” message was received.
+	 * 
+	 * @see FcpListener#receivedAllData(FcpConnection, AllData)
+	 * @param allData
+	 *            The “AllData” message
+	 */
+	private void fireReceivedAllData(AllData allData) {
+		for (int fcpListenerIndex = 0, fcpListenerCount = fcpListeners.size(); fcpListenerIndex < fcpListenerCount; fcpListenerIndex++) {
+			((FcpListener) fcpListeners.get(fcpListenerIndex)).receivedAllData(this, allData);
+		}
+	}
+
+	/**
+	 * Notifies all listeners that a “SimpleProgress” message was received.
+	 * 
+	 * @see FcpListener#receivedSimpleProgress(FcpConnection, SimpleProgress)
+	 * @param simpleProgress
+	 *            The “SimpleProgress” message
+	 */
+	private void fireReceivedSimpleProgress(SimpleProgress simpleProgress) {
+		for (int fcpListenerIndex = 0, fcpListenerCount = fcpListeners.size(); fcpListenerIndex < fcpListenerCount; fcpListenerIndex++) {
+			((FcpListener) fcpListeners.get(fcpListenerIndex)).receivedSimpleProgress(this, simpleProgress);
+		}
+	}
+
+	/**
+	 * Notifies all listeners that a “StartedCompression” message was received.
+	 * 
+	 * @see FcpListener#receivedStartedCompression(FcpConnection,
+	 *      StartedCompression)
+	 * @param startedCompression
+	 *            The “StartedCompression” message
+	 */
+	private void fireReceivedStartedCompression(StartedCompression startedCompression) {
+		for (int fcpListenerIndex = 0, fcpListenerCount = fcpListeners.size(); fcpListenerIndex < fcpListenerCount; fcpListenerIndex++) {
+			((FcpListener) fcpListeners.get(fcpListenerIndex)).receivedStartedCompression(this, startedCompression);
+		}
+	}
+
+	/**
+	 * Notifies all listeners that a “FinishedCompression” message was received.
+	 * 
+	 * @see FcpListener#receviedFinishedCompression(FcpConnection,
+	 *      FinishedCompression)
+	 * @param finishedCompression
+	 *            The “FinishedCompression” message
+	 */
+	private void fireReceivedFinishedCompression(FinishedCompression finishedCompression) {
+		for (int fcpListenerIndex = 0, fcpListenerCount = fcpListeners.size(); fcpListenerIndex < fcpListenerCount; fcpListenerIndex++) {
+			((FcpListener) fcpListeners.get(fcpListenerIndex)).receviedFinishedCompression(this, finishedCompression);
+		}
+	}
+
+	/**
+	 * Notifies all listeners that an “UnknownPeerNoteType” message was
+	 * received.
+	 * 
+	 * @see FcpListener#receivedUnknownPeerNoteType(FcpConnection,
+	 *      UnknownPeerNoteType)
+	 * @param unknownPeerNoteType
+	 *            The “UnknownPeerNoteType” message
+	 */
+	private void fireReceivedUnknownPeerNoteType(UnknownPeerNoteType unknownPeerNoteType) {
+		for (int fcpListenerIndex = 0, fcpListenerCount = fcpListeners.size(); fcpListenerIndex < fcpListenerCount; fcpListenerIndex++) {
+			((FcpListener) fcpListeners.get(fcpListenerIndex)).receivedUnknownPeerNoteType(this, unknownPeerNoteType);
+		}
+	}
+
+	/**
+	 * Notifies all listeners that an “UnknownNodeIdentifier” message was
+	 * received.
+	 * 
+	 * @see FcpListener#receivedUnknownNodeIdentifier(FcpConnection,
+	 *      UnknownNodeIdentifier)
+	 * @param unknownNodeIdentifier
+	 *            The “UnknownNodeIdentifier” message
+	 */
+	private void fireReceivedUnknownNodeIdentifier(UnknownNodeIdentifier unknownNodeIdentifier) {
+		for (int fcpListenerIndex = 0, fcpListenerCount = fcpListeners.size(); fcpListenerIndex < fcpListenerCount; fcpListenerIndex++) {
+			((FcpListener) fcpListeners.get(fcpListenerIndex)).receivedUnknownNodeIdentifier(this, unknownNodeIdentifier);
+		}
+	}
+
+	/**
+	 * Notifies all listeners that a “ConfigData” message was received.
+	 * 
+	 * @see FcpListener#receivedConfigData(FcpConnection, ConfigData)
+	 * @param configData
+	 *            The “ConfigData” message
+	 */
+	private void fireReceivedConfigData(ConfigData configData) {
+		for (int fcpListenerIndex = 0, fcpListenerCount = fcpListeners.size(); fcpListenerIndex < fcpListenerCount; fcpListenerIndex++) {
+			((FcpListener) fcpListeners.get(fcpListenerIndex)).receivedConfigData(this, configData);
+		}
+	}
+
+	/**
+	 * Notifies all listeners that a “GetFailed” message was received.
+	 * 
+	 * @see FcpListener#receivedGetFailed(FcpConnection, GetFailed)
+	 * @param getFailed
+	 *            The “GetFailed” message
+	 */
+	private void fireReceivedGetFailed(GetFailed getFailed) {
+		for (int fcpListenerIndex = 0, fcpListenerCount = fcpListeners.size(); fcpListenerIndex < fcpListenerCount; fcpListenerIndex++) {
+			((FcpListener) fcpListeners.get(fcpListenerIndex)).receivedGetFailed(this, getFailed);
+		}
+	}
+
+	/**
+	 * Notifies all listeners that a “PutFailed” message was received.
+	 * 
+	 * @see FcpListener#receivedPutFailed(FcpConnection, PutFailed)
+	 * @param putFailed
+	 *            The “PutFailed” message
+	 */
+	private void fireReceivedPutFailed(PutFailed putFailed) {
+		for (int fcpListenerIndex = 0, fcpListenerCount = fcpListeners.size(); fcpListenerIndex < fcpListenerCount; fcpListenerIndex++) {
+			((FcpListener) fcpListeners.get(fcpListenerIndex)).receivedPutFailed(this, putFailed);
+		}
+	}
+
+	/**
+	 * Notifies all listeners that an “IdentifierCollision” message was
+	 * received.
+	 * 
+	 * @see FcpListener#receivedIdentifierCollision(FcpConnection,
+	 *      IdentifierCollision)
+	 * @param identifierCollision
+	 *            The “IdentifierCollision” message
+	 */
+	private void fireReceivedIdentifierCollision(IdentifierCollision identifierCollision) {
+		for (int fcpListenerIndex = 0, fcpListenerCount = fcpListeners.size(); fcpListenerIndex < fcpListenerCount; fcpListenerIndex++) {
+			((FcpListener) fcpListeners.get(fcpListenerIndex)).receivedIdentifierCollision(this, identifierCollision);
+		}
+	}
+
+	/**
+	 * Notifies all listeners that an “PersistentPutDir” message was received.
+	 * 
+	 * @see FcpListener#receivedPersistentPutDir(FcpConnection,
+	 *      PersistentPutDir)
+	 * @param persistentPutDir
+	 *            The “PersistentPutDir” message
+	 */
+	private void fireReceivedPersistentPutDir(PersistentPutDir persistentPutDir) {
+		for (int fcpListenerIndex = 0, fcpListenerCount = fcpListeners.size(); fcpListenerIndex < fcpListenerCount; fcpListenerIndex++) {
+			((FcpListener) fcpListeners.get(fcpListenerIndex)).receivedPersistentPutDir(this, persistentPutDir);
+		}
+	}
+
+	/**
+	 * Notifies all listeners that a “PersistentRequestRemoved” message was
+	 * received.
+	 * 
+	 * @see FcpListener#receivedPersistentRequestRemoved(FcpConnection,
+	 *      PersistentRequestRemoved)
+	 * @param persistentRequestRemoved
+	 *            The “PersistentRequestRemoved” message
+	 */
+	private void fireReceivedPersistentRequestRemoved(PersistentRequestRemoved persistentRequestRemoved) {
+		for (int fcpListenerIndex = 0, fcpListenerCount = fcpListeners.size(); fcpListenerIndex < fcpListenerCount; fcpListenerIndex++) {
+			((FcpListener) fcpListeners.get(fcpListenerIndex)).receivedPersistentRequestRemoved(this, persistentRequestRemoved);
+		}
+	}
+
+	/**
+	 * Notifies all listeners that a “SubscribedUSKUpdate” message was received.
+	 * 
+	 * @see FcpListener#receivedSubscribedUSKUpdate(FcpConnection,
+	 *      SubscribedUSKUpdate)
+	 * @param subscribedUSKUpdate
+	 *            The “SubscribedUSKUpdate” message
+	 */
+	private void fireReceivedSubscribedUSKUpdate(SubscribedUSKUpdate subscribedUSKUpdate) {
+		for (int fcpListenerIndex = 0, fcpListenerCount = fcpListeners.size(); fcpListenerIndex < fcpListenerCount; fcpListenerIndex++) {
+			((FcpListener) fcpListeners.get(fcpListenerIndex)).receivedSubscribedUSKUpdate(this, subscribedUSKUpdate);
+		}
+	}
+
+	/**
+	 * Notifies all listeners that a “PluginInfo” message was received.
+	 * 
+	 * @see FcpListener#receivedPluginInfo(FcpConnection, PluginInfo)
+	 * @param pluginInfo
+	 *            The “PluginInfo” message
+	 */
+	private void fireReceivedPluginInfo(PluginInfo pluginInfo) {
+		for (int fcpListenerIndex = 0, fcpListenerCount = fcpListeners.size(); fcpListenerIndex < fcpListenerCount; fcpListenerIndex++) {
+			((FcpListener) fcpListeners.get(fcpListenerIndex)).receivedPluginInfo(this, pluginInfo);
+		}
+	}
+
+	/**
+	 * Notifies all listeners that an “FCPPluginReply” message was received.
+	 * 
+	 * @see FcpListener#receivedFCPPluginReply(FcpConnection, FCPPluginReply)
+	 * @param fcpPluginReply
+	 *            The “FCPPluginReply” message
+	 */
+	private void fireReceivedFCPPluginReply(FCPPluginReply fcpPluginReply) {
+		for (int fcpListenerIndex = 0, fcpListenerCount = fcpListeners.size(); fcpListenerIndex < fcpListenerCount; fcpListenerIndex++) {
+			((FcpListener) fcpListeners.get(fcpListenerIndex)).receivedFCPPluginReply(this, fcpPluginReply);
+		}
+	}
+
+	/**
+	 * Notifies all listeners that a “PersistentRequestModified” message was
+	 * received.
+	 * 
+	 * @see FcpListener#receivedPersistentRequestModified(FcpConnection,
+	 *      PersistentRequestModified)
+	 * @param persistentRequestModified
+	 *            The “PersistentRequestModified” message
+	 */
+	private void fireReceivedPersistentRequestModified(PersistentRequestModified persistentRequestModified) {
+		for (int fcpListenerIndex = 0, fcpListenerCount = fcpListeners.size(); fcpListenerIndex < fcpListenerCount; fcpListenerIndex++) {
+			((FcpListener) fcpListeners.get(fcpListenerIndex)).receivedPersistentRequestModified(this, persistentRequestModified);
+		}
+	}
+
+	/**
+	 * Notifies all listeners that a “PutSuccessful” message was received.
+	 * 
+	 * @see FcpListener#receivedPutSuccessful(FcpConnection, PutSuccessful)
+	 * @param putSuccessful
+	 *            The “PutSuccessful” message
+	 */
+	private void fireReceivedPutSuccessful(PutSuccessful putSuccessful) {
+		for (int fcpListenerIndex = 0, fcpListenerCount = fcpListeners.size(); fcpListenerIndex < fcpListenerCount; fcpListenerIndex++) {
+			((FcpListener) fcpListeners.get(fcpListenerIndex)).receivedPutSuccessful(this, putSuccessful);
+		}
+	}
+
+	/**
+	 * Notifies all listeners that a “PutFetchable” message was received.
+	 * 
+	 * @see FcpListener#receivedPutFetchable(FcpConnection, PutFetchable)
+	 * @param putFetchable
+	 *            The “PutFetchable” message
+	 */
+	private void fireReceivedPutFetchable(PutFetchable putFetchable) {
+		for (int fcpListenerIndex = 0, fcpListenerCount = fcpListeners.size(); fcpListenerIndex < fcpListenerCount; fcpListenerIndex++) {
+			((FcpListener) fcpListeners.get(fcpListenerIndex)).receivedPutFetchable(this, putFetchable);
+		}
+	}
+
+	/**
+	 * Notifies all listeners that a “ProtocolError” message was received.
+	 * 
+	 * @see FcpListener#receivedProtocolError(FcpConnection, ProtocolError)
+	 * @param protocolError
+	 *            The “ProtocolError” message
+	 */
+	private void fireReceivedProtocolError(ProtocolError protocolError) {
+		for (int fcpListenerIndex = 0, fcpListenerCount = fcpListeners.size(); fcpListenerIndex < fcpListenerCount; fcpListenerIndex++) {
+			((FcpListener) fcpListeners.get(fcpListenerIndex)).receivedProtocolError(this, protocolError);
+		}
+	}
+
+	/**
+	 * Notifies all registered listeners that a message has been received.
+	 * 
+	 * @see FcpListener#receivedMessage(FcpConnection, FcpMessage)
+	 * @param fcpMessage
+	 *            The message that was received
+	 */
+	private void fireMessageReceived(FcpMessage fcpMessage) {
+		for (int fcpListenerIndex = 0, fcpListenerCount = fcpListeners.size(); fcpListenerIndex < fcpListenerCount; fcpListenerIndex++) {
+			((FcpListener) fcpListeners.get(fcpListenerIndex)).receivedMessage(this, fcpMessage);
+		}
+	}
+
+	/**
+	 * Notifies all listeners that the connection to the node was closed.
+	 * 
+	 * @see FcpListener#connectionClosed(FcpConnection)
+	 */
+	private void fireConnectionClosed() {
+		for (int fcpListenerIndex = 0, fcpListenerCount = fcpListeners.size(); fcpListenerIndex < fcpListenerCount; fcpListenerIndex++) {
+			((FcpListener) fcpListeners.get(fcpListenerIndex)).connectionClosed(this);
+		}
+	}
+
+	//
+	// 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");
+		}
+		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.
+	 */
+	public synchronized void disconnect() {
+		if (connectionHandler == null) {
+			return;
+		}
+		FcpUtils.close(remoteSocket);
+		connectionHandler.stop();
+		connectionHandler = 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 {
+		System.out.println("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) {
+		String messageName = fcpMessage.getName();
+		countMessage(messageName);
+		if ("SimpleProgress".equals(messageName)) {
+			fireReceivedSimpleProgress(new SimpleProgress(fcpMessage));
+		} else if ("ProtocolError".equals(messageName)) {
+			fireReceivedProtocolError(new ProtocolError(fcpMessage));
+		} else if ("PersistentGet".equals(messageName)) {
+			fireReceivedPersistentGet(new PersistentGet(fcpMessage));
+		} else if ("PersistentPut".equals(messageName)) {
+			fireReceivedPersistentPut(new PersistentPut(fcpMessage));
+		} else if ("PersistentPutDir".equals(messageName)) {
+			fireReceivedPersistentPutDir(new PersistentPutDir(fcpMessage));
+		} else if ("URIGenerated".equals(messageName)) {
+			fireReceivedURIGenerated(new URIGenerated(fcpMessage));
+		} else if ("EndListPersistentRequests".equals(messageName)) {
+			fireReceivedEndListPersistentRequests(new EndListPersistentRequests(fcpMessage));
+		} else if ("Peer".equals(messageName)) {
+			fireReceivedPeer(new Peer(fcpMessage));
+		} else if ("PeerNote".equals(messageName)) {
+			fireReceivedPeerNote(new PeerNote(fcpMessage));
+		} else if ("StartedCompression".equals(messageName)) {
+			fireReceivedStartedCompression(new StartedCompression(fcpMessage));
+		} else if ("FinishedCompression".equals(messageName)) {
+			fireReceivedFinishedCompression(new FinishedCompression(fcpMessage));
+		} else if ("GetFailed".equals(messageName)) {
+			fireReceivedGetFailed(new GetFailed(fcpMessage));
+		} else if ("PutFetchable".equals(messageName)) {
+			fireReceivedPutFetchable(new PutFetchable(fcpMessage));
+		} else if ("PutSuccessful".equals(messageName)) {
+			fireReceivedPutSuccessful(new PutSuccessful(fcpMessage));
+		} else if ("PutFailed".equals(messageName)) {
+			fireReceivedPutFailed(new PutFailed(fcpMessage));
+		} else if ("DataFound".equals(messageName)) {
+			fireReceivedDataFound(new DataFound(fcpMessage));
+		} else if ("SubscribedUSKUpdate".equals(messageName)) {
+			fireReceivedSubscribedUSKUpdate(new SubscribedUSKUpdate(fcpMessage));
+		} else if ("IdentifierCollision".equals(messageName)) {
+			fireReceivedIdentifierCollision(new IdentifierCollision(fcpMessage));
+		} else if ("AllData".equals(messageName)) {
+			LimitedInputStream payloadInputStream = getInputStream(FcpUtils.safeParseLong(fcpMessage.getField("DataLength")));
+			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)) {
+			fireReceivedEndListPeerNotes(new EndListPeerNotes(fcpMessage));
+		} else if ("EndListPeers".equals(messageName)) {
+			fireReceivedEndListPeers(new EndListPeers(fcpMessage));
+		} else if ("SSKKeypair".equals(messageName)) {
+			fireReceivedSSKKeypair(new SSKKeypair(fcpMessage));
+		} else if ("PeerRemoved".equals(messageName)) {
+			fireReceivedPeerRemoved(new PeerRemoved(fcpMessage));
+		} else if ("PersistentRequestModified".equals(messageName)) {
+			fireReceivedPersistentRequestModified(new PersistentRequestModified(fcpMessage));
+		} else if ("PersistentRequestRemoved".equals(messageName)) {
+			fireReceivedPersistentRequestRemoved(new PersistentRequestRemoved(fcpMessage));
+		} else if ("UnknownPeerNoteType".equals(messageName)) {
+			fireReceivedUnknownPeerNoteType(new UnknownPeerNoteType(fcpMessage));
+		} else if ("UnknownNodeIdentifier".equals(messageName)) {
+			fireReceivedUnknownNodeIdentifier(new UnknownNodeIdentifier(fcpMessage));
+		} else if ("FCPPluginReply".equals(messageName)) {
+			LimitedInputStream payloadInputStream = getInputStream(FcpUtils.safeParseLong(fcpMessage.getField("DataLength")));
+			fireReceivedFCPPluginReply(new FCPPluginReply(fcpMessage, payloadInputStream));
+			try {
+				payloadInputStream.consume();
+			} catch (IOException ioe1) {
+				/* ignore. */
+			}
+		} else if ("PluginInfo".equals(messageName)) {
+			fireReceivedPluginInfo(new PluginInfo(fcpMessage));
+		} else if ("NodeData".equals(messageName)) {
+			fireReceivedNodeData(new NodeData(fcpMessage));
+		} else if ("TestDDAReply".equals(messageName)) {
+			fireReceivedTestDDAReply(new TestDDAReply(fcpMessage));
+		} else if ("TestDDAComplete".equals(messageName)) {
+			fireReceivedTestDDAComplete(new TestDDAComplete(fcpMessage));
+		} else if ("ConfigData".equals(messageName)) {
+			fireReceivedConfigData(new ConfigData(fcpMessage));
+		} else if ("NodeHello".equals(messageName)) {
+			fireReceivedNodeHello(new NodeHello(fcpMessage));
+		} else if ("CloseConnectionDuplicateClientName".equals(messageName)) {
+			fireReceivedCloseConnectionDuplicateClientName(new CloseConnectionDuplicateClientName(fcpMessage));
+		} else {
+			fireMessageReceived(fcpMessage);
+		}
+	}
+
+	/**
+	 * Handles a disconnect from the node.
+	 */
+	synchronized void handleDisconnect() {
+		FcpUtils.close(remoteInputStream);
+		FcpUtils.close(remoteOutputStream);
+		FcpUtils.close(remoteSocket);
+		connectionHandler = null;
+		fireConnectionClosed();
+	}
+
+	//
+	// 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 = ((Integer) incomingMessageStatistics.get(name)).intValue();
+		}
+		incomingMessageStatistics.put(name, new Integer(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 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 <a href="mailto:dr at ina-germany.de">David Roden</a>
+	 * @version $Id$
+	 */
+	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()
+		 */
+		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()
+		 */
+		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)
+		 */
+		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)
+		 */
+		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)
+		 */
+		public void mark(int readlimit) {
+			/* do nothing. */
+		}
+
+		/**
+		 * {@inheritDoc}
+		 * 
+		 * @see java.io.FilterInputStream#markSupported()
+		 * @return <code>false</code>
+		 */
+		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()
+		 */
+		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 void consume() throws IOException {
+			while (remaining > 0) {
+				skip(remaining);
+			}
+		}
+
+	}
+
+}


Property changes on: branches/jFCPlib-1.4/src/net/pterodactylus/fcp/FcpConnection.java
___________________________________________________________________
Name: svn:keywords
   + Id

Added: branches/jFCPlib-1.4/src/net/pterodactylus/fcp/FcpConnectionHandler.java
===================================================================
--- branches/jFCPlib-1.4/src/net/pterodactylus/fcp/FcpConnectionHandler.java	                        (rev 0)
+++ branches/jFCPlib-1.4/src/net/pterodactylus/fcp/FcpConnectionHandler.java	2008-04-13 14:24:08 UTC (rev 19264)
@@ -0,0 +1,160 @@
+/*
+ * jSite2 - 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 at freenetproject.org&gt;
+ * @version $Id$
+ */
+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;
+		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".equals(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 e) {
+				break;
+			}
+		}
+		fcpConnection.handleDisconnect();
+	}
+
+	/**
+	 * 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, newReadByt