From: David ‘Bombe’ Roden Date: Sun, 13 Apr 2008 14:26:06 +0000 (+0000) Subject: rename fcplib to jFCPlib X-Git-Tag: v0.1.1~173 X-Git-Url: https://git.pterodactylus.net/?a=commitdiff_plain;h=f553531be78d6d6d95dc152728f2b8d40242b57d;p=jFCPlib.git rename fcplib to jFCPlib git-svn-id: http://trooper/svn/projects/jFCPlib/trunk@809 c3eda9e8-030b-0410-8277-bc7414b0a119 --- diff --git a/.classpath b/.classpath new file mode 100644 index 0000000..4d24f82 --- /dev/null +++ b/.classpath @@ -0,0 +1,7 @@ + + + + + + + diff --git a/.project b/.project new file mode 100644 index 0000000..f9effda --- /dev/null +++ b/.project @@ -0,0 +1,17 @@ + + + fcplib + + + + + + org.eclipse.jdt.core.javabuilder + + + + + + org.eclipse.jdt.core.javanature + + diff --git a/javadoc.xml b/javadoc.xml new file mode 100644 index 0000000..a438648 --- /dev/null +++ b/javadoc.xml @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/src/net/pterodactylus/fcp/ARK.java b/src/net/pterodactylus/fcp/ARK.java new file mode 100644 index 0000000..6fc3da9 --- /dev/null +++ b/src/net/pterodactylus/fcp/ARK.java @@ -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 <bombe@freenetproject.org> + * @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); + } catch (NumberFormatException nfe1) { + throw new IllegalArgumentException("number must be numeric", nfe1); + } + } + + /** + * Returns the public URI of the ARK. + * + * @return The public URI of the ARK + */ + public String getPublicURI() { + return publicURI; + } + + /** + * Returns the private URI of the ARK. + * + * @return The private URI of the ARK + */ + public String getPrivateURI() { + return privateURI; + } + + /** + * Returns the number of the ARK. + * + * @return The number of the ARK + */ + public int getNumber() { + return number; + } + +} \ No newline at end of file diff --git a/src/net/pterodactylus/fcp/AddPeer.java b/src/net/pterodactylus/fcp/AddPeer.java new file mode 100644 index 0000000..0229f17 --- /dev/null +++ b/src/net/pterodactylus/fcp/AddPeer.java @@ -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 <bombe@freenetproject.org> + * @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()); + } + +} diff --git a/src/net/pterodactylus/fcp/AllData.java b/src/net/pterodactylus/fcp/AllData.java new file mode 100644 index 0000000..2f73909 --- /dev/null +++ b/src/net/pterodactylus/fcp/AllData.java @@ -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 David Roden + * @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 -1 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 -1 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 -1 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; + } + +} diff --git a/src/net/pterodactylus/fcp/BaseMessage.java b/src/net/pterodactylus/fcp/BaseMessage.java new file mode 100644 index 0000000..70b1e73 --- /dev/null +++ b/src/net/pterodactylus/fcp/BaseMessage.java @@ -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 <bombe@freenetproject.org> + * @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 null 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(); + } + +} diff --git a/src/net/pterodactylus/fcp/ClientGet.java b/src/net/pterodactylus/fcp/ClientGet.java new file mode 100644 index 0000000..fef608d --- /dev/null +++ b/src/net/pterodactylus/fcp/ClientGet.java @@ -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 <bombe@freenetproject.org> + * @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 + * true to ignore the local data store, + * false 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 + * true to restrict the search to the local data + * store, false 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, + * -1 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 + * true to make the request visible on the global + * queue, false 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 + * true to request the binary blob, + * false to get the “real thing” + */ + public void setBinaryBlob(boolean binaryBlob) { + setField("BinaryBlob", String.valueOf(binaryBlob)); + } + + /** + * Sets the allowed MIME types of the requested file. If the MIME type of + * the file does not match one of the given MIME types the request will + * fail! + * + * @param allowedMimeTypes + * The allowed MIME types + */ + public void setAllowedMimeTypes(String... allowedMimeTypes) { + setField("AllowedMIMETypes", FcpUtils.encodeMultiStringField(allowedMimeTypes)); + } + + /** + * Sets the filename to download the file to. You should only call this + * method if your return type is {@link ReturnType#disk}! + * + * @param filename + * The filename to download the file to + */ + public void setFilename(String filename) { + setField("Filename", filename); + } + + /** + * Sets the name for the temporary file. You should only call this method if + * your return type is {@link ReturnType#disk}! + * + * @param tempFilename + * The name of the temporary file + */ + public void setTempFilename(String tempFilename) { + setField("TempFilename", tempFilename); + } + +} diff --git a/src/net/pterodactylus/fcp/ClientHello.java b/src/net/pterodactylus/fcp/ClientHello.java new file mode 100644 index 0000000..4f83922 --- /dev/null +++ b/src/net/pterodactylus/fcp/ClientHello.java @@ -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 must be sent to the node first thing + * after calling {@link FcpConnection#connect()}. + * + * @author David ‘Bombe’ Roden <bombe@freenetproject.org> + * @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); + } + +} diff --git a/src/net/pterodactylus/fcp/ClientPut.java b/src/net/pterodactylus/fcp/ClientPut.java new file mode 100644 index 0000000..f3d3d1d --- /dev/null +++ b/src/net/pterodactylus/fcp/ClientPut.java @@ -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 <bombe@freenetproject.org> + * @version $Id$ + */ +public class ClientPut extends FcpMessage { + + /** + * Creates a new “ClientPut” message that inserts a file to the given URI. + * The file data has 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 uploadFrom the file data has to be supplied + * in different ways: If uploadFrom is + * {@link UploadFrom#direct}, use + * {@link #setPayloadInputStream(java.io.InputStream)} to supply the input + * data. If uploadFrom 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 uploadFrom 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 + * -1 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 + * true to generate the final CHK only, + * false 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 + * true to put the request on the global queue, + * false 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 + * true to skip compression of the data in the + * node, false 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 + * true 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 uploadFrom 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 uploadFrom is {@link UploadFrom#redirect}, use this + * method to determine that target of the redirect. + * + * @param targetURI + * The target URI to redirect to + */ + public void setTargetURI(String targetURI) { + setField("TargetURI", targetURI); + } + +} diff --git a/src/net/pterodactylus/fcp/ClientPutComplexDir.java b/src/net/pterodactylus/fcp/ClientPutComplexDir.java new file mode 100644 index 0000000..cb40da1 --- /dev/null +++ b/src/net/pterodactylus/fcp/ClientPutComplexDir.java @@ -0,0 +1,222 @@ +/* + * 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.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 <bombe@freenetproject.org> + * @version $Id$ + */ +public class ClientPutComplexDir extends FcpMessage { + + /** The index for added file entries. */ + private int fileIndex = 0; + + /** The input streams from {@link DirectFileEntry}s. */ + private final List 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 + * -1 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 + * true to generate the final CHK only, + * false 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 + * true to put the request on the global queue, + * false 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 + * true to skip compression of the data, + * false 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 + * true to encode the complete data early, + * false 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(); + for (Entry fieldEntry: fields.entrySet()) { + setField("Files." + fileIndex + "." + fieldEntry.getKey(), fieldEntry.getValue()); + } + fileIndex++; + if (fileEntry instanceof FileEntry.DirectFileEntry) { + directFileInputStreams.add(((DirectFileEntry) fileEntry).getInputStream()); + } + } + + /** + * {@inheritDoc} + *

+ * Do not call this method to add input streams! The input streams, if any, + * will be taken directly from the {@link FileEntry}s and the stream you + * set here will be overridden! + */ + @Override + public void setPayloadInputStream(InputStream payloadInputStream) { + /* do nothing. */ + } + + /** + * {@inheritDoc} + */ + @Override + public void write(OutputStream outputStream) throws IOException { + /* create payload stream. */ + setPayloadInputStream(new SequenceInputStream(Collections.enumeration(directFileInputStreams))); + /* write out all the fields. */ + super.write(outputStream); + } + +} diff --git a/src/net/pterodactylus/fcp/ClientPutDiskDir.java b/src/net/pterodactylus/fcp/ClientPutDiskDir.java new file mode 100644 index 0000000..3a81451 --- /dev/null +++ b/src/net/pterodactylus/fcp/ClientPutDiskDir.java @@ -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 <bombe@freenetproject.org> + * @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 + * -1 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 + * true to generate the final CHK only, + * false 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 + * true to put the request on the global queue, + * false 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 + * true to skip compression of the data in the + * node, false 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 + * true to just ignore unreadable files, + * false to let the insert fail when an unreadable + * file is encountered + */ + public void setAllowUnreadableFiles(boolean allowUnreadableFiles) { + setField("AllowUnreadableFiles", String.valueOf(allowUnreadableFiles)); + } + +} diff --git a/src/net/pterodactylus/fcp/CloseConnectionDuplicateClientName.java b/src/net/pterodactylus/fcp/CloseConnectionDuplicateClientName.java new file mode 100644 index 0000000..e36a4c7 --- /dev/null +++ b/src/net/pterodactylus/fcp/CloseConnectionDuplicateClientName.java @@ -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 <bombe@freenetproject.org> + * @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); + } + +} diff --git a/src/net/pterodactylus/fcp/ConfigData.java b/src/net/pterodactylus/fcp/ConfigData.java new file mode 100644 index 0000000..990cbe6 --- /dev/null +++ b/src/net/pterodactylus/fcp/ConfigData.java @@ -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 <bombe@freenetproject.org> + * @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 -1 if the sort + * order could not be parsed + */ + public int getSortOrder(String option) { + return FcpUtils.safeParseInt(getField("sortOrder." + option)); + } + + /** + * Returns the expert flag of the given option. + * + * @param option + * The name of the option + * @return The expert flag of the option + */ + public boolean getExpertFlag(String option) { + return Boolean.valueOf(getField("expertFlag." + option)); + } + + /** + * Returns the force-write flag of the given option + * + * @param option + * The name of the option + * @return The force-write flag of the given option + */ + public boolean getForceWriteFlag(String option) { + return Boolean.valueOf(getField("forceWriteFlag." + option)); + } + +} diff --git a/src/net/pterodactylus/fcp/DSAGroup.java b/src/net/pterodactylus/fcp/DSAGroup.java new file mode 100644 index 0000000..4e501b2 --- /dev/null +++ b/src/net/pterodactylus/fcp/DSAGroup.java @@ -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 <bombe@freenetproject.org> + * @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 diff --git a/src/net/pterodactylus/fcp/DataFound.java b/src/net/pterodactylus/fcp/DataFound.java new file mode 100644 index 0000000..039626a --- /dev/null +++ b/src/net/pterodactylus/fcp/DataFound.java @@ -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 <bombe@freenetproject.org> + * @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 true if the request is on the global queue, + * false if the request is on the client-local queue + */ + public boolean isGlobal() { + return Boolean.valueOf(getField("Global")); + } + + /** + * Returns the identifier of the request. + * + * @return The identifier of the request + */ + public String getIdentifier() { + return getField("Identifier"); + } + + /** + * Returns the content type of the data. + * + * @return The content type of the data + */ + public String getMetadataContentType() { + return getField("Metadata.ContentType"); + } + + /** + * Returns the length of the data. + * + * @return The length of the data + */ + public long getDataLength() { + return FcpUtils.safeParseLong(getField("DataLength")); + } + +} diff --git a/src/net/pterodactylus/fcp/EndListPeerNotes.java b/src/net/pterodactylus/fcp/EndListPeerNotes.java new file mode 100644 index 0000000..1846999 --- /dev/null +++ b/src/net/pterodactylus/fcp/EndListPeerNotes.java @@ -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 <bombe@freenetproject.org> + * @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); + } + +} diff --git a/src/net/pterodactylus/fcp/EndListPeers.java b/src/net/pterodactylus/fcp/EndListPeers.java new file mode 100644 index 0000000..12dedbe --- /dev/null +++ b/src/net/pterodactylus/fcp/EndListPeers.java @@ -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 <bombe@freenetproject.org> + * @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); + } + +} diff --git a/src/net/pterodactylus/fcp/EndListPersistentRequests.java b/src/net/pterodactylus/fcp/EndListPersistentRequests.java new file mode 100644 index 0000000..714306e --- /dev/null +++ b/src/net/pterodactylus/fcp/EndListPersistentRequests.java @@ -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 <bombe@freenetproject.org> + * @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); + } + +} diff --git a/src/net/pterodactylus/fcp/FCPPluginMessage.java b/src/net/pterodactylus/fcp/FCPPluginMessage.java new file mode 100644 index 0000000..43df7d6 --- /dev/null +++ b/src/net/pterodactylus/fcp/FCPPluginMessage.java @@ -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 <bombe@freenetproject.org> + * @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)); + } + +} diff --git a/src/net/pterodactylus/fcp/FCPPluginReply.java b/src/net/pterodactylus/fcp/FCPPluginReply.java new file mode 100644 index 0000000..271b8d7 --- /dev/null +++ b/src/net/pterodactylus/fcp/FCPPluginReply.java @@ -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 <bombe@freenetproject.org> + * @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 -1 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 null if there is no + * payload + */ + public InputStream getPayloadInputStream() { + return payloadInputStream; + } + +} diff --git a/src/net/pterodactylus/fcp/FcpAdapter.java b/src/net/pterodactylus/fcp/FcpAdapter.java new file mode 100644 index 0000000..5f35180 --- /dev/null +++ b/src/net/pterodactylus/fcp/FcpAdapter.java @@ -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 <bombe@freenetproject.org> + * @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. */ + } + +} diff --git a/src/net/pterodactylus/fcp/FcpConnection.java b/src/net/pterodactylus/fcp/FcpConnection.java new file mode 100644 index 0000000..1af3bab --- /dev/null +++ b/src/net/pterodactylus/fcp/FcpConnection.java @@ -0,0 +1,973 @@ +/* + * 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 <bombe@freenetproject.org> + * @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 host 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 host 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 (FcpListener fcpListener: fcpListeners) { + fcpListener.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 (FcpListener fcpListener: fcpListeners) { + fcpListener.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 (FcpListener fcpListener: fcpListeners) { + fcpListener.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 (FcpListener fcpListener: fcpListeners) { + fcpListener.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 (FcpListener fcpListener: fcpListeners) { + fcpListener.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 (FcpListener fcpListener: fcpListeners) { + fcpListener.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 (FcpListener fcpListener: fcpListeners) { + fcpListener.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 (FcpListener fcpListener: fcpListeners) { + fcpListener.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 (FcpListener fcpListener: fcpListeners) { + fcpListener.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 (FcpListener fcpListener: fcpListeners) { + fcpListener.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 (FcpListener fcpListener: fcpListeners) { + fcpListener.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 (FcpListener fcpListener: fcpListeners) { + fcpListener.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 (FcpListener fcpListener: fcpListeners) { + fcpListener.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 (FcpListener fcpListener: fcpListeners) { + fcpListener.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 (FcpListener fcpListener: fcpListeners) { + fcpListener.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 (FcpListener fcpListener: fcpListeners) { + fcpListener.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 (FcpListener fcpListener: fcpListeners) { + fcpListener.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 (FcpListener fcpListener: fcpListeners) { + fcpListener.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 (FcpListener fcpListener: fcpListeners) { + fcpListener.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 (FcpListener fcpListener: fcpListeners) { + fcpListener.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 (FcpListener fcpListener: fcpListeners) { + fcpListener.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 (FcpListener fcpListener: fcpListeners) { + fcpListener.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 (FcpListener fcpListener: fcpListeners) { + fcpListener.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 (FcpListener fcpListener: fcpListeners) { + fcpListener.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 (FcpListener fcpListener: fcpListeners) { + fcpListener.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 (FcpListener fcpListener: fcpListeners) { + fcpListener.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 (FcpListener fcpListener: fcpListeners) { + fcpListener.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 (FcpListener fcpListener: fcpListeners) { + fcpListener.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 (FcpListener fcpListener: fcpListeners) { + fcpListener.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 (FcpListener fcpListener: fcpListeners) { + fcpListener.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 (FcpListener fcpListener: fcpListeners) { + fcpListener.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 (FcpListener fcpListener: fcpListeners) { + fcpListener.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 (FcpListener fcpListener: fcpListeners) { + fcpListener.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 (FcpListener fcpListener: fcpListeners) { + fcpListener.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 (FcpListener fcpListener: fcpListeners) { + fcpListener.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 (FcpListener fcpListener: fcpListeners) { + fcpListener.receivedMessage(this, fcpMessage); + } + } + + /** + * Notifies all listeners that the connection to the node was closed. + * + * @see FcpListener#connectionClosed(FcpConnection) + */ + private void fireConnectionClosed() { + for (FcpListener fcpListener: fcpListeners) { + fcpListener.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 1 + * for the given message name. + * + * @param name + * The name of the message to count + */ + private void countMessage(String name) { + int oldValue = 0; + if (incomingMessageStatistics.containsKey(name)) { + oldValue = incomingMessageStatistics.get(name); + } + incomingMessageStatistics.put(name, oldValue + 1); + } + + /** + * 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 David Roden + * @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 + * length bytes from the given input stream. + * + * @param inputStream + * The input stream + * @param length + * The number of bytes to read + */ + public LimitedInputStream(InputStream inputStream, long length) { + super(inputStream); + remaining = length; + } + + /** + * @see java.io.FilterInputStream#available() + */ + @Override + public synchronized int available() throws IOException { + if (remaining == 0) { + return 0; + } + return (int) Math.min(super.available(), Math.min(Integer.MAX_VALUE, remaining)); + } + + /** + * @see java.io.FilterInputStream#read() + */ + @Override + public synchronized int read() throws IOException { + int read = -1; + if (remaining > 0) { + read = super.read(); + remaining--; + } + return read; + } + + /** + * @see java.io.FilterInputStream#read(byte[], int, int) + */ + @Override + public synchronized int read(byte[] b, int off, int len) throws IOException { + if (remaining == 0) { + return -1; + } + int toCopy = (int) Math.min(len, Math.min(remaining, Integer.MAX_VALUE)); + int read = super.read(b, off, toCopy); + remaining -= read; + return read; + } + + /** + * @see java.io.FilterInputStream#skip(long) + */ + @Override + public synchronized long skip(long n) throws IOException { + if ((n < 0) || (remaining == 0)) { + return 0; + } + long skipped = super.skip(Math.min(n, remaining)); + remaining -= skipped; + return skipped; + } + + /** + * {@inheritDoc} This method does nothing, as {@link #mark(int)} and + * {@link #reset()} are not supported. + * + * @see java.io.FilterInputStream#mark(int) + */ + @Override + public void mark(int readlimit) { + /* do nothing. */ + } + + /** + * {@inheritDoc} + * + * @see java.io.FilterInputStream#markSupported() + * @return false + */ + @Override + public boolean markSupported() { + return false; + } + + /** + * {@inheritDoc} This method does nothing, as {@link #mark(int)} and + * {@link #reset()} are not supported. + * + * @see java.io.FilterInputStream#reset() + */ + @Override + public void reset() throws IOException { + /* do nothing. */ + } + + /** + * Consumes the input stream, i.e. read all bytes until the limit is + * reached. + * + * @throws IOException + * if an I/O error occurs + */ + public void consume() throws IOException { + while (remaining > 0) { + skip(remaining); + } + } + + } + +} diff --git a/src/net/pterodactylus/fcp/FcpConnectionHandler.java b/src/net/pterodactylus/fcp/FcpConnectionHandler.java new file mode 100644 index 0000000..b6404c5 --- /dev/null +++ b/src/net/pterodactylus/fcp/FcpConnectionHandler.java @@ -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 <bombe@freenetproject.org> + * @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, newReadBytes, 0, readBytes.length); + readBytes = newReadBytes; + } + readBytes[readIndex++] = (byte) nextByte; + } + ByteBuffer byteBuffer = ByteBuffer.wrap(readBytes, 0, readIndex); + return Charset.forName("UTF-8").decode(byteBuffer).toString(); + } + +} diff --git a/src/net/pterodactylus/fcp/FcpKeyPair.java b/src/net/pterodactylus/fcp/FcpKeyPair.java new file mode 100644 index 0000000..44ccb5d --- /dev/null +++ b/src/net/pterodactylus/fcp/FcpKeyPair.java @@ -0,0 +1,67 @@ +/* + * jSite2 - FcpKeyPair.java - + * Copyright © 2008 David Roden + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +package net.pterodactylus.fcp; + +/** + * Container for an SSK keypair. + * + * @author David ‘Bombe’ Roden <bombe@freenetproject.org> + * @version $Id$ + */ +public class FcpKeyPair { + + /** The public key. */ + private final String publicKey; + + /** The private key. */ + private final String privateKey; + + /** + * Creates a new keypair from the given keys. + * + * @param publicKey + * The public key + * @param privateKey + * The private key + */ + public FcpKeyPair(String publicKey, String privateKey) { + this.publicKey = publicKey; + this.privateKey = privateKey; + } + + /** + * Returns the public key of this keypair. + * + * @return The public key + */ + public String getPublicKey() { + return publicKey; + } + + /** + * Returns the private key of this keypair. + * + * @return The private key + */ + public String getPrivateKey() { + return privateKey; + } + +} diff --git a/src/net/pterodactylus/fcp/FcpListener.java b/src/net/pterodactylus/fcp/FcpListener.java new file mode 100644 index 0000000..90860e5 --- /dev/null +++ b/src/net/pterodactylus/fcp/FcpListener.java @@ -0,0 +1,407 @@ +/* + * jSite2 - FpcListener.java - + * Copyright © 2008 David Roden + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +package net.pterodactylus.fcp; + +import java.util.EventListener; + +/** + * Interface for objects that want to be notified on certain FCP events. + * + * @author David ‘Bombe’ Roden <bombe@freenetproject.org> + * @version $Id$ + */ +public interface FcpListener extends EventListener { + + /** + * Notifies a listener that a “NodeHello” message was received. + * + * @param fcpConnection + * The connection that received the message + * @param nodeHello + * The “NodeHello” message + */ + public void receivedNodeHello(FcpConnection fcpConnection, NodeHello nodeHello); + + /** + * Notifies a listener that a “CloseConnectionDuplicateClientName” message + * was received. + * + * @param fcpConnection + * The connection that received the message + * @param closeConnectionDuplicateClientName + * The “CloseConnectionDuplicateClientName” message + */ + public void receivedCloseConnectionDuplicateClientName(FcpConnection fcpConnection, CloseConnectionDuplicateClientName closeConnectionDuplicateClientName); + + /** + * Notifies a listener that a “SSKKeypair” message was received. + * + * @param fcpConnection + * The connection that received themessage + * @param sskKeypair + * The “SSKKeypair” message + */ + public void receivedSSKKeypair(FcpConnection fcpConnection, SSKKeypair sskKeypair); + + /** + * Notifies a listener that a “Peer” message was received. + * + * @param fcpConnection + * The connection that received the message + * @param peer + * The “Peer” message + */ + public void receivedPeer(FcpConnection fcpConnection, Peer peer); + + /** + * Notifies a listener that an “EndListPeers” message was received. + * + * @param fcpConnection + * The connection that recevied the message + * @param endListPeers + * The “EndListPeers” message + */ + public void receivedEndListPeers(FcpConnection fcpConnection, EndListPeers endListPeers); + + /** + * Notifies a listener that a “PeerNote” message was received. + * + * @param fcpConnection + * The connection that received the message + * @param peerNote + * The “PeerNote” message + */ + public void receivedPeerNote(FcpConnection fcpConnection, PeerNote peerNote); + + /** + * Notifies a listener that an “EndListPeerNotes” message was received. + * + * @param fcpConnection + * The connection that received the message + * @param endListPeerNotes + * The “EndListPeerNotes” message + */ + public void receivedEndListPeerNotes(FcpConnection fcpConnection, EndListPeerNotes endListPeerNotes); + + /** + * Notifies a listener that a “PeerRemoved” message was received. + * + * @param fcpConnection + * The connection that received the message + * @param peerRemoved + * The “PeerRemoved” message + */ + public void receivedPeerRemoved(FcpConnection fcpConnection, PeerRemoved peerRemoved); + + /** + * Notifies a listener that a “NodeData” message was received. + * + * @param fcpConnection + * The connection that received the message + * @param nodeData + * The “NodeData” message + */ + public void receivedNodeData(FcpConnection fcpConnection, NodeData nodeData); + + /** + * Notifies a listener that a “TestDDAReply” message was received. + * + * @param fcpConnection + * The connection that received the message + * @param testDDAReply + * The “TestDDAReply” message + */ + public void receivedTestDDAReply(FcpConnection fcpConnection, TestDDAReply testDDAReply); + + /** + * Notifies a listener that a “TestDDAComplete” was received. + * + * @param fcpConnection + * The connection that received the message + * @param testDDAComplete + * The “TestDDAComplete” message + */ + public void receivedTestDDAComplete(FcpConnection fcpConnection, TestDDAComplete testDDAComplete); + + /** + * Notifies a listener that a “PersistentGet” was received. + * + * @param fcpConnection + * The connection that received the message + * @param persistentGet + * The “PersistentGet” message + */ + public void receivedPersistentGet(FcpConnection fcpConnection, PersistentGet persistentGet); + + /** + * Notifies a listener that a “PersistentPut” was received. + * + * @param fcpConnection + * The connection that received the message + * @param persistentPut + * The “PersistentPut” message + */ + public void receivedPersistentPut(FcpConnection fcpConnection, PersistentPut persistentPut); + + /** + * Notifies a listener that a “EndListPersistentRequests” was received. + * + * @param fcpConnection + * The connection that received the message + * @param endListPersistentRequests + * The “EndListPersistentRequests” message + */ + public void receivedEndListPersistentRequests(FcpConnection fcpConnection, EndListPersistentRequests endListPersistentRequests); + + /** + * Notifies a listener that a “URIGenerated” was received. + * + * @param fcpConnection + * The connection that received the message + * @param uriGenerated + * The “URIGenerated” message + */ + public void receivedURIGenerated(FcpConnection fcpConnection, URIGenerated uriGenerated); + + /** + * Notifies a listener that a “DataFound” was received. + * + * @param fcpConnection + * The connection that received the message + * @param dataFound + * The “DataFound” message + */ + public void receivedDataFound(FcpConnection fcpConnection, DataFound dataFound); + + /** + * Notifies a listener that an “AllData” was received. + * + * @param fcpConnection + * The connection that received the message + * @param allData + * The “AllData” message + */ + public void receivedAllData(FcpConnection fcpConnection, AllData allData); + + /** + * Notifies a listener that a “SimpleProgress” was received. + * + * @param fcpConnection + * The connection that received the message + * @param simpleProgress + * The “SimpleProgress” message + */ + public void receivedSimpleProgress(FcpConnection fcpConnection, SimpleProgress simpleProgress); + + /** + * Notifies a listener that a “StartedCompression” was received. + * + * @param fcpConnection + * The connection that received the message + * @param startedCompression + * The “StartedCompression” message + */ + public void receivedStartedCompression(FcpConnection fcpConnection, StartedCompression startedCompression); + + /** + * Notifies a listener that a “FinishedCompression” was received. + * + * @param fcpConnection + * The connection that received the message + * @param finishedCompression + * The “FinishedCompression” message + */ + public void receviedFinishedCompression(FcpConnection fcpConnection, FinishedCompression finishedCompression); + + /** + * Notifies a listener that an “UnknownPeerNoteType” was received. + * + * @param fcpConnection + * The connection that received the message + * @param unknownPeerNoteType + * The “UnknownPeerNoteType” message + */ + public void receivedUnknownPeerNoteType(FcpConnection fcpConnection, UnknownPeerNoteType unknownPeerNoteType); + + /** + * Notifies a listener that a “UnknownNodeIdentifier” message was received. + * + * @param fcpConnection + * The connection that received the message + * @param unknownNodeIdentifier + * The “UnknownNodeIdentifier” message + */ + public void receivedUnknownNodeIdentifier(FcpConnection fcpConnection, UnknownNodeIdentifier unknownNodeIdentifier); + + /** + * Notifies a listener that a “ConfigData” message was received. + * + * @param fcpConnection + * The connection that received the message + * @param configData + * The “ConfigData” message + */ + public void receivedConfigData(FcpConnection fcpConnection, ConfigData configData); + + /** + * Notifies a listener that a “GetFailed” message was recevied. + * + * @param fcpConnection + * The connection that received the message + * @param getFailed + * The “GetFailed” message + */ + public void receivedGetFailed(FcpConnection fcpConnection, GetFailed getFailed); + + /** + * Notifies a listener that a “PutFailed” message was received. + * + * @param fcpConnection + * The connection that received the message + * @param putFailed + * The “PutFailed” message + */ + public void receivedPutFailed(FcpConnection fcpConnection, PutFailed putFailed); + + /** + * Notifies a listener that an “IdentifierCollision” message was receied. + * + * @param fcpConnection + * The connection that received the message + * @param identifierCollision + * The “IdentifierCollision” message + */ + public void receivedIdentifierCollision(FcpConnection fcpConnection, IdentifierCollision identifierCollision); + + /** + * Notifies a listener that a “PersistentPutDir” message was received. + * + * @param fcpConnection + * The connection that received the message + * @param persistentPutDir + * The “PersistentPutDir” message + */ + public void receivedPersistentPutDir(FcpConnection fcpConnection, PersistentPutDir persistentPutDir); + + /** + * Notifies a listener that a “PersistentRequestRemoved” message was + * received. + * + * @param fcpConnection + * The connection that received the message + * @param persistentRequestRemoved + * The “PersistentRequestRemoved” message + */ + public void receivedPersistentRequestRemoved(FcpConnection fcpConnection, PersistentRequestRemoved persistentRequestRemoved); + + /** + * Notifies a listener that a “SubscribedUSKUpdate” message was received. + * + * @param fcpConnection + * The connection that recevied the message + * @param subscribedUSKUpdate + * The “SubscribedUSKUpdate” message + */ + public void receivedSubscribedUSKUpdate(FcpConnection fcpConnection, SubscribedUSKUpdate subscribedUSKUpdate); + + /** + * Notifies a listener that a “PluginInfo” message was received. + * + * @param fcpConnection + * The connection that received the message + * @param pluginInfo + * The “PluginInfo” message + */ + public void receivedPluginInfo(FcpConnection fcpConnection, PluginInfo pluginInfo); + + /** + * Notifies a listener that an “FCPPluginReply“ message was received. + * + * @param fcpConnection + * The connection that received the message + * @param fcpPluginReply + * The “FCPPluginReply” message + */ + public void receivedFCPPluginReply(FcpConnection fcpConnection, FCPPluginReply fcpPluginReply); + + /** + * Notifies a listener that a “PersistentRequestModified” message was + * received. + * + * @param fcpConnection + * The connection that received the message + * @param persistentRequestModified + * The “PersistentRequestModified” message + */ + public void receivedPersistentRequestModified(FcpConnection fcpConnection, PersistentRequestModified persistentRequestModified); + + /** + * Notifies a listener that a “PutSuccessful” message was received. + * + * @param fcpConnection + * The connection that received the message + * @param putSuccessful + * The “PutSuccessful” message + */ + public void receivedPutSuccessful(FcpConnection fcpConnection, PutSuccessful putSuccessful); + + /** + * Notifies a listener that a “PutFetchable” message was received. + * + * @param fcpConnection + * The connection that received the message + * @param putFetchable + * The “PutFetchable” message + */ + public void receivedPutFetchable(FcpConnection fcpConnection, PutFetchable putFetchable); + + /** + * Notifies a listener that a “ProtocolError” was received. + * + * @param fcpConnection + * The connection that received the message + * @param protocolError + * The “ProtocolError” message + */ + public void receivedProtocolError(FcpConnection fcpConnection, ProtocolError protocolError); + + /** + * Notifies a listener that a message has been received. This method is only + * called if {@link FcpConnection#handleMessage(FcpMessage)} does not + * recognize the message. Should that ever happen, please file a bug report! + * + * @param fcpConnection + * The connection that received the message + * @param fcpMessage + * The message that was received + */ + public void receivedMessage(FcpConnection fcpConnection, FcpMessage fcpMessage); + + /** + * Notifies a listener that a connection was closed. A closed connection can + * be reestablished by calling {@link FcpConnection#connect()} on the same + * object again. + * + * @param fcpConnection + * The connection that was closed. + */ + public void connectionClosed(FcpConnection fcpConnection); + +} diff --git a/src/net/pterodactylus/fcp/FcpMessage.java b/src/net/pterodactylus/fcp/FcpMessage.java new file mode 100644 index 0000000..cac9196 --- /dev/null +++ b/src/net/pterodactylus/fcp/FcpMessage.java @@ -0,0 +1,197 @@ +/* + * jSite2 - FcpMessage.java - + * Copyright © 2008 David Roden + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +package net.pterodactylus.fcp; + +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.util.Collections; +import java.util.HashMap; +import java.util.Iterator; +import java.util.Map; +import java.util.Map.Entry; + +/** + * An FCP message. FCP messages consist of a name, an arbitrary amount of + * “fields” (i.e. key-value pairs), a message end marker, and optional payload + * data that follows the marker. + * + * @author David ‘Bombe’ Roden <bombe@freenetproject.org> + * @version $Id$ + */ +public class FcpMessage implements Iterable { + + /** Constant for the linefeed. */ + private static final String LINEFEED = "\r\n"; + + /** The name of the message. */ + private final String name; + + /** The fields of the message. */ + private final Map fields = new HashMap(); + + /** The optional payload input stream. */ + private InputStream payloadInputStream; + + /** + * Creates a new FCP message with the given name. + * + * @param name + * The name of the FCP message + */ + public FcpMessage(String name) { + this(name, null); + } + + /** + * Creates a new FCP message with the given name and the given payload input + * stream. The payload input stream is not read until the message is sent to + * the node using {@link FcpConnection#sendMessage(FcpMessage)}. + * + * @param name + * The name of the message + * @param payloadInputStream + * The payload of the message + */ + public FcpMessage(String name, InputStream payloadInputStream) { + this.name = name; + this.payloadInputStream = payloadInputStream; + } + + /** + * Returns the name of the message. + * + * @return The name of the message + */ + public String getName() { + return name; + } + + /** + * Checks whether this message has a field with the given name. + * + * @param field + * The name of the field to check for + * @return true if the message has a field with the given + * name, false otherwise + */ + public boolean hasField(String field) { + return fields.containsKey(field); + } + + /** + * Sets the field with the given name to the given value. If the field + * already exists in this message it is overwritten. + * + * @param field + * The name of the field + * @param value + * The value of the field + */ + public void setField(String field, String value) { + if ((field == null) || (value == null)) { + throw new NullPointerException(((field == null) ? "field " : "value ") + "must not be null"); + } + fields.put(field, value); + } + + /** + * Returns the value of the given field. + * + * @param field + * The name of the field + * @return The value of the field, or null if there is no + * such field + */ + public String getField(String field) { + return fields.get(field); + } + + /** + * Returns all fields of this message. + * + * @return All fields of this message + */ + public Map getFields() { + return Collections.unmodifiableMap(fields); + } + + /** + * {@inheritDoc} + */ + public Iterator iterator() { + return fields.keySet().iterator(); + } + + /** + * Sets the payload input stream of the message. + * + * @param payloadInputStream + * The payload input stream + */ + public void setPayloadInputStream(InputStream payloadInputStream) { + this.payloadInputStream = payloadInputStream; + } + + /** + * Writes this message to the given output stream. If the message has a + * payload (i.e. {@link #payloadInputStream} is not null) + * the payload is written to the given output stream after the message as + * well. That means that this method can only be called once because on the + * second invocation the payload input stream could not be read (again). + * + * @param outputStream + * The output stream to write the message to + * @throws IOException + * if an I/O error occurs + */ + public void write(OutputStream outputStream) throws IOException { + writeLine(outputStream, name); + for (Entry fieldEntry: fields.entrySet()) { + writeLine(outputStream, fieldEntry.getKey() + "=" + fieldEntry.getValue()); + } + writeLine(outputStream, "EndMessage"); + outputStream.flush(); + if (payloadInputStream != null) { + FcpUtils.copy(payloadInputStream, outputStream); + } + outputStream.flush(); + } + + // + // PRIVATE METHODS + // + + /** + * Writes the given line (followed by {@link #LINEFEED} to the given output + * stream, using UTF-8 as encoding. + * + * @param outputStream + * The output stream to write to + * @param line + * The line to write + * @throws IOException + * if an I/O error occurs + */ + private void writeLine(OutputStream outputStream, String line) throws IOException { + outputStream.write((line + LINEFEED).getBytes("UTF-8")); + } + +} diff --git a/src/net/pterodactylus/fcp/FcpTest.java b/src/net/pterodactylus/fcp/FcpTest.java new file mode 100644 index 0000000..a47cbca --- /dev/null +++ b/src/net/pterodactylus/fcp/FcpTest.java @@ -0,0 +1,94 @@ +/* + * jSite2 - FcpTest.java - + * Copyright © 2008 David Roden + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +package net.pterodactylus.fcp; + +import java.io.IOException; + +import junit.framework.TestCase; + +/** + * Tests various commands and the FCP connection. + * + * @author David ‘Bombe’ Roden <bombe@freenetproject.org> + * @version $Id$ + */ +public class FcpTest extends TestCase { + + /** The FCP connection. */ + private FcpConnection fcpConnection; + + /** + * {@inheritDoc} + */ + @Override + protected void setUp() throws Exception { + fcpConnection = new FcpConnection("wing"); + fcpConnection.connect(); + fcpConnection.sendMessage(new ClientHello("FcpTest")); + } + + /** + * {@inheritDoc} + */ + @Override + protected void tearDown() throws Exception { + fcpConnection.disconnect(); + } + + /** + * Tests the FCP connection be simply {@link #setUp() setting it up} and + * {@link #tearDown() tearing it down} again. + */ + public void testFcpConnection() { + /* do nothing. */ + } + + /** + * Generates an SSK key pair. + * + * @throws IOException + * if an I/O error occurs + * @throws InterruptedException + * if {@link Object#wait()} wakes up spuriously + */ + public void testGenerateSSK() throws IOException, InterruptedException { + final SSKKeypair[] keypair = new SSKKeypair[1]; + FcpAdapter fcpAdapter = new FcpAdapter() { + + /** + * {@inheritDoc} + */ + @Override + public void receivedSSKKeypair(FcpConnection fcpConnection, SSKKeypair sskKeypair) { + keypair[0] = sskKeypair; + synchronized (this) { + notify(); + } + } + }; + fcpConnection.addFcpListener(fcpAdapter); + synchronized (fcpAdapter) { + fcpConnection.sendMessage(new GenerateSSK()); + fcpAdapter.wait(); + } + assertNotNull("ssk keypair", keypair[0]); + } + +} diff --git a/src/net/pterodactylus/fcp/FcpUtils.java b/src/net/pterodactylus/fcp/FcpUtils.java new file mode 100644 index 0000000..a67e34b --- /dev/null +++ b/src/net/pterodactylus/fcp/FcpUtils.java @@ -0,0 +1,272 @@ +/* + * jSite2 - FcpUtils.java - + * Copyright © 2008 David Roden + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +package net.pterodactylus.fcp; + +import java.io.Closeable; +import java.io.EOFException; +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.net.Socket; +import java.util.StringTokenizer; +import java.util.concurrent.atomic.AtomicLong; + +/** + * Helper class with utility methods for the FCP protocol. + * + * @author David Roden + * @version $Id$ + */ +public class FcpUtils { + + /** Counter for unique identifiers. */ + private static AtomicLong counter = new AtomicLong(); + + /** + * Returns a unique identifier. + * + * @return A unique identifier + */ + public static String getUniqueIdentifier() { + return new StringBuilder().append(System.currentTimeMillis()).append('-').append(counter.getAndIncrement()).toString(); + } + + /** + * Parses an integer field, separated by ‘;’ and returns the parsed values. + * + * @param field + * The field to parse + * @return An array with the parsed values + * @throws NumberFormatException + * if a value can not be converted to a number + */ + public static int[] decodeMultiIntegerField(String field) throws NumberFormatException { + StringTokenizer fieldTokens = new StringTokenizer(field, ";"); + int[] result = new int[fieldTokens.countTokens()]; + int counter = 0; + while (fieldTokens.hasMoreTokens()) { + String fieldToken = fieldTokens.nextToken(); + result[counter++] = Integer.valueOf(fieldToken); + } + return result; + } + + /** + * Encodes the given integer array into a string, separating the values by + * ‘;’. + * + * @param values + * The values to encode + * @return The encoded values + */ + public static String encodeMultiIntegerField(int[] values) { + StringBuilder encodedField = new StringBuilder(); + for (int value: values) { + if (encodedField.length() > 0) { + encodedField.append(';'); + } + encodedField.append(value); + } + return encodedField.toString(); + } + + /** + * Encodes the given string array into a string, separating the values by + * ‘;’. + * + * @param values + * The values to encode + * @return The encoded values + */ + public static String encodeMultiStringField(String[] values) { + StringBuilder encodedField = new StringBuilder(); + for (String value: values) { + if (encodedField.length() > 0) { + encodedField.append(';'); + } + encodedField.append(value); + } + return encodedField.toString(); + } + + /** + * Tries to parse the given string into an int, returning -1 + * if the string can not be parsed. + * + * @param value + * The string to parse + * @return The parsed int, or -1 + */ + public static int safeParseInt(String value) { + return safeParseInt(value, -1); + } + + /** + * Tries to parse the given string into an int, returning + * defaultValue if the string can not be parsed. + * + * @param value + * The string to parse + * @param defaultValue + * The value to return if the string can not be parsed. + * @return The parsed int, or defaultValue + */ + public static int safeParseInt(String value, int defaultValue) { + try { + return Integer.valueOf(value); + } catch (NumberFormatException nfe1) { + return defaultValue; + } + } + + /** + * Tries to parse the given string into an long, returning -1 + * if the string can not be parsed. + * + * @param value + * The string to parse + * @return The parsed long, or -1 + */ + public static long safeParseLong(String value) { + return safeParseLong(value, -1); + } + + /** + * Tries to parse the given string into an long, returning + * defaultValue if the string can not be parsed. + * + * @param value + * The string to parse + * @param defaultValue + * The value to return if the string can not be parsed. + * @return The parsed long, or defaultValue + */ + public static long safeParseLong(String value, long defaultValue) { + try { + return Integer.valueOf(value); + } catch (NumberFormatException nfe1) { + return defaultValue; + } + } + + /** + * Closes the given socket. + * + * @param socket + * The socket to close + */ + public static void close(Socket socket) { + if (socket != null) { + try { + socket.close(); + } catch (IOException ioe1) { + /* ignore. */ + } + } + } + + /** + * Closes the given Closeable. + * + * @param closeable + * The Closeable to close + */ + public static void close(Closeable closeable) { + if (closeable != null) { + try { + closeable.close(); + } catch (IOException ioe1) { + /* ignore. */ + } + } + } + + /** + * Copies as many bytes as possible (i.e. until {@link InputStream#read()} + * returns -1) from the source input stream to the + * destination output stream. + * + * @param source + * The input stream to read from + * @param destination + * The output stream to write to + * @throws IOException + * if an I/O error occurs + */ + public static void copy(InputStream source, OutputStream destination) throws IOException { + copy(source, destination, -1); + } + + /** + * Copies length bytes from the source input stream to the + * destination output stream. If length is -1 + * as much bytes as possible will be copied (i.e. until + * {@link InputStream#read()} returns -1 to signal the end of + * the stream). + * + * @param source + * The input stream to read from + * @param destination + * The output stream to write to + * @param length + * The number of bytes to copy + * @throws IOException + * if an I/O error occurs + */ + public static void copy(InputStream source, OutputStream destination, long length) throws IOException { + copy(source, destination, length, 1 << 16); + } + + /** + * Copies length bytes from the source input stream to the + * destination output stream. If length is -1 + * as much bytes as possible will be copied (i.e. until + * {@link InputStream#read()} returns -1 to signal the end of + * the stream). + * + * @param source + * The input stream to read from + * @param destination + * The output stream to write to + * @param length + * The number of bytes to copy + * @param bufferSize + * The buffer size + * @throws IOException + * if an I/O error occurs + */ + public static void copy(InputStream source, OutputStream destination, long length, int bufferSize) throws IOException { + long remaining = length; + byte[] buffer = new byte[bufferSize]; + int read = 0; + while ((remaining == -1) || (remaining > 0)) { + read = source.read(buffer, 0, ((remaining > bufferSize) || (remaining == -1)) ? bufferSize : (int) remaining); + if (read == -1) { + if (length == -1) { + return; + } + throw new EOFException("stream reached eof"); + } + destination.write(buffer, 0, read); + remaining -= read; + } + } + +} diff --git a/src/net/pterodactylus/fcp/FileEntry.java b/src/net/pterodactylus/fcp/FileEntry.java new file mode 100644 index 0000000..058cc82 --- /dev/null +++ b/src/net/pterodactylus/fcp/FileEntry.java @@ -0,0 +1,299 @@ +/* + * jSite2 - FileEntry.java - + * Copyright © 2008 David Roden + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +package net.pterodactylus.fcp; + +import java.io.InputStream; +import java.util.HashMap; +import java.util.Map; + +/** + * Container class for file entry data. + * + * @see ClientPutComplexDir#addFileEntry(FileEntry) + * @author David ‘Bombe’ Roden <bombe@freenetproject.org> + * @version $Id$ + */ +public abstract class FileEntry { + + /** The name of the file. */ + protected final String name; + + /** The upload source of the file. */ + protected final UploadFrom uploadFrom; + + /** + * Creates a new file entry with the given name and upload source. + * + * @param name + * The name of the file + * @param uploadFrom + * The upload source of the file + */ + protected FileEntry(String name, UploadFrom uploadFrom) { + this.name = name; + this.uploadFrom = uploadFrom; + } + + /** + * Creates a new file entry for a file that should be transmitted to the + * node in the payload of the message. + * + * @param name + * The name of the file + * @param contentType + * The content type of the file, or null to let + * the node auto-detect it + * @param length + * The length of the file + * @param dataInputStream + * The input stream of the file + * @return A file entry + */ + public static FileEntry createDirectFileEntry(String name, String contentType, long length, InputStream dataInputStream) { + return new DirectFileEntry(name, contentType, length, dataInputStream); + } + + /** + * Creates a new file entry for a file that should be uploaded from disk. + * + * @param name + * The name of the file + * @param filename + * The name of the file on disk + * @param contentType + * The content type of the file, or null to let + * the node auto-detect it + * @param length + * The length of the file, or -1 to not specify a + * size + * @return A file entry + */ + public static FileEntry createDiskFileEntry(String name, String filename, String contentType, long length) { + return new DiskFileEntry(name, filename, contentType, length); + } + + /** + * Creates a new file entry for a file that redirects to another URI. + * + * @param name + * The name of the file + * @param targetURI + * The target URI of the redirect + * @return A file entry + */ + public static FileEntry createRedirectFileEntry(String name, String targetURI) { + return new RedirectFileEntry(name, targetURI); + } + + /** + * Returns the fields for this file entry. + * + * @return The fields for this file entry + */ + abstract Map getFields(); + + /** + * A file entry for a file that should be transmitted in the payload of the + * {@link ClientPutComplexDir} message. + * + * @author David ‘Bombe’ Roden <bombe@freenetproject.org> + * @version $Id$ + */ + static class DirectFileEntry extends FileEntry { + + /** The content type of the data. */ + private final String contentType; + + /** The length of the data. */ + private final long length; + + /** The input stream of the data. */ + private final InputStream inputStream; + + /** + * Creates a new direct file entry with content type auto-detection. + * + * @param name + * The name of the file + * @param length + * The length of the file + * @param inputStream + * The input stream of the file + */ + public DirectFileEntry(String name, long length, InputStream inputStream) { + this(name, null, length, inputStream); + } + + /** + * Creates a new direct file entry. + * + * @param name + * The name of the file + * @param contentType + * The content type of the file, or null to + * let the node auto-detect it + * @param length + * The length of the file + * @param inputStream + * The input stream of the file + */ + public DirectFileEntry(String name, String contentType, long length, InputStream inputStream) { + super(name, UploadFrom.direct); + this.contentType = contentType; + this.length = length; + this.inputStream = inputStream; + } + + /** + * {@inheritDoc} + */ + @Override + Map getFields() { + Map fields = new HashMap(); + fields.put("Name", name); + fields.put("UploadFrom", String.valueOf(uploadFrom)); + fields.put("DataLength", String.valueOf(length)); + if (contentType != null) { + fields.put("Metadata.ContentType", contentType); + } + return fields; + } + + /** + * Returns the input stream of the file. + * + * @return The input stream of the file + */ + InputStream getInputStream() { + return inputStream; + } + + } + + /** + * A file entry for a file that should be uploaded from the disk. + * + * @author David ‘Bombe’ Roden <bombe@freenetproject.org> + * @version $Id$ + */ + static class DiskFileEntry extends FileEntry { + + /** The name of the on-disk file. */ + private final String filename; + + /** The content type of the file. */ + private final String contentType; + + /** The length of the file. */ + private final long length; + + /** + * Creates a new disk file entry. + * + * @param name + * The name of the file + * @param filename + * The name of the on-disk file + * @param length + * The length of the file + */ + public DiskFileEntry(String name, String filename, long length) { + this(name, filename, null, length); + } + + /** + * Creates a new disk file entry. + * + * @param name + * The name of the file + * @param filename + * The name of the on-disk file + * @param contentType + * The content type of the file, or null to + * let the node auto-detect it + * @param length + * The length of the file + */ + public DiskFileEntry(String name, String filename, String contentType, long length) { + super(name, UploadFrom.disk); + this.filename = filename; + this.contentType = contentType; + this.length = length; + } + + /** + * {@inheritDoc} + */ + @Override + Map getFields() { + Map fields = new HashMap(); + fields.put("Name", name); + fields.put("UploadFrom", String.valueOf(uploadFrom)); + fields.put("Filename", filename); + if (length > -1) { + fields.put("DataSize", String.valueOf(length)); + } + if (contentType != null) { + fields.put("Metadata.ContentType", contentType); + } + return fields; + } + + } + + /** + * A file entry for a file that redirects to another URI. + * + * @author David ‘Bombe’ Roden <bombe@freenetproject.org> + * @version $Id$ + */ + static class RedirectFileEntry extends FileEntry { + + /** The target URI of the redirect. */ + private String targetURI; + + /** + * Creates a new redirect file entry. + * + * @param name + * The name of the file + * @param targetURI + * The target URI of the redirect + */ + public RedirectFileEntry(String name, String targetURI) { + super(name, UploadFrom.redirect); + this.targetURI = targetURI; + } + + /** + * {@inheritDoc} + */ + @Override + Map getFields() { + Map fields = new HashMap(); + fields.put("Name", name); + fields.put("UploadFrom", String.valueOf(uploadFrom)); + fields.put("TargetURI", targetURI); + return fields; + } + + } + +} diff --git a/src/net/pterodactylus/fcp/FinishedCompression.java b/src/net/pterodactylus/fcp/FinishedCompression.java new file mode 100644 index 0000000..20038b6 --- /dev/null +++ b/src/net/pterodactylus/fcp/FinishedCompression.java @@ -0,0 +1,78 @@ +/* + * jSite2 - FinishedCompression.java - + * Copyright © 2008 David Roden + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +package net.pterodactylus.fcp; + +/** + * A “FinishedCompression” message signals the client that the compression of + * the request data has been finished. + * + * @author David Roden <droden@gmail.com> + * @version $Id$ + */ +public class FinishedCompression extends BaseMessage { + + /** + * Creates a new “FinishedCompression” message that wraps the received + * message. + * + * @param receivedMessage + * The message that was recevied + */ + FinishedCompression(FcpMessage receivedMessage) { + super(receivedMessage); + } + + /** + * Returns the identifier of the request. + * + * @return The identifier of the request + */ + public String getIdentifier() { + return getField("Identifier"); + } + + /** + * Returns the ID of the codec that was used for compression. + * + * @return The ID of the codec that was used for compression + */ + public int getCodec() { + return FcpUtils.safeParseInt(getField("Codec")); + } + + /** + * Returns the original size of the data (i.e. before compression). + * + * @return The original size of the data + */ + public long getOriginalSize() { + return FcpUtils.safeParseLong(getField("OriginalSize")); + } + + /** + * Returns the compressed size of the data (i.e. after compression). + * + * @return The compressed size of the data + */ + public long getCompressedSize() { + return FcpUtils.safeParseLong(getField("CompressedSize")); + } + +} diff --git a/src/net/pterodactylus/fcp/GenerateSSK.java b/src/net/pterodactylus/fcp/GenerateSSK.java new file mode 100644 index 0000000..910362e --- /dev/null +++ b/src/net/pterodactylus/fcp/GenerateSSK.java @@ -0,0 +1,49 @@ +/* + * jSite2 - GenerateSSK.java - + * Copyright © 2008 David Roden + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +package net.pterodactylus.fcp; + +/** + * A “GenerateSSK” message. This message tells the node to generate a new SSK + * key pair. + * + * @author David ‘Bombe’ Roden <bombe@freenetproject.org> + * @version $Id$ + */ +public class GenerateSSK extends FcpMessage { + + /** + * Creates a new “GenerateSSK” message. + */ + public GenerateSSK() { + this(FcpUtils.getUniqueIdentifier()); + } + + /** + * Creates a new “GenerateSSK” message with the given client identifier. + * + * @param clientIdentifier + * The client identifier + */ + public GenerateSSK(String clientIdentifier) { + super("GenerateSSK"); + setField("Identifier", clientIdentifier); + } + +} diff --git a/src/net/pterodactylus/fcp/GetConfig.java b/src/net/pterodactylus/fcp/GetConfig.java new file mode 100644 index 0000000..c90b989 --- /dev/null +++ b/src/net/pterodactylus/fcp/GetConfig.java @@ -0,0 +1,134 @@ +/* + * jSite2 - GetConfig.java - + * Copyright © 2008 David Roden + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +package net.pterodactylus.fcp; + +/** + * The “GetConfig” command tells the node to send its configuration to the + * client. + * + * @author David ‘Bombe’ Roden <bombe@freenetproject.org> + * @version $Id$ + */ +public class GetConfig extends FcpMessage { + + /** + * Creates a new “GetConfig” command. + */ + public GetConfig() { + super("GetConfig"); + } + + /** + * Sets whether the {@link ConfigData} result message shall include the + * current values. + * + * @param withCurrent + * true to include current values in the result, + * false otherwise + */ + public void setWithCurrent(boolean withCurrent) { + setField("WithCurrent", String.valueOf(withCurrent)); + } + + /** + * Sets whether the {@link ConfigData} result message shall include the + * short descriptions. + * + * @param withShortDescription + * true to include the short descriptions in the + * result, false otherwise + */ + public void setWithShortDescription(boolean withShortDescription) { + setField("WithShortDescription", String.valueOf(withShortDescription)); + } + + /** + * Sets whether the {@link ConfigData} result message shall include the long + * descriptions. + * + * @param withLongDescription + * true to include the long descriptions in the + * result, false otherwise + */ + public void setWithLongDescription(boolean withLongDescription) { + setField("WithLongDescription", String.valueOf(withLongDescription)); + } + + /** + * Sets whether the {@link ConfigData} result message shall include the data + * types. + * + * @param withDataTypes + * true to include the data types in the result, + * false otherwise + */ + public void setWithDataTypes(boolean withDataTypes) { + setField("WithDataTypes", String.valueOf(withDataTypes)); + } + + /** + * Sets whether the {@link ConfigData} result message shall include the + * defaults. + * + * @param setWithDefaults + * true to include the defaults in the result, + * false otherwise + */ + public void setWithDefaults(boolean setWithDefaults) { + setField("WithDefaults", String.valueOf(setWithDefaults)); + } + + /** + * Sets whether the {@link ConfigData} result message shall include the sort + * order. + * + * @param withSortOrder + * true to include the sort order in the result, + * false otherwise + */ + public void setWithSortOrder(boolean withSortOrder) { + setField("WithSortOrder", String.valueOf(withSortOrder)); + } + + /** + * Sets whether the {@link ConfigData} result message shall include the + * expert flag. + * + * @param withExpertFlag + * true to include the expert flag in the result, + * false otherwise + */ + public void setWithExpertFlag(boolean withExpertFlag) { + setField("WithExpertFlag", String.valueOf(withExpertFlag)); + } + + /** + * Sets whether the {@link ConfigData} result message shall include the + * force-write flag. + * + * @param withForceWriteFlag + * true to include the force-write flag in the + * result, false otherwise + */ + public void setWithForceWriteFlag(boolean withForceWriteFlag) { + setField("WithForceWriteFlag", String.valueOf(withForceWriteFlag)); + } + +} diff --git a/src/net/pterodactylus/fcp/GetFailed.java b/src/net/pterodactylus/fcp/GetFailed.java new file mode 100644 index 0000000..cd14e96 --- /dev/null +++ b/src/net/pterodactylus/fcp/GetFailed.java @@ -0,0 +1,201 @@ +/* + * jSite2 - GetFailed.java - + * Copyright © 2008 David Roden + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +package net.pterodactylus.fcp; + +import java.util.ArrayList; +import java.util.List; +import java.util.Map; +import java.util.Map.Entry; + +/** + * The “GetFailed” message signals the client that a {@link ClientGet} request + * has failed. This also means that no further progress messages for that + * request will be sent. + * + * @author David ‘Bombe’ Roden <bombe@freenetproject.org> + * @version $Id$ + */ +public class GetFailed extends BaseMessage { + + /** + * Creates a new “GetFailed” message that wraps the received message. + * + * @param receivedMessage + * The received message + */ + GetFailed(FcpMessage receivedMessage) { + super(receivedMessage); + } + + /** + * Returns the code of the error. + * + * @return The code of the error, or -1 if the error code + * could not be parsed + */ + public int getCode() { + return FcpUtils.safeParseInt(getField("Code")); + } + + /** + * Returns the identifier of the request. + * + * @return The identifier of the request + */ + public String getIdentifier() { + return getField("Identifier"); + } + + /** + * Returns whether the request is on the global queue. + * + * @return true if the request is on the global queue, + * false if it is on the client-local queue + */ + public boolean isGlobal() { + return Boolean.valueOf(getField("Global")); + } + + /** + * Returns the description of the error code. + * + * @return The description of the error code + */ + public String getCodeDescription() { + return getField("CodeDescription"); + } + + /** + * Returns the extra description of the error. + * + * @return The extra description of the error + */ + public String getExtraDescription() { + return getField("ExtraDescription"); + } + + /** + * Returns the short description of the error. + * + * @return The short description of the error + */ + public String getShortCodeDescription() { + return getField("ShortCodeDescription"); + } + + /** + * Returns the expected data length, if already knows. + * + * @return The expected data length, or -1 if the length + * could not be parsed + */ + public long getExpectedDataLength() { + return FcpUtils.safeParseLong(getField("ExpectedDataLength")); + } + + /** + * Returns the expected content type of the request. + * + * @return The expected content type + */ + public String getExpectedMetadataContentType() { + return getField("ExpectedMetadata.ContentType"); + } + + /** + * Returns whether the expected values (see {@link #getExpectedDataLength()} + * and {@link #getExpectedMetadataContentType()}) have already been + * finalized and can be trusted. If the values have not been finalized that + * can change over time. + * + * @return true if the expected values have already been + * finalized, false otherwise + */ + public boolean isFinalizedExpected() { + return Boolean.valueOf(getField("FinalizedExpected")); + } + + /** + * Returns the URI the request is redirected to (in case of a request for a + * USK). This is returned so that client applications know that the URI of + * the key has updated. + * + * @return The URI the request was redirected to + */ + public String getRedirectURI() { + return getField("RedirectURI"); + } + + /** + * Returns a list of complex error codes with the message. Use + * {@link #getComplexErrorDescription(int)} and + * {@link #getComplexErrorCount(int)} to get details. + * + * @return A list of complex error codes + */ + public int[] getComplexErrorCodes() { + Map allFields = getFields(); + List errorCodeList = new ArrayList(); + for (Entry field: allFields.entrySet()) { + String fieldKey = field.getKey(); + if (fieldKey.startsWith("Errors.")) { + int nextDot = fieldKey.indexOf('.', 7); + if (nextDot > -1) { + int errorCode = FcpUtils.safeParseInt(fieldKey.substring(7, nextDot)); + if (errorCode != -1) { + errorCodeList.add(errorCode); + } + } + } + } + int[] errorCodes = new int[errorCodeList.size()]; + int errorIndex = 0; + for (int errorCode: errorCodeList) { + errorCodes[errorIndex++] = errorCode; + } + return errorCodes; + } + + /** + * Returns the description of the complex error. You should only hand it + * error codes you got from {@link #getComplexErrorCodes()}! + * + * @param errorCode + * The error code + * @return The description of the complex error + */ + public String getComplexErrorDescription(int errorCode) { + return getField("Errors." + errorCode + ".Description"); + } + + /** + * Returns the count of the complex error. You should only hand it error + * codes you got from {@link #getComplexErrorCodes()}! + * + * @param errorCode + * The error code + * @return The count of the complex error, or -1 if the count + * could not be parsed + */ + public int getComplexErrorCount(int errorCode) { + return FcpUtils.safeParseInt(getField("Errors." + errorCode + ".Count")); + } + +} diff --git a/src/net/pterodactylus/fcp/GetNode.java b/src/net/pterodactylus/fcp/GetNode.java new file mode 100644 index 0000000..778c308 --- /dev/null +++ b/src/net/pterodactylus/fcp/GetNode.java @@ -0,0 +1,65 @@ +/* + * jSite2 - GetNode.java - + * Copyright © 2008 David Roden + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +package net.pterodactylus.fcp; + +/** + * The “GetNode” command returns the darknet or opennet noderef of the node, + * optionally including private and volatile data. + * + * @author David ‘Bombe’ Roden <bombe@freenetproject.org> + * @version $Id$ + */ +public class GetNode extends FcpMessage { + + /** + * Creates a “GetNode” command that returns the darknet noderef of the node. + */ + public GetNode() { + this(null, null, null); + } + + /** + * Creates a “GetNode” command that returns the request noderef of the node, + * including private and volatile data, if requested. If any of the Boolean + * parameters are null the parameter is ignored and the + * node’s default value is used. + * + * @param giveOpennetRef + * true to request the opennet noderef, + * false for darknet + * @param withPrivate + * true to include private data in the noderef + * @param withVolatile + * true to include volatile data in the noderef + */ + public GetNode(Boolean giveOpennetRef, Boolean withPrivate, Boolean withVolatile) { + super("GetNode"); + if (giveOpennetRef != null) { + setField("GiveOpennetRef", String.valueOf(giveOpennetRef)); + } + if (withPrivate != null) { + setField("WithPrivate", String.valueOf(withPrivate)); + } + if (withVolatile != null) { + setField("WithVolatile", String.valueOf(withVolatile)); + } + } + +} diff --git a/src/net/pterodactylus/fcp/GetPluginInfo.java b/src/net/pterodactylus/fcp/GetPluginInfo.java new file mode 100644 index 0000000..bae14da --- /dev/null +++ b/src/net/pterodactylus/fcp/GetPluginInfo.java @@ -0,0 +1,56 @@ +/* + * jSite2 - GetPluginInfo.java - + * Copyright © 2008 David Roden + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +package net.pterodactylus.fcp; + +/** + * The “GetPluginInfo” message requests information about a plugin from the + * node, which will response with a {@link PluginInfo} message. + * + * @author David ‘Bombe’ Roden <bombe@freenetproject.org> + * @version $Id$ + */ +public class GetPluginInfo extends FcpMessage { + + /** + * Creates a new “GetPluginInfo” message. + * + * @param pluginName + * The name of the plugin + * @param identifier + * The identifier of the request + */ + public GetPluginInfo(String pluginName, String identifier) { + super("GetPluginInfo"); + setField("PluginName", pluginName); + setField("Identifier", identifier); + } + + /** + * Sets whether detailed information about the plugin is wanted. + * + * @param detailed + * true to request detailed information about the + * plugin, false otherwise + */ + public void setDetailed(boolean detailed) { + setField("Detailed", String.valueOf(detailed)); + } + +} diff --git a/src/net/pterodactylus/fcp/GetRequestStatus.java b/src/net/pterodactylus/fcp/GetRequestStatus.java new file mode 100644 index 0000000..3941df6 --- /dev/null +++ b/src/net/pterodactylus/fcp/GetRequestStatus.java @@ -0,0 +1,66 @@ +/* + * jSite2 - GetRequestStatus.java - + * Copyright © 2008 David Roden + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +package net.pterodactylus.fcp; + +/** + * The “GetRequestStatus” message is used request status information about a + * running request. It is also the only way to trigger a download of a persisted + * completed {@link ClientGet} with a return type of {@link ReturnType#direct}. + * + * @author David ‘Bombe’ Roden <bombe@freenetproject.org> + * @version $Id$ + */ +public class GetRequestStatus extends FcpMessage { + + /** + * Creates a new “GetRequestStatus” message. + * + * @param identifier + * The identifier of the request + */ + public GetRequestStatus(String identifier) { + super("GetRequestStatus"); + setField("Identifier", identifier); + } + + /** + * Sets whether the request is on the global queue. + * + * @param global + * true if the request is on the global queue, + * false if it is on the client-local queue + */ + public void setGlobal(boolean global) { + setField("Global", String.valueOf(global)); + } + + /** + * Sets whether the omit the transmission of the request data in a + * {@link AllData} message. + * + * @param onlyData + * true to skip transmission of data, + * false to download data + */ + public void setOnlyData(boolean onlyData) { + setField("OnlyData", String.valueOf(onlyData)); + } + +} diff --git a/src/net/pterodactylus/fcp/IdentifierCollision.java b/src/net/pterodactylus/fcp/IdentifierCollision.java new file mode 100644 index 0000000..67ec01c --- /dev/null +++ b/src/net/pterodactylus/fcp/IdentifierCollision.java @@ -0,0 +1,61 @@ +/* + * jSite2 - IdentifierCollision.java - + * Copyright © 2008 David Roden + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +package net.pterodactylus.fcp; + +/** + * The “IdentifierCollision” message signals the client that the identifier + * chosen for a request is already existing. + * + * @author David ‘Bombe’ Roden <bombe@freenetproject.org> + * @version $Id$ + */ +public class IdentifierCollision extends BaseMessage { + + /** + * Creates a new “IdentifierCollision” message that wraps the received + * message. + * + * @param receivedMessage + * The received message + */ + IdentifierCollision(FcpMessage receivedMessage) { + super(receivedMessage); + } + + /** + * Returns the identifier of the request. + * + * @return The identifier of the request + */ + public String getIdentifier() { + return getField("Identifier"); + } + + /** + * Returns whether the request is on the global queue. + * + * @return true if the request is on the global queue, + * false if it is on the client-local queue + */ + public boolean isGlobal() { + return Boolean.valueOf(getField("Global")); + } + +} diff --git a/src/net/pterodactylus/fcp/ListPeer.java b/src/net/pterodactylus/fcp/ListPeer.java new file mode 100644 index 0000000..7376b85 --- /dev/null +++ b/src/net/pterodactylus/fcp/ListPeer.java @@ -0,0 +1,44 @@ +/* + * jSite2 - ListPeer.java - + * Copyright © 2008 David Roden + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +package net.pterodactylus.fcp; + +/** + * The “ListPeer” request asks the node about the details of a given peer. + * + * @author David ‘Bombe’ Roden <bombe@freenetproject.org> + * @version $Id$ + */ +public class ListPeer extends FcpMessage { + + /** + * Creates a new “ListPeer” request that returns information about the node + * specified by nodeIdentifier. nodeIdentifier + * can be of several formats: The node’s name, its identity, or its IP + * address and port (connection with a ‘:’). + * + * @param nodeIdentifier + * The identifier of the node to get details about + */ + public ListPeer(String nodeIdentifier) { + super("ListPeer"); + setField("NodeIdentifier", nodeIdentifier); + } + +} diff --git a/src/net/pterodactylus/fcp/ListPeerNotes.java b/src/net/pterodactylus/fcp/ListPeerNotes.java new file mode 100644 index 0000000..f43edef --- /dev/null +++ b/src/net/pterodactylus/fcp/ListPeerNotes.java @@ -0,0 +1,43 @@ +/* + * jSite2 - ListPeerNotes.java - + * Copyright © 2008 David Roden + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +package net.pterodactylus.fcp; + +/** + * A “ListPeerNodes” request tells the node to list all notes that have been + * entered for a node. Note that notes are only supported for darknet nodes. + * + * @author David ‘Bombe’ Roden <bombe@freenetproject.org> + * @version $Id$ + */ +public class ListPeerNotes extends FcpMessage { + + /** + * Creates a new “ListPeerNotes” request that lists all notes of the + * specified node. + * + * @param nodeIdentifier + * The identifier of the node + */ + public ListPeerNotes(String nodeIdentifier) { + super("ListPeerNotes"); + setField("NodeIdentifier", nodeIdentifier); + } + +} diff --git a/src/net/pterodactylus/fcp/ListPeers.java b/src/net/pterodactylus/fcp/ListPeers.java new file mode 100644 index 0000000..3ae3637 --- /dev/null +++ b/src/net/pterodactylus/fcp/ListPeers.java @@ -0,0 +1,54 @@ +/* + * jSite2 - ListPeers.java - + * Copyright © 2008 David Roden + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +package net.pterodactylus.fcp; + +/** + * The “ListPeer” requests asks the node for a list of all peers it has. + * + * @author David ‘Bombe’ Roden <bombe@freenetproject.org> + * @version $Id$ + */ +public class ListPeers extends FcpMessage { + + /** + * Creates a new “ListPeers” request that only includes basic data of the + * peers. + */ + public ListPeers() { + this(false, false); + } + + /** + * Creates a new “ListPeers” request that includes wanted data of the peers. + * + * @param withMetadata + * If true metadata of the peers is included in + * the reply + * @param withVolatile + * if true volatile data of the peers is included + * in the reply + */ + public ListPeers(boolean withMetadata, boolean withVolatile) { + super("ListPeers"); + setField("WithMetadata", String.valueOf(withMetadata)); + setField("WithVolatile", String.valueOf(withVolatile)); + } + +} diff --git a/src/net/pterodactylus/fcp/ListPersistentRequests.java b/src/net/pterodactylus/fcp/ListPersistentRequests.java new file mode 100644 index 0000000..b8908ba --- /dev/null +++ b/src/net/pterodactylus/fcp/ListPersistentRequests.java @@ -0,0 +1,40 @@ +/* + * jSite2 - ListPersistentRequests.java - + * Copyright © 2008 David Roden + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +package net.pterodactylus.fcp; + +/** + * Command to tell the node to list all persistent requests from the current + * queue, which is either the global queue or the client-local queue, depending + * on your {@link WatchGlobal} status. + * + * @author David ‘Bombe’ Roden <bombe@freenetproject.org> + * @version $Id$ + */ +public class ListPersistentRequests extends FcpMessage { + + /** + * Creates a new “ListPersistentRequests” command that lists all persistent + * requests in the current queue. + */ + public ListPersistentRequests() { + super("ListPersistentRequests"); + } + +} diff --git a/src/net/pterodactylus/fcp/ModifyConfig.java b/src/net/pterodactylus/fcp/ModifyConfig.java new file mode 100644 index 0000000..8f46d8d --- /dev/null +++ b/src/net/pterodactylus/fcp/ModifyConfig.java @@ -0,0 +1,52 @@ +/* + * jSite2 - ModifyConfig.java - + * Copyright © 2008 David Roden + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +package net.pterodactylus.fcp; + +/** + * The “ModifyConfig” message is used to change the node’s configuration. + * + * @author David ‘Bombe’ Roden <bombe@freenetproject.org> + * @version $Id$ + */ +public class ModifyConfig extends FcpMessage { + + /** + * Creates a new “ModifyConfig” message. + */ + public ModifyConfig() { + super("ModifyConfig"); + } + + /** + * Sets the option with the given name to the given value. + * + * @param option + * The name of the option + * @param value + * The value of the option + */ + public void setOption(String option, String value) { + if (option.indexOf('.') == -1) { + throw new IllegalArgumentException("invalid option name"); + } + setField(option, value); + } + +} diff --git a/src/net/pterodactylus/fcp/ModifyPeer.java b/src/net/pterodactylus/fcp/ModifyPeer.java new file mode 100644 index 0000000..6841cab --- /dev/null +++ b/src/net/pterodactylus/fcp/ModifyPeer.java @@ -0,0 +1,58 @@ +/* + * jSite2 - ModifyPeer.java - + * Copyright © 2008 David Roden + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +package net.pterodactylus.fcp; + +/** + * The “ModifyPeer” request lets you modify certain properties of a peer. + * + * @author David ‘Bombe’ Roden <bombe@freenetproject.org> + * @version $Id$ + */ +public class ModifyPeer extends FcpMessage { + + /** + * Creates a new “ModifyPeer” request. All Boolean parameters may be null to + * not influence the current setting. + * + * @param nodeIdentifier + * The identifier of the node, i.e. name, identity, or IP address + * and port + * @param allowLocalAddresses + * Whether to allow local addresses from this node + * @param disabled + * Whether the node is disabled + * @param listenOnly + * Whether your node should not try to connect the node + */ + public ModifyPeer(String nodeIdentifier, Boolean allowLocalAddresses, Boolean disabled, Boolean listenOnly) { + super("ModifyPeer"); + setField("NodeIdentifier", nodeIdentifier); + if (allowLocalAddresses != null) { + setField("AllowLocalAddresses", String.valueOf(allowLocalAddresses)); + } + if (disabled != null) { + setField("IsDisabled", String.valueOf(disabled)); + } + if (listenOnly != null) { + setField("IsListenOnly", String.valueOf(listenOnly)); + } + } + +} diff --git a/src/net/pterodactylus/fcp/ModifyPeerNote.java b/src/net/pterodactylus/fcp/ModifyPeerNote.java new file mode 100644 index 0000000..b1cd119 --- /dev/null +++ b/src/net/pterodactylus/fcp/ModifyPeerNote.java @@ -0,0 +1,51 @@ +/* + * jSite2 - ModifyPeerNote.java - + * Copyright © 2008 David Roden + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +package net.pterodactylus.fcp; + +/** + * The “ModifyPeerNote” command modifies a peer note. + * + * @author David ‘Bombe’ Roden <bombe@freenetproject.org> + * @version $Id$ + */ +public class ModifyPeerNote extends FcpMessage { + + /** + * Creates a new “ModifyPeerNote” request that changes peer note of the + * given type and node to the given text. + * + * @see PeerNote + * @param nodeIdentifier + * The identifier of the node, i.e. name, identity, or IP address + * and port + * @param noteText + * The base64-encoded text + * @param peerNoteType + * The type of the note to change, possible values are only + * {@link PeerNote#TYPE_PRIVATE_PEER_NOTE} at the moment + */ + public ModifyPeerNote(String nodeIdentifier, String noteText, int peerNoteType) { + super("ModifyPeer"); + setField("NodeIdentifier", nodeIdentifier); + setField("NoteText", noteText); + setField("PeerNoteType", String.valueOf(peerNoteType)); + } + +} diff --git a/src/net/pterodactylus/fcp/ModifyPersistentRequest.java b/src/net/pterodactylus/fcp/ModifyPersistentRequest.java new file mode 100644 index 0000000..2a4bc3c --- /dev/null +++ b/src/net/pterodactylus/fcp/ModifyPersistentRequest.java @@ -0,0 +1,67 @@ +/* + * jSite2 - ModifyPersistentRequest.java - + * Copyright © 2008 David Roden + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +package net.pterodactylus.fcp; + +/** + * A “ModifyPersistentRequest” is used to modify certain properties of a + * persistent request while it is running. + * + * @author David ‘Bombe’ Roden <bombe@freenetproject.org> + * @version $Id$ + */ +public class ModifyPersistentRequest extends FcpMessage { + + /** + * Creates a new “ModifyPersistentRequest” that changes the specified + * request. + * + * @param requestIdentifier + * The identifier of the request + * @param global + * true if the request is on the global queue, + * false if it is on the client-local queue + */ + public ModifyPersistentRequest(String requestIdentifier, boolean global) { + super("ModifyPersistentRequest"); + setField("Identifier", requestIdentifier); + setField("Global", String.valueOf(global)); + } + + /** + * Sets the new client token of the request. + * + * @param newClientToken + * The new client token of the request + */ + public void setClientToken(String newClientToken) { + setField("ClientToken", newClientToken); + } + + /** + * Sets the new priority of the request. + * + * @param newPriority + * The new priority of the request + */ + public void setPriority(Priority newPriority) { + setField("PriorityClass", String.valueOf(newPriority)); + } + +} diff --git a/src/net/pterodactylus/fcp/NodeData.java b/src/net/pterodactylus/fcp/NodeData.java new file mode 100644 index 0000000..ab4845a --- /dev/null +++ b/src/net/pterodactylus/fcp/NodeData.java @@ -0,0 +1,178 @@ +/* + * jSite2 - NodeData.java - + * Copyright © 2008 David Roden + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +package net.pterodactylus.fcp; + +/** + * The “NodeData” contains the noderef of the node, along with additional data. + * + * @author David ‘Bombe’ Roden <bombe@freenetproject.org> + * @version $Id$ + */ +public class NodeData extends BaseMessage { + + /** The noderef of the node. */ + private final NodeRef nodeRef; + + /** + * Creates a new “NodeData” message that wraps the received message. + * + * @param receivedMessage + * The received message + */ + NodeData(FcpMessage receivedMessage) { + super(receivedMessage); + nodeRef = new NodeRef(receivedMessage); + } + + /** + * Returns the noderef of the node. + * + * @return The noderef of the node + */ + public NodeRef getNodeRef() { + return nodeRef; + } + + /** + * Returns the last good version, i.e. the oldest version the node will + * connect to. + * + * @return The last good version + */ + public Version getLastGoodVersion() { + return nodeRef.getLastGoodVersion(); + } + + /** + * Returns the signature of the noderef. + * + * @return The signature of the noderef + */ + public String getSignature() { + return nodeRef.getSignature(); + } + + /** + * Returns whether the noderef is the opennet noderef of the node + * + * @return true if the noderef is the opennet noderef of the + * node, false otherwise + */ + public boolean isOpennet() { + return nodeRef.isOpennet(); + } + + /** + * Returns the identity of the node + * + * @return The identity of the node + */ + public String getIdentity() { + return nodeRef.getIdentity(); + } + + /** + * Returns the name of the node. + * + * @return The name of the node + */ + public String getMyName() { + return nodeRef.getMyName(); + } + + /** + * Returns the version of the node. + * + * @return The version of the node + */ + public Version getVersion() { + return nodeRef.getVersion(); + } + + /** + * Returns IP addresses and port number of the node. + * + * @return The IP addresses and port numbers of the node + */ + public String getPhysicalUDP() { + return nodeRef.getPhysicalUDP(); + } + + /** + * Returns the ARK of the node. + * + * @return The ARK of the node + */ + public ARK getARK() { + return nodeRef.getARK(); + } + + /** + * Returns the public key of the node. + * + * @return The public key of the node + */ + public String getDSAPublicKey() { + return nodeRef.getDSAPublicKey(); + } + + /** + * Returns the private key of the node. + * + * @return The private key of the node + */ + public String getDSKPrivateKey() { + return getField("dsaPrivKey.x"); + } + + /** + * Returns the DSA group of the node. + * + * @return The DSA group of the node + */ + public DSAGroup getDSAGroup() { + return nodeRef.getDSAGroup(); + } + + /** + * Returns the negotiation types supported by the node. + * + * @return The node’s supported negotiation types + */ + public int[] getNegotiationTypes() { + return nodeRef.getNegotiationTypes(); + } + + /** + * Returns one of the volatile fields from the message. The given field name + * is prepended with “volatile.” so if you want to get the value of the + * field with the name “volatile.freeJavaMemory” you only need to specify + * “freeJavaMemory”. + * + * @param field + * The name of the field + * @return The value of the field, or null if there is no + * such field + */ + public String getVolatile(String field) { + return getField("volatile." + field); + } + +} diff --git a/src/net/pterodactylus/fcp/NodeHello.java b/src/net/pterodactylus/fcp/NodeHello.java new file mode 100644 index 0000000..e4665e0 --- /dev/null +++ b/src/net/pterodactylus/fcp/NodeHello.java @@ -0,0 +1,193 @@ +/* + * jSite2 - NodeHello.java - + * Copyright © 2008 David Roden + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +package net.pterodactylus.fcp; + +/** + * Some convenience methods for parsing a “NodeHello” message from the node. + * + * @author David Roden + * @version $Id$ + */ +public class NodeHello extends BaseMessage { + + /** + * Createa a new “NodeHello” message that wraps the received message. + * + * @param receivedMessage + * The received FCP message + */ + NodeHello(FcpMessage receivedMessage) { + super(receivedMessage); + } + + /** + * Returns the build of the node. This may not be a number but also a string + * like “@custom@” in case you built the node yourself. + * + * @return The build of the node + */ + public String getBuild() { + return getField("Build"); + } + + /** + * Returns the build number of the node. This may not be a number but also a + * string like “@custom@” in case you built the node yourself. + * + * @return The build number of the node, or -1 if the build + * number could not be determined + */ + public int getBuildNumber() { + return FcpUtils.safeParseInt(getBuild()); + } + + /** + * Returns the number of compression codecs. + * + * @return The number of compression codecs + */ + public String getCompressionCodecs() { + return getField("CompressionCodecs"); + } + + /** + * Returns the number of compression codecs. + * + * @return The number of compression codecs, or -1 if the + * number of compression codecs could not be determined + */ + public int getCompressionCodecsNumber() { + return FcpUtils.safeParseInt(getCompressionCodecs()); + } + + /** + * Returns the unique connection identifier. + * + * @return The connection identifier + */ + public String getConnectionIdentifier() { + return getField("ConnectionIdentifier"); + } + + /** + * Returns the build of the external library file. + * + * @return The build of the external library file + */ + public String getExtBuild() { + return getField("ExtBuild"); + } + + /** + * Returns the build number of the external library file. + * + * @return The build number of the external library file, or -1 + * if the build number could not be determined + */ + public int getExtBuildNumber() { + return FcpUtils.safeParseInt(getExtBuild()); + } + + /** + * Returns the revision of the external library file. + * + * @return The revision of the external library file + */ + public String getExtRevision() { + return getField("ExtRevision"); + } + + /** + * Returns the revision number of the external library file. + * + * @return The revision number of the external library file, or + * -1 if the revision number could not be determined + */ + public int getExtRevisionNumber() { + return FcpUtils.safeParseInt(getExtRevision()); + } + + /** + * Returns the FCP version the node speaks. + * + * @return The FCP version the node speaks + */ + public String getFCPVersion() { + return getField("FCPVersion"); + } + + /** + * Returns the make of the node, e.g. “Fred” (freenet reference + * implementation). + * + * @return The make of the node + */ + public String getNode() { + return getField("Node"); + } + + /** + * Returns the language of the node as 2-letter code, e.g. “en” or “de”. + * + * @return The language of the node + */ + public String getNodeLanguage() { + return getField("NodeLanguage"); + } + + /** + * Returns the revision of the node. + * + * @return The revision of the node + */ + public String getRevision() { + return getField("Revision"); + } + + /** + * Returns the revision number of the node. + * + * @return The revision number of the node, or -1 if the + * revision number coult not be determined + */ + public int getRevisionNumber() { + return FcpUtils.safeParseInt(getRevision()); + } + + /** + * Returns whether the node is currently is testnet mode. + * + * @return true if the node is currently in testnet mode, + * false otherwise + */ + public boolean getTestnet() { + return Boolean.valueOf(getField("Testnet")); + } + + /** + * Returns the version of the node. + * + * @return The version of the node + */ + public String getVersion() { + return getField("Version"); + } + +} diff --git a/src/net/pterodactylus/fcp/NodeRef.java b/src/net/pterodactylus/fcp/NodeRef.java new file mode 100644 index 0000000..d85c3d4 --- /dev/null +++ b/src/net/pterodactylus/fcp/NodeRef.java @@ -0,0 +1,355 @@ +/* + * jSite2 - NodeRef.java - + * Copyright © 2008 David Roden + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +package net.pterodactylus.fcp; + +/** + * A reference for a node. The noderef contains all data that is necessary to + * establish a trusted and secure connection to the node. + * + * @author David ‘Bombe’ Roden <bombe@freenetproject.org> + * @version $Id$ + */ +public class NodeRef { + + /** The identity of the node. */ + private String identity; + + /** Whether the node is an opennet peer. */ + private boolean opennet; + + /** The name of the node. */ + private String name; + + /** The location of the node. */ + private double location; + + /** The IP addresses and ports of the node. */ + private String physicalUDP; + + /** The ARK of the node. */ + private ARK ark; + + /** The public DSA key of the node. */ + private String dsaPublicKey; + + /** The DSA group of the node. */ + private DSAGroup dsaGroup; + + /** The node’s supported negotiation types. */ + private int[] negotiationTypes; + + /** The version of the node. */ + private Version version; + + /** The oldest version the node will connect to. */ + private Version lastGoodVersion; + + /** Whether the node is a testnet node. */ + private boolean testnet; + + /** The signature of the reference. */ + private String signature; + + /** + * Creates a new, empty noderef. + */ + public NodeRef() { + /* intentionally left blank. */ + } + + /** + * Creates a new noderef that is initialized with fields from the given + * message. + * + * @param fromMessage + * The message to get initial values for the noderef from + */ + public NodeRef(FcpMessage fromMessage) { + identity = fromMessage.getField("identity"); + opennet = Boolean.valueOf(fromMessage.getField("opennet")); + name = fromMessage.getField("myName"); + if (fromMessage.hasField("location")) { + location = Double.valueOf(fromMessage.getField("location")); + } + physicalUDP = fromMessage.getField("physical.udp"); + ark = new ARK(fromMessage.getField("ark.pubURI"), fromMessage.getField("ark.privURI"), fromMessage.getField("ark.number")); + dsaPublicKey = fromMessage.getField("dsaPubKey.y"); + dsaGroup = new DSAGroup(fromMessage.getField("dsaGroup.b"), fromMessage.getField("dsaGroup.p"), fromMessage.getField("dsaGroup.q")); + negotiationTypes = FcpUtils.decodeMultiIntegerField(fromMessage.getField("auth.negTypes")); + version = new Version(fromMessage.getField("version")); + lastGoodVersion = new Version(fromMessage.getField("lastGoodVersion")); + testnet = Boolean.valueOf(fromMessage.getField("testnet")); + signature = fromMessage.getField("sig"); + } + + /** + * Returns the identity of the node. + * + * @return The identity of the node + */ + public String getIdentity() { + return identity; + } + + /** + * Sets the identity of the node. + * + * @param identity + * The identity of the node + */ + public void setIdentity(String identity) { + this.identity = identity; + } + + /** + * Returns whether the node is an opennet peer. + * + * @return true if the node is an opennet peer, + * false otherwise + */ + public boolean isOpennet() { + return opennet; + } + + /** + * Sets whether the node is an opennet peer. + * + * @param opennet + * true if the node is an opennet peer, + * false otherwise + */ + public void setOpennet(boolean opennet) { + this.opennet = opennet; + } + + /** + * Returns the name of the node. If the node is an opennet peer, it will not + * have a name! + * + * @return The name of the node, or null if the node is an + * opennet peer + */ + public String getMyName() { + return name; + } + + /** + * Sets the name of the peer. + * + * @param name + * The name of the peer + */ + public void setName(String name) { + this.name = name; + } + + /** + * Returns the location of the node. + * + * @return The location of the node + */ + public double getLocation() { + return location; + } + + /** + * Sets the location of the node + * + * @param location + * The location of the node + */ + public void setLocation(double location) { + this.location = location; + } + + /** + * Returns the IP addresses and port numbers of the node. + * + * @return The IP addresses and port numbers of the node + */ + public String getPhysicalUDP() { + return physicalUDP; + } + + /** + * Sets the IP addresses and port numbers of the node. + * + * @param physicalUDP + * The IP addresses and port numbers of the node + */ + public void setPhysicalUDP(String physicalUDP) { + this.physicalUDP = physicalUDP; + } + + /** + * Returns the ARK of the node. + * + * @return The ARK of the node + */ + public ARK getARK() { + return ark; + } + + /** + * Sets the ARK of the node. + * + * @param ark + * The ARK of the node + */ + public void setARK(ARK ark) { + this.ark = ark; + } + + /** + * Returns the public DSA key of the node. + * + * @return The public DSA key of the node + */ + public String getDSAPublicKey() { + return dsaPublicKey; + } + + /** + * Sets the public DSA key of the node. + * + * @param dsaPublicKey + * The public DSA key of the node + */ + public void setDSAPublicKey(String dsaPublicKey) { + this.dsaPublicKey = dsaPublicKey; + } + + /** + * Returns the DSA group of the node. + * + * @return The DSA group of the node + */ + public DSAGroup getDSAGroup() { + return dsaGroup; + } + + /** + * Sets the DSA group of the node. + * + * @param dsaGroup + * The DSA group of the node + */ + public void setDSAGroup(DSAGroup dsaGroup) { + this.dsaGroup = dsaGroup; + } + + /** + * Returns the negotiation types supported by the node. + * + * @return The node’s supported negotiation types + */ + public int[] getNegotiationTypes() { + return negotiationTypes; + } + + /** + * Sets the negotiation types supported by the node. + * + * @param negotiationTypes + * The node’s supported negotiation types + */ + public void setNegotiationTypes(int[] negotiationTypes) { + this.negotiationTypes = negotiationTypes; + } + + /** + * Returns the version of the node. + * + * @return The version of the node + */ + public Version getVersion() { + return version; + } + + /** + * Sets the version of the node. + * + * @param version + * The version of the node + */ + public void setVersion(Version version) { + this.version = version; + } + + /** + * Returns the last good version of the node. + * + * @return The oldest version the node will connect to + */ + public Version getLastGoodVersion() { + return lastGoodVersion; + } + + /** + * Sets the last good version of the node. + * + * @param lastGoodVersion + * The oldest version the node will connect to + */ + public void setLastGoodVersion(Version lastGoodVersion) { + this.lastGoodVersion = lastGoodVersion; + } + + /** + * Returns whether the node is a testnet node. + * + * @return true if the node is a testnet node, + * false otherwise + */ + public boolean isTestnet() { + return testnet; + } + + /** + * Sets whether this node is a testnet node. + * + * @param testnet + * true if the node is a testnet node, + * false otherwise + */ + public void setTestnet(boolean testnet) { + this.testnet = testnet; + } + + /** + * Returns the signature of the noderef. + * + * @return The signature of the noderef + */ + public String getSignature() { + return signature; + } + + /** + * Sets the signature of the noderef. + * + * @param signature + * The signature of the noderef + */ + public void setSignature(String signature) { + this.signature = signature; + } + +} diff --git a/src/net/pterodactylus/fcp/Peer.java b/src/net/pterodactylus/fcp/Peer.java new file mode 100644 index 0000000..e45d563 --- /dev/null +++ b/src/net/pterodactylus/fcp/Peer.java @@ -0,0 +1,177 @@ +/* + * jSite2 - Peer.java - + * Copyright © 2008 David Roden + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +package net.pterodactylus.fcp; + +/** + * The “Peer” reply by the node contains information about a peer. + * + * @author David ‘Bombe’ Roden <bombe@freenetproject.org> + * @version $Id$ + */ +public class Peer extends BaseMessage { + + /** + * Creates a new “Peer” reply from the received message. + * + * @param receivedMessage + * The received message + */ + Peer(FcpMessage receivedMessage) { + super(receivedMessage); + } + + /** + * Returns a collection of fields as a node reference. + * + * @return The node reference contained within this message + */ + public NodeRef getNodeRef() { + NodeRef nodeRef = new NodeRef(); + nodeRef.setARK(getARK()); + nodeRef.setDSAGroup(getDSAGroup()); + nodeRef.setDSAPublicKey(getDSAPublicKey()); + nodeRef.setIdentity(getIdentity()); + nodeRef.setLastGoodVersion(getLastGoodVersion()); + nodeRef.setLocation(getLocation()); + nodeRef.setName(getMyName()); + nodeRef.setNegotiationTypes(getNegotiationTypes()); + nodeRef.setOpennet(isOpennet()); + nodeRef.setPhysicalUDP(getPhysicalUDP()); + nodeRef.setVersion(getVersion()); + return nodeRef; + } + + /** + * Returns the “physical.udp” line from the message. It contains all IP + * addresses and port numbers of the peer. + * + * @return The IP addresses and port numbers of the peer + */ + public String getPhysicalUDP() { + return getField("physical.udp"); + } + + /** + * Returns whether the listed peer is an opennet peer. + * + * @return true if the peer is an opennet peer, + * false if the peer is a darknet peer + */ + public boolean isOpennet() { + return Boolean.valueOf(getField("opennet")); + } + + /** + * Returns the “y” part of the peer’s public DSA key. + * + * @return The public DSA key + */ + public String getDSAPublicKey() { + return getField("dsaPubKey.y"); + } + + /** + * Returns the DSA group of the peer. + * + * @return The DSA group of the peer + */ + public DSAGroup getDSAGroup() { + return new DSAGroup(getField("dsaGroup.g"), getField("dsaGroup.p"), getField("dsaGroup.q")); + } + + /** + * Returns the last good version of the peer, i.e. the oldest version the + * peer will connect to. + * + * @return The last good version of the peer + */ + public Version getLastGoodVersion() { + return new Version(getField("lastGoodVersion")); + } + + /** + * Returns the ARK of the peer. + * + * @return The ARK of the peer + */ + public ARK getARK() { + return new ARK(getField("ark.pubURI"), getField("ark.number")); + } + + /** + * Returns the identity of the peer. + * + * @return The identity of the peer + */ + public String getIdentity() { + return getField("identity"); + } + + /** + * Returns the name of the peer. If the peer is not a darknet peer it will + * have no name. + * + * @return The name of the peer, or null if the peer is an + * opennet peer + */ + public String getMyName() { + return getField("myName"); + } + + /** + * Returns the location of the peer. + * + * @return The location of the peer + * @throws NumberFormatException + * if the field can not be parsed + */ + public double getLocation() throws NumberFormatException { + return Double.valueOf(getField("location")); + } + + /** + * Returns whether the peer is a testnet node. + * + * @return true if the peer is a testnet node, + * false otherwise + */ + public boolean isTestnet() { + return Boolean.valueOf("testnet"); + } + + /** + * Returns the version of the peer. + * + * @return The version of the peer + */ + public Version getVersion() { + return new Version(getField("version")); + } + + /** + * Returns the negotiation types the peer supports. + * + * @return The supported negotiation types + */ + public int[] getNegotiationTypes() { + return FcpUtils.decodeMultiIntegerField(getField("auth.negTypes")); + } + +} diff --git a/src/net/pterodactylus/fcp/PeerNote.java b/src/net/pterodactylus/fcp/PeerNote.java new file mode 100644 index 0000000..f139973 --- /dev/null +++ b/src/net/pterodactylus/fcp/PeerNote.java @@ -0,0 +1,63 @@ +/* + * jSite2 - PeerNote.java - + * Copyright © 2008 David Roden + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +package net.pterodactylus.fcp; + +/** + * The “PeerNote” message contains a private note that has been entered for a + * darknet peer. + * + * @author David Roden + * @version $Id$ + */ +public class PeerNote extends BaseMessage { + + /** The type for base64 encoded peer notes. */ + public static final int TYPE_PRIVATE_PEER_NOTE = 1; + + /** + * Creates a “PeerNote” message that wraps the recevied message. + * + * @param receivedMessage + * The received message + */ + PeerNote(FcpMessage receivedMessage) { + super(receivedMessage); + } + + /** + * Returns the base64-encoded note text. + * + * @return The note text + */ + public String getNoteText() { + return getField("NoteText"); + } + + /** + * Returns the type of the peer note. + * + * @return The type of the peer note, or -1 if the type can + * not be parsed + */ + public int getPeerNoteType() { + return FcpUtils.safeParseInt(getField("PeerNoteType")); + } + +} diff --git a/src/net/pterodactylus/fcp/PeerRemoved.java b/src/net/pterodactylus/fcp/PeerRemoved.java new file mode 100644 index 0000000..d1e724a --- /dev/null +++ b/src/net/pterodactylus/fcp/PeerRemoved.java @@ -0,0 +1,58 @@ +/* + * jSite2 - PeerRemoved.java - + * Copyright © 2008 David Roden + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +package net.pterodactylus.fcp; + +/** + * A “PeerRemoved” message is sent by the node when a peer has been removed. + * + * @author David ‘Bombe’ Roden <bombe@freenetproject.org> + * @version $Id$ + */ +public class PeerRemoved extends BaseMessage { + + /** + * Creates a new “PeerRemoved” message that wraps the received message. + * + * @param receivedMessage + * The received message + */ + PeerRemoved(FcpMessage receivedMessage) { + super(receivedMessage); + } + + /** + * Returns the identity of the removed peer. + * + * @return The identity of the removed peer + */ + public String getIdentity() { + return getField("Identity"); + } + + /** + * Returns the node identifier of the removed peer. + * + * @return The node identifier of the removed peer + */ + public String getNodeIdentifier() { + return getField("NodeIdentifier"); + } + +} diff --git a/src/net/pterodactylus/fcp/Persistence.java b/src/net/pterodactylus/fcp/Persistence.java new file mode 100644 index 0000000..a8775fa --- /dev/null +++ b/src/net/pterodactylus/fcp/Persistence.java @@ -0,0 +1,48 @@ +/* + * jSite2 - Persistence.java - + * Copyright © 2008 David Roden + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +package net.pterodactylus.fcp; + +/** + * Convenience class for persistence values. + * + * @author David ‘Bombe’ Roden <bombe@freenetproject.org> + * @version $Id$ + */ +public enum Persistence { + + /** + * Connection persistence. A request with this persistence will die as soon + * as the connection goes down. + */ + connection, + + /** + * Reboot persistence. A request with this persistence will live until the + * node is restarted. + */ + reboot, + + /** Forever persistence. A request with this persistence will live forever. */ + forever, + + /** Unknown persistence. */ + unknown; + +} diff --git a/src/net/pterodactylus/fcp/PersistentGet.java b/src/net/pterodactylus/fcp/PersistentGet.java new file mode 100644 index 0000000..b4bc169 --- /dev/null +++ b/src/net/pterodactylus/fcp/PersistentGet.java @@ -0,0 +1,155 @@ +/* + * jSite2 - PersistentGet.java - + * Copyright © 2008 David Roden + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +package net.pterodactylus.fcp; + +/** + * The “PersistentGet” message is sent to the client to inform it about a + * persistent download, either in the client-local queue or in the global queue. + * + * @author David Roden + * @version $Id$ + */ +public class PersistentGet extends BaseMessage { + + /** + * Creates a new “PersistentGet” message that wraps the received message. + * + * @param receivedMessage + * The received message + */ + PersistentGet(FcpMessage receivedMessage) { + super(receivedMessage); + } + + /** + * Returns the identifier of the request. + * + * @return The identifier of the request + */ + public String getIdentifier() { + return getField("Identifier"); + } + + /** + * Returns the URI of the request. + * + * @return The URI of the request + */ + public String getURI() { + return getField("URI"); + } + + /** + * Returns the verbosity of the request. + * + * @return The verbosity of the request + */ + public Verbosity getVerbosity() { + return Verbosity.valueOf(getField("Verbosity")); + } + + /** + * Returns the return type of the request. + * + * @return The return type of the request + */ + public ReturnType getReturnType() { + try { + return ReturnType.valueOf(getField("ReturnType")); + } catch (IllegalArgumentException iae1) { + return ReturnType.unknown; + } + } + + /** + * Returns the name of the file the data is downloaded to. This field will + * only be set if {@link #getReturnType()} is {@link ReturnType#disk}. + * + * @return The name of the file the data is downloaded to + */ + public String getFilename() { + return getField("Filename"); + } + + /** + * Returns the name of the temporary file. This field will only be set if + * {@link #getReturnType()} is {@link ReturnType#disk}. + * + * @return The name of the temporary file + */ + public String getTempFilename() { + return getField("TempFilename"); + } + + /** + * Returns the client token of the request. + * + * @return The client token of the request + */ + public String getClientToken() { + return getField("ClientToken"); + } + + /** + * Returns the priority of the request. + * + * @return The priority of the request + */ + public Priority getPriority() { + return Priority.values()[FcpUtils.safeParseInt(getField("PriorityClass"), 7)]; + } + + /** + * Returns the persistence of the request. + * + * @return The persistence of the request, or {@link Persistence#unknown} if + * the persistence could not be parsed + */ + public Persistence getPersistence() { + try { + return Persistence.valueOf(getField("Persistence")); + } catch (IllegalArgumentException iae1) { + return Persistence.unknown; + } + } + + /** + * Returns whether this request is on the global queue or on the + * client-local queue. + * + * @return true if the request is on the global queue, + * false if the request is on the client-local queue + */ + public boolean isGlobal() { + return Boolean.valueOf(getField("Global")); + } + + /** + * Returns the maximum number of retries for a failed block. + * + * @return The maximum number of retries for a failed block, -1 + * for endless retries, -2 if the number could not be + * parsed + */ + public int getMaxRetries() { + return FcpUtils.safeParseInt(getField("MaxRetries"), -2); + } + +} diff --git a/src/net/pterodactylus/fcp/PersistentPut.java b/src/net/pterodactylus/fcp/PersistentPut.java new file mode 100644 index 0000000..0ec8a7e --- /dev/null +++ b/src/net/pterodactylus/fcp/PersistentPut.java @@ -0,0 +1,169 @@ +/* + * jSite2 - PersistentPut.java - + * Copyright © 2008 David Roden + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +package net.pterodactylus.fcp; + +/** + * A “PersistentPut” message notifies a client about a persistent + * {@link ClientPut} request. + * + * @author David Roden + * @version $Id$ + */ +public class PersistentPut extends BaseMessage { + + /** + * Creates a new “PersistentPut” message that wraps the received message. + * + * @param receivedMessage + * The received message + */ + PersistentPut(FcpMessage receivedMessage) { + super(receivedMessage); + } + + /** + * Returns the client token of the request. + * + * @return The client token of the request + */ + public String getClientToken() { + return getField("ClientToken"); + } + + /** + * Returns the data length of the request. + * + * @return The data length of the request, or -1 if the + * length could not be parsed + */ + public long getDataLength() { + return FcpUtils.safeParseLong(getField("DataLength")); + } + + /** + * Returns whether the request is on the global queue. + * + * @return true if the request is on the global queue, + * false otherwise + */ + public boolean isGlobal() { + return Boolean.valueOf(getField("Global")); + } + + /** + * Returns the identifier of the request. + * + * @return The identifier of the request + */ + public String getIdentifier() { + return getField("Identifier"); + } + + /** + * Returns the maximum number of retries for failed blocks. When + * -1 is returned each block is tried forever. + * + * @return The maximum number of retries for failed blocks, or + * -1 for unlimited retries, or -2 if + * the number of retries could not be parsed + */ + public int getMaxRetries() { + return FcpUtils.safeParseInt(getField("MaxRetries")); + } + + /** + * Returns the content type of the data. + * + * @return The content type + */ + public String getMetadataContentType() { + return getField("Metadata.ContentType"); + } + + /** + * Returns the persistence of the request. + * + * @return The persistence of the request + */ + public Persistence getPersistence() { + return Persistence.valueOf(getField("Persistence")); + } + + /** + * Returns the priority of the request. + * + * @return The priority of the request, or {@link Priority#unknown} if the + * priority could not be parsed + */ + public Priority getPriority() { + try { + return Priority.values()[Integer.valueOf(getField("PriorityClass"))]; + } catch (NumberFormatException nfe1) { + return Priority.unknown; + } + } + + /** + * Returns whether this request has started. + * + * @return true if the request has started, + * false otherwise + */ + public boolean isStarted() { + return Boolean.valueOf(getField("Started")); + } + + /** + * Returns the target filename of the request. + * + * @return The target filename of the request + */ + public String getTargetFilename() { + return getField("TargetFilename"); + } + + /** + * Returns the upload source of the request. + * + * @return The upload source of the request + */ + public UploadFrom getUploadFrom() { + return UploadFrom.valueOf(getField("UploadFrom")); + } + + /** + * Returns the target URI of the request. + * + * @return The target URI of the request + */ + public String getURI() { + return getField("URI"); + } + + /** + * Returns the verbosity of the request. + * + * @return The verbosity of the request + */ + public Verbosity getVerbosity() { + return Verbosity.valueOf(getField("Verbosity")); + } + +} diff --git a/src/net/pterodactylus/fcp/PersistentPutDir.java b/src/net/pterodactylus/fcp/PersistentPutDir.java new file mode 100644 index 0000000..1980739 --- /dev/null +++ b/src/net/pterodactylus/fcp/PersistentPutDir.java @@ -0,0 +1,174 @@ +/* + * jSite2 - PersistentPutDir.java - + * Copyright © 2008 David Roden + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +package net.pterodactylus.fcp; + +/** + * A “PersistentPutDir” is the response to a {@link ClientPutDiskDir} message. + * It is also sent as a possible response to a {@link ListPersistentRequests} + * message. + * + * @author David ‘Bombe’ Roden <bombe@freenetproject.org> + * @version $Id$ + */ +public class PersistentPutDir extends BaseMessage { + + /** + * Creates a new “PersistentPutDir” message that wraps the received message. + * + * @param receivedMessage + * The received message + */ + PersistentPutDir(FcpMessage receivedMessage) { + super(receivedMessage); + } + + /** + * Returns the identifier of the request. + * + * @return The identifier of the request + */ + public String getIdentifier() { + return getField("Identifier"); + } + + /** + * Returns the URI of the request. + * + * @return The URI of the request + */ + public String getURI() { + return getField("URI"); + } + + /** + * Returns the verbosity of the request. + * + * @return The verbosity of the request + */ + public Verbosity getVerbosity() { + return Verbosity.valueOf(getField("Verbosity")); + } + + /** + * Returns the priority of the request. + * + * @return The priority of the request + */ + public Priority getPriority() { + return Priority.valueOf(getField("PriorityClass")); + } + + /** + * Returns whether the request is on the global queue. + * + * @return true if the request is on the global queue, + * false if it is on the client-local queue + */ + public boolean isGlobal() { + return Boolean.valueOf(getField("Global")); + } + + /** + * Returns the maximum number of retries for failed blocks. + * + * @return The maximum number of retries, or -1 for endless + * retries, or -2 if the number could not be parsed + */ + public int getMaxRetries() { + return FcpUtils.safeParseInt(getField("MaxRetries"), -2); + } + + /** + * Returns the number of files in the request. + * + * @return The number of files in the request + */ + public int getFileCount() { + int fileCount = -1; + while (getField("Files." + ++fileCount + ".UploadFrom") != null) { /* + * do + * nothing. + */ + } + return fileCount; + } + + /** + * Returns the name of the file at the given index. The index is counted + * from 0. + * + * @param fileIndex + * The index of the file + * @return The name of the file at the given index + */ + public String getFileName(int fileIndex) { + return getField("Files." + fileIndex + ".Name"); + } + + /** + * Returns the length of the file at the given index. The index is counted + * from 0. + * + * @param fileIndex + * The index of the file + * @return The length of the file at the given index + */ + public long getFileDataLength(int fileIndex) { + return FcpUtils.safeParseLong(getField("Files." + fileIndex + ".DataLength")); + } + + /** + * Returns the upload source of the file at the given index. The index is + * counted from 0. + * + * @param fileIndex + * The index of the file + * @return The upload source of the file at the given index + */ + public UploadFrom getFileUploadFrom(int fileIndex) { + return UploadFrom.valueOf(getField("Files." + fileIndex + ".UploadFrom")); + } + + /** + * Returns the content type of the file at the given index. The index is + * counted from 0. + * + * @param fileIndex + * The index of the file + * @return The content type of the file at the given index + */ + public String getFileMetadataContentType(int fileIndex) { + return getField("Files." + fileIndex + ".Metadata.ContentType"); + } + + /** + * Returns the filename of the file at the given index. This value is only + * returned if {@link #getFileUploadFrom(int)} is returning + * {@link UploadFrom#disk}. The index is counted from 0. + * + * @param fileIndex + * The index of the file + * @return The filename of the file at the given index + */ + public String getFileFilename(int fileIndex) { + return getField("Files." + fileIndex + ".Filename"); + } + +} diff --git a/src/net/pterodactylus/fcp/PersistentRequestModified.java b/src/net/pterodactylus/fcp/PersistentRequestModified.java new file mode 100644 index 0000000..f176803 --- /dev/null +++ b/src/net/pterodactylus/fcp/PersistentRequestModified.java @@ -0,0 +1,81 @@ +/* + * jSite2 - PersistentRequestModified.java - + * Copyright © 2008 David Roden + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +package net.pterodactylus.fcp; + +/** + * The “PersistentRequestModified” message is a reply to + * {@link ModifyPersistentRequest}. + * + * @author David ‘Bombe’ Roden <bombe@freenetproject.org> + * @version $Id$ + */ +public class PersistentRequestModified extends BaseMessage { + + /** + * Creates a new “PersistentRequestModified” message that wraps the received + * message. + * + * @param receivedMessage + * The received message + */ + PersistentRequestModified(FcpMessage receivedMessage) { + super(receivedMessage); + } + + /** + * Returns the identifier of the changed request. + * + * @return The identifier of the request + */ + public String getIdentifier() { + return getField("Identifier"); + } + + /** + * Returns whether the request is on the global queue. + * + * @return true if the request is on the global queue, + * false if it is on a client-local queue + */ + public boolean isGlobal() { + return Boolean.valueOf(getField("Global")); + } + + /** + * Returns the client token, if it was changed. + * + * @return The new client token, or null if the client token + * was not changed + */ + public String getClientToken() { + return getField("ClientToken"); + } + + /** + * Returns the priority of the request, if it was changed. + * + * @return The new priority of the request, or {@link Priority#unknown} if + * the priority was not changed + */ + public Priority getPriority() { + return Priority.values()[FcpUtils.safeParseInt(getField("PriorityClass"), Priority.unknown.ordinal())]; + } + +} diff --git a/src/net/pterodactylus/fcp/PersistentRequestRemoved.java b/src/net/pterodactylus/fcp/PersistentRequestRemoved.java new file mode 100644 index 0000000..c9cacce --- /dev/null +++ b/src/net/pterodactylus/fcp/PersistentRequestRemoved.java @@ -0,0 +1,62 @@ +/* + * jSite2 - PersistentRequestRemoved.java - + * Copyright © 2008 David Roden + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +package net.pterodactylus.fcp; + +/** + * A “PersistentRequestRemoved” message signals that a persistent request was + * removed from either the global or the client-local queue. + * + * @author David ‘Bombe’ Roden <bombe@freenetproject.org> + * @version $Id$ + */ +public class PersistentRequestRemoved extends BaseMessage { + + /** + * Creates a new “PersistentRequestRemoved” message that wraps the received + * message. + * + * @param receivedMessage + * The received message + */ + PersistentRequestRemoved(FcpMessage receivedMessage) { + super(receivedMessage); + } + + /** + * Returns the identifier of the request. + * + * @return The identifier of the request + */ + public String getIdentifier() { + return getField("Identifier"); + } + + /** + * Returns whether the request was removed from the global queue. + * + * @return true if the request was removed from the global + * queue, false if it was removed from the + * client-local queue + */ + public boolean isGlobal() { + return Boolean.valueOf(getField("Global")); + } + +} diff --git a/src/net/pterodactylus/fcp/PluginInfo.java b/src/net/pterodactylus/fcp/PluginInfo.java new file mode 100644 index 0000000..2cb5d1c --- /dev/null +++ b/src/net/pterodactylus/fcp/PluginInfo.java @@ -0,0 +1,77 @@ +/* + * jSite2 - PluginInfo.java - + * Copyright © 2008 David Roden + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +package net.pterodactylus.fcp; + +/** + * The “PluginInfo” message is a reply to the {@link GetPluginInfo} request. + * + * @author David ‘Bombe’ Roden <bombe@freenetproject.org> + * @version $Id$ + */ +public class PluginInfo extends BaseMessage { + + /** + * Creates a new “PluginInfo” message that wraps the received message. + * + * @param receivedMessage + * The received message + */ + PluginInfo(FcpMessage receivedMessage) { + super(receivedMessage); + } + + /** + * Returns the name of the plugin. + * + * @return The name of the plugin + */ + public String getPluginName() { + return getField("PluginName"); + } + + /** + * Returns the identifier of the request. + * + * @return The identifier of the request + */ + public String getIdentifier() { + return getField("Identifier"); + } + + /** + * Returns the original URI of the plugin. + * + * @return The original URI of the plugin + */ + public String getOriginalURI() { + return getField("OriginalUri"); + } + + /** + * Returns whether the plugin is started. + * + * @return true if the plugin is started, false + * otherwise + */ + public boolean isStarted() { + return Boolean.valueOf("Started"); + } + +} diff --git a/src/net/pterodactylus/fcp/Priority.java b/src/net/pterodactylus/fcp/Priority.java new file mode 100644 index 0000000..3c99a07 --- /dev/null +++ b/src/net/pterodactylus/fcp/Priority.java @@ -0,0 +1,62 @@ +/* + * jSite2 - Priority.java - + * Copyright © 2008 David Roden + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +package net.pterodactylus.fcp; + +/** + * The priority classes used by the Freenet node. + * + * @author David ‘Bombe’ Roden <bombe@freenetproject.org> + * @version $Id$ + */ +public enum Priority { + + /** Maximum priority. */ + maximum, + + /** Priority for interactive request, i.e. FProxy. */ + interactive, + + /** Priority for splitfile manifests. */ + immediateSplitfile, + + /** Priority for USK searches. */ + update, + + /** Priority for splitfile blocks. */ + bulkSplitfile, + + /** Priority for prefetching blocks. */ + prefetch, + + /** Minimum priority. */ + minimum, + + /** Unknown priority. */ + unknown; + + /** + * @see java.lang.Enum#toString() + */ + @Override + public String toString() { + return String.valueOf(ordinal()); + } + +} diff --git a/src/net/pterodactylus/fcp/ProtocolError.java b/src/net/pterodactylus/fcp/ProtocolError.java new file mode 100644 index 0000000..bc4629e --- /dev/null +++ b/src/net/pterodactylus/fcp/ProtocolError.java @@ -0,0 +1,98 @@ +/* + * jSite2 - ProtocolError.java - + * Copyright © 2008 David Roden + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +package net.pterodactylus.fcp; + +/** + * The “ProtocolError” message signals that something has gone really wrong. + * + * @author David Roden + * @version $Id$ + */ +public class ProtocolError extends BaseMessage { + + /** + * Creates a new “ProtocolError” message that wraps the received message. + * + * @param receivedMessage + * The received message + */ + ProtocolError(FcpMessage receivedMessage) { + super(receivedMessage); + } + + /** + * Returns whether the causing message had the “Global” flag set. + * + * @return true if the causing message had the “Global” flag + * set + */ + public boolean isGlobal() { + return Boolean.valueOf(getField("Global")); + } + + /** + * Returns the error code. + * + * @return The error code, or -1 if the error code could not + * be parsed + */ + public int getCode() { + return FcpUtils.safeParseInt(getField("Code")); + } + + /** + * Returns the description of the error. + * + * @return The description of the error + */ + public String getCodeDescription() { + return getField("CodeDescription"); + } + + /** + * Returns some extra description of the error. + * + * @return Extra description of the error, or null if there + * is none + */ + public String getExtraDescription() { + return getField("ExtraDescription"); + } + + /** + * Returns whether the connection to the node can stay open. + * + * @return true when the connection has to be closed, + * false otherwise + */ + public boolean isFatal() { + return Boolean.valueOf(getField("Fatal")); + } + + /** + * The identifier of the causing request, if any. + * + * @return The identifier of the causing request + */ + public String getIdentifier() { + return getField("Identifier"); + } + +} diff --git a/src/net/pterodactylus/fcp/PutFailed.java b/src/net/pterodactylus/fcp/PutFailed.java new file mode 100644 index 0000000..6eedc05 --- /dev/null +++ b/src/net/pterodactylus/fcp/PutFailed.java @@ -0,0 +1,178 @@ +/* + * jSite2 - GetFailed.java - + * Copyright © 2008 David Roden + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +package net.pterodactylus.fcp; + +import java.util.ArrayList; +import java.util.List; +import java.util.Map; +import java.util.Map.Entry; + +/** + * The “PutFailed” message signals the client that a {@link ClientPut} request + * has failed. This also means that no further progress messages for that + * request will be sent. + * + * @author David ‘Bombe’ Roden <bombe@freenetproject.org> + * @version $Id$ + */ +public class PutFailed extends BaseMessage { + + /** + * Creates a new “PutFailed” message that wraps the received message. + * + * @param receivedMessage + * The received message + */ + PutFailed(FcpMessage receivedMessage) { + super(receivedMessage); + } + + /** + * Returns the code of the error. + * + * @return The code of the error, or -1 if the error code + * could not be parsed + */ + public int getCode() { + return FcpUtils.safeParseInt(getField("Code")); + } + + /** + * Returns the identifier of the request. + * + * @return The identifier of the request + */ + public String getIdentifier() { + return getField("Identifier"); + } + + /** + * Returns whether the request is on the global queue. + * + * @return true if the request is on the global queue, + * false if it is on the client-local queue + */ + public boolean isGlobal() { + return Boolean.valueOf(getField("Global")); + } + + /** + * Returns the description of the error code. + * + * @return The description of the error code + */ + public String getCodeDescription() { + return getField("CodeDescription"); + } + + /** + * Returns the extra description of the error. + * + * @return The extra description of the error + */ + public String getExtraDescription() { + return getField("ExtraDescription"); + } + + /** + * Returns the short description of the error. + * + * @return The short description of the error + */ + public String getShortCodeDescription() { + return getField("ShortCodeDescription"); + } + + /** + * Returns the expected URI of the request. + * + * @return The expected URI + */ + public String getExpectedURI() { + return getField("ExpectedURI"); + } + + /** + * Returns whether the request failed fatally. If a request fails fatally it + * can never complete, even with inifinite retries. + * + * @return true if the request failed fatally, + * false otherwise + */ + public boolean isFatal() { + return Boolean.valueOf(getField("Fatal")); + } + + /** + * Returns a list of complex error codes with the message. Use + * {@link #getComplexErrorDescription(int)} and + * {@link #getComplexErrorCount(int)} to get details. + * + * @return A list of complex error codes + */ + public int[] getComplexErrorCodes() { + Map allFields = getFields(); + List errorCodeList = new ArrayList(); + for (Entry field: allFields.entrySet()) { + String fieldKey = field.getKey(); + if (fieldKey.startsWith("Errors.")) { + int nextDot = fieldKey.indexOf('.', 7); + if (nextDot > -1) { + int errorCode = FcpUtils.safeParseInt(fieldKey.substring(7, nextDot)); + if (errorCode != -1) { + errorCodeList.add(errorCode); + } + } + } + } + int[] errorCodes = new int[errorCodeList.size()]; + int errorIndex = 0; + for (int errorCode: errorCodeList) { + errorCodes[errorIndex++] = errorCode; + } + return errorCodes; + } + + /** + * Returns the description of the complex error. You should only hand it + * error codes you got from {@link #getComplexErrorCodes()}! + * + * @param errorCode + * The error code + * @return The description of the complex error + */ + public String getComplexErrorDescription(int errorCode) { + return getField("Errors." + errorCode + ".Description"); + } + + /** + * Returns the count of the complex error. You should only hand it error + * codes you got from {@link #getComplexErrorCodes()}! + * + * @param errorCode + * The error code + * @return The count of the complex error, or -1 if the count + * could not be parsed + */ + public int getComplexErrorCount(int errorCode) { + return FcpUtils.safeParseInt(getField("Errors." + errorCode + ".Count")); + } + +} diff --git a/src/net/pterodactylus/fcp/PutFetchable.java b/src/net/pterodactylus/fcp/PutFetchable.java new file mode 100644 index 0000000..dca0d52 --- /dev/null +++ b/src/net/pterodactylus/fcp/PutFetchable.java @@ -0,0 +1,70 @@ +/* + * jSite2 - PutFetchable.java - + * Copyright © 2008 David Roden + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +package net.pterodactylus.fcp; + +/** + * The “PutFetchable” message informs a client that a {@link ClientPut} request + * has progressed far enough that the resulting final URI might already be + * fetchable. + * + * @author David ‘Bombe’ Roden <bombe@freenetproject.org> + * @version $Id$ + */ +public class PutFetchable extends BaseMessage { + + /** + * Creates a new “PutFetchable” message that wraps the received message. + * + * @param receivedMessage + * The received message + */ + PutFetchable(FcpMessage receivedMessage) { + super(receivedMessage); + } + + /** + * Returns the identifier of the request. + * + * @return The identifier of the request + */ + public String getIdentifier() { + return getField("Identifier"); + } + + /** + * Returns whether the request is on the global queue. + * + * @return true if the request is on the global queue, + * false if it is on the client-local queue + */ + public boolean isGlobal() { + return Boolean.valueOf(getField("Global")); + } + + /** + * Returns the URI of the request. + * + * @return The URI of the request + */ + public String getURI() { + return getField("URI"); + } + +} diff --git a/src/net/pterodactylus/fcp/PutSuccessful.java b/src/net/pterodactylus/fcp/PutSuccessful.java new file mode 100644 index 0000000..7790cd8 --- /dev/null +++ b/src/net/pterodactylus/fcp/PutSuccessful.java @@ -0,0 +1,89 @@ +/* + * jSite2 - PutSuccessful.java - + * Copyright © 2008 David Roden + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +package net.pterodactylus.fcp; + +/** + * The “PutSuccessful” message informs a client about a successfully finished + * {@link ClientPut} (or similar) request. + * + * @author David ‘Bombe’ Roden <bombe@freenetproject.org> + * @version $Id$ + */ +public class PutSuccessful extends BaseMessage { + + /** + * Creates a new “PutSuccessful” message that wraps the received message. + * + * @param receivedMessage + * The received message + */ + PutSuccessful(FcpMessage receivedMessage) { + super(receivedMessage); + } + + /** + * Returns the identifier of the request. + * + * @return The identifier of the request + */ + public String getIdentifier() { + return getField("Identifier"); + } + + /** + * Returns whether the request is on the global queue. + * + * @return true if the request is on the global queue, + * false if it is on the client-local queue + */ + public boolean isGlobal() { + return Boolean.valueOf(getField("Global")); + } + + /** + * Returns the final URI of the {@link ClientPut} request. + * + * @return The final URI of the request + */ + public String getURI() { + return getField("URI"); + } + + /** + * Returns the time the insert started. + * + * @return The time the insert started (in milliseconds since Jan 1, 1970 + * UTC), or -1 if the time could not be parsed + */ + public long getStartupTime() { + return FcpUtils.safeParseLong(getField("StartupTime")); + } + + /** + * Returns the time the insert completed. + * + * @return The time the insert completed (in milliseconds since Jan 1, 1970 + * UTC), or -1 if the time could not be parsed + */ + public long getCompletionTime() { + return FcpUtils.safeParseLong(getField("CompletionTime")); + } + +} diff --git a/src/net/pterodactylus/fcp/RemovePeer.java b/src/net/pterodactylus/fcp/RemovePeer.java new file mode 100644 index 0000000..922801f --- /dev/null +++ b/src/net/pterodactylus/fcp/RemovePeer.java @@ -0,0 +1,42 @@ +/* + * jSite2 - RemovePeer.java - + * Copyright © 2008 David Roden + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +package net.pterodactylus.fcp; + +/** + * The “RemovePeer” command removes a peer. + * + * @author David ‘Bombe’ Roden <bombe@freenetproject.org> + * @version $Id$ + */ +public class RemovePeer extends FcpMessage { + + /** + * Creates a new “RemovePeer” command that removes the given peer. + * + * @param nodeIdentifier + * The identifier of the node, i.e. its name, identity, or IP + * address and port pair + */ + public RemovePeer(String nodeIdentifier) { + super("RemovePeer"); + setField("NodeIdentifier", nodeIdentifier); + } + +} diff --git a/src/net/pterodactylus/fcp/RemovePersistentRequest.java b/src/net/pterodactylus/fcp/RemovePersistentRequest.java new file mode 100644 index 0000000..fcdf0f3 --- /dev/null +++ b/src/net/pterodactylus/fcp/RemovePersistentRequest.java @@ -0,0 +1,54 @@ +/* + * jSite2 - RemovePersistentRequest.java - + * Copyright © 2008 David Roden + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +package net.pterodactylus.fcp; + +/** + * The “RemovePersistentRequest” message tells the node to remove a persistent + * request, cancelling it first (resulting in a {@link GetFailed} or + * {@link PutFailed} message), if necessary. + * + * @author David ‘Bombe’ Roden <bombe@freenetproject.org> + * @version $Id$ + */ +public class RemovePersistentRequest extends FcpMessage { + + /** + * Creates a new “RemovePersistentRequest” message. + * + * @param identifier + * The identifier of the request + */ + public RemovePersistentRequest(String identifier) { + super("RemovePersistentRequest"); + setField("Identifier", identifier); + } + + /** + * Sets whether the request is on the global queue. + * + * @param global + * true if the request is on the global queue, + * false if it is on the client-local queue + */ + public void setGlobal(boolean global) { + setField("Global", String.valueOf(global)); + } + +} diff --git a/src/net/pterodactylus/fcp/ReturnType.java b/src/net/pterodactylus/fcp/ReturnType.java new file mode 100644 index 0000000..4fadad6 --- /dev/null +++ b/src/net/pterodactylus/fcp/ReturnType.java @@ -0,0 +1,42 @@ +/* + * jSite2 - ReturnType.java - + * Copyright © 2008 David Roden + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +package net.pterodactylus.fcp; + +/** + * The different return types for {@link ClientGet} requests. + * + * @author David ‘Bombe’ Roden <bombe@freenetproject.org> + * @version $Id$ + */ +public enum ReturnType { + + /** Don't transfer the data at all. */ + none, + + /** Transfer the data directly after the message. */ + direct, + + /** Copy the data to disk. */ + disk, + + /** Unknown return type. */ + unknown; + +} diff --git a/src/net/pterodactylus/fcp/SSKKeypair.java b/src/net/pterodactylus/fcp/SSKKeypair.java new file mode 100644 index 0000000..dff44e3 --- /dev/null +++ b/src/net/pterodactylus/fcp/SSKKeypair.java @@ -0,0 +1,68 @@ +/* + * jSite2 - SSKKeypair.java - + * Copyright © 2008 David Roden + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +package net.pterodactylus.fcp; + +/** + * An “SSKKeypair” message that is sent as a response to a {@link GenerateSSK} + * message. + * + * @author David ‘Bombe’ Roden <bombe@freenetproject.org> + * @version $Id$ + */ +public class SSKKeypair extends BaseMessage { + + /** + * Creates a new “SSKKeypair” message that wraps the received message. + * + * @param receivedMessage + * The received message + */ + SSKKeypair(FcpMessage receivedMessage) { + super(receivedMessage); + } + + /** + * Returns the identifier of the request. + * + * @return The identifier of the request + */ + public String getIdentifier() { + return getField("Identifier"); + } + + /** + * Returns the URI that must be used to insert data. + * + * @return The insert URI + */ + public String getInsertURI() { + return getField("InsertURI"); + } + + /** + * Returns the URI that must be used to request data. + * + * @return The request URI + */ + public String getRequestURI() { + return getField("RequestURI"); + } + +} diff --git a/src/net/pterodactylus/fcp/Shutdown.java b/src/net/pterodactylus/fcp/Shutdown.java new file mode 100644 index 0000000..ab86c7a --- /dev/null +++ b/src/net/pterodactylus/fcp/Shutdown.java @@ -0,0 +1,37 @@ +/* + * jSite2 - Shutdown.java - + * Copyright © 2008 David Roden + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +package net.pterodactylus.fcp; + +/** + * Command that shuts down the node. + * + * @author David ‘Bombe’ Roden <bombe@freenetproject.org> + * @version $Id$ + */ +public class Shutdown extends FcpMessage { + + /** + * Creates a new “Shutdown” message. + */ + public Shutdown() { + super("Shutdown"); + } + +} diff --git a/src/net/pterodactylus/fcp/SimpleProgress.java b/src/net/pterodactylus/fcp/SimpleProgress.java new file mode 100644 index 0000000..769f623 --- /dev/null +++ b/src/net/pterodactylus/fcp/SimpleProgress.java @@ -0,0 +1,113 @@ +/* + * jSite2 - SimpleProgress.java - + * Copyright © 2008 David Roden + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +package net.pterodactylus.fcp; + +/** + * A “SimpleProgress” message tells the client about the progress of a + * {@link ClientGet} or {@link ClientPut} operation. + * + * @author David ‘Bombe’ Roden <bombe@freenetproject.org> + * @version $Id$ + */ +public class SimpleProgress extends BaseMessage { + + /** + * Creates a new “SimpleProgress” message that wraps the received message. + * + * @param receivedMessage + * The received message + */ + SimpleProgress(FcpMessage receivedMessage) { + super(receivedMessage); + } + + /** + * Returns the total number of blocks. This number may increase as long as + * {@link #isFinalizedTotal()} returns false. + * + * @return The total number of blocks + */ + public int getTotal() { + return FcpUtils.safeParseInt(getField("Total")); + } + + /** + * Returns the number of blocks that are required to completet the request. + * This number might actually be lower than {@link #getTotal} because of + * redundancy information. This number may also increase as long as + * {@link #isFinalizedTotal()} returns false. + * + * @return The number of required blocks + */ + public int getRequired() { + return FcpUtils.safeParseInt(getField("Required")); + } + + /** + * Returns the number of blocks that have failed and run out of retries. + * + * @return The number of failed blocks + */ + public int getFailed() { + return FcpUtils.safeParseInt(getField("Failed")); + } + + /** + * Returns the number of fatally failed blocks. A block that failed fatally + * can never be completed, even with infinite retries. + * + * @return The number of fatally failed blocks + */ + public int getFatallyFailed() { + return FcpUtils.safeParseInt(getField("FatallyFailed")); + } + + /** + * Returns the number of blocks that have been successfully processed. + * + * @return The number of succeeded blocks + */ + public int getSucceeded() { + return FcpUtils.safeParseInt(getField("Succeeded")); + } + + /** + * Returns whether the total number of blocks (see {@link #getTotal()} has + * been finalized. Once the total number of blocks has been finalized for a + * request it will not change any more, and this method of every further + * SimpleProgress message will always return true. + * + * @return true if the number of total blocks has been + * finalized, false otherwise + */ + public boolean isFinalizedTotal() { + return Boolean.valueOf(getField("FinalizedTotal")); + } + + /** + * Returns the identifier of the request. + * + * @return The identifier of the request + */ + public String getIdentifier() { + return getField("Identifier"); + } + +} diff --git a/src/net/pterodactylus/fcp/StartedCompression.java b/src/net/pterodactylus/fcp/StartedCompression.java new file mode 100644 index 0000000..f67f738 --- /dev/null +++ b/src/net/pterodactylus/fcp/StartedCompression.java @@ -0,0 +1,61 @@ +/* + * jSite2 - StartedCompression.java - + * Copyright © 2008 David Roden + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +package net.pterodactylus.fcp; + +/** + * The “StartedCompression” message signals the client the compressing for a + * request has started. + * + * @author David ‘Bombe’ Roden <bombe@freenetproject.org> + * @version $Id$ + */ +public class StartedCompression extends BaseMessage { + + /** + * Creates a new “StartedCompression” message that wraps the received + * message. + * + * @param receivedMessage + * The received message + */ + StartedCompression(FcpMessage receivedMessage) { + super(receivedMessage); + } + + /** + * Returns the identifier of the request. + * + * @return The identifier of the request + */ + public String getIdentifier() { + return getField("Identifier"); + } + + /** + * Returns the number of the codec that is used for compression. + * + * @return The codec used for the compression, or -1 if the + * codec could not be parsed + */ + public int getCodec() { + return FcpUtils.safeParseInt(getField("Codec")); + } + +} diff --git a/src/net/pterodactylus/fcp/SubscribeUSK.java b/src/net/pterodactylus/fcp/SubscribeUSK.java new file mode 100644 index 0000000..07d5fb4 --- /dev/null +++ b/src/net/pterodactylus/fcp/SubscribeUSK.java @@ -0,0 +1,57 @@ +/* + * jSite2 - SubscribeUSK.java - + * Copyright © 2008 David Roden + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +package net.pterodactylus.fcp; + +/** + * With a “SubscribeUSK” a client requests to be notified if the edition number + * of a USK changes. + * + * @author David ‘Bombe’ Roden <bombe@freenetproject.org> + * @version $Id$ + */ +public class SubscribeUSK extends FcpMessage { + + /** + * Creates a new “SubscribeUSK” message. + * + * @param uri + * The URI to watch for changes + * @param identifier + * The identifier of the request + */ + public SubscribeUSK(String uri, String identifier) { + super("SubscribeUSK"); + setField("URI", uri); + setField("Identifier", identifier); + } + + /** + * Sets whether updates for the USK are actively searched. + * + * @param active + * true to actively search for newer editions, + * false to only watch for newer editions that are + * found from other requests + */ + public void setActive(boolean active) { + setField("DontPoll", String.valueOf(!active)); + } + +} diff --git a/src/net/pterodactylus/fcp/SubscribedUSKUpdate.java b/src/net/pterodactylus/fcp/SubscribedUSKUpdate.java new file mode 100644 index 0000000..16ac43e --- /dev/null +++ b/src/net/pterodactylus/fcp/SubscribedUSKUpdate.java @@ -0,0 +1,72 @@ +/* + * jSite2 - SubscribedUSKUpdate.java - + * Copyright © 2008 David Roden + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +package net.pterodactylus.fcp; + +/** + * A “SubscribedUSKUpdate” message is sent each time a new edition of a USK that + * was previously subscribed to with {@link SubscribeUSK} was found. Note that + * if the new edition that was found is several editions ahead of the currently + * last known edition, you will received a SubscribedUSKUpdate for each edition + * inbetween as welL! + * + * @author David ‘Bombe’ Roden <bombe@freenetproject.org> + * @version $Id$ + */ +public class SubscribedUSKUpdate extends BaseMessage { + + /** + * Creates a new “SubscribedUSKUpdate” message that wraps the received + * message. + * + * @param receivedMessage + * The received message + */ + SubscribedUSKUpdate(FcpMessage receivedMessage) { + super(receivedMessage); + } + + /** + * Returns the identifier of the subscription. + * + * @return The identifier of the subscription + */ + public String getIdentifier() { + return getField("Identifier"); + } + + /** + * Returns the new edition that was found. + * + * @return The new edition + */ + public int getEdition() { + return FcpUtils.safeParseInt(getField("Edition")); + } + + /** + * Returns the complete URI, including the new edition. + * + * @return The complete URI + */ + public String getURI() { + return getField("URI"); + } + +} diff --git a/src/net/pterodactylus/fcp/TestDDAComplete.java b/src/net/pterodactylus/fcp/TestDDAComplete.java new file mode 100644 index 0000000..f11a0fd --- /dev/null +++ b/src/net/pterodactylus/fcp/TestDDAComplete.java @@ -0,0 +1,70 @@ +/* + * jSite2 - TestDDAComplete.java - + * Copyright © 2008 David Roden + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +package net.pterodactylus.fcp; + +/** + * The “TestDDAComplete” message signals that the node has finished checking + * your read and write access to a certain directory. + * + * @author David ‘Bombe’ Roden <bombe@freenetproject.org> + * @version $Id$ + */ +public class TestDDAComplete extends BaseMessage { + + /** + * Creates a new “TestDDAComplete” message that wraps the received message. + * + * @param receivedMessage + * The received message + */ + TestDDAComplete(FcpMessage receivedMessage) { + super(receivedMessage); + } + + /** + * Returns the directory the authorization is given for. + * + * @return The directory that was tested for read and/or write access + */ + public String getDirectory() { + return getField("Directory"); + } + + /** + * Returns whether read access to the directory is allowed. + * + * @return true if the client is allowed to read from that + * directory, false otherwise + */ + public boolean isReadDirectoryAllowed() { + return Boolean.valueOf(getField("ReadDirectoryAllowed")); + } + + /** + * Returns whether write access to the directory is allowed. + * + * @return true if the client is allowed to write into that + * directory, false otherwise + */ + public boolean isWriteDirectoryAllowed() { + return Boolean.valueOf(getField("WriteDirectoryAllowed")); + } + +} diff --git a/src/net/pterodactylus/fcp/TestDDAReply.java b/src/net/pterodactylus/fcp/TestDDAReply.java new file mode 100644 index 0000000..6753679 --- /dev/null +++ b/src/net/pterodactylus/fcp/TestDDAReply.java @@ -0,0 +1,84 @@ +/* + * jSite2 - TestDDAReply.java - + * Copyright © 2008 David Roden + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +package net.pterodactylus.fcp; + +/** + * The “TestDDAReply” is sent as a response to {@link TestDDARequest}. If you + * specified that you wanted to read files from that directory + * {@link #getReadFilename()} will give you a filename. Similarly, if you + * specified that you want to write in the directory {@link #getWriteFilename()} + * will give you a filename to write {@link #getContentToWrite()} to. + * + * @author David ‘Bombe’ Roden <bombe@freenetproject.org> + * @version $Id$ + */ +public class TestDDAReply extends BaseMessage { + + /** + * Creates a “TestDDAReply” message that wraps the received message. + * + * @param receivedMessage + * The received message + */ + TestDDAReply(FcpMessage receivedMessage) { + super(receivedMessage); + } + + /** + * Returns the directory the TestDDRequest was made for. + * + * @return The directory to test + */ + public String getDirectory() { + return getField("Directory"); + } + + /** + * Returns the filename you have to read to proof your ability to read that + * specific directory. + * + * @return The name of the file to read + */ + public String getReadFilename() { + return getField("ReadFilename"); + } + + /** + * Returns the filename you have to write to to proof your ability to write + * to that specific directory. + * + * @return The name of the file write to + */ + public String getWriteFilename() { + return getField("WriteFilename"); + } + + /** + * If you requested a test for writing permissions you have to write the + * return value of this method to the file given by + * {@link #getWriteFilename()}. + * + * @return The content to write to the file + */ + public String getContentToWrite() { + return getField("ContentToWrite"); + } + +} diff --git a/src/net/pterodactylus/fcp/TestDDARequest.java b/src/net/pterodactylus/fcp/TestDDARequest.java new file mode 100644 index 0000000..67e5816 --- /dev/null +++ b/src/net/pterodactylus/fcp/TestDDARequest.java @@ -0,0 +1,49 @@ +/* + * jSite2 - TestDDARequest.java - + * Copyright © 2008 David Roden + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +package net.pterodactylus.fcp; + +/** + * The “TestDDARequest” initiates a DDA test sequence. + * + * @author David ‘Bombe’ Roden <bombe@freenetproject.org> + * @version $Id$ + */ +public class TestDDARequest extends FcpMessage { + + /** + * Creates a new “TestDDARequest” command that initiates a DDA test. + * + * @param directory + * The directory you want to access files in + * @param wantReadDirectory + * true if you want to read files from the + * directory + * @param wantWriteDirectory + * true if you want to write files to the + * directory + */ + public TestDDARequest(String directory, boolean wantReadDirectory, boolean wantWriteDirectory) { + super("TestDDARequest"); + setField("Directory", directory); + setField("WantReadDirectory", String.valueOf(wantReadDirectory)); + setField("WantWriteDirectory", String.valueOf(wantWriteDirectory)); + } + +} diff --git a/src/net/pterodactylus/fcp/TestDDAResponse.java b/src/net/pterodactylus/fcp/TestDDAResponse.java new file mode 100644 index 0000000..cb452f7 --- /dev/null +++ b/src/net/pterodactylus/fcp/TestDDAResponse.java @@ -0,0 +1,65 @@ +/* + * jSite2 - TestDDAResponse.java - + * Copyright © 2008 David Roden + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +package net.pterodactylus.fcp; + +/** + * A “TestDDAResponse” is sent to let the node know that either created a file + * with the content from {@link TestDDAReply#getContentToWrite()} or that you + * read the content of the file given by {@link TestDDAReply#getReadFilename()}. + * + * @author David ‘Bombe’ Roden <bombe@freenetproject.org> + * @version $Id$ + */ +public class TestDDAResponse extends FcpMessage { + + /** + * Creates a new “TestDDAResponse” message that signals that you created the + * file given by {@link TestDDAReply#getWriteFilename()} and wrote the + * contents given by {@link TestDDAReply#getContentToWrite()} to it. + * + * @param directory + * The directory from the {@link TestDDARequest} command + */ + public TestDDAResponse(String directory) { + this(directory, null); + } + + /** + * Creates a new “TestDDAResponse” message that signals that you created the + * file given by {@link TestDDAReply#getWriteFilename()} with the contents + * given by {@link TestDDAReply#getContentToWrite()} to it (when you + * specified that you want to write to the directory) and/or that you read + * the file given by {@link TestDDAReply#getReadFilename()} (when you + * specified you wanted to read the directory). + * + * @param directory + * The directory from the {@link TestDDARequest} command + * @param readContent + * The read content, or null if you did not + * request read access + */ + public TestDDAResponse(String directory, String readContent) { + super("TestDDAResponse"); + if (readContent != null) { + setField("ReadContent", readContent); + } + } + +} diff --git a/src/net/pterodactylus/fcp/URIGenerated.java b/src/net/pterodactylus/fcp/URIGenerated.java new file mode 100644 index 0000000..16e2204 --- /dev/null +++ b/src/net/pterodactylus/fcp/URIGenerated.java @@ -0,0 +1,60 @@ +/* + * jSite2 - URIGenerated.java - + * Copyright © 2008 David Roden + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +package net.pterodactylus.fcp; + +/** + * The “URIGenerated” message signals the client that an URI was generated for a + * {@link ClientPut} (or {@link ClientPutDiskDir} or {@link ClientPutComplexDir}) + * request. + * + * @author David ‘Bombe’ Roden <bombe@freenetproject.org> + * @version $Id$ + */ +public class URIGenerated extends BaseMessage { + + /** + * Creates a new “URIGenerated” message that wraps the received message. + * + * @param receivedMessage + * The received message + */ + URIGenerated(FcpMessage receivedMessage) { + super(receivedMessage); + } + + /** + * Returns the identifier of the request that generated an URI. + * + * @return The identifier of the request + */ + public String getIdentifier() { + return getField("Identifier"); + } + + /** + * Returns the URI that was generated by the request. + * + * @return The URI that was generated by the request + */ + public String getURI() { + return getField("URI"); + } + +} diff --git a/src/net/pterodactylus/fcp/UnknownNodeIdentifier.java b/src/net/pterodactylus/fcp/UnknownNodeIdentifier.java new file mode 100644 index 0000000..def420b --- /dev/null +++ b/src/net/pterodactylus/fcp/UnknownNodeIdentifier.java @@ -0,0 +1,51 @@ +/* + * jSite2 - UnknownNodeIdentifier.java - + * Copyright \u00A9 2008 David Roden + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +package net.pterodactylus.fcp; + +/** + * The “UnknownNodeIdentifier” message signals the client that the node + * identifier given in a command like {@link ListPeer} is unknown. + * + * @author David ‘Bombe’ Roden <bombe@freenetproject.org> + * @version $Id$ + */ +public class UnknownNodeIdentifier extends BaseMessage { + + /** + * Creates a new “UnknownNodeIdentifier” message that wraps the received + * message. + * + * @param receivedMessage + * The received message + */ + UnknownNodeIdentifier(FcpMessage receivedMessage) { + super(receivedMessage); + } + + /** + * Returns the unknown node identifier. + * + * @return The unknown node identifier + */ + public String getNodeIdentifier() { + return getField("NodeIdentifier"); + } + +} diff --git a/src/net/pterodactylus/fcp/UnknownPeerNoteType.java b/src/net/pterodactylus/fcp/UnknownPeerNoteType.java new file mode 100644 index 0000000..41691a5 --- /dev/null +++ b/src/net/pterodactylus/fcp/UnknownPeerNoteType.java @@ -0,0 +1,51 @@ +/* + * jSite2 - UnknownPeerNoteType.java - + * Copyright \u00A9 2008 David Roden + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +package net.pterodactylus.fcp; + +/** + * The ”UnknownPeerNoteType” message signals the client that the type of peer + * note used in a previous {@link ModifyPeerNote} is unknown. + * + * @author David ‘Bombe’ Roden <bombe@freenetproject.org> + * @version $Id$ + */ +public class UnknownPeerNoteType extends BaseMessage { + + /** + * Creates a new ”UnknownPeerNoteType” message that wraps the received + * message. + * + * @param receivedMessage + * The received message + */ + public UnknownPeerNoteType(FcpMessage receivedMessage) { + super(receivedMessage); + } + + /** + * Returns the type of peer note that is unkown. + * + * @return The unknown peer note type + */ + public int getPeerNoteType() { + return FcpUtils.safeParseInt(getField("PeerNoteType")); + } + +} diff --git a/src/net/pterodactylus/fcp/UploadFrom.java b/src/net/pterodactylus/fcp/UploadFrom.java new file mode 100644 index 0000000..872ecb3 --- /dev/null +++ b/src/net/pterodactylus/fcp/UploadFrom.java @@ -0,0 +1,40 @@ +/* + * jSite2 - UploadFrom.java - + * Copyright © 2008 David Roden + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +package net.pterodactylus.fcp; + +/** + * Enumeration for the different values for the “UploadFrom” field in + * {@link ClientPut} and {@link ClientGet} requests. + * + * @author David ‘Bombe’ Roden <bombe@freenetproject.org> + * @version $Id$ + */ +public enum UploadFrom { + + /** Request data follows the request. */ + direct, + + /** Request data is written to or read from disk. */ + disk, + + /** Request data is just a redirect. */ + redirect; + +} diff --git a/src/net/pterodactylus/fcp/Verbosity.java b/src/net/pterodactylus/fcp/Verbosity.java new file mode 100644 index 0000000..393e7f5 --- /dev/null +++ b/src/net/pterodactylus/fcp/Verbosity.java @@ -0,0 +1,107 @@ +/* + * jSite2 - Verbosity.java - + * Copyright © 2008 David Roden + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +package net.pterodactylus.fcp; + +/** + * Convenicence class for verbosity handling. This might come in handy with the + * {@link ClientPut} and {@link ClientGet} requests. The verbosity is a bit-mask + * that can be composed of several bits. {@link #PROGRESS} and + * {@link #COMPRESSION} are single bits in that mask and can be combined into a + * new verbosity using {@link #add(Verbosity)}. + * + * @author David ‘Bombe’ Roden <bombe@freenetproject.org> + * @version $Id$ + */ +public class Verbosity { + + /** Constant for no verbosity at all. */ + public static final Verbosity NONE = new Verbosity(0); + + /** Constant for progress message verbosity. */ + public static final Verbosity PROGRESS = new Verbosity(1); + + /** Constant for compression message verbosity. */ + public static final Verbosity COMPRESSION = new Verbosity(512); + + /** Constant for all events. */ + public static final Verbosity ALL = new Verbosity(-1); + + /** The verbosity level. */ + private final int level; + + /** + * Creates a new verbosity with the given level. + * + * @param level + * The verbosity level + */ + private Verbosity(int level) { + this.level = level; + } + + /** + * Adds the given verbosity to this verbosity and returns a verbosity with + * the new value. The value of this verbosity is not changed. + * + * @param verbosity + * The verbosity to add to this verbosity + * @return The verbosity with the new level. + */ + public Verbosity add(Verbosity verbosity) { + return new Verbosity(level | verbosity.level); + } + + /** + * Checks whether this Verbosity contains all bits of the given Verbosity. + * + * @param verbosity + * The verbosity to check for in this Verbosity + * @return true if and only if all set bits in the given + * Verbosity are also set in this Verbosity + */ + public boolean contains(Verbosity verbosity) { + return (level & verbosity.level) == verbosity.level; + } + + /** + * @see java.lang.Object#toString() + */ + @Override + public String toString() { + return String.valueOf(level); + } + + /** + * Parses the given string and creates a Verbosity with the given level. + * + * @param s + * The string to parse + * @return The parsed verbosity, or {@link #NONE} if the string could not be + * parsed + */ + public static Verbosity valueOf(String s) { + try { + return new Verbosity(Integer.valueOf(s)); + } catch (NumberFormatException nfe1) { + return NONE; + } + } + +} diff --git a/src/net/pterodactylus/fcp/Version.java b/src/net/pterodactylus/fcp/Version.java new file mode 100644 index 0000000..1ce7c1b --- /dev/null +++ b/src/net/pterodactylus/fcp/Version.java @@ -0,0 +1,137 @@ +/* + * jSite2 - Version.java - + * Copyright © 2008 David Roden + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +package net.pterodactylus.fcp; + +import java.util.StringTokenizer; + +/** + * Container for the “lastGoodVersion” field. + * + * @author David ‘Bombe’ Roden <bombe@freenetproject.org> + * @version $Id$ + */ +public class Version { + + /** The name of the node implementation. */ + private final String nodeName; + + /** The tree version of the node. */ + private final String treeVersion; + + /** The protocol version of the node. */ + private final String protocolVersion; + + /** The build number of the node. */ + private final int buildNumber; + + /** + * Creates a new Version from the given string. The string consists of the + * four required fields node name, tree version, protocol version, and build + * number, separated by a comma. + * + * @param version + * The version string + * @throws NullPointerException + * if version is null + * @throws IllegalArgumentException + * if version is not in the right format + */ + public Version(String version) { + if (version == null) { + throw new NullPointerException("version must not be null"); + } + StringTokenizer versionTokens = new StringTokenizer(version, ","); + if (versionTokens.countTokens() != 4) { + throw new IllegalArgumentException("version must consist of four fields"); + } + this.nodeName = versionTokens.nextToken(); + this.treeVersion = versionTokens.nextToken(); + this.protocolVersion = versionTokens.nextToken(); + try { + this.buildNumber = Integer.valueOf(versionTokens.nextToken()); + } catch (NumberFormatException nfe1) { + throw new IllegalArgumentException("last part of version must be numeric", nfe1); + } + } + + /** + * Creates a new Version from the given parts. + * + * @param nodeName + * The name of the node implementation + * @param treeVersion + * The tree version + * @param protocolVersion + * The protocol version + * @param buildNumber + * The build number of the node + */ + public Version(String nodeName, String treeVersion, String protocolVersion, int buildNumber) { + this.nodeName = nodeName; + this.treeVersion = treeVersion; + this.protocolVersion = protocolVersion; + this.buildNumber = buildNumber; + } + + /** + * Returns the name of the node implementation. + * + * @return The node name + */ + public String getNodeName() { + return nodeName; + } + + /** + * The tree version of the node. + * + * @return The tree version of the node + */ + public String getTreeVersion() { + return treeVersion; + } + + /** + * The protocol version of the node + * + * @return The protocol version of the node + */ + public String getProtocolVersion() { + return protocolVersion; + } + + /** + * The build number of the node. + * + * @return The build number of the node + */ + public int getBuildNumber() { + return buildNumber; + } + + /** + * @see java.lang.Object#toString() + */ + @Override + public String toString() { + return nodeName + "," + treeVersion + "," + protocolVersion + "," + buildNumber; + } + +} \ No newline at end of file diff --git a/src/net/pterodactylus/fcp/WatchGlobal.java b/src/net/pterodactylus/fcp/WatchGlobal.java new file mode 100644 index 0000000..e78ad0e --- /dev/null +++ b/src/net/pterodactylus/fcp/WatchGlobal.java @@ -0,0 +1,60 @@ +/* + * jSite2 - WatchGlobal.java - + * Copyright © 2008 David Roden + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +package net.pterodactylus.fcp; + +/** + * The “WatchGlobal” messages enables clients to watch the global queue in + * addition to the client-local queue. + * + * @author David ‘Bombe’ Roden <bombe@freenetproject.org> + * @version $Id$ + */ +public class WatchGlobal extends FcpMessage { + + /** + * Enables or disables watching the global queue. + * + * @param enabled + * true to watch the global queue and the + * client-local queue, false to watch only the + * client-local queue + */ + public WatchGlobal(boolean enabled) { + this(enabled, Verbosity.ALL); + } + + /** + * Enables or disables watching the global queue, optionally masking out + * certain events. + * + * @param enabled + * true to watch the global queue and the + * client-local queue, false to watch only the + * client-local queue + * @param verbosityMask + * A verbosity mask that determines which events are received + */ + public WatchGlobal(boolean enabled, Verbosity verbosityMask) { + super("WatchGlobal"); + setField("Enabled", String.valueOf(enabled)); + setField("VerbosityMask", String.valueOf(verbosityMask)); + } + +} diff --git a/src/net/pterodactylus/fcp/package-info.java b/src/net/pterodactylus/fcp/package-info.java new file mode 100644 index 0000000..dbda870 --- /dev/null +++ b/src/net/pterodactylus/fcp/package-info.java @@ -0,0 +1,36 @@ +/** + * Package that holds all the message types that are used in the communication + * with a Freenet Node. + * + *

Usage

+ * + * This library was designed to implement the full range of the Freenet Client + * Protocol, Version 2.0. At the moment the library provides a rather low-level + * approach, wrapping each FCP message into its own object but some kind of + * high-level client that does not require any interfaces to be implemented + * will probably provided as well. + * + * First, create a connection to the node: + * + *
+ * FcpConnection fcpConnection = new FcpConnection();
+ * 
+ * + * Now implement the {@link net.pterodactylus.fcp.FcpListener} interface + * and handle all incoming events. + * + *
+ * public class MyClass implements FcpListener {
+ * 
+ * 	public void receivedProtocolError(FcpConnection fcpConnection, ProtocolError protocolError) {
+ * 		…
+ * 	}
+ * 
+ * 	// implement all further methods here
+ * 
+ * }
+ * 
+ */ + +package net.pterodactylus.fcp; +